From a6d829e86fb228be6a8ed8f19b2276e07d5a89e2 Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Wed, 13 Nov 2024 03:39:58 -0500
Subject: [PATCH 01/44] Fix error in CLI EmailDomainBlocks when supplying
 `--with-dns-records` (#32863)

---
 lib/mastodon/cli/email_domain_blocks.rb          |  2 +-
 .../lib/mastodon/cli/email_domain_blocks_spec.rb | 16 ++++++++++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/lib/mastodon/cli/email_domain_blocks.rb b/lib/mastodon/cli/email_domain_blocks.rb
index 7b2da8ef9f..a830ca3661 100644
--- a/lib/mastodon/cli/email_domain_blocks.rb
+++ b/lib/mastodon/cli/email_domain_blocks.rb
@@ -48,7 +48,7 @@ module Mastodon::CLI
         if options[:with_dns_records]
           Resolv::DNS.open do |dns|
             dns.timeouts = 5
-            other_domains = dns.getresources(@email_domain_block.domain, Resolv::DNS::Resource::IN::MX).to_a
+            other_domains = dns.getresources(domain, Resolv::DNS::Resource::IN::MX).to_a.map { |e| e.exchange.to_s }.compact_blank
           end
         end
 
diff --git a/spec/lib/mastodon/cli/email_domain_blocks_spec.rb b/spec/lib/mastodon/cli/email_domain_blocks_spec.rb
index a5fbd23e65..6ce1a7c5f3 100644
--- a/spec/lib/mastodon/cli/email_domain_blocks_spec.rb
+++ b/spec/lib/mastodon/cli/email_domain_blocks_spec.rb
@@ -63,6 +63,22 @@ RSpec.describe Mastodon::CLI::EmailDomainBlocks do
           .and(change(EmailDomainBlock, :count).by(1))
       end
     end
+
+    context 'with --with-dns-records true' do
+      let(:domain) { 'host.example' }
+      let(:arguments) { [domain] }
+      let(:options) { { with_dns_records: true } }
+
+      before do
+        configure_mx(domain: domain, exchange: 'other.host')
+      end
+
+      it 'adds a new block for parent and children' do
+        expect { subject }
+          .to output_results('Added 2')
+          .and(change(EmailDomainBlock, :count).by(2))
+      end
+    end
   end
 
   describe '#remove' do

From baad7953849307fa4a6bcdd878b9b2207226352d Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
 <41898282+github-actions[bot]@users.noreply.github.com>
Date: Wed, 13 Nov 2024 10:33:02 +0100
Subject: [PATCH 02/44] New Crowdin Translations (automated) (#32868)

Co-authored-by: GitHub Actions <noreply@github.com>
---
 app/javascript/mastodon/locales/ca.json    |  1 +
 app/javascript/mastodon/locales/da.json    |  1 +
 app/javascript/mastodon/locales/de.json    |  1 +
 app/javascript/mastodon/locales/eo.json    | 11 ++--
 app/javascript/mastodon/locales/es-AR.json |  1 +
 app/javascript/mastodon/locales/es-MX.json |  5 +-
 app/javascript/mastodon/locales/es.json    |  1 +
 app/javascript/mastodon/locales/fi.json    | 13 +++++
 app/javascript/mastodon/locales/fo.json    |  1 +
 app/javascript/mastodon/locales/gl.json    |  8 +++
 app/javascript/mastodon/locales/hu.json    |  1 +
 app/javascript/mastodon/locales/is.json    |  1 +
 app/javascript/mastodon/locales/ko.json    |  1 +
 app/javascript/mastodon/locales/nl.json    |  1 +
 app/javascript/mastodon/locales/nn.json    | 22 +++++++
 app/javascript/mastodon/locales/pt-BR.json |  1 +
 app/javascript/mastodon/locales/ru.json    |  4 ++
 app/javascript/mastodon/locales/sq.json    |  1 +
 app/javascript/mastodon/locales/sv.json    |  1 +
 app/javascript/mastodon/locales/tr.json    |  1 +
 app/javascript/mastodon/locales/uk.json    |  1 +
 app/javascript/mastodon/locales/vi.json    |  1 +
 app/javascript/mastodon/locales/zh-CN.json |  1 +
 app/javascript/mastodon/locales/zh-TW.json |  1 +
 config/locales/ca.yml                      |  8 +++
 config/locales/da.yml                      |  8 +++
 config/locales/de.yml                      |  8 +++
 config/locales/fi.yml                      | 10 +++-
 config/locales/fo.yml                      |  8 +++
 config/locales/gl.yml                      |  8 +++
 config/locales/hu.yml                      |  8 +++
 config/locales/is.yml                      |  8 +++
 config/locales/ko.yml                      |  8 +++
 config/locales/lt.yml                      |  8 +++
 config/locales/nn.yml                      | 11 ++++
 config/locales/pt-BR.yml                   | 16 ++++-
 config/locales/ru.yml                      | 68 ++++++++++++----------
 config/locales/simple_form.ko.yml          |  2 +-
 config/locales/simple_form.lt.yml          |  1 +
 config/locales/simple_form.nl.yml          |  2 +-
 config/locales/simple_form.nn.yml          |  1 +
 config/locales/simple_form.pl.yml          |  1 +
 config/locales/simple_form.ru.yml          |  1 +
 config/locales/simple_form.sv.yml          |  1 +
 config/locales/sq.yml                      |  8 +++
 config/locales/sv.yml                      | 16 +++--
 config/locales/tr.yml                      |  8 +++
 config/locales/vi.yml                      |  8 +++
 config/locales/zh-CN.yml                   |  8 +++
 config/locales/zh-TW.yml                   | 10 +++-
 50 files changed, 278 insertions(+), 47 deletions(-)

diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json
index 160a74af4f..53bfc4474c 100644
--- a/app/javascript/mastodon/locales/ca.json
+++ b/app/javascript/mastodon/locales/ca.json
@@ -97,6 +97,7 @@
   "annual_report.summary.highlighted_post.possessive": "de {name}",
   "annual_report.summary.most_used_app.most_used_app": "l'aplicació més utilitzada",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "l'etiqueta més utilitzada",
+  "annual_report.summary.most_used_hashtag.none": "Cap",
   "annual_report.summary.new_posts.new_posts": "publicacions noves",
   "annual_report.summary.thanks": "Gràcies per formar part de Mastodon!",
   "attachments_list.unprocessed": "(sense processar)",
diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json
index 927d0a7cb8..4ba1f4d9e1 100644
--- a/app/javascript/mastodon/locales/da.json
+++ b/app/javascript/mastodon/locales/da.json
@@ -101,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "{name}s",
   "annual_report.summary.most_used_app.most_used_app": "mest benyttede app",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "mest benyttede hashtag",
+  "annual_report.summary.most_used_hashtag.none": "Intet",
   "annual_report.summary.new_posts.new_posts": "nye indlæg",
   "annual_report.summary.percentile.text": "<topLabel>Det betyder, at man er i top</topLabel><percentage></percentage><bottomLabel>af Mastodon-brugere.</bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "Vi fortæller det ikke til Bernie.",
diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json
index e7679a363c..bd24ccd48f 100644
--- a/app/javascript/mastodon/locales/de.json
+++ b/app/javascript/mastodon/locales/de.json
@@ -101,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "{name}",
   "annual_report.summary.most_used_app.most_used_app": "am häufigsten verwendete App",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "am häufigsten verwendeter Hashtag",
+  "annual_report.summary.most_used_hashtag.none": "Kein",
   "annual_report.summary.new_posts.new_posts": "neue Beiträge",
   "annual_report.summary.percentile.text": "<topLabel>Damit gehörst du zu den obersten</topLabel><percentage></percentage><bottomLabel>der Mastodon-Nutzer*innen.</bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "Wir werden Bernie nichts verraten.",
diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json
index 757bb39866..731e11f27a 100644
--- a/app/javascript/mastodon/locales/eo.json
+++ b/app/javascript/mastodon/locales/eo.json
@@ -90,6 +90,7 @@
   "annual_report.summary.archetype.replier": "La plej societema",
   "annual_report.summary.followers.followers": "sekvantoj",
   "annual_report.summary.highlighted_post.by_replies": "afiŝo kun la plej multaj respondoj",
+  "annual_report.summary.most_used_hashtag.none": "Nenio",
   "annual_report.summary.new_posts.new_posts": "novaj afiŝoj",
   "annual_report.summary.thanks": "Dankon pro esti parto de Mastodon!",
   "attachments_list.unprocessed": "(neprilaborita)",
@@ -219,7 +220,7 @@
   "dismissable_banner.community_timeline": "Jen la plej novaj publikaj afiŝoj de uzantoj, kies kontojn gastigas {domain}.",
   "dismissable_banner.dismiss": "Eksigi",
   "dismissable_banner.explore_links": "Tiuj novaĵoj estas aktuale priparolataj de uzantoj en tiu ĉi kaj aliaj serviloj, sur la malcentrigita reto.",
-  "dismissable_banner.explore_statuses": "Ĉi tiuj estas afiŝoj de la tuta socia reto, kiuj populariĝas hodiaŭ. Pli novaj afiŝoj kun pli da diskonigoj kaj plej ŝatataj estas rangigitaj pli alte.",
+  "dismissable_banner.explore_statuses": "Jen afiŝoj en la socia reto kiuj populariĝis hodiaŭ. Novaj afiŝoj kun pli da diskonigoj kaj stelumoj aperas pli alte.",
   "dismissable_banner.explore_tags": "Ĉi tiuj kradvostoj populariĝas en ĉi tiu kaj aliaj serviloj en la malcentraliza reto nun.",
   "dismissable_banner.public_timeline": "Ĉi tiuj estas la plej lastatempaj publikaj afiŝoj de homoj en la socia reto, kiujn homoj sur {domain} sekvas.",
   "domain_block_modal.block": "Bloki servilon",
@@ -646,7 +647,7 @@
   "onboarding.start.lead": "Vi nun estas parto de Mastodon, unika, malcentralizita socia amaskomunikilara platformo, kie vi—ne algoritmo—zorgas vian propran sperton. Ni komencu vin sur ĉi tiu nova socia limo:",
   "onboarding.start.skip": "Ĉu vi ne bezonas helpon por komenci?",
   "onboarding.start.title": "Vi atingas ĝin!",
-  "onboarding.steps.follow_people.body": "Sekvi interesajn homojn estas pri kio Mastodonto temas.",
+  "onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.",
   "onboarding.steps.follow_people.title": "Agordu vian hejman fluon",
   "onboarding.steps.publish_status.body": "Salutu la mondon per teksto, fotoj, filmetoj aŭ balotenketoj {emoji}",
   "onboarding.steps.publish_status.title": "Fari vian unuan afiŝon",
@@ -780,9 +781,9 @@
   "server_banner.is_one_of_many": "{domain} estas unu el la multaj sendependaj Mastodon-serviloj, kiujn vi povas uzi por partopreni en la fediverso.",
   "server_banner.server_stats": "Statistikoj de la servilo:",
   "sign_in_banner.create_account": "Krei konton",
-  "sign_in_banner.follow_anyone": "Sekvi iun ajn tra la fediverso kaj vidi ĉion en kronologia ordo. Neniuj algoritmoj, reklamoj aŭ klakbetoj videblas.",
-  "sign_in_banner.mastodon_is": "Mastodonto estas la plej bona maniero por resti flank-al-flanke kun kio okazas.",
-  "sign_in_banner.sign_in": "Saluti",
+  "sign_in_banner.follow_anyone": "Sekvu iun ajn tra la fediverso kaj vidu ĉion laŭ templinio. Nul algoritmo, reklamo aŭ kliklogilo ĉeestas.",
+  "sign_in_banner.mastodon_is": "Mastodon estas la plej bona maniero resti ĝisdata pri aktualaĵoj.",
+  "sign_in_banner.sign_in": "Ensaluti",
   "sign_in_banner.sso_redirect": "Ensalutu aŭ Registriĝi",
   "status.admin_account": "Malfermi fasadon de moderigado por @{name}",
   "status.admin_domain": "Malfermu moderigan interfacon por {domain}",
diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json
index 9dc7b0d6c0..406c526983 100644
--- a/app/javascript/mastodon/locales/es-AR.json
+++ b/app/javascript/mastodon/locales/es-AR.json
@@ -101,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "{name}",
   "annual_report.summary.most_used_app.most_used_app": "la aplicación más usada",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "la etiqueta más usada",
+  "annual_report.summary.most_used_hashtag.none": "Ninguna",
   "annual_report.summary.new_posts.new_posts": "nuevos mensajes",
   "annual_report.summary.percentile.text": "<topLabel>Eso te pone en la cima</topLabel><percentage></percentage><bottomLabel>de los usuarios de Mastodon.</bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "No se lo diremos a Bernie.",
diff --git a/app/javascript/mastodon/locales/es-MX.json b/app/javascript/mastodon/locales/es-MX.json
index 4faa35e5c8..63dc31c6df 100644
--- a/app/javascript/mastodon/locales/es-MX.json
+++ b/app/javascript/mastodon/locales/es-MX.json
@@ -89,9 +89,9 @@
   "announcement.announcement": "Anuncio",
   "annual_report.summary.archetype.booster": "El cazador de tendencias",
   "annual_report.summary.archetype.lurker": "El acechador",
-  "annual_report.summary.archetype.oracle": "El oráculo",
+  "annual_report.summary.archetype.oracle": "El oraculo",
   "annual_report.summary.archetype.pollster": "El encuestador",
-  "annual_report.summary.archetype.replier": "El más sociable",
+  "annual_report.summary.archetype.replier": "La mariposa sociable",
   "annual_report.summary.followers.followers": "seguidores",
   "annual_report.summary.followers.total": "{count} en total",
   "annual_report.summary.here_it_is": "Aquí está tu resumen de {year}:",
@@ -101,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "de {name}",
   "annual_report.summary.most_used_app.most_used_app": "aplicación más usada",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "etiqueta más usada",
+  "annual_report.summary.most_used_hashtag.none": "Ninguna",
   "annual_report.summary.new_posts.new_posts": "nuevas publicaciones",
   "annual_report.summary.percentile.text": "<topLabel>Eso te pone en el top</topLabel><percentage></percentage><bottomLabel>de usuarios de Mastodon.</bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "No se lo diremos a Bernie.",
diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json
index d14b718016..258b19f411 100644
--- a/app/javascript/mastodon/locales/es.json
+++ b/app/javascript/mastodon/locales/es.json
@@ -101,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "de {name}",
   "annual_report.summary.most_used_app.most_used_app": "aplicación más usada",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "etiqueta más usada",
+  "annual_report.summary.most_used_hashtag.none": "Ninguna",
   "annual_report.summary.new_posts.new_posts": "nuevas publicaciones",
   "annual_report.summary.percentile.text": "<topLabel>Eso te pone en el top</topLabel><percentage></percentage><bottomLabel>de usuarios de Mastodon.</bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "No se lo diremos a Bernie.",
diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json
index 32069b1a03..2763c39168 100644
--- a/app/javascript/mastodon/locales/fi.json
+++ b/app/javascript/mastodon/locales/fi.json
@@ -87,10 +87,22 @@
   "alert.unexpected.title": "Hups!",
   "alt_text_badge.title": "Vaihtoehtoinen teksti",
   "announcement.announcement": "Tiedote",
+  "annual_report.summary.archetype.booster": "Tehostaja",
+  "annual_report.summary.archetype.lurker": "Lymyilijä",
+  "annual_report.summary.archetype.oracle": "Oraakkeli",
+  "annual_report.summary.archetype.pollster": "Mielipidetutkija",
   "annual_report.summary.archetype.replier": "Sosiaalinen perhonen",
+  "annual_report.summary.followers.followers": "seuraajaa",
+  "annual_report.summary.followers.total": "{count} yhteensä",
+  "annual_report.summary.here_it_is": "Tässä on katsaus vuoteesi {year}:",
+  "annual_report.summary.highlighted_post.by_favourites": "suosikkeihin lisätyin julkaisu",
   "annual_report.summary.highlighted_post.by_reblogs": "tehostetuin julkaisu",
+  "annual_report.summary.highlighted_post.by_replies": "julkaisu, jolla on eniten vastauksia",
+  "annual_report.summary.highlighted_post.possessive": "Käyttäjän {name}",
   "annual_report.summary.most_used_app.most_used_app": "käytetyin sovellus",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "käytetyin aihetunniste",
+  "annual_report.summary.new_posts.new_posts": "uutta julkaisua",
+  "annual_report.summary.percentile.text": "<topLabel>Olet osa huippujoukkoa, johon kuuluu</topLabel><percentage></percentage><bottomLabel>Mastodon-käyttäjistä.</bottomLabel>",
   "annual_report.summary.thanks": "Kiitos, että olet osa Mastodonia!",
   "attachments_list.unprocessed": "(käsittelemätön)",
   "audio.hide": "Piilota ääni",
@@ -513,6 +525,7 @@
   "notification.admin.report_statuses_other": "{name} raportoi käyttäjän {target}",
   "notification.admin.sign_up": "{name} rekisteröityi",
   "notification.admin.sign_up.name_and_others": "{name} ja {count, plural, one {# muu} other {# muuta}} rekisteröityivät",
+  "notification.annual_report.message": "Vuoden {year} #Wrapstodon odottaa! Paljasta vuotesi kohokohdat ikimuistoiset hetket Mastodonissa!",
   "notification.annual_report.view": "Näytä #Wrapstodon",
   "notification.favourite": "{name} lisäsi julkaisusi suosikkeihinsa",
   "notification.favourite.name_and_others_with_link": "{name} ja <a>{count, plural, one {# muu} other {# muuta}}</a> lisäsivät julkaisusi suosikkeihinsa",
diff --git a/app/javascript/mastodon/locales/fo.json b/app/javascript/mastodon/locales/fo.json
index 6b26ed84fd..789efaa40e 100644
--- a/app/javascript/mastodon/locales/fo.json
+++ b/app/javascript/mastodon/locales/fo.json
@@ -101,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "hjá {name}",
   "annual_report.summary.most_used_app.most_used_app": "mest brúkta app",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "mest brúkta frámerki",
+  "annual_report.summary.most_used_hashtag.none": "Einki",
   "annual_report.summary.new_posts.new_posts": "nýggir postar",
   "annual_report.summary.percentile.text": "<topLabel>Tað fær teg í topp</topLabel><percentage></percentage><bottomLabel>av Mastodon brúkarum.</bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "Vit fara ikki at fortelja Bernie tað.",
diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json
index 23f444715b..c69a431f4b 100644
--- a/app/javascript/mastodon/locales/gl.json
+++ b/app/javascript/mastodon/locales/gl.json
@@ -87,6 +87,11 @@
   "alert.unexpected.title": "Vaites!",
   "alt_text_badge.title": "Texto Alt",
   "announcement.announcement": "Anuncio",
+  "annual_report.summary.archetype.booster": "A axencia de noticias",
+  "annual_report.summary.archetype.lurker": "Volleur",
+  "annual_report.summary.archetype.oracle": "Sabichón/e",
+  "annual_report.summary.archetype.pollster": "O INE",
+  "annual_report.summary.archetype.replier": "Lareteire",
   "annual_report.summary.followers.followers": "seguidoras",
   "annual_report.summary.followers.total": "{count} en total",
   "annual_report.summary.here_it_is": "Este é o resumo do teu {year}:",
@@ -96,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "de {name}",
   "annual_report.summary.most_used_app.most_used_app": "app que mais usaches",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "o cancelo mais utilizado",
+  "annual_report.summary.most_used_hashtag.none": "Nada",
   "annual_report.summary.new_posts.new_posts": "novas publicacións",
   "annual_report.summary.percentile.text": "<topLabel>Sitúante no top</topLabel><percentage></percentage><bottomLabel> das usuarias de Mastodon.</bottomLabel>",
   "annual_report.summary.thanks": "Grazas por ser parte de Mastodon!",
@@ -520,6 +526,8 @@
   "notification.admin.report_statuses_other": "{name} denunciou a {target}",
   "notification.admin.sign_up": "{name} rexistrouse",
   "notification.admin.sign_up.name_and_others": "{name} e {count, plural, one {# máis} other {# máis}} crearon unha conta",
+  "notification.annual_report.message": "A #VidaEnMastodon de {year} agarda por ti! Desvela os momentos máis destacados e historias reseñables en Mastodon!",
+  "notification.annual_report.view": "Ver #VidaEnMastodon",
   "notification.favourite": "{name} marcou como favorita a túa publicación",
   "notification.favourite.name_and_others_with_link": "{name} e <a>{count, plural, one {# máis} other {# máis}}</a> favoreceron a túa publicación",
   "notification.follow": "{name} comezou a seguirte",
diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json
index cdc113d8d7..2ba7aef34b 100644
--- a/app/javascript/mastodon/locales/hu.json
+++ b/app/javascript/mastodon/locales/hu.json
@@ -101,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "{name} fióktól",
   "annual_report.summary.most_used_app.most_used_app": "legtöbbet használt app",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "legtöbbet használt hashtag",
+  "annual_report.summary.most_used_hashtag.none": "Nincs",
   "annual_report.summary.new_posts.new_posts": "új bejegyzés",
   "annual_report.summary.percentile.text": "<topLabel>Ezzel a</topLabel><percentage></percentage><bottomLabel>csúcs Mastodon felhasználó között vagy.</bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "Nem mondjuk el Bernie-nek.",
diff --git a/app/javascript/mastodon/locales/is.json b/app/javascript/mastodon/locales/is.json
index adc86faf40..ecfc642969 100644
--- a/app/javascript/mastodon/locales/is.json
+++ b/app/javascript/mastodon/locales/is.json
@@ -101,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "{name}",
   "annual_report.summary.most_used_app.most_used_app": "mest notaða forrit",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "mest notaða myllumerki",
+  "annual_report.summary.most_used_hashtag.none": "Ekkert",
   "annual_report.summary.new_posts.new_posts": "nýjar færslur",
   "annual_report.summary.percentile.text": "<topLabel>Það setur þig á meðal efstu</topLabel><percentage></percentage><bottomLabel>notenda Mastodon.</bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "Við förum ekkert að raupa um þetta.",
diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json
index b5c8d4bd21..43f1e59e5e 100644
--- a/app/javascript/mastodon/locales/ko.json
+++ b/app/javascript/mastodon/locales/ko.json
@@ -101,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "{name} 님의",
   "annual_report.summary.most_used_app.most_used_app": "가장 많이 사용한 앱",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "가장 많이 사용한 해시태그",
+  "annual_report.summary.most_used_hashtag.none": "없음",
   "annual_report.summary.new_posts.new_posts": "새 게시물",
   "annual_report.summary.percentile.text": "<topLabel>마스토돈 사용자의 상위</topLabel><percentage></percentage><bottomLabel>입니다.</bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "엄마한테 말 안 할게요.",
diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json
index b66fcf09c0..eb21d2ad1d 100644
--- a/app/javascript/mastodon/locales/nl.json
+++ b/app/javascript/mastodon/locales/nl.json
@@ -101,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "{name}'s",
   "annual_report.summary.most_used_app.most_used_app": "meest gebruikte app",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "meest gebruikte hashtag",
+  "annual_report.summary.most_used_hashtag.none": "Geen",
   "annual_report.summary.new_posts.new_posts": "nieuwe berichten",
   "annual_report.summary.percentile.text": "<topLabel>Dat zet je in de top</topLabel><percentage></percentage><bottomLabel>van Mastodon-gebruikers.</bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "We zullen Bernie niets vertellen.",
diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json
index cc56754193..b45ff90585 100644
--- a/app/javascript/mastodon/locales/nn.json
+++ b/app/javascript/mastodon/locales/nn.json
@@ -87,6 +87,24 @@
   "alert.unexpected.title": "Oi sann!",
   "alt_text_badge.title": "Alternativ tekst",
   "announcement.announcement": "Kunngjering",
+  "annual_report.summary.archetype.booster": "Den som jaktar på noko kult",
+  "annual_report.summary.archetype.lurker": "Den som heng på hjørnet",
+  "annual_report.summary.archetype.oracle": "Orakelet",
+  "annual_report.summary.archetype.pollster": "Meiningsmålaren",
+  "annual_report.summary.archetype.replier": "Den sosiale sumarfuglen",
+  "annual_report.summary.followers.followers": "fylgjarar",
+  "annual_report.summary.followers.total": "{count} i alt",
+  "annual_report.summary.here_it_is": "Her er eit gjensyn med {year}:",
+  "annual_report.summary.highlighted_post.by_favourites": "det mest omtykte innlegget",
+  "annual_report.summary.highlighted_post.by_reblogs": "det mest framheva innlegget",
+  "annual_report.summary.highlighted_post.by_replies": "innlegget med flest svar",
+  "annual_report.summary.highlighted_post.possessive": "som {name} laga",
+  "annual_report.summary.most_used_app.most_used_app": "mest brukte app",
+  "annual_report.summary.most_used_hashtag.most_used_hashtag": "mest brukte emneknagg",
+  "annual_report.summary.new_posts.new_posts": "nye innlegg",
+  "annual_report.summary.percentile.text": "<topLabel>Du er av dei</topLabel><percentage></percentage><bottomLabel>ivrigaste Mastodon-brukarane.</bottomLabel>",
+  "annual_report.summary.percentile.we_wont_tell_bernie": "Ikkje eit ord til pressa.",
+  "annual_report.summary.thanks": "Takk for at du er med i Mastodon!",
   "attachments_list.unprocessed": "(ubehandla)",
   "audio.hide": "Gøym lyd",
   "block_modal.remote_users_caveat": "Me vil be tenaren {domain} om å respektere di avgjerd. Me kan ikkje garantera at det vert gjort, sidan nokre tenarar kan handtera blokkering ulikt. Offentlege innlegg kan framleis vera synlege for ikkje-innlogga brukarar.",
@@ -197,6 +215,7 @@
   "confirmations.unfollow.title": "Slutt å fylgja brukaren?",
   "content_warning.hide": "Gøym innlegg",
   "content_warning.show": "Vis likevel",
+  "content_warning.show_more": "Vis meir",
   "conversation.delete": "Slett samtale",
   "conversation.mark_as_read": "Marker som lesen",
   "conversation.open": "Sjå samtale",
@@ -305,6 +324,7 @@
   "filter_modal.select_filter.subtitle": "Bruk ein eksisterande kategori eller opprett ein ny",
   "filter_modal.select_filter.title": "Filtrer dette innlegget",
   "filter_modal.title.status": "Filtrer eit innlegg",
+  "filter_warning.matches_filter": "Passar med filteret «<span>{title}</span>»",
   "filtered_notifications_banner.pending_requests": "Frå {count, plural, =0 {ingen} one {éin person} other {# personar}} du kanskje kjenner",
   "filtered_notifications_banner.title": "Filtrerte varslingar",
   "firehose.all": "Alle",
@@ -506,6 +526,8 @@
   "notification.admin.report_statuses_other": "{name} rapporterte {target}",
   "notification.admin.sign_up": "{name} er registrert",
   "notification.admin.sign_up.name_and_others": "{name} og {count, plural, one {# annan} other {# andre}} vart med",
+  "notification.annual_report.message": "#Året ditt for {year} ventar! Sjå kva som skjedde i løpet av Mastodon-året ditt!",
+  "notification.annual_report.view": "Sjå #Året ditt",
   "notification.favourite": "{name} markerte innlegget ditt som favoritt",
   "notification.favourite.name_and_others_with_link": "{name} og <a>{count, plural, one {# annan} other {# andre}}</a> favorittmerka innlegget ditt",
   "notification.follow": "{name} fylgde deg",
diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json
index 5e69741f20..e2fbaff02b 100644
--- a/app/javascript/mastodon/locales/pt-BR.json
+++ b/app/javascript/mastodon/locales/pt-BR.json
@@ -101,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "{name}",
   "annual_report.summary.most_used_app.most_used_app": "aplicativo mais usado",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "hashtag mais usada",
+  "annual_report.summary.most_used_hashtag.none": "Nenhuma",
   "annual_report.summary.new_posts.new_posts": "novas publicações",
   "annual_report.summary.percentile.text": "<topLabel>Isso o coloca no topo</topLabel></percentage><bottomLabel>dos usuários de Mastodon.</bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "Não contaremos à Bernie.",
diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json
index f5617550e1..e336e39e01 100644
--- a/app/javascript/mastodon/locales/ru.json
+++ b/app/javascript/mastodon/locales/ru.json
@@ -89,9 +89,11 @@
   "announcement.announcement": "Объявление",
   "annual_report.summary.archetype.booster": "Репостер",
   "annual_report.summary.archetype.lurker": "Молчун",
+  "annual_report.summary.archetype.oracle": "Шаман",
   "annual_report.summary.archetype.pollster": "Опросчик",
   "annual_report.summary.archetype.replier": "Душа компании",
   "annual_report.summary.followers.followers": "подписчиков",
+  "annual_report.summary.followers.total": "{count} за всё время",
   "annual_report.summary.here_it_is": "Вот ваши итоги {year} года:",
   "annual_report.summary.highlighted_post.by_favourites": "пост с наибольшим количеством звёздочек",
   "annual_report.summary.highlighted_post.by_reblogs": "пост с наибольшим количеством продвижений",
@@ -99,7 +101,9 @@
   "annual_report.summary.highlighted_post.possessive": "{name}",
   "annual_report.summary.most_used_app.most_used_app": "наиболее часто используемое приложение",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "наиболее часто используемый хэштег",
+  "annual_report.summary.most_used_hashtag.none": "Нет",
   "annual_report.summary.new_posts.new_posts": "новых постов",
+  "annual_report.summary.percentile.text": "<topLabel>Всё это помещает вас в топ</topLabel><percentage></percentage><bottomLabel>пользователей Mastodon.</bottomLabel>",
   "annual_report.summary.thanks": "Спасибо за то, что были вместе с Mastodon!",
   "attachments_list.unprocessed": "(не обработан)",
   "audio.hide": "Скрыть аудио",
diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json
index 0faee304c6..d1d92c69f6 100644
--- a/app/javascript/mastodon/locales/sq.json
+++ b/app/javascript/mastodon/locales/sq.json
@@ -96,6 +96,7 @@
   "annual_report.summary.highlighted_post.possessive": "nga {name}",
   "annual_report.summary.most_used_app.most_used_app": "aplikacioni më i përdorur",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "hashtag-u më i përdorur",
+  "annual_report.summary.most_used_hashtag.none": "Asnjë",
   "annual_report.summary.new_posts.new_posts": "postime të reja",
   "annual_report.summary.percentile.text": "<topLabel>Kjo ju vë në krye</topLabel><percentage></percentage><bottomLabel>të përdoruesve të Mastodon-it.</bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "Nuk do t’ia themi Bernit.",
diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json
index ef2d912c00..df24db9634 100644
--- a/app/javascript/mastodon/locales/sv.json
+++ b/app/javascript/mastodon/locales/sv.json
@@ -101,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "{name}s",
   "annual_report.summary.most_used_app.most_used_app": "mest använda app",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "mest använda hashtag",
+  "annual_report.summary.most_used_hashtag.none": "Inga",
   "annual_report.summary.new_posts.new_posts": "nya inlägg",
   "annual_report.summary.percentile.text": "<topLabel>Det placerar dig i topp</topLabel><percentage></percentage><bottomLabel>av Mastodon-användare.</bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "Vi berättar inte för Bernie.",
diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json
index 4699b9f4bd..ece97614ad 100644
--- a/app/javascript/mastodon/locales/tr.json
+++ b/app/javascript/mastodon/locales/tr.json
@@ -101,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "{name}",
   "annual_report.summary.most_used_app.most_used_app": "en çok kullanılan uygulama",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "en çok kullanılan etiket",
+  "annual_report.summary.most_used_hashtag.none": "Yok",
   "annual_report.summary.new_posts.new_posts": "yeni gönderiler",
   "annual_report.summary.percentile.text": "<bottomLabel>Mastodon kullanıcılarının</bottomLabel><percentage></percentage><topLabel>üst dilimindesiniz</topLabel>.",
   "annual_report.summary.percentile.we_wont_tell_bernie": "Bernie'ye söylemeyiz.",
diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json
index dcbf8cec58..0e0906eb37 100644
--- a/app/javascript/mastodon/locales/uk.json
+++ b/app/javascript/mastodon/locales/uk.json
@@ -101,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "{name}",
   "annual_report.summary.most_used_app.most_used_app": "найчастіше використовуваний застосунок",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "найчастіший хештег",
+  "annual_report.summary.most_used_hashtag.none": "Немає",
   "annual_report.summary.new_posts.new_posts": "нові дописи",
   "annual_report.summary.percentile.text": "<topLabel>Це виводить вас в топ</topLabel><percentage></percentage><bottomLabel> користувачів Mastodon.</bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "Ми не скажемо Bernie.",
diff --git a/app/javascript/mastodon/locales/vi.json b/app/javascript/mastodon/locales/vi.json
index 2b5401a878..73016ed8c9 100644
--- a/app/javascript/mastodon/locales/vi.json
+++ b/app/javascript/mastodon/locales/vi.json
@@ -101,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "{name}",
   "annual_report.summary.most_used_app.most_used_app": "app dùng nhiều nhất",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "hashtag dùng nhiều nhất",
+  "annual_report.summary.most_used_hashtag.none": "Không có",
   "annual_report.summary.new_posts.new_posts": "tút mới",
   "annual_report.summary.percentile.text": "<topLabel>Bạn nằm trong top</topLabel><percentage></percentage><bottomLabel>thành viên Mastodon.</bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "Chúng tôi sẽ không kể cho Bernie.",
diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json
index 57b2011bb1..887410dd51 100644
--- a/app/javascript/mastodon/locales/zh-CN.json
+++ b/app/javascript/mastodon/locales/zh-CN.json
@@ -101,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "{name} 的",
   "annual_report.summary.most_used_app.most_used_app": "最常用的应用",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "最常用的话题",
+  "annual_report.summary.most_used_hashtag.none": "无",
   "annual_report.summary.new_posts.new_posts": "新发嘟",
   "annual_report.summary.percentile.text": "<topLabel>这使你跻身 Mastodon 用户的前</topLabel><percentage></percentage><bottomLabel></bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "我们打死也不会告诉Bernie。",
diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json
index 91d7f6e45d..56ddd9745e 100644
--- a/app/javascript/mastodon/locales/zh-TW.json
+++ b/app/javascript/mastodon/locales/zh-TW.json
@@ -101,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "{name} 的",
   "annual_report.summary.most_used_app.most_used_app": "最常使用的應用程式",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "最常使用的主題標籤",
+  "annual_report.summary.most_used_hashtag.none": "無最常用之主題標籤",
   "annual_report.summary.new_posts.new_posts": "新嘟文",
   "annual_report.summary.percentile.text": "<topLabel>這讓您成為前</topLabel><percentage></percentage><bottomLabel>Mastodon 的使用者。</bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "我們不會告訴 Bernie。",
diff --git a/config/locales/ca.yml b/config/locales/ca.yml
index 9d861fa30c..00c8f57a85 100644
--- a/config/locales/ca.yml
+++ b/config/locales/ca.yml
@@ -187,6 +187,7 @@ ca:
         create_domain_block: Crea un bloqueig de domini
         create_email_domain_block: Crea un blocatge del domini del correu electrònic
         create_ip_block: Crear regla IP
+        create_relay: Crea un repetidor
         create_unavailable_domain: Crea un domini no disponible
         create_user_role: Crea Rol
         demote_user: Degrada l'usuari
@@ -198,14 +199,17 @@ ca:
         destroy_email_domain_block: Elimina el blocatge del domini del correu electrònic
         destroy_instance: Purga Domini
         destroy_ip_block: Eliminar regla IP
+        destroy_relay: Esborra el repetidor
         destroy_status: Elimina la publicació
         destroy_unavailable_domain: Esborra domini no disponible
         destroy_user_role: Destrueix Rol
         disable_2fa_user: Desactiva 2FA
         disable_custom_emoji: Desactiva l'emoji personalitzat
+        disable_relay: Desactiva el repetidor
         disable_sign_in_token_auth_user: Desactivar l'autenticació de token per correu-e per a l'usuari
         disable_user: Deshabilita l'usuari
         enable_custom_emoji: Activa l'emoji personalitzat
+        enable_relay: Activa el repetidor
         enable_sign_in_token_auth_user: Activar l'autenticació de token per correu-e per a l'usuari
         enable_user: Activa l'usuari
         memorialize_account: Memoritza el compte
@@ -247,6 +251,7 @@ ca:
         create_domain_block_html: "%{name} ha bloquejat el domini %{target}"
         create_email_domain_block_html: "%{name} ha blocat el domini de correu electrònic %{target}"
         create_ip_block_html: "%{name} ha creat una regla per a l'IP %{target}"
+        create_relay_html: "%{name} ha creat un repetidor %{target}"
         create_unavailable_domain_html: "%{name} ha aturat el lliurament al domini %{target}"
         create_user_role_html: "%{name} ha creat el rol %{target}"
         demote_user_html: "%{name} ha degradat l'usuari %{target}"
@@ -258,14 +263,17 @@ ca:
         destroy_email_domain_block_html: "%{name} ha desblocat el domini de correu electrònic %{target}"
         destroy_instance_html: "%{name} ha purgat el domini %{target}"
         destroy_ip_block_html: "%{name} ha esborrat la regla per a l'IP %{target}"
+        destroy_relay_html: "%{name} ha esborrat el repetidor %{target}"
         destroy_status_html: "%{name} ha eliminat el tut de %{target}"
         destroy_unavailable_domain_html: "%{name} ha représ el lliurament delivery al domini %{target}"
         destroy_user_role_html: "%{name} ha esborrat el rol %{target}"
         disable_2fa_user_html: "%{name} ha desactivat el requisit de dos factors per a l'usuari %{target}"
         disable_custom_emoji_html: "%{name} ha desactivat l'emoji %{target}"
+        disable_relay_html: "%{name} ha desactivat el repetidor %{target}"
         disable_sign_in_token_auth_user_html: "%{name} ha desactivat l'autenticació de token per correu-e per a %{target}"
         disable_user_html: "%{name} ha desactivat l'accés del usuari %{target}"
         enable_custom_emoji_html: "%{name} ha activat l'emoji %{target}"
+        enable_relay_html: "%{name} ha activat el repetidor %{target}"
         enable_sign_in_token_auth_user_html: "%{name} ha activat l'autenticació de token per correu-e per a %{target}"
         enable_user_html: "%{name} ha activat l'accés del usuari %{target}"
         memorialize_account_html: "%{name} ha convertit el compte %{target} en una pàgina de memorial"
diff --git a/config/locales/da.yml b/config/locales/da.yml
index 6447afb493..daf683637d 100644
--- a/config/locales/da.yml
+++ b/config/locales/da.yml
@@ -187,6 +187,7 @@ da:
         create_domain_block: Opret domæneblokering
         create_email_domain_block: Opret e-maildomæneblokering
         create_ip_block: Opret IP-regel
+        create_relay: Opret Videresendelse
         create_unavailable_domain: Opret Utilgængeligt Domæne
         create_user_role: Opret rolle
         demote_user: Degradér bruger
@@ -198,14 +199,17 @@ da:
         destroy_email_domain_block: Slet e-maildomæneblokering
         destroy_instance: Udrens domæne
         destroy_ip_block: Slet IP-regel
+        destroy_relay: Slet Videresendelse
         destroy_status: Slet indlæg
         destroy_unavailable_domain: Slet Utilgængeligt Domæne
         destroy_user_role: Ødelæg rolle
         disable_2fa_user: Deaktivér 2FA
         disable_custom_emoji: Deaktivér tilpasset emoji
+        disable_relay: Deaktivér Videresendelse
         disable_sign_in_token_auth_user: Deaktivér e-mailtoken godkendelse for bruger
         disable_user: Deaktivér bruger
         enable_custom_emoji: Aktivér tilpasset emoji
+        enable_relay: Aktivér Relay
         enable_sign_in_token_auth_user: Aktivér e-mailtoken godkendelse for bruger
         enable_user: Aktivér bruger
         memorialize_account: Memoralisér konto
@@ -247,6 +251,7 @@ da:
         create_domain_block_html: "%{name} blokerede domænet %{target}"
         create_email_domain_block_html: "%{name} blokerede e-maildomænet %{target}"
         create_ip_block_html: "%{name} oprettede en regel for IP %{target}"
+        create_relay_html: "%{name} oprettede videresendelsen %{target}"
         create_unavailable_domain_html: "%{name} stoppede levering til domænet %{target}"
         create_user_role_html: "%{name} oprettede %{target}-rolle"
         demote_user_html: "%{name} degraderede brugeren %{target}"
@@ -258,14 +263,17 @@ da:
         destroy_email_domain_block_html: "%{name} afblokerede e-maildomænet %{target}"
         destroy_instance_html: "%{name} udrensede domænet %{target}"
         destroy_ip_block_html: "%{name} slettede en regel for IP %{target}"
+        destroy_relay_html: "%{name} oprettede videresendelsen %{target}"
         destroy_status_html: "%{name} fjernede indlægget fra %{target}"
         destroy_unavailable_domain_html: "%{name} genoptog levering til domænet %{target}"
         destroy_user_role_html: "%{name} slettede %{target}-rolle"
         disable_2fa_user_html: "%{name} deaktiverede tofaktorkravet for brugeren %{target}"
         disable_custom_emoji_html: "%{name} deaktiverede emojien %{target}"
+        disable_relay_html: "%{name} deaktiverede videresendelsen %{target}"
         disable_sign_in_token_auth_user_html: "%{name} deaktiverede e-mailtoken godkendelsen for %{target}"
         disable_user_html: "%{name} deaktiverede indlogning for brugeren %{target}"
         enable_custom_emoji_html: "%{name} aktiverede emojien %{target}"
+        enable_relay_html: "%{name} aktiverede videresendelsen %{target}"
         enable_sign_in_token_auth_user_html: "%{name} aktiverede e-mailtoken godkendelse for %{target}"
         enable_user_html: "%{name} aktiverede indlogning for brugeren %{target}"
         memorialize_account_html: "%{name} gjorde %{target}s konto til en mindeside"
diff --git a/config/locales/de.yml b/config/locales/de.yml
index 323579f25f..10223f2278 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -187,6 +187,7 @@ de:
         create_domain_block: Domain sperren
         create_email_domain_block: E-Mail-Domain-Sperre erstellen
         create_ip_block: IP-Regel erstellen
+        create_relay: Relay erstellen
         create_unavailable_domain: Nicht verfügbare Domain erstellen
         create_user_role: Rolle erstellen
         demote_user: Benutzer*in herabstufen
@@ -198,14 +199,17 @@ de:
         destroy_email_domain_block: E-Mail-Domain-Sperre entfernen
         destroy_instance: Domain-Daten entfernen
         destroy_ip_block: IP-Regel löschen
+        destroy_relay: Relay löschen
         destroy_status: Beitrag entfernen
         destroy_unavailable_domain: Nicht-verfügbare Domain entfernen
         destroy_user_role: Rolle entfernen
         disable_2fa_user: 2FA deaktivieren
         disable_custom_emoji: Eigenes Emoji deaktivieren
+        disable_relay: Relay deaktivieren
         disable_sign_in_token_auth_user: E-Mail-Token-Authentisierung für dieses Konto deaktivieren
         disable_user: Benutzer*in deaktivieren
         enable_custom_emoji: Eigenes Emoji aktivieren
+        enable_relay: Relay aktivieren
         enable_sign_in_token_auth_user: E-Mail-Token-Authentisierung für dieses Konto aktivieren
         enable_user: Benutzer*in aktivieren
         memorialize_account: Gedenkkonto
@@ -247,6 +251,7 @@ de:
         create_domain_block_html: "%{name} sperrte die Domain %{target}"
         create_email_domain_block_html: "%{name} sperrte die E-Mail-Domain %{target}"
         create_ip_block_html: "%{name} erstellte eine IP-Regel für %{target}"
+        create_relay_html: "%{name} erstellte ein Relay %{target}"
         create_unavailable_domain_html: "%{name} beendete die Zustellung an die Domain %{target}"
         create_user_role_html: "%{name} erstellte die Rolle %{target}"
         demote_user_html: "%{name} stufte %{target} herunter"
@@ -258,14 +263,17 @@ de:
         destroy_email_domain_block_html: "%{name} entsperrte die E-Mail-Domain %{target}"
         destroy_instance_html: "%{name} entfernte die Daten der Domain %{target} von diesem Server"
         destroy_ip_block_html: "%{name} entfernte eine IP-Regel für %{target}"
+        destroy_relay_html: "%{name} löschte das Relay %{target}"
         destroy_status_html: "%{name} entfernte einen Beitrag von %{target}"
         destroy_unavailable_domain_html: "%{name} nahm die Zustellung an die Domain %{target} wieder auf"
         destroy_user_role_html: "%{name} löschte die Rolle %{target}"
         disable_2fa_user_html: "%{name} deaktivierte die Zwei-Faktor-Authentisierung für %{target}"
         disable_custom_emoji_html: "%{name} deaktivierte das Emoji %{target}"
+        disable_relay_html: "%{name} deaktivierte das Relay %{target}"
         disable_sign_in_token_auth_user_html: "%{name} deaktivierte die E-Mail-Token-Authentisierung für %{target}"
         disable_user_html: "%{name} deaktivierte den Zugang für %{target}"
         enable_custom_emoji_html: "%{name} aktivierte das Emoji %{target}"
+        enable_relay_html: "%{name} aktivierte das Relay %{target}"
         enable_sign_in_token_auth_user_html: "%{name} aktivierte die E-Mail-Token-Authentisierung für %{target}"
         enable_user_html: "%{name} aktivierte den Zugang für %{target}"
         memorialize_account_html: "%{name} wandelte das Konto von %{target} in eine Gedenkseite um"
diff --git a/config/locales/fi.yml b/config/locales/fi.yml
index 2f9a76c80d..6fe9c14591 100644
--- a/config/locales/fi.yml
+++ b/config/locales/fi.yml
@@ -187,6 +187,7 @@ fi:
         create_domain_block: Luo verkkotunnuksen esto
         create_email_domain_block: Luo sähköpostiverkkotunnuksen esto
         create_ip_block: Luo IP-sääntö
+        create_relay: Luo välittäjä
         create_unavailable_domain: Luo ei-saatavilla oleva verkkotunnus
         create_user_role: Luo rooli
         demote_user: Alenna käyttäjä
@@ -198,14 +199,17 @@ fi:
         destroy_email_domain_block: Poista sähköpostiverkkotunnuksen esto
         destroy_instance: Tyhjennä verkkotunnus
         destroy_ip_block: Poista IP-sääntö
+        destroy_relay: Poista välittäjä
         destroy_status: Poista julkaisu
         destroy_unavailable_domain: Poista ei-saatavilla oleva verkkotunnus
         destroy_user_role: Hävitä rooli
         disable_2fa_user: Poista kaksivaiheinen todennus käytöstä
         disable_custom_emoji: Poista mukautettu emoji käytöstä
+        disable_relay: Poista välittäjä käytöstä
         disable_sign_in_token_auth_user: Poista sähköpostitunnuksella todennus käytöstä käyttäjältä
         disable_user: Poista tili käytöstä
         enable_custom_emoji: Ota mukautettu emoji käyttöön
+        enable_relay: Ota välittäjä käyttöön
         enable_sign_in_token_auth_user: Ota sähköpostitunnuksella todennus käyttöön käyttäjälle
         enable_user: Ota tili käyttöön
         memorialize_account: Muuta muistotiliksi
@@ -216,7 +220,7 @@ fi:
         reopen_report: Avaa raportti uudelleen
         resend_user: Lähetä vahvistusviesti uudelleen
         reset_password_user: Palauta salasana
-        resolve_report: Selvitä raportti
+        resolve_report: Ratkaise raportti
         sensitive_account: Pakota arkaluonteiseksi tiliksi
         silence_account: Rajoita tiliä
         suspend_account: Jäädytä tili
@@ -247,6 +251,7 @@ fi:
         create_domain_block_html: "%{name} esti verkkotunnuksen %{target}"
         create_email_domain_block_html: "%{name} esti sähköpostiverkkotunnuksen %{target}"
         create_ip_block_html: "%{name} loi säännön IP-osoitteelle %{target}"
+        create_relay_html: "%{name} loi välittäjän %{target}"
         create_unavailable_domain_html: "%{name} pysäytti toimituksen verkkotunnukseen %{target}"
         create_user_role_html: "%{name} loi roolin %{target}"
         demote_user_html: "%{name} alensi käyttäjän %{target}"
@@ -258,14 +263,17 @@ fi:
         destroy_email_domain_block_html: "%{name} kumosi sähköpostiverkkotunnuksen %{target} eston"
         destroy_instance_html: "%{name} tyhjensi verkkotunnuksen %{target}"
         destroy_ip_block_html: "%{name} poisti säännön IP-osoitteelta %{target}"
+        destroy_relay_html: "%{name} poisti välittäjän %{target}"
         destroy_status_html: "%{name} poisti käyttäjän %{target} julkaisun"
         destroy_unavailable_domain_html: "%{name} jatkoi toimitusta verkkotunnukseen %{target}"
         destroy_user_role_html: "%{name} poisti roolin %{target}"
         disable_2fa_user_html: "%{name} poisti käyttäjältä %{target} vaatimuksen kaksivaiheiseen todentamiseen"
         disable_custom_emoji_html: "%{name} poisti emojin %{target} käytöstä"
+        disable_relay_html: "%{name} poisti välittäjän %{target} käytöstä"
         disable_sign_in_token_auth_user_html: "%{name} poisti sähköpostitunnuksella todennuksen käytöstä käyttäjältä %{target}"
         disable_user_html: "%{name} poisti kirjautumisen käytöstä käyttäjältä %{target}"
         enable_custom_emoji_html: "%{name} otti emojin %{target} käyttöön"
+        enable_relay_html: "%{name} otti välittäjän %{target} käyttöön"
         enable_sign_in_token_auth_user_html: "%{name} otti sähköpostitunnuksella todennuksen käyttöön käyttäjälle %{target}"
         enable_user_html: "%{name} otti kirjautumisen käyttöön käyttäjälle %{target}"
         memorialize_account_html: "%{name} muutti käyttäjän %{target} tilin muistosivuksi"
diff --git a/config/locales/fo.yml b/config/locales/fo.yml
index 1060ee1609..6cc1fda6a0 100644
--- a/config/locales/fo.yml
+++ b/config/locales/fo.yml
@@ -187,6 +187,7 @@ fo:
         create_domain_block: Stovna navnaøkjablokering
         create_email_domain_block: Stovna t-post-økisnavnablokk
         create_ip_block: Stovna IP reglu
+        create_relay: Stovna reiðlag
         create_unavailable_domain: Stovna navnaøki, sum ikki er tøkt
         create_user_role: Stovna leiklut
         demote_user: Lækka brúkara í tign
@@ -198,14 +199,17 @@ fo:
         destroy_email_domain_block: Strika t-posta-økisnavnablokk
         destroy_instance: Reinsa navnaøki
         destroy_ip_block: Strika IP reglu
+        destroy_relay: Strika reiðlag
         destroy_status: Strika post
         destroy_unavailable_domain: Strika navnaøki, sum ikki er tøkt
         destroy_user_role: Bein burtur leiklut
         disable_2fa_user: Ger 2FA óvirkið
         disable_custom_emoji: Ger serligt kenslutekn óvirkið
+        disable_relay: Ger reiðlag óvirkið
         disable_sign_in_token_auth_user: Ger váttan við teldupostateknum óvirkna fyri brúkara
         disable_user: Ger brúkara óvirknan
         enable_custom_emoji: Ger serligt kenslutekn virkið
+        enable_relay: Ger reiðlag virkið
         enable_sign_in_token_auth_user: Ger váttan við teldupostateknum virkna fyri brúkara
         enable_user: Ger brúkara virknan
         memorialize_account: Minnst til Konto
@@ -247,6 +251,7 @@ fo:
         create_domain_block_html: "%{name} blokeraði navnaøkið %{target}"
         create_email_domain_block_html: "%{name} blokeraði teldupostanavnaøkið %{target}"
         create_ip_block_html: "%{name} gjørdi reglu fyri IP %{target}"
+        create_relay_html: "%{name} gjørdi eitt reiðlag %{target}"
         create_unavailable_domain_html: "%{name} steðgaði veiting til navnaøkið %{target}"
         create_user_role_html: "%{name} stovnaði %{target} leiklutin"
         demote_user_html: "%{name} lækkaði tignina hjá brúkaranum %{target}"
@@ -258,14 +263,17 @@ fo:
         destroy_email_domain_block_html: "%{name} leysgav teldupostanavnaøkið %{target}"
         destroy_instance_html: "%{name} reinsaði navnaøkið %{target}"
         destroy_ip_block_html: "%{name} slettaðar reglur fyri IP %{target}"
+        destroy_relay_html: "%{name} strikaði reiðlagið %{target}"
         destroy_status_html: "%{name} slettaði upplegg hjá %{target}"
         destroy_unavailable_domain_html: "%{name} tók upp aftir veiting til navnaøkið %{target}"
         destroy_user_role_html: "%{name} slettaði leiklutin hjá %{target}"
         disable_2fa_user_html: "%{name} slepti kravið um váttan í tveimum stigum fyri brúkaran %{target}"
         disable_custom_emoji_html: "%{name} gjørdi kensluteknið %{target} óvirkið"
+        disable_relay_html: "%{name} gjørdi reiðlagið %{target} óvirkið"
         disable_sign_in_token_auth_user_html: "%{name} gjørdi váttan við teldupostteknum óvirkna fyri %{target}"
         disable_user_html: "%{name} gjørdi innritan hjá brúkaranum %{target} óvirkna"
         enable_custom_emoji_html: "%{name} gjørdi kensluteknið %{target} virkið"
+        enable_relay_html: "%{name} gjørdi reiðlagið %{target} virkið"
         enable_sign_in_token_auth_user_html: "%{name} gjørdi váttan við teldupostteknum virkna fyri %{target}"
         enable_user_html: "%{name} gjørdi innritan virkna fyri brúkaran %{target}"
         memorialize_account_html: "%{name} broytti kontuna hjá %{target} til eina minnissíðu"
diff --git a/config/locales/gl.yml b/config/locales/gl.yml
index a4f63a50e0..1ad8deb179 100644
--- a/config/locales/gl.yml
+++ b/config/locales/gl.yml
@@ -187,6 +187,7 @@ gl:
         create_domain_block: Crear bloquedo do Dominio
         create_email_domain_block: Crear Bloqueo de Dominio do correo
         create_ip_block: Crear regra IP
+        create_relay: Crear Repetidor
         create_unavailable_domain: Crear dominio Non dispoñible
         create_user_role: Crear Rol
         demote_user: Degradar usuaria
@@ -198,14 +199,17 @@ gl:
         destroy_email_domain_block: Eliminar bloqueo do dominio do correo
         destroy_instance: Purgar Dominio
         destroy_ip_block: Eliminar regra IP
+        destroy_relay: Eliminar Repetidor
         destroy_status: Eliminar publicación
         destroy_unavailable_domain: Eliminar dominio Non dispoñible
         destroy_user_role: Eliminar Rol
         disable_2fa_user: Desactivar 2FA
         disable_custom_emoji: Desactivar emoticona personalizada
+        disable_relay: Desactivar Repetidor
         disable_sign_in_token_auth_user: Desactivar Autenticación por Token no Correo para a Usuaria
         disable_user: Desactivar usuaria
         enable_custom_emoji: Activar emoticona personalizada
+        enable_relay: Activar Repetidor
         enable_sign_in_token_auth_user: Activar Autenticación con Token no Correo para a Usuaria
         enable_user: Activar usuaria
         memorialize_account: Transformar en conta conmemorativa
@@ -247,6 +251,7 @@ gl:
         create_domain_block_html: "%{name} bloqueou o dominio %{target}"
         create_email_domain_block_html: "%{name} bloqueou o dominio de correo %{target}"
         create_ip_block_html: "%{name} creou regra para o IP %{target}"
+        create_relay_html: "%{name} creou un repetidor en %{target}"
         create_unavailable_domain_html: "%{name} deixou de interactuar co dominio %{target}"
         create_user_role_html: "%{name} creou o rol %{target}"
         demote_user_html: "%{name} degradou a usuaria %{target}"
@@ -258,14 +263,17 @@ gl:
         destroy_email_domain_block_html: "%{name} desbloqueou o dominio de correo %{target}"
         destroy_instance_html: "%{name} purgou o dominio %{target}"
         destroy_ip_block_html: "%{name} eliminou a regra para o IP %{target}"
+        destroy_relay_html: "%{name} eliminou o repetidor %{target}"
         destroy_status_html: "%{name} eliminou a publicación de %{target}"
         destroy_unavailable_domain_html: "%{name} retomou a interacción co dominio %{target}"
         destroy_user_role_html: "%{name} eliminou o rol %{target}"
         disable_2fa_user_html: "%{name} desactivou o requerimento do segundo factor para a usuaria %{target}"
         disable_custom_emoji_html: "%{name} desactivou o emoji %{target}"
+        disable_relay_html: "%{name} desactivou o repetidor %{target}"
         disable_sign_in_token_auth_user_html: "%{name} desactivou a autenticación por token no email para %{target}"
         disable_user_html: "%{name} desactivou as credenciais para a usuaria %{target}"
         enable_custom_emoji_html: "%{name} activou o emoji %{target}"
+        enable_relay_html: "%{name} activou o repetidor %{target}"
         enable_sign_in_token_auth_user_html: "%{name} activou a autenticación con token no email para %{target}"
         enable_user_html: "%{name} activou as credenciais para a usuaria %{target}"
         memorialize_account_html: "%{name} convertiu a conta de %{target} nunha páxina para o recordo"
diff --git a/config/locales/hu.yml b/config/locales/hu.yml
index 47bd24fccf..1892009238 100644
--- a/config/locales/hu.yml
+++ b/config/locales/hu.yml
@@ -187,6 +187,7 @@ hu:
         create_domain_block: Domain tiltás létrehozása
         create_email_domain_block: E-mail-domain-tiltás létrehozása
         create_ip_block: IP szabály létrehozása
+        create_relay: Továbbító létrehozása
         create_unavailable_domain: Elérhetetlen domain létrehozása
         create_user_role: Szerepkör létrehozása
         demote_user: Felhasználó lefokozása
@@ -198,14 +199,17 @@ hu:
         destroy_email_domain_block: E-mail-domain-tiltás törlése
         destroy_instance: Domain végleges törlése
         destroy_ip_block: IP szabály törlése
+        destroy_relay: Továbbító törlése
         destroy_status: Bejegyzés törlése
         destroy_unavailable_domain: Elérhetetlen domain törlése
         destroy_user_role: Szerepkör eltávolítása
         disable_2fa_user: Kétlépcsős hitelesítés letiltása
         disable_custom_emoji: Egyéni emodzsi letiltása
+        disable_relay: Továbbító letiltása
         disable_sign_in_token_auth_user: A felhasználó tokenes e-mail-hitelesítésének letiltása
         disable_user: Felhasználói letiltása
         enable_custom_emoji: Egyéni emodzsi engedélyezése
+        enable_relay: Továbbító engedélyezése
         enable_sign_in_token_auth_user: A felhasználó tokenes e-mail-hitelesítésének engedélyezése
         enable_user: Felhasználó engedélyezése
         memorialize_account: Fiók emlékké nyilvánítása
@@ -247,6 +251,7 @@ hu:
         create_domain_block_html: "%{name} letiltotta a %{target} domaint"
         create_email_domain_block_html: "%{name} letiltotta a(z) %{target} e-mail-domaint"
         create_ip_block_html: "%{name} létrehozta a(z) %{target} IP-címre vonatkozó szabályt"
+        create_relay_html: "%{name} létrehozta az átirányítót: %{target}"
         create_unavailable_domain_html: "%{name} leállította a kézbesítést a %{target} domainbe"
         create_user_role_html: "%{name} létrehozta a(z) %{target} szerepkört"
         demote_user_html: "%{name} lefokozta %{target} felhasználót"
@@ -258,14 +263,17 @@ hu:
         destroy_email_domain_block_html: "%{name} engedélyezte a(z) %{target} e-mail-domaint"
         destroy_instance_html: "%{name} véglegesen törölte a(z) %{target} domaint"
         destroy_ip_block_html: "%{name} törölte a(z) %{target} IP-címre vonatkozó szabályt"
+        destroy_relay_html: "%{name} törölte az átirányítót: %{target}"
         destroy_status_html: "%{name} eltávolította %{target} felhasználó bejegyzését"
         destroy_unavailable_domain_html: "%{name} újraindította a kézbesítést a %{target} domainbe"
         destroy_user_role_html: "%{name} törölte a(z) %{target} szerepkört"
         disable_2fa_user_html: "%{name} kikapcsolta a kétlépcsős hitelesítést %{target} felhasználó fiókján"
         disable_custom_emoji_html: "%{name} letiltotta az emodzsit: %{target}"
+        disable_relay_html: "%{name} letiltotta az átirányítót: %{target}"
         disable_sign_in_token_auth_user_html: "%{name} letiltotta a tokenes e-mail-hitelesítést %{target} felhasználóra"
         disable_user_html: "%{name} letiltotta %{target} felhasználó bejelentkezését"
         enable_custom_emoji_html: "%{name} engedélyezte az emodzsit: %{target}"
+        enable_relay_html: "%{name} engedélyezte az átirányítót: %{target}"
         enable_sign_in_token_auth_user_html: "%{name} engedélyezte a tokenes e-mail-hitelesítést %{target} felhasználóra"
         enable_user_html: "%{name} engedélyezte %{target} felhasználó bejelentkezését"
         memorialize_account_html: "%{name} emléket állított %{target} felhasználónak"
diff --git a/config/locales/is.yml b/config/locales/is.yml
index c50b3dd20d..552df8f064 100644
--- a/config/locales/is.yml
+++ b/config/locales/is.yml
@@ -187,6 +187,7 @@ is:
         create_domain_block: Búa til útilokun léns
         create_email_domain_block: Búa til útilokun tölvupóstléns
         create_ip_block: Búa til IP-reglu
+        create_relay: Búa til endurvarpa
         create_unavailable_domain: Útbúa lén sem ekki er tiltækt
         create_user_role: Útbúa hlutverk
         demote_user: Lækka notanda í tign
@@ -198,14 +199,17 @@ is:
         destroy_email_domain_block: Eyða útilokun tölvupóstléns
         destroy_instance: Henda léni
         destroy_ip_block: Eyða IP-reglu
+        destroy_relay: Eyða endurvarpa
         destroy_status: Eyða færslu
         destroy_unavailable_domain: Eyða léni sem ekki er tiltækt
         destroy_user_role: Eyða hlutverki
         disable_2fa_user: Gera tveggja-þátta auðkenningu óvirka
         disable_custom_emoji: Gera sérsniðið tjáningartákn óvirkt
+        disable_relay: Gera endurvarpa óvirkan
         disable_sign_in_token_auth_user: Gera óvirka auðkenningu með teikni í tölvupósti fyrir notandann
         disable_user: Gera notanda óvirkan
         enable_custom_emoji: Virkja sérsniðið tjáningartákn
+        enable_relay: Virkja endurvarpa
         enable_sign_in_token_auth_user: Gera virka auðkenningu með teikni í tölvupósti fyrir notandann
         enable_user: Virkja notanda
         memorialize_account: Gera aðgang að minningargrein
@@ -247,6 +251,7 @@ is:
         create_domain_block_html: "%{name} útilokaði lénið %{target}"
         create_email_domain_block_html: "%{name} útilokaði póstlénið %{target}"
         create_ip_block_html: "%{name} útbjó reglu fyrir IP-vistfangið %{target}"
+        create_relay_html: "%{name} bjó til endurvarpa %{target}"
         create_unavailable_domain_html: "%{name} stöðvaði afhendingu til lénsins %{target}"
         create_user_role_html: "%{name} útbjó %{target} hlutverk"
         demote_user_html: "%{name} lækkaði notandann %{target} í tign"
@@ -258,14 +263,17 @@ is:
         destroy_email_domain_block_html: "%{name} aflétti útilokun af póstléninu %{target}"
         destroy_instance_html: "%{name} henti léninu %{target}"
         destroy_ip_block_html: "%{name} eyddi reglu fyrir IP-vistfangið %{target}"
+        destroy_relay_html: "%{name} eyddi endurvarpanum %{target}"
         destroy_status_html: "%{name} fjarlægði færslu frá %{target}"
         destroy_unavailable_domain_html: "%{name} hóf aftur afhendingu til lénsins %{target}"
         destroy_user_role_html: "%{name} eyddi hlutverki %{target}"
         disable_2fa_user_html: "%{name} gerði kröfu um tveggja-þátta innskráningu óvirka fyrir notandann %{target}"
         disable_custom_emoji_html: "%{name} gerði tjáningartáknið %{target} óvirkt"
+        disable_relay_html: "%{name} gerði endurvarpann %{target} óvirkan"
         disable_sign_in_token_auth_user_html: "%{name} gerði óvirka auðkenningu með teikni í tölvupósti fyrir %{target}"
         disable_user_html: "%{name} gerði innskráningu óvirka fyrir notandann %{target}"
         enable_custom_emoji_html: "%{name} gerði tjáningartáknið %{target} virkt"
+        enable_relay_html: "%{name} virkjaði endurvarpann %{target}"
         enable_sign_in_token_auth_user_html: "%{name} gerði virka auðkenningu með teikni í tölvupósti fyrir %{target}"
         enable_user_html: "%{name} gerði innskráningu virka fyrir notandann %{target}"
         memorialize_account_html: "%{name} breytti notandaaðgangnum %{target} í minningargreinarsíðu"
diff --git a/config/locales/ko.yml b/config/locales/ko.yml
index 6bff1703e6..1fe43f7e75 100644
--- a/config/locales/ko.yml
+++ b/config/locales/ko.yml
@@ -184,6 +184,7 @@ ko:
         create_domain_block: 도메인 차단 추가
         create_email_domain_block: 이메일 도메인 차단 생성
         create_ip_block: IP 규칙 만들기
+        create_relay: 릴레이 생성
         create_unavailable_domain: 사용 불가능한 도메인 생성
         create_user_role: 역할 생성
         demote_user: 사용자 강등
@@ -195,14 +196,17 @@ ko:
         destroy_email_domain_block: 이메일 도메인 차단 삭제
         destroy_instance: 도메인 퍼지하기
         destroy_ip_block: IP 규칙 삭제
+        destroy_relay: 릴레이 삭제
         destroy_status: 게시물 삭제
         destroy_unavailable_domain: 사용 불가능한 도메인 제거
         destroy_user_role: 역할 삭제
         disable_2fa_user: 2단계 인증 비활성화
         disable_custom_emoji: 커스텀 에모지 비활성화
+        disable_relay: 릴레이 비활성화
         disable_sign_in_token_auth_user: 사용자의 이메일 토큰 인증 비활성화
         disable_user: 사용자 비활성화
         enable_custom_emoji: 커스텀 에모지 활성화
+        enable_relay: 릴레이 활성화
         enable_sign_in_token_auth_user: 사용자의 이메일 토큰 인증 활성화
         enable_user: 사용자 활성화
         memorialize_account: 고인의 계정으로 전환
@@ -244,6 +248,7 @@ ko:
         create_domain_block_html: "%{name} 님이 도메인 %{target}를 차단했습니다"
         create_email_domain_block_html: "%{name} 님이 이메일 도메인 %{target}를 차단했습니다"
         create_ip_block_html: "%{name} 님이 IP 규칙 %{target}을 만들었습니다"
+        create_relay_html: "%{name} 님이 릴레이 %{target}를 생성했습니다"
         create_unavailable_domain_html: "%{name} 님이 도메인 %{target}에 대한 전달을 중지했습니다"
         create_user_role_html: "%{name} 님이 %{target} 역할을 생성했습니다"
         demote_user_html: "%{name} 님이 사용자 %{target} 님을 강등했습니다"
@@ -255,14 +260,17 @@ ko:
         destroy_email_domain_block_html: "%{name} 님이 이메일 도메인 %{target}을 차단 해제하였습니다"
         destroy_instance_html: "%{name} 님이 도메인 %{target}를 제거했습니다"
         destroy_ip_block_html: "%{name} 님이 IP 규칙 %{target}을 삭제하였습니다"
+        destroy_relay_html: "%{name} 님이 릴레이 %{target}를 삭제했습니다"
         destroy_status_html: "%{name} 님이 %{target} 님의 게시물을 삭제했습니다"
         destroy_unavailable_domain_html: "%{name} 님이 도메인 %{target}에 대한 전달을 재개"
         destroy_user_role_html: "%{name} 님이 %{target} 역할을 삭제했습니다"
         disable_2fa_user_html: "%{name} 님이 사용자 %{target} 님의 2단계 인증을 비활성화 했습니다"
         disable_custom_emoji_html: "%{name} 님이 에모지 %{target}를 비활성화했습니다"
+        disable_relay_html: "%{name} 님이 릴레이 %{target}를 비활성화했습니다"
         disable_sign_in_token_auth_user_html: "%{name} 님이 %{target} 님의 이메일 토큰 인증을 비활성화했습니다"
         disable_user_html: "%{name} 님이 사용자 %{target}의 로그인을 비활성화했습니다"
         enable_custom_emoji_html: "%{name} 님이 에모지 %{target}를 활성화했습니다"
+        enable_relay_html: "%{name} 님이 릴레이 %{target}를 활성화했습니다"
         enable_sign_in_token_auth_user_html: "%{name} 님이 %{target} 님의 이메일 토큰 인증을 활성화했습니다"
         enable_user_html: "%{name} 님이 사용자 %{target}의 로그인을 활성화했습니다"
         memorialize_account_html: "%{name} 님이 %{target}의 계정을 고인의 계정 페이지로 전환했습니다"
diff --git a/config/locales/lt.yml b/config/locales/lt.yml
index 8ba3bad070..3850e2e071 100644
--- a/config/locales/lt.yml
+++ b/config/locales/lt.yml
@@ -185,6 +185,7 @@ lt:
         create_domain_allow: Kurti domeno leidimą
         create_domain_block: Kurti domeno bloką
         create_ip_block: Kurti IP taisyklę
+        create_relay: Kurti perdavimą
         create_unavailable_domain: Kurti nepasiekiamą domeną
         create_user_role: Kurti vaidmenį
         demote_user: Pažeminti naudotoją
@@ -194,13 +195,16 @@ lt:
         destroy_domain_block: Ištrinti domeno bloką
         destroy_instance: Išvalyti domeną
         destroy_ip_block: Ištrinti IP taisyklę
+        destroy_relay: Ištrinti perdavimą
         destroy_status: Ištrinti įrašą
         destroy_unavailable_domain: Ištrinti nepasiekiamą domeną
         destroy_user_role: Sunaikinti vaidmenį
         disable_2fa_user: Išjungti 2FA
         disable_custom_emoji: Išjungti pasirinktinį jaustuką
+        disable_relay: Išjungti perdavimą
         disable_user: Išjungti naudotoją
         enable_custom_emoji: Įjungti pasirinktinį jaustuką
+        enable_relay: Įjungti perdavimą
         enable_user: Įjungti naudotoją
         memorialize_account: Memorializuoti paskyrą
         promote_user: Paaukštinti naudotoją
@@ -237,6 +241,7 @@ lt:
         create_domain_allow_html: "%{name} leido federaciją su domenu %{target}"
         create_domain_block_html: "%{name} užblokavo domeną %{target}"
         create_ip_block_html: "%{name} sukūrė taisyklę IP %{target}"
+        create_relay_html: "%{name} sukūrė perdavimą %{target}"
         create_unavailable_domain_html: "%{name} sustabdė tiekimą į domeną %{target}"
         create_user_role_html: "%{name} sukūrė %{target} vaidmenį"
         demote_user_html: "%{name} pažemino naudotoją %{target}"
@@ -246,13 +251,16 @@ lt:
         destroy_domain_block_html: "%{name} atblokavo domeną %{target}"
         destroy_instance_html: "%{name} išvalė domeną %{target}"
         destroy_ip_block_html: "%{name} ištrynė taisyklę IP %{target}"
+        destroy_relay_html: "%{name} ištrynė perdavimą %{target}"
         destroy_status_html: "%{name} pašalino įrašą %{target}"
         destroy_unavailable_domain_html: "%{name} pratęsė tiekimą į domeną %{target}"
         destroy_user_role_html: "%{name} ištrynė %{target} vaidmenį"
         disable_2fa_user_html: "%{name} išjungė dviejų veiksnių reikalavimą naudotojui %{target}"
         disable_custom_emoji_html: "%{name} išjungė jaustuką %{target}"
+        disable_relay_html: "%{name} išjungė perdavimą %{target}"
         disable_user_html: "%{name} išjungė prisijungimą naudotojui %{target}"
         enable_custom_emoji_html: "%{name} įjungė jaustuką %{target}"
+        enable_relay_html: "%{name} įjungė perdavimą %{target}"
         enable_user_html: "%{name} įjungė prisijungimą naudotojui %{target}"
         memorialize_account_html: "%{name} pavertė %{target} paskyrą į atminimo puslapį"
         promote_user_html: "%{name} paaukštino naudotoją %{target}"
diff --git a/config/locales/nn.yml b/config/locales/nn.yml
index 9ec4f29f42..62b08f42ed 100644
--- a/config/locales/nn.yml
+++ b/config/locales/nn.yml
@@ -187,6 +187,7 @@ nn:
         create_domain_block: Opprett domene-blokk
         create_email_domain_block: Opprett blokkering av e-postdomene
         create_ip_block: Opprett IP-regel
+        create_relay: Opprett eit relé
         create_unavailable_domain: Opprett utilgjengeleg domene
         create_user_role: Opprett rolle
         demote_user: Degrader brukar
@@ -198,14 +199,17 @@ nn:
         destroy_email_domain_block: Fjern blokkering av e-postdomene
         destroy_instance: Slett domene
         destroy_ip_block: Slett IP-regel
+        destroy_relay: Slett relé
         destroy_status: Slett status
         destroy_unavailable_domain: Slett utilgjengeleg domene
         destroy_user_role: Øydelegg rolle
         disable_2fa_user: Skruv av 2FA
         disable_custom_emoji: Skruv av tilpassa emoji
+        disable_relay: Skru av reléet
         disable_sign_in_token_auth_user: Slå av e-post-token-autentisering for brukar
         disable_user: Skruv av brukar
         enable_custom_emoji: Skruv på tilpassa emoji
+        enable_relay: Skru på reléet
         enable_sign_in_token_auth_user: Slå på e-post-token-autentisering for brukar
         enable_user: Skruv på brukar
         memorialize_account: Opprett minnekonto
@@ -247,6 +251,7 @@ nn:
         create_domain_block_html: "%{name} blokkerte domenet %{target}"
         create_email_domain_block_html: "%{name} blokkerte e-postdomenet %{target}"
         create_ip_block_html: "%{name} oppretta ein regel for IP-en %{target}"
+        create_relay_html: "%{name} laga reléet %{target}"
         create_unavailable_domain_html: "%{name} stogga levering til domenet %{target}"
         create_user_role_html: "%{name} oppretta rolla %{target}"
         demote_user_html: "%{name} degraderte brukaren %{target}"
@@ -258,14 +263,17 @@ nn:
         destroy_email_domain_block_html: "%{name} avblokkerte e-postdomenet %{target}"
         destroy_instance_html: "%{name} tømde domenet %{target}"
         destroy_ip_block_html: "%{name} sletta ein regel for IP-en %{target}"
+        destroy_relay_html: "%{name} sletta reléet %{target}"
         destroy_status_html: "%{name} fjerna innlegget frå %{target}"
         destroy_unavailable_domain_html: "%{name} tok opp att levering til domenet %{target}"
         destroy_user_role_html: "%{name} sletta rolla %{target}"
         disable_2fa_user_html: "%{name} tok vekk krav om tofaktorautentisering for brukaren %{target}"
         disable_custom_emoji_html: "%{name} deaktiverte emojien %{target}"
+        disable_relay_html: "%{name} skrudde av reléet %{target}"
         disable_sign_in_token_auth_user_html: "%{name} deaktiverte e-post-token-autentisering for %{target}"
         disable_user_html: "%{name} slo av innlogging for brukaren %{target}"
         enable_custom_emoji_html: "%{name} aktiverte emojien %{target}"
+        enable_relay_html: "%{name} skrudde på reléet %{target}"
         enable_sign_in_token_auth_user_html: "%{name} aktiverte e-post-token-autentisering for %{target}"
         enable_user_html: "%{name} aktiverte innlogging for brukaren %{target}"
         memorialize_account_html: "%{name} endret %{target}s konto til en minneside"
@@ -1381,6 +1389,9 @@ nn:
       following_html:
         one: Du skal til å <strong>fylgja</strong> opp til <strong>%{count} brukarkonto</strong> frå <strong>%{filename}</strong> og <strong>slutta å fylgja alle andre</strong>.
         other: Du skal til å <strong>fylgja</strong> opp til <strong>%{count} brukarkontoar</strong> frå <strong>%{filename}</strong> og <strong>slutta å fylgja alle andre</strong>.
+      lists_html:
+        one: Du er i ferd med å <strong>erstatta listene dine</strong> med innhaldet i <strong>%{filename}</strong>. Opptil <strong>%{count} konto</strong> vil bli lagt til i dei nye listene.
+        other: Du er i ferd med å <strong>erstatta listene dine</strong> med innhaldet i <strong>%{filename}</strong>. Opptil <strong>%{count} kontoar</strong> vil bli lagt til i dei nye listene.
       muting_html:
         one: Du skal til å <strong>byta ut lista di over dempa brukarkontoar</strong> med opp til <strong>%{count} brukarkonto</strong> frå <strong>%{filename}</strong>.
         other: Du skal til å <strong>byta ut lista di over dempa brukarkontoar</strong> med opp til <strong>%{count} brukarkontoar</strong> frå <strong>%{filename}</strong>.
diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml
index 8b2feb5193..0ff944e108 100644
--- a/config/locales/pt-BR.yml
+++ b/config/locales/pt-BR.yml
@@ -35,12 +35,12 @@ pt-BR:
     accounts:
       add_email_domain_block: Bloquear domínio de email
       approve: Aprovar
-      approved_msg: O registro de %{username} foi aprovado
+      approved_msg: Aprovado com sucesso o pedido de registro de %{username}
       are_you_sure: Você tem certeza?
       avatar: Imagem de perfil
       by_domain: Domínio
       change_email:
-        changed_msg: E-mail alterado!
+        changed_msg: E-mail alterado com sucesso!
         current_email: E-mail atual
         label: Alterar e-mail
         new_email: Novo e-mail
@@ -187,6 +187,7 @@ pt-BR:
         create_domain_block: Bloquear domínio
         create_email_domain_block: Criar Bloqueio de Domínio de Email
         create_ip_block: Criar regra de IP
+        create_relay: Criar Retransmissão
         create_unavailable_domain: Criar domínio indisponível
         create_user_role: Criar cargo
         demote_user: Rebaixar usuário
@@ -198,14 +199,17 @@ pt-BR:
         destroy_email_domain_block: Deletar bloqueio de domínio Email
         destroy_instance: Limpar domínio
         destroy_ip_block: Excluir regra de IP
+        destroy_relay: Excluir Retransmissão
         destroy_status: Excluir publicação
         destroy_unavailable_domain: Excluir domínio indisponível
         destroy_user_role: Destruir cargo
         disable_2fa_user: Desativar autenticação de dois fatores
         disable_custom_emoji: Desativar emoji personalizado
+        disable_relay: Desativar Retransmissão
         disable_sign_in_token_auth_user: Desativar autenticação via Token de Email para Usuário
         disable_user: Desativar usuário
         enable_custom_emoji: Ativar emoji personalizado
+        enable_relay: Ativar Retransmissão
         enable_sign_in_token_auth_user: Ativar autenticação via Token de Email para Usuário
         enable_user: Ativar usuário
         memorialize_account: Converter conta em memorial
@@ -247,6 +251,7 @@ pt-BR:
         create_domain_block_html: "%{name} bloqueou o domínio %{target}"
         create_email_domain_block_html: "%{name} bloqueou o domínio de e-mail %{target}"
         create_ip_block_html: "%{name} criou a regra para o IP %{target}"
+        create_relay_html: "%{name} criou uma retransmissão %{target}"
         create_unavailable_domain_html: "%{name} parou a entrega ao domínio %{target}"
         create_user_role_html: "%{name} criou o cargo %{target}"
         demote_user_html: "%{name} rebaixou o usuário %{target}"
@@ -258,14 +263,17 @@ pt-BR:
         destroy_email_domain_block_html: "%{name} desbloqueou o domínio de e-mail %{target}"
         destroy_instance_html: "%{name} limpou o domínio %{target}"
         destroy_ip_block_html: "%{name} excluiu a regra para o IP %{target}"
+        destroy_relay_html: "%{name} excluiu uma retransmissão %{target}"
         destroy_status_html: "%{name} removeu a publicação de %{target}"
         destroy_unavailable_domain_html: "%{name} retomou a entrega ao domínio %{target}"
         destroy_user_role_html: "%{name} excluiu o cargo %{target}"
         disable_2fa_user_html: "%{name} desativou a exigência da autenticação de dois fatores para o usuário %{target}"
         disable_custom_emoji_html: "%{name} desativou o emoji %{target}"
+        disable_relay_html: "%{name} desativou uma retransmissão %{target}"
         disable_sign_in_token_auth_user_html: "%{name} desativou a autenticação via token por e-mail para %{target}"
         disable_user_html: "%{name} desativou o login para %{target}"
         enable_custom_emoji_html: "%{name} ativou o emoji %{target}"
+        enable_relay_html: "%{name} ativou uma retransmissão %{target}"
         enable_sign_in_token_auth_user_html: "%{name} ativou a autenticação via token por e-mail para %{target}"
         enable_user_html: "%{name} ativou o login para %{target}"
         memorialize_account_html: "%{name} transformou a conta de %{target} em um memorial"
@@ -1368,6 +1376,10 @@ pt-BR:
       merge_long: Manter os registros existentes e adicionar novos
       overwrite: Sobrescrever
       overwrite_long: Substituir os registros atuais com os novos
+    overwrite_preambles:
+      bookmarks_html:
+        one: Você está prestes a <strong>substituir seus salvos</strong> por até <strong>%{count} publicação</strong> de <strong>%{filename}</strong>.
+        other: Você está prestes a <strong>substituir seus salvos</strong> por até <strong>%{count} publicações</strong> de <strong>%{filename}</strong>.
     preface: Você pode importar dados que você exportou de outro servidor, como a lista de pessoas que você segue ou bloqueou.
     recent_imports: Importações recentes
     states:
diff --git a/config/locales/ru.yml b/config/locales/ru.yml
index 831f68b24b..8a84f22115 100644
--- a/config/locales/ru.yml
+++ b/config/locales/ru.yml
@@ -179,104 +179,112 @@ ru:
       whitelisted: В белом списке
     action_logs:
       action_types:
-        approve_appeal: Одобрить обжалование
-        approve_user: Утвердить
+        approve_appeal: Одобрение обжалований
+        approve_user: Утверждение регистраций
         assigned_to_self_report: Присвоение жалоб
-        change_email_user: Сменить e-mail для пользователя
-        change_role_user: Изменить роль пользователя
+        change_email_user: Смена e-mail пользователей
+        change_role_user: Смена ролей пользователей
         confirm_user: Подтверждение пользователей
         create_account_warning: Выдача предупреждения
         create_announcement: Создание объявлений
-        create_canonical_email_block: Создать блок электронной почты
+        create_canonical_email_block: Создание блокировок e-mail
         create_custom_emoji: Добавление эмодзи
         create_domain_allow: Разрешение доменов
         create_domain_block: Блокировка доменов
-        create_email_domain_block: Создать блок домена электронной почты
+        create_email_domain_block: Создание доменных блокировок e-mail
         create_ip_block: Создание правил для IP-адресов
+        create_relay: Создание ретранслятора
         create_unavailable_domain: Добавление домена в список недоступных
-        create_user_role: Создать роль
+        create_user_role: Создание ролей
         demote_user: Разжалование пользователей
         destroy_announcement: Удаление объявлений
-        destroy_canonical_email_block: Удалить блок электронной почты
+        destroy_canonical_email_block: Удаление блокировок e-mail
         destroy_custom_emoji: Удаление эмодзи
         destroy_domain_allow: Отзыв разрешений для доменов
         destroy_domain_block: Разблокировка доменов
-        destroy_email_domain_block: Удалить блок домена электронной почты
+        destroy_email_domain_block: Удаление доменных блокировок e-mail
         destroy_instance: Очистить домен
         destroy_ip_block: Удаление правил для IP-адресов
+        destroy_relay: Удаление ретранслятора
         destroy_status: Удаление постов
         destroy_unavailable_domain: Исключение доменов из списка недоступных
-        destroy_user_role: Удалить роль
+        destroy_user_role: Удаление ролей
         disable_2fa_user: Отключение 2FA
         disable_custom_emoji: Отключение эмодзи
-        disable_sign_in_token_auth_user: Отключить аутентификацию пользователя с помощью токена электронной почты
+        disable_relay: Отключение ретранслятора
+        disable_sign_in_token_auth_user: Отключение аутентификации по e-mail кодам
         disable_user: Заморозка пользователей
         enable_custom_emoji: Включение эмодзи
-        enable_sign_in_token_auth_user: Включить аутентификацию пользователя с помощью токена электронной почты
+        enable_relay: Включение ретранслятора
+        enable_sign_in_token_auth_user: Включение аутентификации по e-mail кодам
         enable_user: Разморозка пользователей
         memorialize_account: Присвоение пользователям статуса «мемориала»
         promote_user: Повышение пользователей
-        reject_appeal: Отклонить обжалование
-        reject_user: Отклонить
+        reject_appeal: Отклонение обжалований
+        reject_user: Отклонение регистраций
         remove_avatar_user: Удаление аватаров
         reopen_report: Возобновление жалоб
-        resend_user: Повторно отправить письмо с подтверждением
+        resend_user: Повторная отправка писем с подтверждением
         reset_password_user: Сброс пароля пользователей
         resolve_report: Отметка жалоб «решёнными»
         sensitive_account: Присвоение пользователям отметки «деликатного содержания»
         silence_account: Скрытие пользователей
         suspend_account: Блокировка пользователей
         unassigned_report: Снятие жалоб
-        unblock_email_account: Разблокировать e-mail адрес
+        unblock_email_account: Разблокировка e-mail адресов
         unsensitive_account: Снятие с пользователей отметки «деликатного содержания»
         unsilence_account: Отмена скрытия пользователей
         unsuspend_account: Разблокировка пользователей
         update_announcement: Обновление объявлений
         update_custom_emoji: Обновление эмодзи
         update_domain_block: Изменение блокировки домена
-        update_ip_block: Обновить правило для IP-адреса
-        update_report: Обновить рапорт
+        update_ip_block: Обновление правил для IP-адресов
+        update_report: Изменение жалоб
         update_status: Изменение постов
-        update_user_role: Обновить роль
+        update_user_role: Изменение ролей
       actions:
-        approve_appeal_html: "%{name} одобрил апелляцию на умеренное решение от %{target}"
+        approve_appeal_html: "%{name} одобрил(а) обжалование действий модерации от %{target}"
         approve_user_html: "%{name} утвердил(а) регистрацию %{target}"
         assigned_to_self_report_html: "%{name} назначил(а) себя для решения жалобы %{target}"
-        change_email_user_html: "%{name} изменил адрес электронной почты пользователя %{target}"
+        change_email_user_html: "%{name} cменил(а) e-mail адрес пользователя %{target}"
         change_role_user_html: "%{name} изменил(а) роль %{target}"
-        confirm_user_html: "%{name} подтвержденный адрес электронной почты пользователя %{target}"
+        confirm_user_html: "%{name} подтвердил(а) e-mail адрес пользователя %{target}"
         create_account_warning_html: "%{name} выдал(а) предупреждение %{target}"
         create_announcement_html: "%{name} создал(а) новое объявление %{target}"
-        create_canonical_email_block_html: "%{name} заблокировал письмо с хэшем %{target}"
+        create_canonical_email_block_html: "%{name} заблокировал(а) e-mail с хешем %{target}"
         create_custom_emoji_html: "%{name} загрузил(а) новый эмодзи %{target}"
         create_domain_allow_html: "%{name} разрешил(а) федерацию с доменом %{target}"
         create_domain_block_html: "%{name} заблокировал(а) домен %{target}"
-        create_email_domain_block_html: "%{name} заблокированный почтовый домен %{target}"
+        create_email_domain_block_html: "%{name} заблокировал(а) e-mail домен %{target}"
         create_ip_block_html: "%{name} создал(а) правило для IP %{target}"
+        create_relay_html: "%{name} создал(а) ретранслятор %{target}"
         create_unavailable_domain_html: "%{name} приостановил доставку на узел %{target}"
         create_user_role_html: "%{name} создал(а) роль %{target}"
         demote_user_html: "%{name} разжаловал(а) пользователя %{target}"
         destroy_announcement_html: "%{name} удалил(а) объявление %{target}"
-        destroy_canonical_email_block_html: "%{name} разблокированное письмо с хэшем %{target}"
+        destroy_canonical_email_block_html: "%{name} снял(а) блокировку e-mail с хэшем %{target}"
         destroy_custom_emoji_html: "%{name} удалил(а) эмодзи %{target}"
         destroy_domain_allow_html: "%{name} запретил(а) федерацию с доменом %{target}"
         destroy_domain_block_html: "%{name} снял(а) блокировку с домена %{target}"
-        destroy_email_domain_block_html: "%{name} разблокированный почтовый домен %{target}"
+        destroy_email_domain_block_html: "%{name} снял(а) блокировку с e-mail домена %{target}"
         destroy_instance_html: "%{name} очистил(а) данные для домена %{target}"
         destroy_ip_block_html: "%{name} удалил(а) правило для IP %{target}"
+        destroy_relay_html: "%{name} удалил(а) ретранслятор %{target}"
         destroy_status_html: "%{name} удалил(а) пост пользователя %{target}"
         destroy_unavailable_domain_html: "%{name} возобновил доставку на узел %{target}"
         destroy_user_role_html: "%{name} удалил(а) роль %{target}"
         disable_2fa_user_html: "%{name} отключил(а) требование двухэтапной авторизации для пользователя %{target}"
         disable_custom_emoji_html: "%{name} отключил(а) эмодзи %{target}"
-        disable_sign_in_token_auth_user_html: "%{name} отключил аутентификацию по маркеру электронной почты для %{target}"
+        disable_relay_html: "%{name} отключил(а) ретранслятор %{target}"
+        disable_sign_in_token_auth_user_html: "%{name} отключил(а) аутентификацию по e-mail кодам для %{target}"
         disable_user_html: "%{name} заморозил(а) пользователя %{target}"
         enable_custom_emoji_html: "%{name} включил(а) эмодзи %{target}"
-        enable_sign_in_token_auth_user_html: "%{name} включил аутентификацию с помощью маркера электронной почты для %{target}"
+        enable_relay_html: "%{name} включил(а) ретранслятор %{target}"
+        enable_sign_in_token_auth_user_html: "%{name} включил(а) аутентификацию по e-mail кодам для %{target}"
         enable_user_html: "%{name} разморозил(а) пользователя %{target}"
         memorialize_account_html: "%{name} перевел(а) учётную запись пользователя %{target} в статус памятника"
         promote_user_html: "%{name} повысил(а) пользователя %{target}"
-        reject_appeal_html: "%{name} отклонил апелляцию на модерацию от %{target}"
+        reject_appeal_html: "%{name} отклонил(а) обжалование действий модерации от %{target}"
         reject_user_html: "%{name} отклонил(а) регистрацию %{target}"
         remove_avatar_user_html: "%{name} убрал(а) аватарку пользователя %{target}"
         reopen_report_html: "%{name} повторно открыл(а) жалобу %{target}"
@@ -295,7 +303,7 @@ ru:
         update_custom_emoji_html: "%{name} обновил(а) эмодзи %{target}"
         update_domain_block_html: "%{name} обновил(а) блокировку домена для %{target}"
         update_ip_block_html: "%{name} изменил(а) правило для IP %{target}"
-        update_report_html: "%{name} обновленный отчет %{target}"
+        update_report_html: "%{name} изменил(а) жалобу %{target}"
         update_status_html: "%{name} изменил(а) пост пользователя %{target}"
         update_user_role_html: "%{name} изменил(а) роль %{target}"
       deleted_account: удалённая учётная запись
diff --git a/config/locales/simple_form.ko.yml b/config/locales/simple_form.ko.yml
index b2ebf5666d..962f062534 100644
--- a/config/locales/simple_form.ko.yml
+++ b/config/locales/simple_form.ko.yml
@@ -46,7 +46,7 @@ ko:
         current_password: 보안을 위해 현재 계정의 암호를 입력해주세요
         current_username: 확인을 위해, 현재 계정의 사용자명을 입력해주세요
         digest: 오랫동안 활동하지 않았을 때 받은 멘션들에 대한 요약 받기
-        email: 확인용 이메일을 보냈습니다.
+        email: 확인용 이메일을 보내게 됩니다
         header: WEBP, PNG, GIF 혹은 JPG. 최대 %{size}. %{dimensions}px로 축소됨
         inbox_url: 사용 할 릴레이 서버의 프론트페이지에서 URL을 복사합니다
         irreversible: 필터링 된 게시물은 나중에 필터가 사라지더라도 돌아오지 않게 됩니다
diff --git a/config/locales/simple_form.lt.yml b/config/locales/simple_form.lt.yml
index d9204efaaa..77482d8012 100644
--- a/config/locales/simple_form.lt.yml
+++ b/config/locales/simple_form.lt.yml
@@ -10,6 +10,7 @@ lt:
         indexable: Tavo vieši įrašai gali būti rodomi Mastodon paieškos rezultatuose. Žmonės, kurie bendravo su tavo įrašais, gali jų ieškoti nepriklausomai nuo to.
         note: 'Gali @paminėti kitus žmones arba #saitažodžius.'
         show_collections: Žmonės galės peržiūrėti tavo sekimus ir sekėjus. Žmonės, kuriuos seki, matys, kad juos seki, nepaisant to.
+        unlocked: Žmonės galės jus sekti nepaprašę patvirtinimo. Panaikinkite žymėjimą, jei norite peržiūrėti sekimo prašymus ir pasirinkti, ar priimti, ar atmesti naujus sekėjus.
       account_alias:
         acct: Nurodyk paskyros, iš kurios nori perkelti, naudotojo vardą@domeną
       account_migration:
diff --git a/config/locales/simple_form.nl.yml b/config/locales/simple_form.nl.yml
index 5318059f4a..2bb31aa0f9 100644
--- a/config/locales/simple_form.nl.yml
+++ b/config/locales/simple_form.nl.yml
@@ -3,7 +3,7 @@ nl:
   simple_form:
     hints:
       account:
-        attribution_domains_as_text: Eén per regel. Beschermt tegen valse toeschrijvingen.
+        attribution_domains_as_text: Eén per regel. Beschermt tegen ongeldige attributies.
         discoverable: Jouw openbare berichten kunnen worden uitgelicht op verschillende plekken binnen Mastodon en jouw account kan worden aanbevolen aan andere gebruikers.
         display_name: Jouw volledige naam of een leuke bijnaam.
         fields: Jouw website, persoonlijke voornaamwoorden, leeftijd, alles wat je maar kwijt wilt.
diff --git a/config/locales/simple_form.nn.yml b/config/locales/simple_form.nn.yml
index 008af2c5ac..46b7af4bdb 100644
--- a/config/locales/simple_form.nn.yml
+++ b/config/locales/simple_form.nn.yml
@@ -10,6 +10,7 @@ nn:
         indexable: Dei offentlege innlegga dine kan dukka opp i søkjeresultat på Mastodon. Folk som har reagert på oinnlegga dine kan uansett søkja gjennom dei.
         note: 'Du kan @nemne folk eller #emneknaggar.'
         show_collections: Andre kan sjå kven du fylgjer og kven som fylgjer deg. Dei du fylgjer kan alltid sjå at du fylgjer dei.
+        unlocked: Alle kan fylgja deg utan å måtta be om det. Vel bort dersom du vil gå gjennom førespurnader om å fylgja deg og seia ja eller nei til kvar av dei.
       account_alias:
         acct: Angi brukarnamn@domene til brukaren du ynskjer å flytta frå
       account_migration:
diff --git a/config/locales/simple_form.pl.yml b/config/locales/simple_form.pl.yml
index 4fba45098d..c5ff55c15d 100644
--- a/config/locales/simple_form.pl.yml
+++ b/config/locales/simple_form.pl.yml
@@ -10,6 +10,7 @@ pl:
         indexable: Twoje publiczne wpisy mogą pojawiać się w wynikach wyszukiwania w Mastodonie. Użytkownicy, którzy wchodzili w interakcje z twoimi wpisami będą mogli je znaleźć niezależnie od tego ustawienia.
         note: 'Możesz @wspomnieć użytkowników albo #hasztagi.'
         show_collections: Twoja lista obserwowanych i obserwujących będzie widoczna dla wszystkich. Użytkownicy których obserwujesz będą jednak o tym wiedzieli.
+        unlocked: Inni użytkownicy będą mogli cię obserwować bez proszenia o zgodę. Odznacz, jeżeli chcesz aprobować obserwujących ręcznie po przejrzeniu próśb o obserwowanie.
       account_alias:
         acct: Określ nazwę@domenę konta z którego chcesz się przenieść
       account_migration:
diff --git a/config/locales/simple_form.ru.yml b/config/locales/simple_form.ru.yml
index d8822d35b9..37626ff9fd 100644
--- a/config/locales/simple_form.ru.yml
+++ b/config/locales/simple_form.ru.yml
@@ -10,6 +10,7 @@ ru:
         indexable: Ваши публичные сообщения могут появляться в результатах поиска на Mastodon. Люди, которые взаимодействовали с вашими сообщениями, могут искать их независимо от этого.
         note: 'Вы можете @упоминать других людей или #хэштеги.'
         show_collections: Люди смогут просматривать список ваших подписок и подписчиков. Люди, за которыми вы следуете, будут видеть, что вы подписаны на них, несмотря ни на что.
+        unlocked: Люди смогут подписываться на вас, не запрашивая подтверждения. Снимите флажок, если вы хотите просматривать запросы на подписку и выбирать, принимать или отклонять новых подписчиков.
       account_alias:
         acct: Укажите имя_пользователя@домен учётной записи, с которой вы собираетесь мигрировать
       account_migration:
diff --git a/config/locales/simple_form.sv.yml b/config/locales/simple_form.sv.yml
index b8303e2945..72c3f000f6 100644
--- a/config/locales/simple_form.sv.yml
+++ b/config/locales/simple_form.sv.yml
@@ -10,6 +10,7 @@ sv:
         indexable: Dina offentliga inlägg kan visas i sökresultat på Mastodon. Personer som har interagerat med dina inlägg kan söka dem oavsett.
         note: 'Du kan @nämna andra personer eller #hashtaggar.'
         show_collections: Andra kan se vem du följer och vem som följer dig. De du följer kan alltid se att du följer dem.
+        unlocked: Andra kommer att kunna följa dig utan att begära godkännande. Avmarkera om du vill granska följeslagare och välja om du vill acceptera eller avvisa nya följare.
       account_alias:
         acct: Ange användarnamn@domän för kontot som du vill flytta från
       account_migration:
diff --git a/config/locales/sq.yml b/config/locales/sq.yml
index 6cff74fb50..e5becbd916 100644
--- a/config/locales/sq.yml
+++ b/config/locales/sq.yml
@@ -187,6 +187,7 @@ sq:
         create_domain_block: Krijo Bllokim Përkatësie
         create_email_domain_block: Krijoni Bllokim Përkatësie Email-esh
         create_ip_block: Krijoni Rregull IP
+        create_relay: Krijoni Rele
         create_unavailable_domain: Krijo Përkatësi të Papërdorshme
         create_user_role: Krijoni Rol
         demote_user: Zhgradoje Përdoruesin
@@ -198,14 +199,17 @@ sq:
         destroy_email_domain_block: Fshini Bllokim Përkatësie Email-esh
         destroy_instance: Spastroje Përkatësinë
         destroy_ip_block: Fshini Rregull IP
+        destroy_relay: Fshije Relenë
         destroy_status: Fshi Gjendje
         destroy_unavailable_domain: Fshi Përkatësi të Papërdorshme
         destroy_user_role: Asgjësoje Rolin
         disable_2fa_user: Çaktivizo 2FA-në
         disable_custom_emoji: Çaktivizo Emotikon Vetjak
+        disable_relay: Çaktivizoje Relenë
         disable_sign_in_token_auth_user: Çaktivizoni për Përdoruesin Mirëfilltësim Me Token Email-i
         disable_user: Çaktivizo Përdorues
         enable_custom_emoji: Aktivizo Emotikon Vetjak
+        enable_relay: Aktivizoje Relenë
         enable_sign_in_token_auth_user: Aktivizoni për Përdoruesin Mirëfilltësim Me Token Email-i
         enable_user: Aktivizo Përdorues
         memorialize_account: Bëje Llogari Përkujtimore
@@ -247,6 +251,7 @@ sq:
         create_domain_block_html: "%{name} bllokoi përkatësinë %{target}"
         create_email_domain_block_html: "%{name} bllokoi përkatësinë email %{target}"
         create_ip_block_html: "%{name} krijoi rregull për IP-në %{target}"
+        create_relay_html: "%{name} krijoi një rele %{target}"
         create_unavailable_domain_html: "%{name} ndali dërgimin drejt përkatësisë %{target}"
         create_user_role_html: "%{name} krijoi rolin %{target}"
         demote_user_html: "%{name} zhgradoi përdoruesin %{target}"
@@ -258,14 +263,17 @@ sq:
         destroy_email_domain_block_html: "%{name} zhbllokoi përkatësi email %{target}"
         destroy_instance_html: "%{name} spastroi përkatësinë %{target}"
         destroy_ip_block_html: "%{name} fshiu rregull për IP-në %{target}"
+        destroy_relay_html: "%{name} fshiu relenë %{target}"
         destroy_status_html: "%{name} hoqi gjendje nga %{target}"
         destroy_unavailable_domain_html: "%{name} rinisi dërgimin drejt përkatësisë %{target}"
         destroy_user_role_html: "%{name} fshiu rolin %{target}"
         disable_2fa_user_html: "%{name} çaktivizoi domosdoshmërinë për dyfaktorësh për përdoruesin %{target}"
         disable_custom_emoji_html: "%{name} çaktivizoi emoxhin %{target}"
+        disable_relay_html: "%{name} çaktivizoi relenë %{target}"
         disable_sign_in_token_auth_user_html: "%{name} çaktivizoi mirëfilltësim me token email për %{target}"
         disable_user_html: "%{name} çaktivizoi hyrje për përdoruesin %{target}"
         enable_custom_emoji_html: "%{name} aktivizoi emoxhin %{target}"
+        enable_relay_html: "%{name} aktivizoi relenë %{target}"
         enable_sign_in_token_auth_user_html: "%{name} aktivizoi mirëfilltësim me token email për %{target}"
         enable_user_html: "%{name} aktivizoi hyrje për përdoruesin %{target}"
         memorialize_account_html: "%{name} e shndërroi llogarinë e %{target} në një faqe përkujtimore"
diff --git a/config/locales/sv.yml b/config/locales/sv.yml
index b2ec21b82e..c41795a168 100644
--- a/config/locales/sv.yml
+++ b/config/locales/sv.yml
@@ -187,6 +187,7 @@ sv:
         create_domain_block: Skapa blockerad domän
         create_email_domain_block: Skapa E-post domän block
         create_ip_block: Skapa IP-regel
+        create_relay: Skapa ombud
         create_unavailable_domain: Skapa otillgänglig domän
         create_user_role: Skapa roll
         demote_user: Degradera användare
@@ -198,14 +199,17 @@ sv:
         destroy_email_domain_block: Ta bort E-post domän block
         destroy_instance: Rensa domänen
         destroy_ip_block: Radera IP-regel
+        destroy_relay: Radera ombud
         destroy_status: Radera inlägg
         destroy_unavailable_domain: Ta bort otillgänglig domän
         destroy_user_role: Förstör roll
         disable_2fa_user: Inaktivera 2FA
         disable_custom_emoji: Inaktivera egna emojis
+        disable_relay: Inaktivera ombud
         disable_sign_in_token_auth_user: Inaktivera autentisering med pollett via e-post för användare
         disable_user: Inaktivera användare
         enable_custom_emoji: Aktivera egna emojis
+        enable_relay: Aktivera ombud
         enable_sign_in_token_auth_user: Aktivera autentisering med pollett via e-post för användare
         enable_user: Aktivera användare
         memorialize_account: Minnesmärk konto
@@ -247,6 +251,7 @@ sv:
         create_domain_block_html: "%{name} blockerade domänen %{target}"
         create_email_domain_block_html: "%{name} blockerade e-post domänet%{target}"
         create_ip_block_html: "%{name} skapade regel för IP %{target}"
+        create_relay_html: "%{name} skapade ombudet %{target}"
         create_unavailable_domain_html: "%{name} stoppade leverans till domänen %{target}"
         create_user_role_html: "%{name} skapade rollen %{target}"
         demote_user_html: "%{name} nedgraderade användare %{target}"
@@ -258,14 +263,17 @@ sv:
         destroy_email_domain_block_html: "%{name} avblockerade e-post domänet %{target}"
         destroy_instance_html: "%{name} rensade domän %{target}"
         destroy_ip_block_html: "%{name} tog bort regel för IP %{target}"
+        destroy_relay_html: "%{name} tog bort ombudet %{target}"
         destroy_status_html: "%{name} tog bort inlägget av %{target}"
         destroy_unavailable_domain_html: "%{name} återupptog leverans till domänen %{target}"
         destroy_user_role_html: "%{name} raderade rollen %{target}"
         disable_2fa_user_html: "%{name} inaktiverade tvåfaktorsautentiseringskrav för användaren %{target}"
         disable_custom_emoji_html: "%{name} inaktiverade emoji %{target}"
+        disable_relay_html: "%{name} inaktiverade ombudet %{target}"
         disable_sign_in_token_auth_user_html: "%{name} inaktiverade e-posttokenautentisering för %{target}"
         disable_user_html: "%{name} stängde av inloggning för användaren %{target}"
         enable_custom_emoji_html: "%{name} aktiverade emoji %{target}"
+        enable_relay_html: "%{name} aktiverat ombudet %{target}"
         enable_sign_in_token_auth_user_html: "%{name} aktiverade e-posttokenautentisering för %{target}"
         enable_user_html: "%{name} aktiverade inloggning för användaren %{target}"
         memorialize_account_html: "%{name} gjorde %{target}s konto till en minnessida"
@@ -571,7 +579,7 @@ sv:
     relationships:
       title: "%{acct}s relationer"
     relays:
-      add_new: Lägg till nytt relä
+      add_new: Lägg till nytt ombud
       delete: Radera
       description_html: Ett <strong>federeringsombud</strong> är en mellanliggande server som utbyter höga antal offentliga inlägg mellan servrar som prenumererar på och publicerar till det. <strong>Det kan hjälpa små och medelstora servrar upptäcka innehåll från fediversumet</strong>, vilket annars skulle kräva att lokala användare manuellt följer personer på fjärrservrar.
       disable: Inaktivera
@@ -582,10 +590,10 @@ sv:
       inbox_url: Ombuds-URL
       pending: Väntar på ombudets godkännande
       save_and_enable: Spara och aktivera
-      setup: Konfigurera en relä-anslutning
-      signatures_not_enabled: Ombud fungerar inte korrekt medan säkert läge eller begränsat federeringsläge är aktiverade
+      setup: Konfigurera ett ombud
+      signatures_not_enabled: Ombud fungerar inte korrekt om säkert läge eller begränsat federeringsläge är aktiverade
       status: Status
-      title: Relä
+      title: Ombud
     report_notes:
       created_msg: Anmälningsanteckning har skapats!
       destroyed_msg: Anmälningsanteckning har raderats!
diff --git a/config/locales/tr.yml b/config/locales/tr.yml
index 942ee2fbf2..88636ef21b 100644
--- a/config/locales/tr.yml
+++ b/config/locales/tr.yml
@@ -187,6 +187,7 @@ tr:
         create_domain_block: Engellenen Alan Adı Oluştur
         create_email_domain_block: E-Posta Alan Adı Engeli Oluştur
         create_ip_block: IP kuralı oluştur
+        create_relay: Aktarıcı Oluştur
         create_unavailable_domain: Mevcut Olmayan Alan Adı Oluştur
         create_user_role: Rol Oluştur
         demote_user: Kullanıcıyı Düşür
@@ -198,14 +199,17 @@ tr:
         destroy_email_domain_block: E-posta Alan Adı Engelini Sil
         destroy_instance: Alan adını temizle
         destroy_ip_block: IP kuralını sil
+        destroy_relay: Aktarıcı Sil
         destroy_status: Durumu Sil
         destroy_unavailable_domain: Mevcut Olmayan Alan Adı Sil
         destroy_user_role: Rolü Kaldır
         disable_2fa_user: 2AD Kapat
         disable_custom_emoji: Özel İfadeyi Devre Dışı Bırak
+        disable_relay: Aktarıcıyı Devre Dışı Bırak
         disable_sign_in_token_auth_user: Kullanıcı için E-posta Token Doğrulamayı Devre Dışı Bırak
         disable_user: Kullanıcıyı Devre Dışı Bırak
         enable_custom_emoji: Özel İfadeyi Etkinleştir
+        enable_relay: Aktarıcıyı Etkinleştir
         enable_sign_in_token_auth_user: Kullanıcı için E-posta Token Doğrulamayı Etkinleştir
         enable_user: Kullanıcıyı Etkinleştir
         memorialize_account: Hesabı Anıtlaştır
@@ -247,6 +251,7 @@ tr:
         create_domain_block_html: "%{name}, %{target} alan adını engelledi"
         create_email_domain_block_html: "%{name}, %{target} e-posta alan adını engelledi"
         create_ip_block_html: "%{name}, %{target} IP adresi için kural oluşturdu"
+        create_relay_html: "%{name}, %{target} aktarıcısını oluşturdu"
         create_unavailable_domain_html: "%{name}, %{target} alan adına teslimatı durdurdu"
         create_user_role_html: "%{name}, %{target} rolünü oluşturdu"
         demote_user_html: "%{name}, %{target} kullanıcısını düşürdü"
@@ -258,14 +263,17 @@ tr:
         destroy_email_domain_block_html: "%{name}, %{target} e-posta alan adı engelini kaldırdı"
         destroy_instance_html: "%{name}, %{target} alan adını temizledi"
         destroy_ip_block_html: "%{name}, %{target} IP adresi kuralını sildi"
+        destroy_relay_html: "%{name}, %{target} aktarıcısını sildi"
         destroy_status_html: "%{name}, %{target} kullanıcısının gönderisini kaldırdı"
         destroy_unavailable_domain_html: "%{name}, %{target} alan adına teslimatı sürdürdü"
         destroy_user_role_html: "%{name}, %{target} rolünü sildi"
         disable_2fa_user_html: "%{name}, %{target} kullanıcısının iki aşamalı doğrulama gereksinimini kapattı"
         disable_custom_emoji_html: "%{name}, %{target} emojisini devre dışı bıraktı"
+        disable_relay_html: "%{name}, %{target} aktarıcısını devre dışı bıraktı"
         disable_sign_in_token_auth_user_html: "%{name}, %{target} için e-posta token doğrulamayı devre dışı bıraktı"
         disable_user_html: "%{name}, %{target} kullanıcısı için oturum açmayı devre dışı bıraktı"
         enable_custom_emoji_html: "%{name}, %{target} emojisini etkinleştirdi"
+        enable_relay_html: "%{name}, %{target} aktarıcısını etkinleştirdi"
         enable_sign_in_token_auth_user_html: "%{name}, %{target} için e-posta token doğrulamayı etkinleştirdi"
         enable_user_html: "%{name}, %{target} kullanıcısı için oturum açmayı etkinleştirdi"
         memorialize_account_html: "%{name}, %{target} kullanıcısının hesabını bir anıt sayfaya dönüştürdü"
diff --git a/config/locales/vi.yml b/config/locales/vi.yml
index 172ce55a3d..1d04f796f8 100644
--- a/config/locales/vi.yml
+++ b/config/locales/vi.yml
@@ -184,6 +184,7 @@ vi:
         create_domain_block: Chặn máy chủ
         create_email_domain_block: Chặn tên miền email
         create_ip_block: Chặn IP
+        create_relay: Tạo relay
         create_unavailable_domain: Bỏ liên hợp
         create_user_role: Tạo vai trò
         demote_user: Hạ vai trò
@@ -195,14 +196,17 @@ vi:
         destroy_email_domain_block: Bỏ chặn tên miền email
         destroy_instance: Thanh trừng máy chủ
         destroy_ip_block: Bỏ chặn IP
+        destroy_relay: Xóa relay
         destroy_status: Xóa tút
         destroy_unavailable_domain: Cho phép liên hợp
         destroy_user_role: Xóa vai trò
         disable_2fa_user: Vô hiệu hóa 2FA
         disable_custom_emoji: Vô hiệu hóa emoji
+        disable_relay: Tắt relay
         disable_sign_in_token_auth_user: Tắt xác minh bằng email cho người dùng
         disable_user: Vô hiệu hóa đăng nhập
         enable_custom_emoji: Cho phép emoji
+        enable_relay: Bật relay
         enable_sign_in_token_auth_user: Bật xác minh bằng email cho người dùng
         enable_user: Cho phép đăng nhập
         memorialize_account: Gán tưởng niệm
@@ -244,6 +248,7 @@ vi:
         create_domain_block_html: "%{name} đã chặn máy chủ %{target}"
         create_email_domain_block_html: "%{name} đã chặn tên miền email %{target}"
         create_ip_block_html: "%{name} đã chặn IP %{target}"
+        create_relay_html: "%{name} đã tạo relay %{target}"
         create_unavailable_domain_html: "%{name} đã bỏ liên hợp với máy chủ %{target}"
         create_user_role_html: "%{name} đã tạo vai trò %{target}"
         demote_user_html: "%{name} đã hạ vai trò của %{target}"
@@ -255,14 +260,17 @@ vi:
         destroy_email_domain_block_html: "%{name} đã bỏ chặn email %{target}"
         destroy_instance_html: "%{name} đã thanh trừng máy chủ %{target}"
         destroy_ip_block_html: "%{name} đã bỏ chặn IP %{target}"
+        destroy_relay_html: "%{name} đã xóa relay %{target}"
         destroy_status_html: "%{name} đã xóa tút của %{target}"
         destroy_unavailable_domain_html: "%{name} tiếp tục liên hợp với máy chủ %{target}"
         destroy_user_role_html: "%{name} đã xóa vai trò %{target}"
         disable_2fa_user_html: "%{name} đã vô hiệu hóa xác minh hai bước của %{target}"
         disable_custom_emoji_html: "%{name} đã ẩn emoji %{target}"
+        disable_relay_html: "%{name} đã tắt relay %{target}"
         disable_sign_in_token_auth_user_html: "%{name} đã tắt xác minh email của %{target}"
         disable_user_html: "%{name} đã vô hiệu hóa đăng nhập %{target}"
         enable_custom_emoji_html: "%{name} đã cho phép emoji %{target}"
+        enable_relay_html: "%{name} đã bật relay %{target}"
         enable_sign_in_token_auth_user_html: "%{name} đã bật xác minh email của %{target}"
         enable_user_html: "%{name} đã bỏ vô hiệu hóa đăng nhập %{target}"
         memorialize_account_html: "%{name} đã biến tài khoản %{target} thành một trang tưởng niệm"
diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml
index 209683e21c..36d316649c 100644
--- a/config/locales/zh-CN.yml
+++ b/config/locales/zh-CN.yml
@@ -184,6 +184,7 @@ zh-CN:
         create_domain_block: 封禁新域名
         create_email_domain_block: 封禁新的邮箱域名
         create_ip_block: 新建 IP 规则
+        create_relay: 创建中继站
         create_unavailable_domain: 创建不可用域名
         create_user_role: 创建角色
         demote_user: 给用户降职
@@ -195,14 +196,17 @@ zh-CN:
         destroy_email_domain_block: 解除邮箱域名封禁
         destroy_instance: 删除实例
         destroy_ip_block: 删除 IP 规则
+        destroy_relay: 删除中继站
         destroy_status: 删除嘟文
         destroy_unavailable_domain: 删除不可用域名
         destroy_user_role: 销毁角色
         disable_2fa_user: 停用双因素认证
         disable_custom_emoji: 禁用自定义表情符号
+        disable_relay: 禁用中继站
         disable_sign_in_token_auth_user: 为用户禁用邮件令牌身份验证
         disable_user: 禁用用户
         enable_custom_emoji: 启用自定义表情符号
+        enable_relay: 启用中继站
         enable_sign_in_token_auth_user: 为用户启用邮件令牌身份验证
         enable_user: 启用用户
         memorialize_account: 将账户设为追悼模式
@@ -244,6 +248,7 @@ zh-CN:
         create_domain_block_html: "%{name} 屏蔽了域名 %{target}"
         create_email_domain_block_html: "%{name} 封禁了邮箱域名 %{target}"
         create_ip_block_html: "%{name} 为 IP %{target} 创建了规则"
+        create_relay_html: "%{name} 添加了中继站 %{target}"
         create_unavailable_domain_html: "%{name} 停止了向域名 %{target} 的投递"
         create_user_role_html: "%{name} 创建了 %{target} 角色"
         demote_user_html: "%{name} 对用户 %{target} 进行了降任操作"
@@ -255,14 +260,17 @@ zh-CN:
         destroy_email_domain_block_html: "%{name} 解封了邮箱域名 %{target}"
         destroy_instance_html: "%{name} 删除了实例 %{target}"
         destroy_ip_block_html: "%{name} 删除了 IP %{target} 的规则"
+        destroy_relay_html: "%{name} 删除了中继站 %{target}"
         destroy_status_html: "%{name} 删除了 %{target} 的嘟文"
         destroy_unavailable_domain_html: "%{name} 恢复了向域名 %{target} 的投递"
         destroy_user_role_html: "%{name} 删除了 %{target} 角色"
         disable_2fa_user_html: "%{name} 停用了用户 %{target} 的双因素认证"
         disable_custom_emoji_html: "%{name} 停用了自定义表情 %{target}"
+        disable_relay_html: "%{name} 停用了中继站 %{target}"
         disable_sign_in_token_auth_user_html: "%{name} 为 %{target} 禁用了邮件令牌身份验证"
         disable_user_html: "%{name} 将用户 %{target} 设置为禁止登录"
         enable_custom_emoji_html: "%{name} 启用了自定义表情 %{target}"
+        enable_relay_html: "%{name} 启用了中继站 %{target}"
         enable_sign_in_token_auth_user_html: "%{name} 为 %{target} 启用了邮件令牌身份验证"
         enable_user_html: "%{name} 将用户 %{target} 设置为允许登录"
         memorialize_account_html: "%{name} 将 %{target} 设置为追悼账户"
diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml
index d8fef10816..495a6a4742 100644
--- a/config/locales/zh-TW.yml
+++ b/config/locales/zh-TW.yml
@@ -184,6 +184,7 @@ zh-TW:
         create_domain_block: 新增網域封鎖
         create_email_domain_block: 新增電子郵件網域封鎖
         create_ip_block: 新增IP規則
+        create_relay: 新增中繼
         create_unavailable_domain: 新增無法存取的網域
         create_user_role: 新增角色
         demote_user: 將用戶降級
@@ -195,14 +196,17 @@ zh-TW:
         destroy_email_domain_block: 刪除電子郵件網域封鎖
         destroy_instance: 清除網域
         destroy_ip_block: 刪除 IP 規則
+        destroy_relay: 刪除中繼
         destroy_status: 刪除狀態
         destroy_unavailable_domain: 刪除無法存取的網域
         destroy_user_role: 移除角色
         disable_2fa_user: 停用兩階段驗證
         disable_custom_emoji: 停用自訂 emoji 表情符號
+        disable_relay: 停用中繼
         disable_sign_in_token_auth_user: 停用使用者電子郵件 token 驗證
         disable_user: 停用帳號
         enable_custom_emoji: 啟用自訂 emoji 表情符號
+        enable_relay: 啟用中繼
         enable_sign_in_token_auth_user: 啟用使用者電子郵件 token 驗證
         enable_user: 啓用帳號
         memorialize_account: 設定成追悼帳號
@@ -244,6 +248,7 @@ zh-TW:
         create_domain_block_html: "%{name} 已封鎖網域 %{target}"
         create_email_domain_block_html: "%{name} 已封鎖電子郵件網域 %{target}"
         create_ip_block_html: "%{name} 已設定 IP %{target} 的規則"
+        create_relay_html: "%{name} 已新增中繼 %{target}"
         create_unavailable_domain_html: "%{name} 停止發送至網域 %{target}"
         create_user_role_html: "%{name} 已新增 %{target} 角色"
         demote_user_html: "%{name} 將使用者 %{target} 降級"
@@ -255,14 +260,17 @@ zh-TW:
         destroy_email_domain_block_html: "%{name} 已解除封鎖電子郵件網域 %{target}"
         destroy_instance_html: "%{name} 已清除網域 %{target}"
         destroy_ip_block_html: "%{name} 已刪除 IP %{target} 的規則"
+        destroy_relay_html: "%{name} 已刪除中繼 %{target}"
         destroy_status_html: "%{name} 已刪除 %{target} 的嘟文"
         destroy_unavailable_domain_html: "%{name} 已恢復對網域 %{target} 的發送"
         destroy_user_role_html: "%{name} 已刪除 %{target} 角色"
         disable_2fa_user_html: "%{name} 已停用使用者 %{target} 的兩階段驗證 (2FA) "
         disable_custom_emoji_html: "%{name} 已停用自訂 emoji 表情符號 %{target}"
+        disable_relay_html: "%{name} 已停用中繼 %{target}"
         disable_sign_in_token_auth_user_html: "%{name} 已停用 %{target} 之使用者電子郵件 token 驗證"
         disable_user_html: "%{name} 將使用者 %{target} 設定為禁止登入"
         enable_custom_emoji_html: "%{name} 已啟用自訂 emoji 表情符號 %{target}"
+        enable_relay_html: "%{name} 已啟用中繼 %{target}"
         enable_sign_in_token_auth_user_html: "%{name} 已啟用 %{target} 之使用者電子郵件 token 驗證"
         enable_user_html: "%{name} 將使用者 %{target} 設定為允許登入"
         memorialize_account_html: "%{name} 將 %{target} 設定為追悼帳號"
@@ -560,7 +568,7 @@ zh-TW:
     relationships:
       title: "%{acct} 的關係"
     relays:
-      add_new: 新增中繼站
+      add_new: 新增中繼
       delete: 刪除
       description_html: "<strong>聯邦中繼站</strong> 是種中繼伺服器,會於訂閱並推送至此中繼站的伺服器之間交換大量的公開嘟文。<strong>中繼站也能協助小型或中型伺服器自聯邦宇宙中探索內容</strong>,而無須本地使用者手動跟隨遠端伺服器的其他使用者。"
       disable: 停用

From 95d7120ce6671ec1765e8435b248eb2dc7d8ee02 Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Wed, 13 Nov 2024 04:35:21 -0500
Subject: [PATCH 03/44] Misc gem version bumps (#32854)

---
 Gemfile.lock | 36 ++++++++++++++++++------------------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/Gemfile.lock b/Gemfile.lock
index 743a78ad54..b832a18df6 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -97,7 +97,7 @@ GEM
     attr_required (1.0.2)
     awrence (1.2.1)
     aws-eventstream (1.3.0)
-    aws-partitions (1.1001.0)
+    aws-partitions (1.1004.0)
     aws-sdk-core (3.212.0)
       aws-eventstream (~> 1, >= 1.3.0)
       aws-partitions (~> 1, >= 1.992.0)
@@ -112,7 +112,7 @@ GEM
       aws-sigv4 (~> 1.5)
     aws-sigv4 (1.10.1)
       aws-eventstream (~> 1, >= 1.0.2)
-    azure-blob (0.5.2)
+    azure-blob (0.5.3)
       rexml
     base64 (0.2.0)
     bcp47_spec (0.2.1)
@@ -178,7 +178,7 @@ GEM
       activerecord (>= 5.a)
       database_cleaner-core (~> 2.0.0)
     database_cleaner-core (2.0.1)
-    date (3.3.4)
+    date (3.4.0)
     debug (1.9.2)
       irb (~> 1.10)
       reline (>= 0.3.8)
@@ -189,10 +189,10 @@ GEM
       railties (>= 4.1.0)
       responders
       warden (~> 1.2.3)
-    devise-two-factor (6.0.0)
-      activesupport (~> 7.0)
+    devise-two-factor (6.1.0)
+      activesupport (>= 7.0, < 8.1)
       devise (~> 4.0)
-      railties (~> 7.0)
+      railties (>= 7.0, < 8.1)
       rotp (~> 6.0)
     devise_pam_authenticatable2 (9.2.0)
       devise (>= 4.0.0)
@@ -330,7 +330,7 @@ GEM
       azure-blob (~> 0.5.2)
       hashie (~> 5.0)
     jmespath (1.6.2)
-    json (2.7.4)
+    json (2.8.1)
     json-canonicalization (1.0.0)
     json-jwt (1.15.3.1)
       activesupport (>= 4.2)
@@ -407,16 +407,16 @@ GEM
     mime-types (3.6.0)
       logger
       mime-types-data (~> 3.2015)
-    mime-types-data (3.2024.1001)
+    mime-types-data (3.2024.1105)
     mini_mime (1.1.5)
     mini_portile2 (2.8.7)
     minitest (5.25.1)
-    msgpack (1.7.3)
+    msgpack (1.7.5)
     multi_json (1.15.0)
     mutex_m (0.2.0)
     net-http (0.5.0)
       uri
-    net-imap (0.5.0)
+    net-imap (0.5.1)
       date
       net-protocol
     net-ldap (0.19.0)
@@ -554,10 +554,10 @@ GEM
     opentelemetry-semantic_conventions (1.10.1)
       opentelemetry-api (~> 1.0)
     orm_adapter (0.5.0)
-    ostruct (0.6.0)
+    ostruct (0.6.1)
     ox (2.14.18)
     parallel (1.26.3)
-    parser (3.3.5.0)
+    parser (3.3.6.0)
       ast (~> 2.4.1)
       racc
     parslet (2.0.0)
@@ -579,7 +579,7 @@ GEM
       activesupport (>= 7.0.0)
       rack
       railties (>= 7.0.0)
-    psych (5.1.2)
+    psych (5.2.0)
       stringio
     public_suffix (6.0.1)
     puma (6.4.3)
@@ -664,7 +664,7 @@ GEM
     redlock (1.3.2)
       redis (>= 3.0.0, < 6.0)
     regexp_parser (2.9.2)
-    reline (0.5.10)
+    reline (0.5.11)
       io-console (~> 0.5)
     request_store (1.6.0)
       rack (>= 1.4)
@@ -673,7 +673,7 @@ GEM
       railties (>= 5.2)
     rexml (3.3.9)
     rotp (6.3.0)
-    rouge (4.4.0)
+    rouge (4.5.1)
     rpam2 (4.0.2)
     rqrcode (2.2.0)
       chunky_png (~> 1.0)
@@ -693,7 +693,7 @@ GEM
     rspec-mocks (3.13.2)
       diff-lcs (>= 1.2.0, < 2.0)
       rspec-support (~> 3.13.0)
-    rspec-rails (7.0.1)
+    rspec-rails (7.1.0)
       actionpack (>= 7.0)
       activesupport (>= 7.0)
       railties (>= 7.0)
@@ -794,7 +794,7 @@ GEM
     stackprof (0.2.26)
     stoplight (4.1.0)
       redlock (~> 1.0)
-    stringio (3.1.1)
+    stringio (3.1.2)
     strong_migrations (2.1.0)
       activerecord (>= 6.1)
     swd (1.3.0)
@@ -867,7 +867,7 @@ GEM
       rack-proxy (>= 0.6.1)
       railties (>= 5.2)
       semantic_range (>= 2.3.0)
-    webrick (1.8.2)
+    webrick (1.9.0)
     websocket (1.2.11)
     websocket-driver (0.7.6)
       websocket-extensions (>= 0.1.0)

From 8f5cbf537026915215d84945efad9a878ac8cdb4 Mon Sep 17 00:00:00 2001
From: Claire <claire.github-309c@sitedethib.com>
Date: Wed, 13 Nov 2024 11:22:11 +0100
Subject: [PATCH 04/44] Fix list creation limit check (#32869)

---
 app/models/list.rb       | 2 +-
 spec/models/list_spec.rb | 6 +++++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/app/models/list.rb b/app/models/list.rb
index d4915f56fa..bb7dd4cfc0 100644
--- a/app/models/list.rb
+++ b/app/models/list.rb
@@ -34,7 +34,7 @@ class List < ApplicationRecord
   private
 
   def validate_account_lists_limit
-    errors.add(:base, I18n.t('lists.errors.limit')) if account.lists.count >= PER_ACCOUNT_LIMIT
+    errors.add(:base, I18n.t('lists.errors.limit')) if account.owned_lists.count >= PER_ACCOUNT_LIMIT
   end
 
   def clean_feed_manager
diff --git a/spec/models/list_spec.rb b/spec/models/list_spec.rb
index 62a84dfebf..48c273d3ec 100644
--- a/spec/models/list_spec.rb
+++ b/spec/models/list_spec.rb
@@ -11,7 +11,11 @@ RSpec.describe List do
     context 'when account has hit max list limit' do
       let(:account) { Fabricate :account }
 
-      before { stub_const 'List::PER_ACCOUNT_LIMIT', 0 }
+      before do
+        stub_const 'List::PER_ACCOUNT_LIMIT', 1
+
+        Fabricate(:list, account: account)
+      end
 
       context 'when creating a new list' do
         it { is_expected.to_not allow_value(account).for(:account).against(:base).with_message(I18n.t('lists.errors.limit')) }

From 03ecf5df3bee1c667bfdba26887613c8620dc5c5 Mon Sep 17 00:00:00 2001
From: Jaz-Michael King <141073565+jmking-iftas@users.noreply.github.com>
Date: Wed, 13 Nov 2024 08:10:01 -0500
Subject: [PATCH 05/44] Adds a range of reserved usernames to reduce potential
 misuse by malicious actors (#32828)

---
 config/settings.yml | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/config/settings.yml b/config/settings.yml
index 297bf0281d..673a4c1be2 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -21,14 +21,27 @@ defaults: &defaults
   trends_as_landing_page: true
   trendable_by_default: false
   reserved_usernames:
+    - abuse
+    - account
+    - accounts
     - admin
-    - support
-    - help
-    - root
-    - webmaster
+    - administration
     - administrator
+    - admins
+    - help
+    - helpdesk
+    - instance
     - mod
     - moderator
+    - moderators
+    - mods
+    - owner
+    - root
+    - security
+    - server
+    - staff
+    - support
+    - webmaster
   disallowed_hashtags: # space separated string or list of hashtags without the hash
   bootstrap_timeline_accounts: ''
   activity_api_enabled: true

From 7fc8292ea540fda71434d24dd78622d8e94d024c Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Wed, 13 Nov 2024 16:08:10 +0100
Subject: [PATCH 06/44] Update dependency react-textarea-autosize to v8.5.5
 (#32872)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
 yarn.lock | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/yarn.lock b/yarn.lock
index 9e3ec41017..7fd68ac8c1 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -14787,15 +14787,15 @@ __metadata:
   linkType: hard
 
 "react-textarea-autosize@npm:^8.4.1":
-  version: 8.5.4
-  resolution: "react-textarea-autosize@npm:8.5.4"
+  version: 8.5.5
+  resolution: "react-textarea-autosize@npm:8.5.5"
   dependencies:
     "@babel/runtime": "npm:^7.20.13"
     use-composed-ref: "npm:^1.3.0"
     use-latest: "npm:^1.2.1"
   peerDependencies:
     react: ^16.8.0 || ^17.0.0 || ^18.0.0
-  checksum: 10c0/ea92fda2128983c1a8e84c74706ffb4b8bfa1a19c803d210868ec031c1ac3b8ceee8028766ef5d91017265da2bdccf6a85e5b6e5d553005e839f0c47e5758b43
+  checksum: 10c0/d708a31b39a409d0246cd8afbd956ce51db58ce0b6411b9d4e1dc876ce93c329d20875933ce5d337662fdcd3699596966dc630149236fee2835d74e302404c98
   languageName: node
   linkType: hard
 

From 980970ddfd659393877cc4fa87d2811bbd0e0a79 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Thu, 14 Nov 2024 10:15:49 +0100
Subject: [PATCH 07/44] Update dependency browser to v6.1.0 (#32878)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
 Gemfile.lock | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Gemfile.lock b/Gemfile.lock
index b832a18df6..106fb0d0fd 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -131,7 +131,7 @@ GEM
       msgpack (~> 1.2)
     brakeman (6.2.2)
       racc
-    browser (6.0.0)
+    browser (6.1.0)
     brpoplpush-redis_script (0.1.3)
       concurrent-ruby (~> 1.0, >= 1.0.5)
       redis (>= 1.0, < 6)

From aaebf142aac8ae0f52faa847a9e0c206da57a555 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
 <41898282+github-actions[bot]@users.noreply.github.com>
Date: Thu, 14 Nov 2024 10:39:33 +0100
Subject: [PATCH 08/44] New Crowdin Translations (automated) (#32884)

Co-authored-by: GitHub Actions <noreply@github.com>
---
 app/javascript/mastodon/locales/ar.json    |  1 +
 app/javascript/mastodon/locales/eo.json    |  5 +++--
 app/javascript/mastodon/locales/fr-CA.json |  3 +++
 app/javascript/mastodon/locales/fr.json    |  3 +++
 app/javascript/mastodon/locales/it.json    |  1 +
 app/javascript/mastodon/locales/lad.json   | 25 ++++++++++++++++++++++
 config/locales/bg.yml                      | 18 ++++++++++++++++
 config/locales/es.yml                      | 24 ++++++++++-----------
 config/locales/lad.yml                     |  9 ++++++++
 config/locales/simple_form.bg.yml          |  3 +++
 config/locales/simple_form.lad.yml         |  1 +
 11 files changed, 79 insertions(+), 14 deletions(-)

diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json
index 54ed1cb8c8..5c7dfeb128 100644
--- a/app/javascript/mastodon/locales/ar.json
+++ b/app/javascript/mastodon/locales/ar.json
@@ -86,6 +86,7 @@
   "alert.unexpected.title": "المعذرة!",
   "alt_text_badge.title": "نص بديل",
   "announcement.announcement": "إعلان",
+  "annual_report.summary.archetype.booster": "The cool-hunter",
   "attachments_list.unprocessed": "(غير معالَج)",
   "audio.hide": "إخفاء المقطع الصوتي",
   "block_modal.remote_users_caveat": "سوف نطلب من الخادم {domain} أن يحترم قرارك، لكن الالتزام غير مضمون لأن بعض الخواديم قد تتعامل مع نصوص الكتل بشكل مختلف. قد تظل المنشورات العامة مرئية للمستخدمين غير المسجلين الدخول.",
diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json
index 731e11f27a..6d8c82385b 100644
--- a/app/javascript/mastodon/locales/eo.json
+++ b/app/javascript/mastodon/locales/eo.json
@@ -90,6 +90,7 @@
   "annual_report.summary.archetype.replier": "La plej societema",
   "annual_report.summary.followers.followers": "sekvantoj",
   "annual_report.summary.highlighted_post.by_replies": "afiŝo kun la plej multaj respondoj",
+  "annual_report.summary.most_used_app.most_used_app": "plej uzita apo",
   "annual_report.summary.most_used_hashtag.none": "Nenio",
   "annual_report.summary.new_posts.new_posts": "novaj afiŝoj",
   "annual_report.summary.thanks": "Dankon pro esti parto de Mastodon!",
@@ -339,7 +340,7 @@
   "followed_tags": "Sekvataj kradvortoj",
   "footer.about": "Pri",
   "footer.directory": "Profilujo",
-  "footer.get_app": "Akiru la Programon",
+  "footer.get_app": "Akiri la apon",
   "footer.invite": "Inviti homojn",
   "footer.keyboard_shortcuts": "Fulmoklavoj",
   "footer.privacy_policy": "Politiko de privateco",
@@ -388,7 +389,7 @@
   "ignore_notifications_modal.not_followers_title": "Ĉu ignori sciigojn de homoj, kiuj ne sekvas vin?",
   "ignore_notifications_modal.not_following_title": "Ĉu ignori sciigojn de homoj, kiujn vi ne sekvas?",
   "ignore_notifications_modal.private_mentions_title": "Ĉu ignori sciigojn de nepetitaj privataj mencioj?",
-  "interaction_modal.description.favourite": "Per konto ĉe Mastodon, vi povas stelumiti ĉi tiun afiŝon por sciigi la afiŝanton ke vi aprezigas ŝin kaj konservas por la estonteco.",
+  "interaction_modal.description.favourite": "Per konto ĉe Mastodon, vi povas stelumi ĉi tiun afiŝon por sciigi la afiŝanton ke vi sâtas kaj konservas ĝin por poste.",
   "interaction_modal.description.follow": "Kun konto ĉe Mastodon, vi povas sekvi {name} por ricevi iliajn afiŝojn en via hejma fluo.",
   "interaction_modal.description.reblog": "Kun konto ĉe Mastodon, vi povas diskonigi ĉi tiun afiŝon, por ke viaj propraj sekvantoj vidu ĝin.",
   "interaction_modal.description.reply": "Kun konto ĉe Mastodon, vi povos respondi al ĉi tiu afiŝo.",
diff --git a/app/javascript/mastodon/locales/fr-CA.json b/app/javascript/mastodon/locales/fr-CA.json
index 65bbc25c21..fed111e7e8 100644
--- a/app/javascript/mastodon/locales/fr-CA.json
+++ b/app/javascript/mastodon/locales/fr-CA.json
@@ -87,6 +87,9 @@
   "alert.unexpected.title": "Oups!",
   "alt_text_badge.title": "Texte Alt",
   "announcement.announcement": "Annonce",
+  "annual_report.summary.archetype.oracle": "L’oracle",
+  "annual_report.summary.here_it_is": "Voici votre récap de {year} :",
+  "annual_report.summary.most_used_app.most_used_app": "appli la plus utilisée",
   "attachments_list.unprocessed": "(non traité)",
   "audio.hide": "Masquer l'audio",
   "block_modal.remote_users_caveat": "Nous allons demander au serveur {domain} de respecter votre décision. Cependant, ce respect n'est pas garanti, car certains serveurs peuvent gérer différemment les blocages. Les messages publics peuvent rester visibles par les utilisateur·rice·s non connecté·e·s.",
diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json
index ed751c244b..10bfc22bd8 100644
--- a/app/javascript/mastodon/locales/fr.json
+++ b/app/javascript/mastodon/locales/fr.json
@@ -87,6 +87,9 @@
   "alert.unexpected.title": "Oups !",
   "alt_text_badge.title": "Texte Alt",
   "announcement.announcement": "Annonce",
+  "annual_report.summary.archetype.oracle": "L’oracle",
+  "annual_report.summary.here_it_is": "Voici votre récap de {year} :",
+  "annual_report.summary.most_used_app.most_used_app": "appli la plus utilisée",
   "attachments_list.unprocessed": "(non traité)",
   "audio.hide": "Masquer l'audio",
   "block_modal.remote_users_caveat": "Nous allons demander au serveur {domain} de respecter votre décision. Cependant, ce respect n'est pas garanti, car certains serveurs peuvent gérer différemment les blocages. Les messages publics peuvent rester visibles par les utilisateur·rice·s non connecté·e·s.",
diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json
index bf179ea2f2..06779d337c 100644
--- a/app/javascript/mastodon/locales/it.json
+++ b/app/javascript/mastodon/locales/it.json
@@ -97,6 +97,7 @@
   "annual_report.summary.highlighted_post.possessive": "di {name}",
   "annual_report.summary.most_used_app.most_used_app": "l'app più utilizzata",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "l'hashtag più usato",
+  "annual_report.summary.most_used_hashtag.none": "Nessuno",
   "annual_report.summary.new_posts.new_posts": "nuovi post",
   "annual_report.summary.percentile.text": "<topLabel>Questo ti colloca tra il</topLabel><percentage></percentage><bottomLabel>dei migliori utenti Mastodon.</bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "Non lo diremo a Bernie.",
diff --git a/app/javascript/mastodon/locales/lad.json b/app/javascript/mastodon/locales/lad.json
index 563eb3b190..0a5f82aee3 100644
--- a/app/javascript/mastodon/locales/lad.json
+++ b/app/javascript/mastodon/locales/lad.json
@@ -87,6 +87,17 @@
   "alert.unexpected.title": "Atyo!",
   "alt_text_badge.title": "Teksto alternativo",
   "announcement.announcement": "Pregon",
+  "annual_report.summary.archetype.pollster": "El anketero",
+  "annual_report.summary.followers.followers": "suivantes",
+  "annual_report.summary.highlighted_post.by_favourites": "la puvlikasyon mas favoritada",
+  "annual_report.summary.highlighted_post.by_reblogs": "la puvlikasyon mas repartajada",
+  "annual_report.summary.highlighted_post.by_replies": "la puvlikasyon kon mas repuestas",
+  "annual_report.summary.highlighted_post.possessive": "de {name}",
+  "annual_report.summary.most_used_app.most_used_app": "la aplikasyon mas uzada",
+  "annual_report.summary.most_used_hashtag.most_used_hashtag": "la etiketa mas uzada",
+  "annual_report.summary.most_used_hashtag.none": "Dinguno",
+  "annual_report.summary.new_posts.new_posts": "puvlikasyones muevas",
+  "annual_report.summary.thanks": "Mersi por ser parte de Mastodon!",
   "attachments_list.unprocessed": "(no prosesado)",
   "audio.hide": "Eskonde audio",
   "block_modal.show_less": "Amostra manko",
@@ -97,6 +108,7 @@
   "block_modal.you_wont_see_mentions": "No veras publikasyones ke lo enmentan.",
   "boost_modal.combo": "Puedes klikar {combo} para ometer esto la proksima vez",
   "boost_modal.reblog": "Repartajar puvlikasyon?",
+  "boost_modal.undo_reblog": "Departajar puvlikasyon?",
   "bundle_column_error.copy_stacktrace": "Kopia el raporto de yerro",
   "bundle_column_error.error.body": "La pajina solisitada no pudo ser renderada. Podria ser por un yerro en muestro kodiche o un problem de kompatibilita kon el navigador.",
   "bundle_column_error.error.title": "Atyo, no!",
@@ -155,6 +167,7 @@
   "compose_form.poll.duration": "Durasion de anketa",
   "compose_form.poll.multiple": "Multiples opsyones",
   "compose_form.poll.option_placeholder": "Opsyon {number}",
+  "compose_form.poll.single": "Opsyon unika",
   "compose_form.poll.switch_to_multiple": "Troka anketa para permeter a eskojer mas ke una opsyon",
   "compose_form.poll.switch_to_single": "Troka anketa para permeter a eskojer solo una opsyon",
   "compose_form.poll.type": "Estilo",
@@ -213,6 +226,7 @@
   "dismissable_banner.public_timeline": "Estas son las publikasyones publikas mas resientes de personas en la red sosyala a las kualas la djente de {domain} sige.",
   "domain_block_modal.block": "Bloka sirvidor",
   "domain_block_modal.block_account_instead": "Bloka @{name} en su lugar",
+  "domain_block_modal.they_can_interact_with_old_posts": "Las personas de este sirvidor pueden enteraktuar kon tus puvlikasyones viejas.",
   "domain_block_modal.they_cant_follow": "Dingun de este sirvidor puede segirte.",
   "domain_block_modal.they_wont_know": "No savra ke tiene sido blokado.",
   "domain_block_modal.title": "Bloka el domeno?",
@@ -307,6 +321,7 @@
   "follow_suggestions.personalized_suggestion": "Sujestion personalizada",
   "follow_suggestions.popular_suggestion": "Sujestion populara",
   "follow_suggestions.popular_suggestion_longer": "Popular en {domain}",
+  "follow_suggestions.similar_to_recently_followed_longer": "Similares a los profils ke tienes segido resyentemente",
   "follow_suggestions.view_all": "Ve todos",
   "follow_suggestions.who_to_follow": "A ken segir",
   "followed_tags": "Etiketas segidas",
@@ -335,6 +350,9 @@
   "hashtag.follow": "Sige etiketa",
   "hashtag.unfollow": "Desige etiketa",
   "hashtags.and_other": "…i {count, plural, one {}other {# mas}}",
+  "hints.profiles.followers_may_be_missing": "Puede ser ke algunos suivantes de este profil no se amostren.",
+  "hints.profiles.follows_may_be_missing": "Puede ser ke algunos kuentos segidos por este profil no se amostren.",
+  "hints.profiles.posts_may_be_missing": "Puede ser ke algunas puvlikasyones de este profil no se amostren.",
   "hints.profiles.see_more_followers": "Ve mas suivantes en {domain}",
   "hints.profiles.see_more_follows": "Ve mas segidos en {domain}",
   "hints.profiles.see_more_posts": "Ve mas puvlikasyones en {domain}",
@@ -352,10 +370,12 @@
   "ignore_notifications_modal.new_accounts_title": "Inyorar avizos de kuentos muevos?",
   "ignore_notifications_modal.not_followers_title": "Inyorar avizos de personas a las kualas no te sigen?",
   "ignore_notifications_modal.not_following_title": "Inyorar avizos de personas a las kualas no siges?",
+  "ignore_notifications_modal.private_mentions_title": "Ignorar avizos de mensyones privadas no solisitadas?",
   "interaction_modal.description.favourite": "Kon un kuento en Mastodon, puedes markar esta publikasyon komo favorita para ke el autor sepa ke te plaze i para guadrarla para dempues.",
   "interaction_modal.description.follow": "Kon un kuento en Mastodon, puedes segir a {name} para risivir sus publikasyones en tu linya temporal prinsipala.",
   "interaction_modal.description.reblog": "Kon un kuento en Mastodon, puedes repartajar esta publikasyon para amostrarla a tus suivantes.",
   "interaction_modal.description.reply": "Kon un kuento en Mastodon, puedes arispondir a esta publikasyon.",
+  "interaction_modal.description.vote": "Kon un kuento en Mastodon, puedes votar en esta anketa.",
   "interaction_modal.login.action": "Va a tu sirvidor",
   "interaction_modal.login.prompt": "Domeno del sirvidor de tu kuento, por enshemplo mastodon.social",
   "interaction_modal.no_account_yet": "No tyenes kuento de Mastodon?",
@@ -367,6 +387,7 @@
   "interaction_modal.title.follow": "Sige a {name}",
   "interaction_modal.title.reblog": "Repartaja publikasyon de {name}",
   "interaction_modal.title.reply": "Arisponde a publikasyon de {name}",
+  "interaction_modal.title.vote": "Vota en la anketa de {name}",
   "intervals.full.days": "{number, plural, one {# diya} other {# diyas}}",
   "intervals.full.hours": "{number, plural, one {# ora} other {# oras}}",
   "intervals.full.minutes": "{number, plural, one {# minuto} other {# minutos}}",
@@ -466,13 +487,16 @@
   "navigation_bar.security": "Segurita",
   "not_signed_in_indicator.not_signed_in": "Nesesitas konektarse kon tu kuento para akseder este rekurso.",
   "notification.admin.report": "{name} raporto {target}",
+  "notification.admin.report_statuses": "{name} raporto {target} por {category}",
   "notification.admin.report_statuses_other": "{name} raporto {target}",
   "notification.admin.sign_up": "{name} kriyo un konto",
+  "notification.annual_report.view": "Ve #Wrapstodon",
   "notification.favourite": "A {name} le plaze tu publikasyon",
   "notification.follow": "{name} te ampeso a segir",
   "notification.follow_request": "{name} tiene solisitado segirte",
   "notification.label.mention": "Enmenta",
   "notification.label.private_mention": "Enmentadura privada",
+  "notification.label.private_reply": "Repuesta privada",
   "notification.label.reply": "Arisponde",
   "notification.mention": "Enmenta",
   "notification.mentioned_you": "{name} te enmento",
@@ -536,6 +560,7 @@
   "notifications.policy.accept_hint": "Amostra en avizos",
   "notifications.policy.drop": "Inyora",
   "notifications.policy.filter": "Filtra",
+  "notifications.policy.filter_limited_accounts_hint": "Limitadas por moderadores del sirvidor",
   "notifications.policy.filter_limited_accounts_title": "Kuentos moderados",
   "notifications.policy.filter_new_accounts.hint": "Kriyadas durante {days, plural, one {el ultimo diya} other {los ultimos # diyas}}",
   "notifications.policy.filter_new_accounts_title": "Muevos kuentos",
diff --git a/config/locales/bg.yml b/config/locales/bg.yml
index 1fdd0e3533..7181b35b6d 100644
--- a/config/locales/bg.yml
+++ b/config/locales/bg.yml
@@ -412,6 +412,7 @@ bg:
       attempts_over_week:
         one: "%{count} опит за изминалата седмица"
         other: "%{count} опита за регистрация през изминалата седмица"
+      created_msg: Успешно блокиран домейн на е-поща
       delete: Изтриване
       dns:
         types:
@@ -420,8 +421,11 @@ bg:
       new:
         create: Добавяне на домейн
         resolve: Преобразуване на домейна
+        title: Блокиране на нов домейн на имейл
+      no_email_domain_block_selected: Няма промяна, тъй като няма избрани блокирания на домейн на имейл
       not_permitted: Няма позволение
       resolved_through_html: Преобразувано чрез %{domain}
+      title: Блокирани домейни на имейл
     export_domain_allows:
       new:
         title: Внасяне на позволенията на домейни
@@ -842,6 +846,9 @@ bg:
         message_html: Не сте определили никакви правила на сървъра.
       sidekiq_process_check:
         message_html: Не работи процес Sidekiq за %{value} опашка/и. Прегледайте настройките си за Sidekiq
+      software_version_check:
+        action: Преглед на наличните обновявания
+        message_html: Налично е обновяване на Mastodon.
       software_version_critical_check:
         action: Преглед на наличните обновявания
         message_html: Налично e критично обновяване на Mastodon. Обновете възможно най-бързо.
@@ -1102,11 +1109,18 @@ bg:
     status:
       account_status: Състояние на акаунта
       functional: Вашият акаунт е в изправност.
+      pending: Вашето приложение чака преглед от персонала ни. Това може да отнеме време. Ще получите е-писмо, ако приложението ви се одобри.
       redirecting_to: Вашият акаунт е бездеен, защото сега се пренасочва към %{acct}.
       self_destruct: Затваряйки %{domain}, ще получите само ограничен достъп до акаунта си.
       view_strikes: Преглед на предишните предупреждения против акаунта ви
     too_fast: Образецът подаден пребързо, опитайте пак.
     use_security_key: Употреба на ключ за сигурност
+  author_attribution:
+    example_title: Примерен текст
+    more_from_html: Още от %{name}
+    s_blog: Блогът на %{name}
+    then_instructions: Тогава добавете име на домейна на публикацията в долното поле.
+    title: Приписване на авторството
   challenge:
     confirm: Продължаване
     hint_html: "<strong>Съвет</strong>: няма да ви питаме пак за паролата през следващия час."
@@ -1450,6 +1464,7 @@ bg:
     update:
       subject: "%{name} промени публикация"
   notifications:
+    administration_emails: Известия за администратори по е-поща
     email_events_hint: 'Изберете събития, за които искате да получавате известия:'
   number:
     human:
@@ -1607,6 +1622,7 @@ bg:
     import: Импортиране
     import_and_export: Импортиране и експортиране
     migrate: Миграция на акаунта
+    notifications: Известия по е-поща
     preferences: Предпочитания
     profile: Профил
     relationships: Последвания и последователи
@@ -1842,6 +1858,7 @@ bg:
     invalid_otp_token: Невалиден код
     otp_lost_help_html: Ако загубите достъп до двете, то може да се свържете с %{email}
     rate_limited: Премного опити за удостоверяване. Опитайте пак по-късно.
+    seamless_external_login: Влезли сте чрез външна услуга, така че настройките за парола и имейл не са налични.
     signed_in_as: 'Влезли като:'
   verification:
     extra_instructions_html: <strong>Съвет:</strong>Връзката в уебсайта ви може да е невидима. Важна част е <code>rel="me"</code>, която предотврятява имитирането на уебсайтове с породено от потребителите съдържание. Може дори да употребите етикет за <code>връзката</code> в заглавката на странице вместо <code>а</code>, но HTML трябва да достъпен без изпълнение на JavaScript.
@@ -1850,6 +1867,7 @@ bg:
     instructions_html: Копипейстнете кода долу в HTML на уебсайта си. Тогава добавете адреса на уебсайта си в едно от допълнителните полета на профила ви от раздела "Редактиране на профила" и запазане на промените.
     verification: Проверка
     verified_links: Вашите потвърдени връзки
+    website_verification: Потвърждаване на уебсайта
   webauthn_credentials:
     add: Добавяне на нов ключ за сигурност
     create:
diff --git a/config/locales/es.yml b/config/locales/es.yml
index 8690c1cdfb..ddd53a2387 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -67,8 +67,8 @@ es:
       display_name: Nombre
       domain: Dominio
       edit: Editar
-      email: E-mail
-      email_status: E-mail Status
+      email: Correo electrónico
+      email_status: Estado del correo electrónico
       enable: Habilitar
       enable_sign_in_token_auth: Habilitar la autenticación por token de correo electrónico
       enabled: Habilitada
@@ -86,7 +86,7 @@ es:
         local: Local
         remote: Remoto
         title: Localización
-      login_status: Estado del login
+      login_status: Estado de inicio de sesión
       media_attachments: Multimedia
       memorialize: Convertir en memorial
       memorialized: Cuenta conmemorativa
@@ -102,7 +102,7 @@ es:
       moderation_notes: Notas de moderación
       most_recent_activity: Actividad más reciente
       most_recent_ip: IP más reciente
-      no_account_selected: Ninguna cuenta se cambió como ninguna fue seleccionada
+      no_account_selected: Ninguna cuenta se cambió, ya que ninguna fue seleccionada
       no_limits_imposed: Sin límites impuestos
       no_role_assigned: Ningún rol asignado
       not_subscribed: No se está suscrito
@@ -132,17 +132,17 @@ es:
         success: "¡Enlace de confirmación enviado con éxito!"
       reset: Reiniciar
       reset_password: Reiniciar contraseña
-      resubscribe: Re-suscribir
+      resubscribe: Volver a suscribirse
       role: Rol
       search: Buscar
       search_same_email_domain: Otros usuarios con el mismo dominio de correo
       search_same_ip: Otros usuarios con la misma IP
       security: Seguridad
       security_measures:
-        only_password: Sólo contraseña
+        only_password: Solo contraseña
         password_and_2fa: Contraseña y 2FA
       sensitive: Sensible
-      sensitized: marcado como sensible
+      sensitized: Marcada como sensible
       shared_inbox_url: URL de bandeja compartida
       show:
         created_reports: Reportes hechos por esta cuenta
@@ -161,10 +161,10 @@ es:
       unblocked_email_msg: Se ha desbloqueado correctamente la dirección de correo de %{username}
       unconfirmed_email: Correo electrónico sin confirmar
       undo_sensitized: Desmarcar como sensible
-      undo_silenced: Des-silenciar
-      undo_suspension: Des-suspender
+      undo_silenced: Dejar de silenciar
+      undo_suspension: Deshacer suspensión
       unsilenced_msg: Se quitó con éxito el límite de la cuenta %{username}
-      unsubscribe: Desuscribir
+      unsubscribe: Cancelar suscripción
       unsuspended_msg: Se quitó con éxito la suspensión de la cuenta de %{username}
       username: Nombre de usuario
       view_domain: Ver resumen del dominio
@@ -296,7 +296,7 @@ es:
       empty: No se encontraron registros.
       filter_by_action: Filtrar por acción
       filter_by_user: Filtrar por usuario
-      title: Log de auditoría
+      title: Registro de auditoría
       unavailable_instance: "(nombre de dominio no disponible)"
     announcements:
       destroyed_msg: "¡Anuncio eliminado con éxito!"
@@ -338,7 +338,7 @@ es:
       listed: Listados
       new:
         title: Añadir nuevo emoji personalizado
-      no_emoji_selected: No se cambió ningún emoji ya que no se seleccionó ninguno
+      no_emoji_selected: No se cambió ningún emoji, ya que no se seleccionó ninguno
       not_permitted: No tienes permiso para realizar esta acción
       overwrite: Sobrescribir
       shortcode: Código de atajo
diff --git a/config/locales/lad.yml b/config/locales/lad.yml
index ad241856a4..4486df637e 100644
--- a/config/locales/lad.yml
+++ b/config/locales/lad.yml
@@ -24,6 +24,7 @@ lad:
   admin:
     account_actions:
       action: Realiza aksion
+      already_silenced: Este kuento ya tiene sido limitado.
       already_suspended: Este kuento ya tiene sido suspendido.
       title: Modera %{acct}
     account_moderation_notes:
@@ -638,6 +639,7 @@ lad:
       report: 'Raporta #%{id}'
       reported_account: Kuento raportado
       reported_by: Raportado por
+      reported_with_application: Raportado kon aplikasyon
       resolved: Rezolvido
       resolved_msg: Tienes rezolvido la denunsia djustamente!
       skip_to_actions: Va direktamente a las aksyones
@@ -752,6 +754,7 @@ lad:
         desc_html: Esto se baza en eskriptos eksternos de hCaptcha, ke pueden ser una influensya negra a la sigurita i privasita. Ademas, <strong>esto puede rezultar en un proseso de enrejistrasyon signifikativamente manko aksesivle para algunas personas (espesyalmente diskapasitadas)</strong>. Por estas razones, por favor, konsidera otras alternativas komo rejistrasyon por aprovasyon manuala o kon envitasyon.
         title: Solisita ke los muevos utilizadores rezolven un CAPTCHA para konfirmar su konto
       content_retention:
+        danger_zone: Zona de perikolo
         preamble: Kontrola komo el kontenido jenerado por el utilizador se magazina en Mastodon.
         title: Retensyon de kontenido
       default_noindex:
@@ -882,9 +885,12 @@ lad:
         message_html: "<strong>Tu magazinaje de objektos es mal konfigurado. La privasita de tus utilizadores esta en riziko.</strong>"
     tags:
       moderation:
+        not_trendable: No trendavle
+        not_usable: No uzavle
         pending_review: Revizion esta asperando
         reviewed: Revizado
         title: Estado
+        trendable: Trendavle
         unreviewed: No revizado
         usable: Uzavle
       name: Nombre
@@ -959,6 +965,7 @@ lad:
         used_by_over_week:
           one: Uzada por una persona durante la ultima semana
           other: Uzada por %{count} personas durante la ultima semana
+      title: Rekomendasyones i trendes
       trending: En trend
     warning_presets:
       add_new: Adjusta muevo
@@ -1138,7 +1145,9 @@ lad:
     too_fast: Formulario enviado demaziado rapido, aprovalo de muevo.
     use_security_key: Uza la yave de sigurita
   author_attribution:
+    example_title: Teksto de enshemplo
     more_from_html: Mas de %{name}
+    s_blog: Blog de %{name}
   challenge:
     confirm: Kontinua
     hint_html: "<strong>Konsejo:</strong> No retornaremos a demandarte por el kod durante la sigiente ora."
diff --git a/config/locales/simple_form.bg.yml b/config/locales/simple_form.bg.yml
index 5540942d93..17b7bd6239 100644
--- a/config/locales/simple_form.bg.yml
+++ b/config/locales/simple_form.bg.yml
@@ -3,12 +3,14 @@ bg:
   simple_form:
     hints:
       account:
+        attribution_domains_as_text: Едно на ред. Защитава от фалшиви атрибути.
         discoverable: Вашите публични публикации и профил може да се представят или препоръчват в различни области на Mastodon и вашия профил може да се предлага на други потребители.
         display_name: Вашето пълно име или псевдоним.
         fields: Вашата начална страница, местоимения, години, всичко що искате.
         indexable: Вашите обществени публикации може да се появят в резултатите от търсене в Mastodon. Взаимодействалите с публикациите ви може да ги търсят независимо.
         note: 'Може да @споменавате други хора или #хаштагове.'
         show_collections: Хората ще може да разглеждат през вашите последвания и последователи. Хората, които сте следвали, ще видят, че ги следвате независимо от това.
+        unlocked: Хората ще могат да ви последват без изискване на одобрение. Размаркирайте, ако искате да преглеждате заявките за последване и избирате дали да приемете или отхвърлите новите последователи.
       account_alias:
         acct: Посочете потребителско_име@домейн на акаунта си, от който искате да се преместите
       account_migration:
@@ -142,6 +144,7 @@ bg:
         url: До къде ще се изпращат събитията
     labels:
       account:
+        attribution_domains_as_text: Уебсайтове, на които е позволено да приписват авторството ви
         discoverable: Включване на профил и публикации в алгоритмите за откриване
         fields:
           name: Етикет
diff --git a/config/locales/simple_form.lad.yml b/config/locales/simple_form.lad.yml
index 712c2f4e8a..de37005312 100644
--- a/config/locales/simple_form.lad.yml
+++ b/config/locales/simple_form.lad.yml
@@ -9,6 +9,7 @@ lad:
         indexable: Tus publikasyones publikas pueden apareser en rezultados de bushkeda en Mastodon. Personas ke enteraktuaron kon tus publikasyones syempre pueden bushkarlas inkluzo si trokes esta preferensya.
         note: 'Puedes @enmentar a otra djente o #etiketas.'
         show_collections: Otra djente podra ver tus segidos i suivantes. Personas a las kualas siges siempre podran ver que las estas sigiendo.
+        unlocked: Djente va poder segirte sin solisitar tu achetasyon. Deseleksyona si keres revizar solisitasyones de segimyento i dechidir si keres achetar o refuzar a muevos suivantes.
       account_alias:
         acct: Espesifika tu nombre de utilizador@domeno del kuento de ande keres migrar
       account_migration:

From ec663eaba13294d803fdb8ddab373d7534c5a644 Mon Sep 17 00:00:00 2001
From: Claire <claire.github-309c@sitedethib.com>
Date: Thu, 14 Nov 2024 13:50:36 +0100
Subject: [PATCH 09/44] Fix Content Warning and filter states not applying to
 boosted posts properly (#32887)

---
 app/javascript/mastodon/components/status.jsx | 29 ++++++++++---------
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/app/javascript/mastodon/components/status.jsx b/app/javascript/mastodon/components/status.jsx
index 96ccf3aad4..f17f0367c1 100644
--- a/app/javascript/mastodon/components/status.jsx
+++ b/app/javascript/mastodon/components/status.jsx
@@ -393,20 +393,6 @@ class Status extends ImmutablePureComponent {
     };
 
     let media, statusAvatar, prepend, rebloggedByText;
-    const matchedFilters = status.get('matched_filters');
-    const expanded = (!matchedFilters || this.state.showDespiteFilter) && (!status.get('hidden') || status.get('spoiler_text').length === 0);
-
-    if (hidden) {
-      return (
-        <HotKeys handlers={handlers} tabIndex={unfocusable ? null : -1}>
-          <div ref={this.handleRef} className={classNames('status__wrapper', { focusable: !this.props.muted })} tabIndex={unfocusable ? null : 0}>
-            <span>{status.getIn(['account', 'display_name']) || status.getIn(['account', 'username'])}</span>
-            {status.get('spoiler_text').length > 0 && (<span>{status.get('spoiler_text')}</span>)}
-            {expanded && <span>{status.get('content')}</span>}
-          </div>
-        </HotKeys>
-      );
-    }
 
     const connectUp = previousId && previousId === status.get('in_reply_to_id');
     const connectToRoot = rootId && rootId === status.get('in_reply_to_id');
@@ -446,6 +432,21 @@ class Status extends ImmutablePureComponent {
       );
     }
 
+    const matchedFilters = status.get('matched_filters');
+    const expanded = (!matchedFilters || this.state.showDespiteFilter) && (!status.get('hidden') || status.get('spoiler_text').length === 0);
+
+    if (hidden) {
+      return (
+        <HotKeys handlers={handlers} tabIndex={unfocusable ? null : -1}>
+          <div ref={this.handleRef} className={classNames('status__wrapper', { focusable: !this.props.muted })} tabIndex={unfocusable ? null : 0}>
+            <span>{status.getIn(['account', 'display_name']) || status.getIn(['account', 'username'])}</span>
+            {status.get('spoiler_text').length > 0 && (<span>{status.get('spoiler_text')}</span>)}
+            {expanded && <span>{status.get('content')}</span>}
+          </div>
+        </HotKeys>
+      );
+    }
+
     if (pictureInPicture.get('inUse')) {
       media = <PictureInPicturePlaceholder aspectRatio={this.getAttachmentAspectRatio()} />;
     } else if (status.get('media_attachments').size > 0) {

From e8b6607ece43e6fcda99e76f8db0ad40d54b50b6 Mon Sep 17 00:00:00 2001
From: Claire <claire.github-309c@sitedethib.com>
Date: Thu, 14 Nov 2024 14:28:00 +0100
Subject: [PATCH 10/44] Fix titles being escaped twice (#32889)

---
 app/helpers/application_helper.rb          | 2 +-
 app/views/about/show.html.haml             | 3 +--
 app/views/accounts/show.html.haml          | 3 +--
 app/views/privacy/show.html.haml           | 3 +--
 app/views/statuses/show.html.haml          | 3 +--
 spec/helpers/application_helper_spec.rb    | 6 +++---
 spec/views/statuses/show.html.haml_spec.rb | 6 +-----
 7 files changed, 9 insertions(+), 17 deletions(-)

diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index e36de19255..3d5025724f 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -79,7 +79,7 @@ module ApplicationHelper
 
   def html_title
     safe_join(
-      [content_for(:page_title).to_s.chomp, title]
+      [content_for(:page_title), title]
       .compact_blank,
       ' - '
     )
diff --git a/app/views/about/show.html.haml b/app/views/about/show.html.haml
index 05d8989add..e8f7b43eaa 100644
--- a/app/views/about/show.html.haml
+++ b/app/views/about/show.html.haml
@@ -1,5 +1,4 @@
-- content_for :page_title do
-  = t('about.title')
+- content_for :page_title, t('about.title')
 
 - content_for :header_tags do
   = render partial: 'shared/og'
diff --git a/app/views/accounts/show.html.haml b/app/views/accounts/show.html.haml
index dde9c50847..1f5f81348e 100644
--- a/app/views/accounts/show.html.haml
+++ b/app/views/accounts/show.html.haml
@@ -1,5 +1,4 @@
-- content_for :page_title do
-  #{display_name(@account)} (#{acct(@account)})
+- content_for :page_title, "#{display_name(@account)} (#{acct(@account)})"
 
 - content_for :header_tags do
   - if @account.user_prefers_noindex?
diff --git a/app/views/privacy/show.html.haml b/app/views/privacy/show.html.haml
index 95e506641b..9eb4f7a570 100644
--- a/app/views/privacy/show.html.haml
+++ b/app/views/privacy/show.html.haml
@@ -1,5 +1,4 @@
-- content_for :page_title do
-  = t('privacy_policy.title')
+- content_for :page_title, t('privacy_policy.title')
 
 - content_for :header_tags do
   = render partial: 'shared/og'
diff --git a/app/views/statuses/show.html.haml b/app/views/statuses/show.html.haml
index 08bab63073..f669885de0 100644
--- a/app/views/statuses/show.html.haml
+++ b/app/views/statuses/show.html.haml
@@ -1,5 +1,4 @@
-- content_for :page_title do
-  = t('statuses.title', name: display_name(@account), quote: truncate(@status.spoiler_text.presence || @status.text, length: 50, omission: '…', escape: false))
+- content_for :page_title, t('statuses.title', name: display_name(@account), quote: truncate(@status.spoiler_text.presence || @status.text, length: 50, omission: '…', escape: false))
 
 - content_for :header_tags do
   - if @account.user_prefers_noindex?
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index ffcc5b81b6..557d08e851 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -257,11 +257,11 @@ RSpec.describe ApplicationHelper do
         expect(helper.html_title).to be_html_safe
       end
 
-      it 'removes extra new lines' do
+      it 'does not escape twice' do
         Setting.site_title = 'Site Title'
-        helper.content_for(:page_title, "Test Value\n")
+        helper.content_for(:page_title, '&quot;Test Value&quot;'.html_safe)
 
-        expect(helper.html_title).to eq 'Test Value - Site Title'
+        expect(helper.html_title).to eq '&quot;Test Value&quot; - Site Title'
         expect(helper.html_title).to be_html_safe
       end
     end
diff --git a/spec/views/statuses/show.html.haml_spec.rb b/spec/views/statuses/show.html.haml_spec.rb
index 1afcb046d4..02b1fe7384 100644
--- a/spec/views/statuses/show.html.haml_spec.rb
+++ b/spec/views/statuses/show.html.haml_spec.rb
@@ -18,7 +18,7 @@ RSpec.describe 'statuses/show.html.haml' do
     assign(:descendant_threads, [])
   end
 
-  it 'has valid opengraph tags' do
+  it 'has valid opengraph tags and twitter player tags' do
     render
 
     expect(header_tags)
@@ -26,10 +26,6 @@ RSpec.describe 'statuses/show.html.haml' do
       .and match(/<meta content="article" property="og:type">/)
       .and match(/<meta content=".+" property="og:image">/)
       .and match(%r{<meta content="http://.+" property="og:url">})
-  end
-
-  it 'has twitter player tag' do
-    render
 
     expect(header_tags)
       .to match(%r{<meta content="http://.+/media/.+/player" property="twitter:player">})

From 62d65504f66e0361d178ea882c97bdcfbc426c25 Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Thu, 14 Nov 2024 08:47:29 -0500
Subject: [PATCH 11/44] Add `DomainResource` class to wrap MX lookup/normalize
 (#32864)

---
 .../admin/email_domain_blocks_controller.rb   |  5 +----
 app/lib/domain_resource.rb                    | 22 +++++++++++++++++++
 app/models/user.rb                            |  8 +------
 .../admin/email_domain_blocks/new.html.haml   |  4 ++--
 lib/mastodon/cli/email_domain_blocks.rb       |  7 +-----
 spec/lib/domain_resource_spec.rb              | 19 ++++++++++++++++
 6 files changed, 46 insertions(+), 19 deletions(-)
 create mode 100644 app/lib/domain_resource.rb
 create mode 100644 spec/lib/domain_resource_spec.rb

diff --git a/app/controllers/admin/email_domain_blocks_controller.rb b/app/controllers/admin/email_domain_blocks_controller.rb
index fe822d8c99..9501ebd63a 100644
--- a/app/controllers/admin/email_domain_blocks_controller.rb
+++ b/app/controllers/admin/email_domain_blocks_controller.rb
@@ -58,10 +58,7 @@ module Admin
     private
 
     def set_resolved_records
-      Resolv::DNS.open do |dns|
-        dns.timeouts = 5
-        @resolved_records = dns.getresources(@email_domain_block.domain, Resolv::DNS::Resource::IN::MX).to_a
-      end
+      @resolved_records = DomainResource.new(@email_domain_block.domain).mx
     end
 
     def resource_params
diff --git a/app/lib/domain_resource.rb b/app/lib/domain_resource.rb
new file mode 100644
index 0000000000..59a29d8797
--- /dev/null
+++ b/app/lib/domain_resource.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class DomainResource
+  attr_reader :domain
+
+  RESOLVE_TIMEOUT = 5
+
+  def initialize(domain)
+    @domain = domain
+  end
+
+  def mx
+    Resolv::DNS.open do |dns|
+      dns.timeouts = RESOLVE_TIMEOUT
+      dns
+        .getresources(domain, Resolv::DNS::Resource::IN::MX)
+        .to_a
+        .map { |mx| mx.exchange.to_s }
+        .compact_blank
+    end
+  end
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index 9a215669b9..f717dcd860 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -457,13 +457,7 @@ class User < ApplicationRecord
 
     # Doing this conditionally is not very satisfying, but this is consistent
     # with the MX records validations we do and keeps the specs tractable.
-    unless self.class.skip_mx_check?
-      Resolv::DNS.open do |dns|
-        dns.timeouts = 5
-
-        records = dns.getresources(domain, Resolv::DNS::Resource::IN::MX).to_a.map { |e| e.exchange.to_s }.compact_blank
-      end
-    end
+    records = DomainResource.new(domain).mx unless self.class.skip_mx_check?
 
     EmailDomainBlock.requires_approval?(records + [domain], attempt_ip: sign_up_ip)
   end
diff --git a/app/views/admin/email_domain_blocks/new.html.haml b/app/views/admin/email_domain_blocks/new.html.haml
index 2dfdca9376..4db8fbe5e5 100644
--- a/app/views/admin/email_domain_blocks/new.html.haml
+++ b/app/views/admin/email_domain_blocks/new.html.haml
@@ -30,12 +30,12 @@
             %label.batch-table__row__select.batch-table__row__select--aligned.batch-checkbox
               = f.input_field :other_domains,
                               as: :boolean,
-                              checked_value: record.exchange.to_s,
+                              checked_value: record,
                               include_hidden: false,
                               multiple: true
             .batch-table__row__content.pending-account
               .pending-account__header
-                %samp= record.exchange.to_s
+                %samp= record
                 %br
                 = t('admin.email_domain_blocks.dns.types.mx')
 
diff --git a/lib/mastodon/cli/email_domain_blocks.rb b/lib/mastodon/cli/email_domain_blocks.rb
index a830ca3661..0cc9ccb705 100644
--- a/lib/mastodon/cli/email_domain_blocks.rb
+++ b/lib/mastodon/cli/email_domain_blocks.rb
@@ -45,12 +45,7 @@ module Mastodon::CLI
         end
 
         other_domains = []
-        if options[:with_dns_records]
-          Resolv::DNS.open do |dns|
-            dns.timeouts = 5
-            other_domains = dns.getresources(domain, Resolv::DNS::Resource::IN::MX).to_a.map { |e| e.exchange.to_s }.compact_blank
-          end
-        end
+        other_domains = DomainResource.new(domain).mx if options[:with_dns_records]
 
         email_domain_block = EmailDomainBlock.new(domain: domain, other_domains: other_domains)
         email_domain_block.save!
diff --git a/spec/lib/domain_resource_spec.rb b/spec/lib/domain_resource_spec.rb
new file mode 100644
index 0000000000..0d239fd9de
--- /dev/null
+++ b/spec/lib/domain_resource_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe DomainResource do
+  describe '#mx' do
+    subject { described_class.new(domain) }
+
+    let(:domain) { 'example.host' }
+    let(:exchange) { 'mx.host' }
+
+    before { configure_mx(domain: domain, exchange: exchange) }
+
+    it 'returns array of hostnames' do
+      expect(subject.mx)
+        .to eq([exchange])
+    end
+  end
+end

From 766358e52b86ca0dc6cf9bb091565e97af00b19a Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Thu, 14 Nov 2024 09:03:57 -0500
Subject: [PATCH 12/44] Add coverage for malformed version cleanup in
 `SoftwareUpdateCheckService`, add helper query methods (#32876)

---
 app/models/software_update.rb                 | 16 +++++-
 app/services/software_update_check_service.rb |  2 +-
 spec/models/software_update_spec.rb           | 54 +++++++++++++++++++
 .../software_update_check_service_spec.rb     |  5 +-
 4 files changed, 73 insertions(+), 4 deletions(-)

diff --git a/app/models/software_update.rb b/app/models/software_update.rb
index 2cb935130a..7e2b15656e 100644
--- a/app/models/software_update.rb
+++ b/app/models/software_update.rb
@@ -22,6 +22,14 @@ class SoftwareUpdate < ApplicationRecord
     Gem::Version.new(version)
   end
 
+  def outdated?
+    runtime_version >= gem_version
+  end
+
+  def pending?
+    gem_version > runtime_version
+  end
+
   class << self
     def check_enabled?
       Rails.configuration.x.mastodon.software_update_url.present?
@@ -30,11 +38,17 @@ class SoftwareUpdate < ApplicationRecord
     def pending_to_a
       return [] unless check_enabled?
 
-      all.to_a.filter { |update| update.gem_version > Mastodon::Version.gem_version }
+      all.to_a.filter(&:pending?)
     end
 
     def urgent_pending?
       pending_to_a.any?(&:urgent?)
     end
   end
+
+  private
+
+  def runtime_version
+    Mastodon::Version.gem_version
+  end
 end
diff --git a/app/services/software_update_check_service.rb b/app/services/software_update_check_service.rb
index 148f269289..45ec1f50db 100644
--- a/app/services/software_update_check_service.rb
+++ b/app/services/software_update_check_service.rb
@@ -12,7 +12,7 @@ class SoftwareUpdateCheckService < BaseService
 
   def clean_outdated_updates!
     SoftwareUpdate.find_each do |software_update|
-      software_update.delete if Mastodon::Version.gem_version >= software_update.gem_version
+      software_update.delete if software_update.outdated?
     rescue ArgumentError
       software_update.delete
     end
diff --git a/spec/models/software_update_spec.rb b/spec/models/software_update_spec.rb
index 0a494b0c4c..43e9cd058f 100644
--- a/spec/models/software_update_spec.rb
+++ b/spec/models/software_update_spec.rb
@@ -3,6 +3,60 @@
 require 'rails_helper'
 
 RSpec.describe SoftwareUpdate do
+  describe '#pending?' do
+    subject { described_class.new(version: update_version) }
+
+    before { allow(Mastodon::Version).to receive(:gem_version).and_return(Gem::Version.new(mastodon_version)) }
+
+    context 'when the runtime version is older than the update' do
+      let(:mastodon_version) { '4.0.0' }
+      let(:update_version) { '5.0.0' }
+
+      it { is_expected.to be_pending }
+    end
+
+    context 'when the runtime version is newer than the update' do
+      let(:mastodon_version) { '6.0.0' }
+      let(:update_version) { '5.0.0' }
+
+      it { is_expected.to_not be_pending }
+    end
+
+    context 'when the runtime version is same as the update' do
+      let(:mastodon_version) { '4.0.0' }
+      let(:update_version) { '4.0.0' }
+
+      it { is_expected.to_not be_pending }
+    end
+  end
+
+  describe '#outdated?' do
+    subject { described_class.new(version: update_version) }
+
+    before { allow(Mastodon::Version).to receive(:gem_version).and_return(Gem::Version.new(mastodon_version)) }
+
+    context 'when the runtime version is older than the update' do
+      let(:mastodon_version) { '4.0.0' }
+      let(:update_version) { '5.0.0' }
+
+      it { is_expected.to_not be_outdated }
+    end
+
+    context 'when the runtime version is newer than the update' do
+      let(:mastodon_version) { '6.0.0' }
+      let(:update_version) { '5.0.0' }
+
+      it { is_expected.to be_outdated }
+    end
+
+    context 'when the runtime version is same as the update' do
+      let(:mastodon_version) { '4.0.0' }
+      let(:update_version) { '4.0.0' }
+
+      it { is_expected.to be_outdated }
+    end
+  end
+
   describe '.pending_to_a' do
     before do
       allow(Mastodon::Version).to receive(:gem_version).and_return(Gem::Version.new(mastodon_version))
diff --git a/spec/services/software_update_check_service_spec.rb b/spec/services/software_update_check_service_spec.rb
index 4098bd470a..637e1e26c5 100644
--- a/spec/services/software_update_check_service_spec.rb
+++ b/spec/services/software_update_check_service_spec.rb
@@ -27,6 +27,7 @@ RSpec.describe SoftwareUpdateCheckService do
     before do
       Fabricate(:software_update, version: '3.5.0', type: 'major', urgent: false)
       Fabricate(:software_update, version: '42.13.12', type: 'major', urgent: false)
+      Fabricate(:software_update, version: 'Malformed', type: 'major', urgent: false)
 
       owner_user.settings.update('notification_emails.software_updates': 'all')
       owner_user.save!
@@ -50,7 +51,7 @@ RSpec.describe SoftwareUpdateCheckService do
       end
 
       it 'deletes outdated update records but keeps valid update records' do
-        expect { subject.call }.to change { SoftwareUpdate.pluck(:version).sort }.from(['3.5.0', '42.13.12']).to(['42.13.12'])
+        expect { subject.call }.to change { SoftwareUpdate.pluck(:version).sort }.from(['3.5.0', '42.13.12', 'Malformed']).to(['42.13.12'])
       end
     end
 
@@ -85,7 +86,7 @@ RSpec.describe SoftwareUpdateCheckService do
       end
 
       it 'updates the list of known updates' do
-        expect { subject.call }.to change { SoftwareUpdate.pluck(:version).sort }.from(['3.5.0', '42.13.12']).to(['4.2.1', '4.3.0', '5.0.0'])
+        expect { subject.call }.to change { SoftwareUpdate.pluck(:version).sort }.from(['3.5.0', '42.13.12', 'Malformed']).to(['4.2.1', '4.3.0', '5.0.0'])
       end
 
       context 'when no update is urgent' do

From 2de018256ae2ec5e7a508aff6e0e7905ec517118 Mon Sep 17 00:00:00 2001
From: Claire <claire.github-309c@sitedethib.com>
Date: Thu, 14 Nov 2024 20:42:43 +0100
Subject: [PATCH 13/44] Fix filters not being correctly applied to boosted
 posts (#32895)

---
 app/javascript/mastodon/components/status.jsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/javascript/mastodon/components/status.jsx b/app/javascript/mastodon/components/status.jsx
index f17f0367c1..95ea53521f 100644
--- a/app/javascript/mastodon/components/status.jsx
+++ b/app/javascript/mastodon/components/status.jsx
@@ -397,6 +397,7 @@ class Status extends ImmutablePureComponent {
     const connectUp = previousId && previousId === status.get('in_reply_to_id');
     const connectToRoot = rootId && rootId === status.get('in_reply_to_id');
     const connectReply = nextInReplyToId && nextInReplyToId === status.get('id');
+    const matchedFilters = status.get('matched_filters');
 
     if (featured) {
       prepend = (
@@ -432,7 +433,6 @@ class Status extends ImmutablePureComponent {
       );
     }
 
-    const matchedFilters = status.get('matched_filters');
     const expanded = (!matchedFilters || this.state.showDespiteFilter) && (!status.get('hidden') || status.get('spoiler_text').length === 0);
 
     if (hidden) {

From ddfb3d123bb4195f0b086fe19bc90700fa5170b4 Mon Sep 17 00:00:00 2001
From: Emelia Smith <ThisIsMissEm@users.noreply.github.com>
Date: Fri, 15 Nov 2024 10:38:01 +0100
Subject: [PATCH 14/44] Improve display of statuses in admin panel (#30813)

---
 app/controllers/admin/statuses_controller.rb  |  2 +
 .../admin/account_moderation_notes_helper.rb  |  4 +-
 app/javascript/styles/mastodon/admin.scss     | 28 +++++++
 app/javascript/styles/mastodon/tables.scss    | 16 ++--
 app/views/admin/reports/_status.html.haml     | 78 +++++++++++--------
 app/views/admin/statuses/index.html.haml      | 21 +++--
 app/views/admin/statuses/show.html.haml       | 64 ++++++++++++++-
 config/locales/an.yml                         |  2 +-
 config/locales/ar.yml                         |  2 +-
 config/locales/be.yml                         |  2 +-
 config/locales/bg.yml                         |  2 +-
 config/locales/br.yml                         |  2 +-
 config/locales/ca.yml                         |  2 +-
 config/locales/ckb.yml                        |  2 +-
 config/locales/co.yml                         |  2 +-
 config/locales/cs.yml                         |  2 +-
 config/locales/cy.yml                         |  2 +-
 config/locales/da.yml                         |  2 +-
 config/locales/de.yml                         |  2 +-
 config/locales/el.yml                         |  2 +-
 config/locales/en-GB.yml                      |  2 +-
 config/locales/en.yml                         |  8 +-
 config/locales/eo.yml                         |  2 +-
 config/locales/es-AR.yml                      |  2 +-
 config/locales/es-MX.yml                      |  2 +-
 config/locales/es.yml                         |  2 +-
 config/locales/et.yml                         |  2 +-
 config/locales/eu.yml                         |  2 +-
 config/locales/fa.yml                         |  2 +-
 config/locales/fi.yml                         |  2 +-
 config/locales/fo.yml                         |  2 +-
 config/locales/fr-CA.yml                      |  2 +-
 config/locales/fr.yml                         |  2 +-
 config/locales/fy.yml                         |  2 +-
 config/locales/ga.yml                         |  2 +-
 config/locales/gd.yml                         |  2 +-
 config/locales/gl.yml                         |  2 +-
 config/locales/he.yml                         |  2 +-
 config/locales/hu.yml                         |  2 +-
 config/locales/hy.yml                         |  2 +-
 config/locales/ia.yml                         |  2 +-
 config/locales/id.yml                         |  2 +-
 config/locales/ie.yml                         |  2 +-
 config/locales/io.yml                         |  2 +-
 config/locales/is.yml                         |  2 +-
 config/locales/it.yml                         |  2 +-
 config/locales/ja.yml                         |  2 +-
 config/locales/ka.yml                         |  2 +-
 config/locales/kab.yml                        |  2 +-
 config/locales/kk.yml                         |  2 +-
 config/locales/ko.yml                         |  2 +-
 config/locales/ku.yml                         |  2 +-
 config/locales/lad.yml                        |  2 +-
 config/locales/lt.yml                         |  2 +-
 config/locales/lv.yml                         |  2 +-
 config/locales/ms.yml                         |  2 +-
 config/locales/my.yml                         |  2 +-
 config/locales/nl.yml                         |  2 +-
 config/locales/nn.yml                         |  2 +-
 config/locales/no.yml                         |  2 +-
 config/locales/oc.yml                         |  2 +-
 config/locales/pl.yml                         |  2 +-
 config/locales/pt-BR.yml                      |  2 +-
 config/locales/pt-PT.yml                      |  2 +-
 config/locales/ru.yml                         |  2 +-
 config/locales/sc.yml                         |  2 +-
 config/locales/sco.yml                        |  2 +-
 config/locales/si.yml                         |  2 +-
 config/locales/sk.yml                         |  2 +-
 config/locales/sl.yml                         |  2 +-
 config/locales/sq.yml                         |  2 +-
 config/locales/sr-Latn.yml                    |  2 +-
 config/locales/sr.yml                         |  2 +-
 config/locales/sv.yml                         |  2 +-
 config/locales/th.yml                         |  2 +-
 config/locales/tr.yml                         |  2 +-
 config/locales/uk.yml                         |  2 +-
 config/locales/vi.yml                         |  2 +-
 config/locales/zh-CN.yml                      |  2 +-
 config/locales/zh-HK.yml                      |  2 +-
 config/locales/zh-TW.yml                      |  2 +-
 81 files changed, 236 insertions(+), 131 deletions(-)

diff --git a/app/controllers/admin/statuses_controller.rb b/app/controllers/admin/statuses_controller.rb
index e53b22dca3..40d1a481b2 100644
--- a/app/controllers/admin/statuses_controller.rb
+++ b/app/controllers/admin/statuses_controller.rb
@@ -16,6 +16,8 @@ module Admin
 
     def show
       authorize [:admin, @status], :show?
+
+      @status_batch_action = Admin::StatusBatchAction.new
     end
 
     def batch
diff --git a/app/helpers/admin/account_moderation_notes_helper.rb b/app/helpers/admin/account_moderation_notes_helper.rb
index 2a3d954a35..7c931c1157 100644
--- a/app/helpers/admin/account_moderation_notes_helper.rb
+++ b/app/helpers/admin/account_moderation_notes_helper.rb
@@ -12,12 +12,12 @@ module Admin::AccountModerationNotesHelper
     )
   end
 
-  def admin_account_inline_link_to(account)
+  def admin_account_inline_link_to(account, path: nil)
     return if account.nil?
 
     link_to(
       account_inline_text(account),
-      admin_account_path(account.id),
+      path || admin_account_path(account.id),
       class: class_names('inline-name-tag', suspended: suspended_account?(account)),
       title: account.acct
     )
diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss
index c7b32a9c9e..579b2a4f69 100644
--- a/app/javascript/styles/mastodon/admin.scss
+++ b/app/javascript/styles/mastodon/admin.scss
@@ -1922,3 +1922,31 @@ a.sparkline {
     }
   }
 }
+
+.status__card {
+  padding: 15px;
+  border-radius: 4px;
+  background: $ui-base-color;
+  font-size: 15px;
+  line-height: 20px;
+  word-wrap: break-word;
+  font-weight: 400;
+  border: 1px solid lighten($ui-base-color, 4%);
+  color: $primary-text-color;
+  box-sizing: border-box;
+  min-height: 100%;
+
+  .status__prepend {
+    padding: 0 0 15px;
+    gap: 4px;
+    align-items: center;
+  }
+
+  .status__content {
+    padding-top: 0;
+
+    summary {
+      display: list-item;
+    }
+  }
+}
diff --git a/app/javascript/styles/mastodon/tables.scss b/app/javascript/styles/mastodon/tables.scss
index 0cbf5c1d55..07d1ce12fd 100644
--- a/app/javascript/styles/mastodon/tables.scss
+++ b/app/javascript/styles/mastodon/tables.scss
@@ -339,16 +339,12 @@ a.table-action-link {
     }
   }
 
-  .status__content {
-    padding-top: 0;
-
-    summary {
-      display: list-item;
-    }
-
-    strong {
-      font-weight: 700;
-    }
+  // Reset the status card to not have borders, background or padding when
+  // inline in the table of statuses
+  .status__card {
+    border: none;
+    background: none;
+    padding: 0;
   }
 
   .nothing-here {
diff --git a/app/views/admin/reports/_status.html.haml b/app/views/admin/reports/_status.html.haml
index f4630ed25a..3a35fdd272 100644
--- a/app/views/admin/reports/_status.html.haml
+++ b/app/views/admin/reports/_status.html.haml
@@ -2,40 +2,52 @@
   %label.batch-table__row__select.batch-checkbox
     = f.check_box :status_ids, { multiple: true, include_hidden: false }, status.id
   .batch-table__row__content
-    .status__content><
-      - if status.proper.spoiler_text.blank?
-        = prerender_custom_emojis(status_content_format(status.proper), status.proper.emojis)
-      - else
-        %details<
-          %summary><
-            %strong> Content warning: #{prerender_custom_emojis(h(status.proper.spoiler_text), status.proper.emojis)}
-          = prerender_custom_emojis(status_content_format(status.proper), status.proper.emojis)
-
-    - unless status.proper.ordered_media_attachments.empty?
-      = render partial: 'admin/reports/media_attachments', locals: { status: status.proper }
-
-    .detailed-status__meta
-      - if status.application
-        = status.application.name
-        ·
-      = link_to ActivityPub::TagManager.instance.url_for(status.proper), class: 'detailed-status__datetime', target: stream_link_target, rel: 'noopener noreferrer' do
-        %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
-      - if status.edited?
-        ·
-        = link_to t('statuses.edited_at_html', date: content_tag(:time, l(status.edited_at), datetime: status.edited_at.iso8601, title: l(status.edited_at), class: 'formatted')),
-                  admin_account_status_path(status.account_id, status),
-                  class: 'detailed-status__datetime'
-      - if status.discarded?
-        ·
-        %span.negative-hint= t('admin.statuses.deleted')
-      ·
+    .status__card
       - if status.reblog?
-        = material_symbol('repeat_active')
-        = t('statuses.boosted_from_html', acct_link: admin_account_inline_link_to(status.proper.account))
-      - else
+        .status__prepend
+          = material_symbol('repeat')
+          = t('statuses.boosted_from_html', acct_link: admin_account_inline_link_to(status.proper.account, path: admin_account_status_path(status.proper.account.id, status.proper.id)))
+      - elsif status.reply? && status.in_reply_to_id.present?
+        .status__prepend
+          = material_symbol('reply')
+          = t('admin.statuses.replied_to_html', acct_link: admin_account_inline_link_to(status.in_reply_to_account, path: admin_account_status_path(status.thread.account_id, status.in_reply_to_id)))
+      .status__content><
+        - if status.proper.spoiler_text.blank?
+          = prerender_custom_emojis(status_content_format(status.proper), status.proper.emojis)
+        - else
+          %details<
+            %summary><
+              %strong> Content warning: #{prerender_custom_emojis(h(status.proper.spoiler_text), status.proper.emojis)}
+            = prerender_custom_emojis(status_content_format(status.proper), status.proper.emojis)
+
+      - unless status.proper.ordered_media_attachments.empty?
+        = render partial: 'admin/reports/media_attachments', locals: { status: status.proper }
+
+      .detailed-status__meta
+        - if status.application
+          = status.application.name
+          ·
+
+        = link_to admin_account_status_path(status.account.id, status), class: 'detailed-status__datetime' do
+          %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
+        - if status.edited?
+          ·
+          = link_to t('statuses.edited_at_html', date: content_tag(:time, l(status.edited_at), datetime: status.edited_at.iso8601, title: l(status.edited_at), class: 'formatted')),
+                    admin_account_status_path(status.account_id, status),
+                    class: 'detailed-status__datetime'
+        - if status.discarded?
+          ·
+          %span.negative-hint= t('admin.statuses.deleted')
+        ·
+
         = material_symbol visibility_icon(status)
         = t("statuses.visibilities.#{status.visibility}")
-      - if status.proper.sensitive?
         ·
-        = material_symbol('visibility_off')
-        = t('stream_entries.sensitive_content')
+
+        = link_to ActivityPub::TagManager.instance.url_for(status.proper), class: 'detailed-status__link', target: stream_link_target, rel: 'noopener noreferrer' do
+          = t('admin.statuses.view_publicly')
+
+        - if status.proper.sensitive?
+          ·
+          = material_symbol('visibility_off')
+          = t('stream_entries.sensitive_content')
diff --git a/app/views/admin/statuses/index.html.haml b/app/views/admin/statuses/index.html.haml
index 4d5d037060..57b9fe0e15 100644
--- a/app/views/admin/statuses/index.html.haml
+++ b/app/views/admin/statuses/index.html.haml
@@ -1,7 +1,5 @@
 - content_for :page_title do
-  = t('admin.statuses.title')
-  \-
-  @#{@account.pretty_acct}
+  = t('admin.statuses.title', name: @account.pretty_acct)
 
 .filters
   .filter-subset
@@ -33,11 +31,18 @@
         = check_box_tag :batch_checkbox_all, nil, false
       .batch-table__toolbar__actions
         - unless @statuses.empty?
-          = f.button safe_join([material_symbol('flag'), t('admin.statuses.batch.report')]),
-                     class: 'table-action-link',
-                     data: { confirm: t('admin.reports.are_you_sure') },
-                     name: :report,
-                     type: :submit
+          - if params[:report_id]
+            = f.button safe_join([material_symbol('add'), t('admin.statuses.batch.add_to_report', id: params[:report_id])]),
+                       class: 'table-action-link',
+                       data: { confirm: t('admin.reports.are_you_sure') },
+                       name: :report,
+                       type: :submit
+          - else
+            = f.button safe_join([material_symbol('flag'), t('admin.statuses.batch.report')]),
+                       class: 'table-action-link',
+                       data: { confirm: t('admin.reports.are_you_sure') },
+                       name: :report,
+                       type: :submit
     .batch-table__body
       - if @statuses.empty?
         = nothing_here 'nothing-here--under-tabs'
diff --git a/app/views/admin/statuses/show.html.haml b/app/views/admin/statuses/show.html.haml
index 9cadde2870..49c23e921c 100644
--- a/app/views/admin/statuses/show.html.haml
+++ b/app/views/admin/statuses/show.html.haml
@@ -1,7 +1,14 @@
 - content_for :page_title do
-  = t('statuses.title', name: display_name(@account), quote: truncate(@status.spoiler_text.presence || @status.text, length: 50, omission: '…', escape: false))
+  = t('admin.statuses.status_title', name: @account.pretty_acct)
 
 - content_for :heading_actions do
+  = form_with model: @status_batch_action, url: batch_admin_account_statuses_path(@account.id) do |f|
+    = f.hidden_field :status_ids, { multiple: true, value: @status.id }
+    = f.button safe_join([material_symbol('flag'), t('admin.statuses.batch.report')]),
+               class: 'button',
+               data: { confirm: t('admin.reports.are_you_sure') },
+               name: :report,
+               type: :submit
   = link_to t('admin.statuses.open'), ActivityPub::TagManager.instance.url_for(@status), class: 'button', target: '_blank', rel: 'noopener noreferrer'
 
 %h3= t('admin.statuses.metadata')
@@ -44,7 +51,56 @@
 
 %hr.spacer/
 
-%h3= t('admin.statuses.history')
+%h3= t('admin.statuses.contents')
 
-%ol.history
-  = render partial: 'admin/status_edits/status_edit', collection: batched_ordered_status_edits
+.status__card
+  - if @status.reblog?
+    .status__prepend
+      = material_symbol('repeat')
+      = t('statuses.boosted_from_html', acct_link: admin_account_inline_link_to(@status.proper.account, path: admin_account_status_path(@status.proper.account.id, @status.proper.id)))
+  - elsif @status.reply? && @status.in_reply_to_id.present?
+    .status__prepend
+      = material_symbol('reply')
+      = t('admin.statuses.replied_to_html', acct_link: admin_account_inline_link_to(@status.in_reply_to_account, path: admin_account_status_path(@status.thread.account_id, @status.in_reply_to_id)))
+  .status__content><
+    - if @status.proper.spoiler_text.blank?
+      = prerender_custom_emojis(status_content_format(@status.proper), @status.proper.emojis)
+    - else
+      %details<
+        %summary><
+          %strong> Content warning: #{prerender_custom_emojis(h(@status.proper.spoiler_text), @status.proper.emojis)}
+        = prerender_custom_emojis(status_content_format(@status.proper), @status.proper.emojis)
+
+    - unless @status.proper.ordered_media_attachments.empty?
+      = render partial: 'admin/reports/media_attachments', locals: { status: @status.proper }
+
+    .detailed-status__meta
+      - if @status.application
+        = @status.application.name
+        ·
+      %span.detailed-status__datetime
+        %time.formatted{ datetime: @status.created_at.iso8601, title: l(@status.created_at) }= l(@status.created_at)
+      - if @status.edited?
+        ·
+        %span.detailed-status__datetime
+          = t('statuses.edited_at_html', date: content_tag(:time, l(@status.edited_at), datetime: @status.edited_at.iso8601, title: l(@status.edited_at), class: 'formatted'))
+      - if @status.discarded?
+        ·
+        %span.negative-hint= t('admin.statuses.deleted')
+      - unless @status.reblog?
+        ·
+        = material_symbol(visibility_icon(@status))
+        = t("statuses.visibilities.#{@status.visibility}")
+      - if @status.proper.sensitive?
+        ·
+        = material_symbol('visibility_off')
+        = t('stream_entries.sensitive_content')
+
+%hr.spacer/
+
+%h3= t('admin.statuses.history')
+- if @status.edits.empty?
+  %p= t('admin.statuses.no_history')
+- else
+  %ol.history
+    = render partial: 'admin/status_edits/status_edit', collection: batched_ordered_status_edits
diff --git a/config/locales/an.yml b/config/locales/an.yml
index 2db042f1b1..43f8d358cc 100644
--- a/config/locales/an.yml
+++ b/config/locales/an.yml
@@ -723,7 +723,7 @@ an:
       original_status: Publicación orichinal
       reblogs: Impulsos
       status_changed: Publicación cambiada
-      title: Estau d'as cuentas
+      title: Estau d'as cuentas - @%{name}
       trending: En tendencia
       visibility: Visibilidat
       with_media: Con multimedia
diff --git a/config/locales/ar.yml b/config/locales/ar.yml
index 1a6f0da8c6..bbc481a137 100644
--- a/config/locales/ar.yml
+++ b/config/locales/ar.yml
@@ -847,7 +847,7 @@ ar:
       original_status: المنشور الأصلي
       reblogs: المعاد تدوينها
       status_changed: عُدّل المنشور
-      title: منشورات الحساب
+      title: منشورات الحساب - @%{name}
       trending: المتداولة
       visibility: مدى الظهور
       with_media: تحتوي على وسائط
diff --git a/config/locales/be.yml b/config/locales/be.yml
index b627672b2d..c59233eb8b 100644
--- a/config/locales/be.yml
+++ b/config/locales/be.yml
@@ -856,7 +856,7 @@ be:
       original_status: Зыходны допіс
       reblogs: Рэпосты
       status_changed: Допіс зменены
-      title: Допісы уліковага запісу
+      title: Допісы уліковага запісу - @%{name}
       trending: Папулярныя
       visibility: Бачнасць
       with_media: З медыя
diff --git a/config/locales/bg.yml b/config/locales/bg.yml
index 7181b35b6d..e10ce3197c 100644
--- a/config/locales/bg.yml
+++ b/config/locales/bg.yml
@@ -803,7 +803,7 @@ bg:
       original_status: Първообразна публикация
       reblogs: Блогване пак
       status_changed: Публикацията променена
-      title: Публикации на акаунта
+      title: Публикации на акаунта - @%{name}
       trending: Изгряващи
       visibility: Видимост
       with_media: С мултимедия
diff --git a/config/locales/br.yml b/config/locales/br.yml
index f9fbd34adb..098b20934f 100644
--- a/config/locales/br.yml
+++ b/config/locales/br.yml
@@ -263,7 +263,7 @@ br:
       original_status: Toud orin
       reblogs: Skignadennoù
       status_changed: Toud kemmet
-      title: Toudoù ar gont
+      title: Toudoù ar gont - @%{name}
       visibility: Gwelusted
       with_media: Gant mediaoù
     strikes:
diff --git a/config/locales/ca.yml b/config/locales/ca.yml
index 00c8f57a85..970fd99fff 100644
--- a/config/locales/ca.yml
+++ b/config/locales/ca.yml
@@ -841,7 +841,7 @@ ca:
       original_status: Publicació original
       reblogs: Impulsos
       status_changed: Publicació canviada
-      title: Estats del compte
+      title: Estats del compte - @%{name}
       trending: Tendència
       visibility: Visibilitat
       with_media: Amb contingut multimèdia
diff --git a/config/locales/ckb.yml b/config/locales/ckb.yml
index 88dadff014..6e1b11379c 100644
--- a/config/locales/ckb.yml
+++ b/config/locales/ckb.yml
@@ -520,7 +520,7 @@ ckb:
       media:
         title: میدیا
       no_status_selected: هیچ دۆخیک نەگۆڕاوە وەک ئەوەی هیچ بارێک دەستنیشان نەکراوە
-      title: دۆخی ئەژمێر
+      title: دۆخی ئەژمێر - @%{name}
       with_media: بە میدیا
     tags:
       review: پێداچوونەوەی دۆخ
diff --git a/config/locales/co.yml b/config/locales/co.yml
index dad3e08ffd..b81427e833 100644
--- a/config/locales/co.yml
+++ b/config/locales/co.yml
@@ -459,7 +459,7 @@ co:
       media:
         title: Media
       no_status_selected: I statuti ùn sò micca stati mudificati perchè manc'unu era selezziunatu
-      title: Statuti di u contu
+      title: Statuti di u contu - @%{name}
       with_media: Cù media
     system_checks:
       rules_check:
diff --git a/config/locales/cs.yml b/config/locales/cs.yml
index 15211b928a..f5f7f4d731 100644
--- a/config/locales/cs.yml
+++ b/config/locales/cs.yml
@@ -826,7 +826,7 @@ cs:
       original_status: Původní příspěvek
       reblogs: Boosty
       status_changed: Příspěvek změněn
-      title: Příspěvky účtu
+      title: Příspěvky účtu - @%{name}
       trending: Populární
       visibility: Viditelnost
       with_media: S médii
diff --git a/config/locales/cy.yml b/config/locales/cy.yml
index 2d6a0eb38d..ca18de17bc 100644
--- a/config/locales/cy.yml
+++ b/config/locales/cy.yml
@@ -889,7 +889,7 @@ cy:
       original_status: Postiad gwreiddiol
       reblogs: Ailflogiadau
       status_changed: Postiad wedi'i newid
-      title: Postiadau cyfrif
+      title: Postiadau cyfrif - @%{name}
       trending: Yn trendio
       visibility: Gwelededd
       with_media: Gyda chyfryngau
diff --git a/config/locales/da.yml b/config/locales/da.yml
index daf683637d..e157af9cc2 100644
--- a/config/locales/da.yml
+++ b/config/locales/da.yml
@@ -841,7 +841,7 @@ da:
       original_status: Oprindeligt indlæg
       reblogs: Genblogninger
       status_changed: Indlæg ændret
-      title: Kontoindlæg
+      title: Kontoindlæg - @%{name}
       trending: Populære
       visibility: Synlighed
       with_media: Med medier
diff --git a/config/locales/de.yml b/config/locales/de.yml
index 10223f2278..e3ee03264e 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -841,7 +841,7 @@ de:
       original_status: Ursprünglicher Beitrag
       reblogs: Geteilte Beiträge
       status_changed: Beitrag bearbeitet
-      title: Beiträge des Kontos
+      title: Beiträge des Kontos - @%{name}
       trending: Trends
       visibility: Sichtbarkeit
       with_media: Mit Medien
diff --git a/config/locales/el.yml b/config/locales/el.yml
index 3a145cbdab..26b0ec00a2 100644
--- a/config/locales/el.yml
+++ b/config/locales/el.yml
@@ -817,7 +817,7 @@ el:
       original_status: Αρχική ανάρτηση
       reblogs: Αναδημοσιεύσεις
       status_changed: Η ανάρτηση άλλαξε
-      title: Καταστάσεις λογαριασμού
+      title: Καταστάσεις λογαριασμού - @%{name}
       trending: Τάσεις
       visibility: Ορατότητα
       with_media: Με πολυμέσα
diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml
index fb284479f2..e22ed62051 100644
--- a/config/locales/en-GB.yml
+++ b/config/locales/en-GB.yml
@@ -832,7 +832,7 @@ en-GB:
       original_status: Original post
       reblogs: Reblogs
       status_changed: Post changed
-      title: Account posts
+      title: Account posts - @%{name}
       trending: Trending
       visibility: Visibility
       with_media: With media
diff --git a/config/locales/en.yml b/config/locales/en.yml
index cf783338e2..2971fe1f25 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -826,8 +826,10 @@ en:
       back_to_account: Back to account page
       back_to_report: Back to report page
       batch:
+        add_to_report: 'Add to report #%{id}'
         remove_from_report: Remove from report
         report: Report
+      contents: Contents
       deleted: Deleted
       favourites: Favorites
       history: Version history
@@ -836,13 +838,17 @@ en:
       media:
         title: Media
       metadata: Metadata
+      no_history: This post hasn't been edited
       no_status_selected: No posts were changed as none were selected
       open: Open post
       original_status: Original post
       reblogs: Reblogs
+      replied_to_html: Replied to %{acct_link}
       status_changed: Post changed
-      title: Account posts
+      status_title: Post by @%{name}
+      title: Account posts - @%{name}
       trending: Trending
+      view_publicly: View publicly
       visibility: Visibility
       with_media: With media
     strikes:
diff --git a/config/locales/eo.yml b/config/locales/eo.yml
index 12cae075f0..b5287d9e2a 100644
--- a/config/locales/eo.yml
+++ b/config/locales/eo.yml
@@ -814,7 +814,7 @@ eo:
       original_status: Originala afiŝo
       reblogs: Reblogaĵoj
       status_changed: Afiŝo ŝanĝiĝis
-      title: Afiŝoj de la konto
+      title: Afiŝoj de la konto - @%{name}
       trending: Popularaĵoj
       visibility: Videbleco
       with_media: Kun aŭdovidaĵoj
diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml
index 79bfdfbdbf..6dc9d99f37 100644
--- a/config/locales/es-AR.yml
+++ b/config/locales/es-AR.yml
@@ -833,7 +833,7 @@ es-AR:
       original_status: Mensaje original
       reblogs: Adhesiones
       status_changed: Mensaje cambiado
-      title: Mensajes de la cuenta
+      title: Mensajes de la cuenta - @%{name}
       trending: En tendencia
       visibility: Visibilidad
       with_media: Con medios
diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml
index fef805680a..7e6570f068 100644
--- a/config/locales/es-MX.yml
+++ b/config/locales/es-MX.yml
@@ -833,7 +833,7 @@ es-MX:
       original_status: Publicación original
       reblogs: Impulsos
       status_changed: Publicación cambiada
-      title: Estado de las cuentas
+      title: Estado de las cuentas - @%{name}
       trending: En tendencia
       visibility: Visibilidad
       with_media: Con multimedia
diff --git a/config/locales/es.yml b/config/locales/es.yml
index ddd53a2387..32abd9420d 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -833,7 +833,7 @@ es:
       original_status: Publicación original
       reblogs: Impulsos
       status_changed: Publicación cambiada
-      title: Publicaciones de la cuenta
+      title: Publicaciones de la cuenta - @%{name}
       trending: En tendencia
       visibility: Visibilidad
       with_media: Con multimedia
diff --git a/config/locales/et.yml b/config/locales/et.yml
index 3be9add91c..f8a4f7f69e 100644
--- a/config/locales/et.yml
+++ b/config/locales/et.yml
@@ -833,7 +833,7 @@ et:
       original_status: Algne postitus
       reblogs: Jagamised
       status_changed: Muudetud postitus
-      title: Konto postitused
+      title: Konto postitused - @%{name}
       trending: Populaarne
       visibility: Nähtavus
       with_media: Meediaga
diff --git a/config/locales/eu.yml b/config/locales/eu.yml
index e9c3be2d24..a764e88bac 100644
--- a/config/locales/eu.yml
+++ b/config/locales/eu.yml
@@ -793,7 +793,7 @@ eu:
       original_status: Jatorrizko bidalketa
       reblogs: Bultzadak
       status_changed: Bidalketa aldatuta
-      title: Kontuaren bidalketak
+      title: Kontuaren bidalketak - @%{name}
       trending: Joera
       visibility: Ikusgaitasuna
       with_media: Multimediarekin
diff --git a/config/locales/fa.yml b/config/locales/fa.yml
index 603cfe8de1..38daf70d29 100644
--- a/config/locales/fa.yml
+++ b/config/locales/fa.yml
@@ -741,7 +741,7 @@ fa:
       original_status: فرستهٔ اصلی
       reblogs: تقویت‌ها
       status_changed: فرسته تغییر کرد
-      title: نوشته‌های حساب
+      title: "@%{name} - نوشته‌های حساب"
       trending: پرطرفدار
       visibility: نمایانی
       with_media: دارای عکس یا ویدیو
diff --git a/config/locales/fi.yml b/config/locales/fi.yml
index 6fe9c14591..efdfdfed04 100644
--- a/config/locales/fi.yml
+++ b/config/locales/fi.yml
@@ -841,7 +841,7 @@ fi:
       original_status: Alkuperäinen julkaisu
       reblogs: Edelleen jako
       status_changed: Julkaisua muutettu
-      title: Tilin tilat
+      title: Tilin tilat - @%{name}
       trending: Suosituttua
       visibility: Näkyvyys
       with_media: Sisältää mediaa
diff --git a/config/locales/fo.yml b/config/locales/fo.yml
index 6cc1fda6a0..8dab61c267 100644
--- a/config/locales/fo.yml
+++ b/config/locales/fo.yml
@@ -841,7 +841,7 @@ fo:
       original_status: Upprunapostur
       reblogs: Endurbloggar
       status_changed: Postur broyttur
-      title: Postar hjá kontu
+      title: Postar hjá kontu - @%{name}
       trending: Vælumtókt
       visibility: Sýni
       with_media: Við miðli
diff --git a/config/locales/fr-CA.yml b/config/locales/fr-CA.yml
index 3c771d4c64..bb0501d0e3 100644
--- a/config/locales/fr-CA.yml
+++ b/config/locales/fr-CA.yml
@@ -836,7 +836,7 @@ fr-CA:
       original_status: Message original
       reblogs: Partages
       status_changed: Publication modifiée
-      title: Messages du compte
+      title: Messages du compte - @%{name}
       trending: Tendances
       visibility: Visibilité
       with_media: Avec médias
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index 58fc63fc1b..0c35dea62a 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -836,7 +836,7 @@ fr:
       original_status: Message original
       reblogs: Partages
       status_changed: Publication modifiée
-      title: Messages du compte
+      title: Messages du compte - @%{name}
       trending: Tendances
       visibility: Visibilité
       with_media: Avec médias
diff --git a/config/locales/fy.yml b/config/locales/fy.yml
index a6656f91b8..8a4f519e0c 100644
--- a/config/locales/fy.yml
+++ b/config/locales/fy.yml
@@ -833,7 +833,7 @@ fy:
       original_status: Oarspronklik berjocht
       reblogs: Boosts
       status_changed: Berjocht wizige
-      title: Accountberjochten
+      title: Accountberjochten - @%{name}
       trending: Trending
       visibility: Sichtberheid
       with_media: Mei media
diff --git a/config/locales/ga.yml b/config/locales/ga.yml
index 5e5ecb238e..67461f3c2a 100644
--- a/config/locales/ga.yml
+++ b/config/locales/ga.yml
@@ -875,7 +875,7 @@ ga:
       original_status: Bunphostáil
       reblogs: Athbhlaganna
       status_changed: Athraíodh postáil
-      title: Poist chuntais
+      title: Poist chuntais - @%{name}
       trending: Ag treochtáil
       visibility: Infheictheacht
       with_media: Le meáin
diff --git a/config/locales/gd.yml b/config/locales/gd.yml
index c804f42523..89198bd514 100644
--- a/config/locales/gd.yml
+++ b/config/locales/gd.yml
@@ -861,7 +861,7 @@ gd:
       original_status: Am post tùsail
       reblogs: Brosnachaidhean
       status_changed: Post air atharrachadh
-      title: Postaichean a’ chunntais
+      title: Postaichean a’ chunntais - @%{name}
       trending: A’ treandadh
       visibility: Faicsinneachd
       with_media: Le meadhanan riutha
diff --git a/config/locales/gl.yml b/config/locales/gl.yml
index 1ad8deb179..0f3420a7f3 100644
--- a/config/locales/gl.yml
+++ b/config/locales/gl.yml
@@ -841,7 +841,7 @@ gl:
       original_status: Publicación orixinal
       reblogs: Promocións
       status_changed: Publicación editada
-      title: Publicacións da conta
+      title: Publicacións da conta - @%{name}
       trending: Popular
       visibility: Visibilidade
       with_media: con medios
diff --git a/config/locales/he.yml b/config/locales/he.yml
index 10b4611b9a..59dc09799d 100644
--- a/config/locales/he.yml
+++ b/config/locales/he.yml
@@ -861,7 +861,7 @@ he:
       original_status: הודעה מקורית
       reblogs: שיתופים
       status_changed: הודעה שונתה
-      title: הודעות החשבון
+      title: הודעות החשבון - @%{name}
       trending: נושאים חמים
       visibility: נראות
       with_media: עם מדיה
diff --git a/config/locales/hu.yml b/config/locales/hu.yml
index 1892009238..da4ff78dc4 100644
--- a/config/locales/hu.yml
+++ b/config/locales/hu.yml
@@ -841,7 +841,7 @@ hu:
       original_status: Eredeti bejegyzés
       reblogs: Megosztások
       status_changed: A bejegyzés megváltozott
-      title: Fiók bejegyzései
+      title: Fiók bejegyzései - @%{name}
       trending: Felkapott
       visibility: Láthatóság
       with_media: Médiával
diff --git a/config/locales/hy.yml b/config/locales/hy.yml
index 201922d102..d8cf2a97ba 100644
--- a/config/locales/hy.yml
+++ b/config/locales/hy.yml
@@ -402,7 +402,7 @@ hy:
       deleted: Ջնջված է
       media:
         title: Մեդիա
-      title: Օգտատիրոջ գրառումները
+      title: Օգտատիրոջ գրառումները - @%{name}
       with_media: Մեդիայի հետ
     tags:
       review: Վերանայել գրառումը
diff --git a/config/locales/ia.yml b/config/locales/ia.yml
index 843e8724b9..1398ae51d4 100644
--- a/config/locales/ia.yml
+++ b/config/locales/ia.yml
@@ -833,7 +833,7 @@ ia:
       original_status: Message original
       reblogs: Republicationes
       status_changed: Message cambiate
-      title: Messages del conto
+      title: Messages del conto - @%{name}
       trending: Tendentias
       visibility: Visibilitate
       with_media: Con multimedia
diff --git a/config/locales/id.yml b/config/locales/id.yml
index 6a005fddaa..9c31daf420 100644
--- a/config/locales/id.yml
+++ b/config/locales/id.yml
@@ -711,7 +711,7 @@ id:
       original_status: Kiriman asli
       reblogs: Reblog
       status_changed: Kiriman diubah
-      title: Status akun
+      title: Status akun - @%{name}
       trending: Sedang tren
       visibility: Visibilitas
       with_media: Dengan media
diff --git a/config/locales/ie.yml b/config/locales/ie.yml
index 94c4b7f4f0..d7df83ef69 100644
--- a/config/locales/ie.yml
+++ b/config/locales/ie.yml
@@ -791,7 +791,7 @@ ie:
       original_status: Original posta
       reblogs: Boosts
       status_changed: Posta modificat
-      title: Postas del conto
+      title: Postas del conto - @%{name}
       trending: Populari
       visibility: Visibilitá
       with_media: Con medie
diff --git a/config/locales/io.yml b/config/locales/io.yml
index 8ce5f3403b..1ff5d98bf2 100644
--- a/config/locales/io.yml
+++ b/config/locales/io.yml
@@ -779,7 +779,7 @@ io:
       original_status: Originala posto
       reblogs: Dissemi
       status_changed: Posto chanjita
-      title: Kontoposti
+      title: Kontoposti - @%{name}
       trending: Populara
       visibility: Videbleso
       with_media: Kun medii
diff --git a/config/locales/is.yml b/config/locales/is.yml
index 552df8f064..9ba29f2af0 100644
--- a/config/locales/is.yml
+++ b/config/locales/is.yml
@@ -843,7 +843,7 @@ is:
       original_status: Upprunaleg færsla
       reblogs: Endurbirtingar
       status_changed: Færslu breytt
-      title: Færslur notandaaðgangs
+      title: Færslur notandaaðgangs - @%{name}
       trending: Vinsælt
       visibility: Sýnileiki
       with_media: Með myndefni
diff --git a/config/locales/it.yml b/config/locales/it.yml
index e18cb0e8f6..08e224ad94 100644
--- a/config/locales/it.yml
+++ b/config/locales/it.yml
@@ -833,7 +833,7 @@ it:
       original_status: Post originale
       reblogs: Condivisioni
       status_changed: Post modificato
-      title: Gli status dell'account
+      title: Gli status dell'account - @%{name}
       trending: Di tendenza
       visibility: Visibilità
       with_media: con media
diff --git a/config/locales/ja.yml b/config/locales/ja.yml
index a70ae680e4..76152c3744 100644
--- a/config/locales/ja.yml
+++ b/config/locales/ja.yml
@@ -819,7 +819,7 @@ ja:
       original_status: オリジナルの投稿
       reblogs: ブースト
       status_changed: 投稿を変更しました
-      title: 投稿一覧
+      title: 投稿一覧 - @%{name}
       trending: トレンド
       visibility: 公開範囲
       with_media: メディアあり
diff --git a/config/locales/ka.yml b/config/locales/ka.yml
index 2a0365fbf5..93f7a39dc3 100644
--- a/config/locales/ka.yml
+++ b/config/locales/ka.yml
@@ -190,7 +190,7 @@ ka:
       media:
         title: მედია
       no_status_selected: სატუსები არ შეცვლილა, რადგან არცერთი არ მონიშნულა
-      title: ანგარიშის სტატუსები
+      title: ანგარიშის სტატუსები - @%{name}
       with_media: მედიით
     title: ადმინისტრაცია
   admin_mailer:
diff --git a/config/locales/kab.yml b/config/locales/kab.yml
index 993488f1fc..c74540cfbf 100644
--- a/config/locales/kab.yml
+++ b/config/locales/kab.yml
@@ -419,7 +419,7 @@ kab:
       media:
         title: Amidya
       open: Ldi tasuffeɣt
-      title: Tisuffaɣ n umiḍan
+      title: Tisuffaɣ n umiḍan - @%{name}
       trending: Ayen mucaɛen
       visibility: Abani
       with_media: S umidya
diff --git a/config/locales/kk.yml b/config/locales/kk.yml
index 537104ba51..4b9cef245e 100644
--- a/config/locales/kk.yml
+++ b/config/locales/kk.yml
@@ -285,7 +285,7 @@ kk:
       media:
         title: Медиa
       no_status_selected: Бірде-бір статус өзгерген жоқ, себебі ештеңе таңдалмады
-      title: Аккаунт статустары
+      title: Аккаунт статустары - @%{name}
       with_media: Медиамен
     tags:
       review: Статусты көрсету
diff --git a/config/locales/ko.yml b/config/locales/ko.yml
index 1fe43f7e75..36a13397d0 100644
--- a/config/locales/ko.yml
+++ b/config/locales/ko.yml
@@ -829,7 +829,7 @@ ko:
       original_status: 원본 게시물
       reblogs: 리블로그
       status_changed: 게시물 변경됨
-      title: 계정 게시물
+      title: 계정 게시물 - @%{name}
       trending: 유행 중
       visibility: 공개 설정
       with_media: 미디어 있음
diff --git a/config/locales/ku.yml b/config/locales/ku.yml
index ddd214441c..54188d2514 100644
--- a/config/locales/ku.yml
+++ b/config/locales/ku.yml
@@ -720,7 +720,7 @@ ku:
       original_status: Şandiyê resen
       reblogs: Ji nû ve nivîsandin
       status_changed: Şandî hate guhertin
-      title: Şandiyên ajimêr
+      title: Şandiyên ajimêr - @%{name}
       trending: Rojev
       visibility: Xuyabarî
       with_media: Bi medya yê re
diff --git a/config/locales/lad.yml b/config/locales/lad.yml
index 4486df637e..3b33888c71 100644
--- a/config/locales/lad.yml
+++ b/config/locales/lad.yml
@@ -825,7 +825,7 @@ lad:
       original_status: Publikasyon orijinala
       reblogs: Repartajasyones
       status_changed: Publikasyon trokada
-      title: Publikasyones del kuento
+      title: Publikasyones del kuento - @%{name}
       trending: Trendes
       visibility: Vizivilita
       with_media: Kon multimedia
diff --git a/config/locales/lt.yml b/config/locales/lt.yml
index 3850e2e071..3519cb5b32 100644
--- a/config/locales/lt.yml
+++ b/config/locales/lt.yml
@@ -601,7 +601,7 @@ lt:
       no_status_selected: Jokie įrašai nebuvo pakeisti, nes nė vienas buvo pasirinktas
       open: Atidaryti įrašą
       original_status: Originalus įrašas
-      title: Paskyros statusai
+      title: Paskyros statusai - @%{name}
       trending: Tendencinga
       with_media: Su medija
     system_checks:
diff --git a/config/locales/lv.yml b/config/locales/lv.yml
index 3e5a1db00e..d793c8e196 100644
--- a/config/locales/lv.yml
+++ b/config/locales/lv.yml
@@ -830,7 +830,7 @@ lv:
       original_status: Oriģinālā ziņa
       reblogs: Reblogi
       status_changed: Ziņa mainīta
-      title: Konta ziņas
+      title: Konta ziņas - @%{name}
       trending: Aktuāli
       visibility: Redzamība
       with_media: Ar multividi
diff --git a/config/locales/ms.yml b/config/locales/ms.yml
index 90493a30b6..76f914dd16 100644
--- a/config/locales/ms.yml
+++ b/config/locales/ms.yml
@@ -768,7 +768,7 @@ ms:
       original_status: Hantaran asal
       reblogs: Ulang siar
       status_changed: Hantaran diubah
-      title: Hantaran akaun
+      title: Hantaran akaun - @%{name}
       trending: Sohor kini
       visibility: Visibiliti
       with_media: Dengan media
diff --git a/config/locales/my.yml b/config/locales/my.yml
index 6a330a16c7..b238abb051 100644
--- a/config/locales/my.yml
+++ b/config/locales/my.yml
@@ -764,7 +764,7 @@ my:
       original_status: မူရင်းပို့စ်
       reblogs: Reblog များ
       status_changed: ပို့စ်ပြောင်းပြီးပါပြီ
-      title: အကောင့်ပို့စ်များ
+      title: "@%{name} - အကောင့်ပို့စ်များ"
       trending: လက်ရှိခေတ်စားနေခြင်း
       visibility: မြင်နိုင်မှု
       with_media: မီဒီယာနှင့်အတူ
diff --git a/config/locales/nl.yml b/config/locales/nl.yml
index 1af30bca98..d4a88b3bea 100644
--- a/config/locales/nl.yml
+++ b/config/locales/nl.yml
@@ -833,7 +833,7 @@ nl:
       original_status: Oorspronkelijk bericht
       reblogs: Boosts
       status_changed: Bericht veranderd
-      title: Berichten van account
+      title: Berichten van account - @%{name}
       trending: Trending
       visibility: Zichtbaarheid
       with_media: Met media
diff --git a/config/locales/nn.yml b/config/locales/nn.yml
index 62b08f42ed..e04c0168f2 100644
--- a/config/locales/nn.yml
+++ b/config/locales/nn.yml
@@ -841,7 +841,7 @@ nn:
       original_status: Opprinnelig innlegg
       reblogs: Framhevingar
       status_changed: Innlegg endret
-      title: Kontostatusar
+      title: Kontostatusar - @%{name}
       trending: Populært
       visibility: Synlighet
       with_media: Med media
diff --git a/config/locales/no.yml b/config/locales/no.yml
index 94986f4cae..408fdd5ae1 100644
--- a/config/locales/no.yml
+++ b/config/locales/no.yml
@@ -786,7 +786,7 @@
       original_status: Opprinnelig innlegg
       reblogs: Fremheve
       status_changed: Innlegg endret
-      title: Kontostatuser
+      title: Kontostatuser - @%{name}
       trending: Populært
       visibility: Synlighet
       with_media: Med media
diff --git a/config/locales/oc.yml b/config/locales/oc.yml
index a30126c44b..5130977cb3 100644
--- a/config/locales/oc.yml
+++ b/config/locales/oc.yml
@@ -401,7 +401,7 @@ oc:
       media:
         title: Mèdia
       no_status_selected: Cap d’estatut pas cambiat estant que cap èra pas seleccionat
-      title: Estatuts del compte
+      title: Estatuts del compte - @%{name}
       visibility: Visibilitat
       with_media: Amb mèdia
     system_checks:
diff --git a/config/locales/pl.yml b/config/locales/pl.yml
index d50a042a22..c5d63e1d73 100644
--- a/config/locales/pl.yml
+++ b/config/locales/pl.yml
@@ -861,7 +861,7 @@ pl:
       original_status: Oryginalny post
       reblogs: Podbicia
       status_changed: Post zmieniony
-      title: Wpisy konta
+      title: Wpisy konta - @%{name}
       trending: Popularne
       visibility: Widoczność
       with_media: Z zawartością multimedialną
diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml
index 0ff944e108..c5a0f3764a 100644
--- a/config/locales/pt-BR.yml
+++ b/config/locales/pt-BR.yml
@@ -841,7 +841,7 @@ pt-BR:
       original_status: Publicação original
       reblogs: Reblogs
       status_changed: Publicação alterada
-      title: Publicações da conta
+      title: Publicações da conta - @%{name}
       trending: Em alta
       visibility: Visibilidade
       with_media: Com mídia
diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml
index 1761ec3f0c..ff80948848 100644
--- a/config/locales/pt-PT.yml
+++ b/config/locales/pt-PT.yml
@@ -832,7 +832,7 @@ pt-PT:
       original_status: Publicação original
       reblogs: Re-publicacões
       status_changed: Publicação alterada
-      title: Estado das contas
+      title: Estado das contas - @%{name}
       trending: Em tendência
       visibility: Visibilidade
       with_media: Com media
diff --git a/config/locales/ru.yml b/config/locales/ru.yml
index 8a84f22115..09d89cef9d 100644
--- a/config/locales/ru.yml
+++ b/config/locales/ru.yml
@@ -869,7 +869,7 @@ ru:
       original_status: Оригинальный пост
       reblogs: Продвинули
       status_changed: Пост изменен
-      title: Посты пользователя
+      title: Посты пользователя - @%{name}
       trending: Популярное
       visibility: Видимость
       with_media: С файлами
diff --git a/config/locales/sc.yml b/config/locales/sc.yml
index 9ab62cea71..09f8ba0e0e 100644
--- a/config/locales/sc.yml
+++ b/config/locales/sc.yml
@@ -582,7 +582,7 @@ sc:
       open: Aberi sa publicatzione
       original_status: Publicatzione originale
       status_changed: Publicatzione modificada
-      title: Istados de su contu
+      title: Istados de su contu - @%{name}
       trending: Populares
       visibility: Visibilidade
       with_media: Cun elementos multimediales
diff --git a/config/locales/sco.yml b/config/locales/sco.yml
index 8cc733a4ac..55e0603d45 100644
--- a/config/locales/sco.yml
+++ b/config/locales/sco.yml
@@ -713,7 +713,7 @@ sco:
       original_status: Original post
       reblogs: Reblogs
       status_changed: Post chynged
-      title: Accoont posts
+      title: Accoont posts - @%{name}
       trending: Trendin
       visibility: Visibility
       with_media: Wi media
diff --git a/config/locales/si.yml b/config/locales/si.yml
index 270e0ae3fc..b0eb1d3b0c 100644
--- a/config/locales/si.yml
+++ b/config/locales/si.yml
@@ -607,7 +607,7 @@ si:
       open: ලිපිය අරින්න
       original_status: මුල් ලිපිය
       status_changed: ලිපිය සංශෝධිතයි
-      title: ගිණුමේ ලිපි
+      title: ගිණුමේ ලිපි - @%{name}
       trending: නැගී එන
       with_media: මාධ්‍ය සමඟ
     strikes:
diff --git a/config/locales/sk.yml b/config/locales/sk.yml
index 6ef78a8f21..d576bf0382 100644
--- a/config/locales/sk.yml
+++ b/config/locales/sk.yml
@@ -684,7 +684,7 @@ sk:
       open: Otvor príspevok
       original_status: Pôvodný príspevok
       status_changed: Príspevok bol zmenený
-      title: Príspevky na účte
+      title: Príspevky na účte - @%{name}
       trending: Populárne
       visibility: Viditeľnosť
       with_media: S médiami
diff --git a/config/locales/sl.yml b/config/locales/sl.yml
index e9c06bcaa6..6ae239d69f 100644
--- a/config/locales/sl.yml
+++ b/config/locales/sl.yml
@@ -853,7 +853,7 @@ sl:
       original_status: Izvorna objava
       reblogs: Ponovljeni blogi
       status_changed: Objava spremenjena
-      title: Objave računa
+      title: Objave računa - @%{name}
       trending: V trendu
       visibility: Vidnost
       with_media: Z mediji
diff --git a/config/locales/sq.yml b/config/locales/sq.yml
index e5becbd916..b1e2a4f61e 100644
--- a/config/locales/sq.yml
+++ b/config/locales/sq.yml
@@ -838,7 +838,7 @@ sq:
       original_status: Postim origjinal
       reblogs: Riblogime
       status_changed: Postimi ndryshoi
-      title: Gjendje llogarish
+      title: Gjendje llogarish - @%{name}
       trending: Në modë
       visibility: Dukshmëri
       with_media: Me media
diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml
index f56cdb9cb5..76a0f8afe9 100644
--- a/config/locales/sr-Latn.yml
+++ b/config/locales/sr-Latn.yml
@@ -807,7 +807,7 @@ sr-Latn:
       original_status: Originalna objava
       reblogs: Deljenja
       status_changed: Objava promenjena
-      title: Statusi naloga
+      title: Statusi naloga - @%{name}
       trending: U trendu
       visibility: Vidljivost
       with_media: Sa multimedijom
diff --git a/config/locales/sr.yml b/config/locales/sr.yml
index 45feb0b5fc..6a75316c23 100644
--- a/config/locales/sr.yml
+++ b/config/locales/sr.yml
@@ -837,7 +837,7 @@ sr:
       original_status: Оригинална објава
       reblogs: Дељења
       status_changed: Објава промењена
-      title: Статуси налога
+      title: Статуси налога - @%{name}
       trending: У тренду
       visibility: Видљивост
       with_media: Са мултимедијом
diff --git a/config/locales/sv.yml b/config/locales/sv.yml
index c41795a168..11b37f8bfc 100644
--- a/config/locales/sv.yml
+++ b/config/locales/sv.yml
@@ -841,7 +841,7 @@ sv:
       original_status: Ursprungligt inlägg
       reblogs: Ombloggningar
       status_changed: Inlägg ändrat
-      title: Kontoinlägg
+      title: Kontoinlägg - @%{name}
       trending: Trendande
       visibility: Synlighet
       with_media: Med media
diff --git a/config/locales/th.yml b/config/locales/th.yml
index ea039a2b99..32f2b30292 100644
--- a/config/locales/th.yml
+++ b/config/locales/th.yml
@@ -819,7 +819,7 @@ th:
       original_status: โพสต์ดั้งเดิม
       reblogs: การดัน
       status_changed: เปลี่ยนโพสต์แล้ว
-      title: โพสต์ของบัญชี
+      title: โพสต์ของบัญชี - @%{name}
       trending: กำลังนิยม
       visibility: การมองเห็น
       with_media: มีสื่อ
diff --git a/config/locales/tr.yml b/config/locales/tr.yml
index 88636ef21b..2eafed1b47 100644
--- a/config/locales/tr.yml
+++ b/config/locales/tr.yml
@@ -841,7 +841,7 @@ tr:
       original_status: Özgün gönderi
       reblogs: Yeniden Paylaşımlar
       status_changed: Gönderi değişti
-      title: Hesap durumları
+      title: Hesap durumları - @%{name}
       trending: Öne çıkanlar
       visibility: Görünürlük
       with_media: Medya ile
diff --git a/config/locales/uk.yml b/config/locales/uk.yml
index e6a765267f..7ea76b2a75 100644
--- a/config/locales/uk.yml
+++ b/config/locales/uk.yml
@@ -861,7 +861,7 @@ uk:
       original_status: Оригінальний допис
       reblogs: Поширення
       status_changed: Допис змінено
-      title: Дописи облікових записів
+      title: Дописи облікових записів - @%{name}
       trending: Популярне
       visibility: Видимість
       with_media: З медіа
diff --git a/config/locales/vi.yml b/config/locales/vi.yml
index 1d04f796f8..71c4357f2f 100644
--- a/config/locales/vi.yml
+++ b/config/locales/vi.yml
@@ -827,7 +827,7 @@ vi:
       original_status: Tút gốc
       reblogs: Lượt đăng lại
       status_changed: Tút đã sửa
-      title: Tất cả tút
+      title: Tất cả tút - @%{name}
       trending: Xu hướng
       visibility: Hiển thị
       with_media: Có media
diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml
index 36d316649c..cae0efee57 100644
--- a/config/locales/zh-CN.yml
+++ b/config/locales/zh-CN.yml
@@ -827,7 +827,7 @@ zh-CN:
       original_status: 原始嘟文
       reblogs: 转发
       status_changed: 嘟文已编辑
-      title: 帐户嘟文
+      title: 帐户嘟文 - @%{name}
       trending: 当前热门
       visibility: 可见性
       with_media: 含有媒体文件
diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml
index e33ebeadb4..6f0a99a5b3 100644
--- a/config/locales/zh-HK.yml
+++ b/config/locales/zh-HK.yml
@@ -777,7 +777,7 @@ zh-HK:
       original_status: 原始帖文
       reblogs: 轉發
       status_changed: 帖文已變更
-      title: 帳戶文章
+      title: 帳戶文章 - @%{name}
       trending: 熱門
       visibility: 可見性
       with_media: 含有媒體檔案
diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml
index 495a6a4742..ce6bd3e8f5 100644
--- a/config/locales/zh-TW.yml
+++ b/config/locales/zh-TW.yml
@@ -829,7 +829,7 @@ zh-TW:
       original_status: 原始嘟文
       reblogs: 轉嘟
       status_changed: 嘟文已編輯
-      title: 帳號嘟文
+      title: 帳號嘟文 - @%{name}
       trending: 熱門
       visibility: 可見性
       with_media: 含有媒體檔案

From c546aa57cb0b89c5d4ec7f7d7d38656d9e378402 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
 <41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 15 Nov 2024 11:30:11 +0100
Subject: [PATCH 15/44] New Crowdin Translations (automated) (#32900)

Co-authored-by: GitHub Actions <noreply@github.com>
---
 app/javascript/mastodon/locales/bg.json | 27 +++++++++++++++++++++++++
 app/javascript/mastodon/locales/cy.json |  1 +
 app/javascript/mastodon/locales/lt.json |  1 +
 app/javascript/mastodon/locales/lv.json |  4 ++++
 config/locales/bg.yml                   |  9 +++++++++
 config/locales/cy.yml                   |  8 ++++++++
 config/locales/devise.lv.yml            | 10 ++++-----
 config/locales/eo.yml                   | 26 +++++++++++++++++++++++-
 config/locales/hu.yml                   | 16 +++++++--------
 config/locales/lv.yml                   | 25 +++++++++++++++--------
 config/locales/simple_form.cy.yml       |  3 ++-
 config/locales/simple_form.hu.yml       |  4 ++--
 config/locales/simple_form.lv.yml       |  5 +++--
 13 files changed, 112 insertions(+), 27 deletions(-)

diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json
index 3d5d8a8585..44482f6c96 100644
--- a/app/javascript/mastodon/locales/bg.json
+++ b/app/javascript/mastodon/locales/bg.json
@@ -87,6 +87,17 @@
   "alert.unexpected.title": "Опаа!",
   "alt_text_badge.title": "Алтернативен текст",
   "announcement.announcement": "Оповестяване",
+  "annual_report.summary.archetype.lurker": "Дебнещото",
+  "annual_report.summary.archetype.oracle": "Оракул",
+  "annual_report.summary.archetype.pollster": "Анкетьорче",
+  "annual_report.summary.archetype.replier": "Социална пеперуда",
+  "annual_report.summary.followers.followers": "последователи",
+  "annual_report.summary.followers.total": "{count} общо",
+  "annual_report.summary.highlighted_post.by_favourites": "най-правено като любима публикация",
+  "annual_report.summary.most_used_app.most_used_app": "най-употребявано приложение",
+  "annual_report.summary.most_used_hashtag.most_used_hashtag": "най-употребяван хаштаг",
+  "annual_report.summary.new_posts.new_posts": "нови публикации",
+  "annual_report.summary.thanks": "Благодарим, че сте част от Mastodon!",
   "attachments_list.unprocessed": "(необработено)",
   "audio.hide": "Скриване на звука",
   "block_modal.remote_users_caveat": "Ще поискаме сървърът {domain} да почита решението ви. Съгласието обаче не се гарантира откак някои сървъри могат да боравят с блоковете по различен начин. Обществените публикации още може да се виждат от невлезли в системата потребители.",
@@ -158,6 +169,7 @@
   "compose_form.poll.duration": "Времетраене на анкетата",
   "compose_form.poll.multiple": "Множествен избор",
   "compose_form.poll.option_placeholder": "Избор {number}",
+  "compose_form.poll.single": "Единичен избор",
   "compose_form.poll.switch_to_multiple": "Промяна на анкетата, за да се позволят множество възможни избора",
   "compose_form.poll.switch_to_single": "Промяна на анкетата, за да се позволи един възможен избор",
   "compose_form.poll.type": "Стил",
@@ -195,6 +207,8 @@
   "confirmations.unfollow.message": "Наистина ли искате да не следвате {name}?",
   "confirmations.unfollow.title": "Спирате ли да следвате потребителя?",
   "content_warning.hide": "Скриване на публ.",
+  "content_warning.show": "Нека се покаже",
+  "content_warning.show_more": "Показване на още",
   "conversation.delete": "Изтриване на разговора",
   "conversation.mark_as_read": "Маркиране като прочетено",
   "conversation.open": "Преглед на разговора",
@@ -365,6 +379,9 @@
   "home.pending_critical_update.link": "Преглед на обновяванията",
   "home.pending_critical_update.title": "Налично критично обновяване на сигурността!",
   "home.show_announcements": "Показване на оповестяванията",
+  "ignore_notifications_modal.disclaimer": "Mastodon не може да осведоми потребители, че сте пренебрегнали известията им. Пренебрегването на известията няма да спре самите съобщения да не бъдат изпращани.",
+  "ignore_notifications_modal.filter_to_act_users": "Вие все още ще може да приемате, отхвърляте или докладвате потребители",
+  "ignore_notifications_modal.filter_to_avoid_confusion": "Прецеждането помага за избягване на възможно объркване",
   "interaction_modal.description.favourite": "Имайки акаунт в Mastodon, може да сложите тази публикации в любими, за да позволите на автора да узнае, че я цените и да я запазите за по-късно.",
   "interaction_modal.description.follow": "С акаунт в Mastodon може да последвате {name}, за да получавате публикациите от този акаунт в началния си инфоканал.",
   "interaction_modal.description.reblog": "С акаунт в Mastodon може да подсилите тази публикация, за да я споделите с последователите си.",
@@ -380,6 +397,7 @@
   "interaction_modal.title.follow": "Последване на {name}",
   "interaction_modal.title.reblog": "Подсилване на публикацията на {name}",
   "interaction_modal.title.reply": "Отговаряне на публикацията на {name}",
+  "interaction_modal.title.vote": "Гласувайте в анкетата на {name}",
   "intervals.full.days": "{number, plural, one {# ден} other {# дни}}",
   "intervals.full.hours": "{number, plural, one {# час} other {# часа}}",
   "intervals.full.minutes": "{number, plural, one {# минута} other {# минути}}",
@@ -420,6 +438,8 @@
   "lightbox.close": "Затваряне",
   "lightbox.next": "Напред",
   "lightbox.previous": "Назад",
+  "lightbox.zoom_in": "Увеличение до действителната големина",
+  "lightbox.zoom_out": "Увеличение до побиране",
   "limited_account_hint.action": "Показване на профила въпреки това",
   "limited_account_hint.title": "Този профил е бил скрит от модераторите на {domain}.",
   "link_preview.author": "От {name}",
@@ -441,6 +461,7 @@
   "lists.subheading": "Вашите списъци",
   "load_pending": "{count, plural, one {# нов елемент} other {# нови елемента}}",
   "loading_indicator.label": "Зареждане…",
+  "media_gallery.hide": "Скриване",
   "moved_to_account_banner.text": "Вашият акаунт {disabledAccount} сега е изключен, защото се преместихте в {movedToAccount}.",
   "mute_modal.hide_from_notifications": "Скриване от известията",
   "mute_modal.hide_options": "Скриване на възможностите",
@@ -489,6 +510,7 @@
   "notification.favourite": "{name} направи любима публикацията ви",
   "notification.favourite.name_and_others_with_link": "{name} и <a>{count, plural, one {# друг} other {# други}}</a> направиха любима ваша публикация",
   "notification.follow": "{name} ви последва",
+  "notification.follow.name_and_others": "{name} и <a>{count, plural, one {# друг} other {# други}}</a> ви последваха",
   "notification.follow_request": "{name} поиска да ви последва",
   "notification.follow_request.name_and_others": "{name} и {count, plural, one {# друг} other {# други}} поискаха да ви последват",
   "notification.label.mention": "Споменаване",
@@ -496,6 +518,7 @@
   "notification.label.private_reply": "Личен отговор",
   "notification.label.reply": "Отговор",
   "notification.mention": "Споменаване",
+  "notification.mentioned_you": "{name} ви спомена",
   "notification.moderation-warning.learn_more": "Научете повече",
   "notification.moderation_warning": "Получихте предупреждение за модериране",
   "notification.moderation_warning.action_delete_statuses": "Някои от публикациите ви са премахнати.",
@@ -752,6 +775,7 @@
   "status.bookmark": "Отмятане",
   "status.cancel_reblog_private": "Край на подсилването",
   "status.cannot_reblog": "Публикацията не може да се подсилва",
+  "status.continued_thread": "Продължена нишка",
   "status.copy": "Копиране на връзката към публикация",
   "status.delete": "Изтриване",
   "status.detailed_status": "Подробен изглед на разговора",
@@ -760,6 +784,7 @@
   "status.edit": "Редактиране",
   "status.edited": "Последно редактирано на {date}",
   "status.edited_x_times": "Редактирано {count, plural,one {{count} път} other {{count} пъти}}",
+  "status.embed": "Вземане на кода за вграждане",
   "status.favourite": "Любимо",
   "status.favourites": "{count, plural, one {любимо} other {любими}}",
   "status.filter": "Филтриране на публ.",
@@ -784,6 +809,7 @@
   "status.reblogs.empty": "Още никого не е подсилвал публикацията. Подсилващият ще се покаже тук.",
   "status.redraft": "Изтриване и преработване",
   "status.remove_bookmark": "Премахване на отметката",
+  "status.replied_in_thread": "Отговорено в нишката",
   "status.replied_to": "В отговор до {name}",
   "status.reply": "Отговор",
   "status.replyAll": "Отговор на нишка",
@@ -821,6 +847,7 @@
   "upload_error.poll": "Качването на файлове не е позволено с анкети.",
   "upload_form.audio_description": "Опишете за хора, които са глухи или трудно чуват",
   "upload_form.description": "Опишете за хора, които са слепи или имат слабо зрение",
+  "upload_form.drag_and_drop.instructions": "Натиснете интервал или enter, за да подберете мултимедийно прикачване. Провлачвайки, ползвайте клавишите със стрелки, за да премествате мултимедията във всяка дадена посока. Натиснете пак интервал или enter, за да се стовари мултимедийното прикачване в новото си положение или натиснете Esc за отмяна.",
   "upload_form.edit": "Редактиране",
   "upload_form.thumbnail": "Промяна на миниобраза",
   "upload_form.video_description": "Опишете за хора, които са глухи или трудно чуват, слепи или имат слабо зрение",
diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json
index ca83af9215..1fa17e56ea 100644
--- a/app/javascript/mastodon/locales/cy.json
+++ b/app/javascript/mastodon/locales/cy.json
@@ -101,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "{name}",
   "annual_report.summary.most_used_app.most_used_app": "ap a ddefnyddiwyd fwyaf",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "hashnod a ddefnyddiwyd fwyaf",
+  "annual_report.summary.most_used_hashtag.none": "Dim",
   "annual_report.summary.new_posts.new_posts": "postiadau newydd",
   "annual_report.summary.percentile.text": "<topLabel>Rydych chi yn y </topLabel><percentage></percentage><bottomLabel>mwyaf o ddefnyddwyr Mastodon.</bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "Ni fyddwn yn dweud wrth Bernie.",
diff --git a/app/javascript/mastodon/locales/lt.json b/app/javascript/mastodon/locales/lt.json
index d03833e11f..378f642cfe 100644
--- a/app/javascript/mastodon/locales/lt.json
+++ b/app/javascript/mastodon/locales/lt.json
@@ -101,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "{name}",
   "annual_report.summary.most_used_app.most_used_app": "labiausiai naudota programa",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "labiausiai naudotas saitažodis",
+  "annual_report.summary.most_used_hashtag.none": "Nieko",
   "annual_report.summary.new_posts.new_posts": "nauji įrašai",
   "annual_report.summary.percentile.text": "<topLabel>Tai reiškia, kad esate tarp</topLabel><percentage></percentage><bottomLabel>populiariausių „Mastodon“ naudotojų.</bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "Mes nesakysime Bernie.",
diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json
index 30fc0ea348..f6053b2e09 100644
--- a/app/javascript/mastodon/locales/lv.json
+++ b/app/javascript/mastodon/locales/lv.json
@@ -86,6 +86,10 @@
   "alert.unexpected.message": "Radās negaidīta kļūda.",
   "alert.unexpected.title": "Ups!",
   "announcement.announcement": "Paziņojums",
+  "annual_report.summary.followers.followers": "sekotāji",
+  "annual_report.summary.followers.total": "pavisam {count}",
+  "annual_report.summary.here_it_is": "Šeit ir {year}. gada pārskats:",
+  "annual_report.summary.new_posts.new_posts": "jauni ieraksti",
   "attachments_list.unprocessed": "(neapstrādāti)",
   "audio.hide": "Slēpt audio",
   "block_modal.remote_users_caveat": "Mēs vaicāsim serverim {domain} ņemt vērā Tavu lēmumu. Tomēr atbilstība nav nodrošināta, jo atsevišķi serveri var apstrādāt bloķēšanu citādi. Publiski ieraksti joprojām var būt redzami lietotājiem, kuri nav pieteikušies.",
diff --git a/config/locales/bg.yml b/config/locales/bg.yml
index e10ce3197c..2c5edf0b13 100644
--- a/config/locales/bg.yml
+++ b/config/locales/bg.yml
@@ -21,9 +21,12 @@ bg:
       one: Публикация
       other: Публикации
     posts_tab_heading: Публикации
+    self_follow_error: Не е позволено да следвате собствения си акаунт
   admin:
     account_actions:
       action: Изпълняване на действие
+      already_silenced: Този акаунт вече е ограничен.
+      already_suspended: Този акаунт вече е спрян.
       title: Извършване на модериращо действие за %{acct}
     account_moderation_notes:
       create: Оставяне на бележка
@@ -45,6 +48,7 @@ bg:
         title: Промяна на имейл за %{username}
       change_role:
         changed_msg: Успешно променена роля!
+        edit_roles: Управление на потребителските роли
         label: Промяна на ролята
         no_role: Без роля
         title: Промяна на ролята за %{username}
@@ -875,6 +879,7 @@ bg:
       name: Име
       newest: Най-нови
       oldest: Най-стари
+      open: Преглед публично
       reset: Нулиране
       review: Преглед на състояние
       search: Търсене
@@ -888,6 +893,7 @@ bg:
       links:
         allow: Позволяване на връзка
         allow_provider: Позволяване на публикуващия
+        confirm_allow: Наистина ли искате да позволите избраните връзки?
         confirm_allow_provider: Наистина ли искате да позволите избраните доставчици?
         description_html: Това са връзки, които в момента са много пъти споделяни от акаунти, чиито публикации сървърът ви вижда. Може да помогне на потребителите ви да разберат какво се случва по света. Никоя връзка няма да се показва публично, докато не одобрите публикуващия. Може още и да одобрявате или отхвърляте отделни връзки.
         disallow: Забранявам връзката
@@ -912,6 +918,8 @@ bg:
       statuses:
         allow: Позволяване на публикацията
         allow_account: Позволяване на автора
+        confirm_allow: Наистина ли искате да позволите избраните статуси?
+        confirm_allow_account: Наистина ли искате да позволите избраните акаунти?
         description_html: Това са публикации, за които сървърът ви знае, че са често споделяни или харесвани в момента. Това може да помогне на вашите нови и завръщащи се потребители да открият повече хора за следване. Никоя от публикациите няма да бъде показана публично, докато не одобрите автора и докато авторът не позволи акаунтът му да бъде предлган на другите. Също така можете да позволявате или отхвърляте отделни публикации.
         disallow: Забраняване на публикацията
         disallow_account: Забрана на автора
@@ -1028,6 +1036,7 @@ bg:
       guide_link_text: Всеки може да участва.
     sensitive_content: Деликатно съдържание
   application_mailer:
+    notification_preferences: Промяна на предпочитанията за е-поща
     salutation: "%{name},"
     unsubscribe: Стоп на абонамента
     view: 'Преглед:'
diff --git a/config/locales/cy.yml b/config/locales/cy.yml
index ca18de17bc..f479f0f0a0 100644
--- a/config/locales/cy.yml
+++ b/config/locales/cy.yml
@@ -199,6 +199,7 @@ cy:
         create_domain_block: Creu Gwaharddiad Parth
         create_email_domain_block: Creu Rhwystr Parth E-bost
         create_ip_block: Creu rheol IP
+        create_relay: Creu Cyfnewidiad
         create_unavailable_domain: Creu Parth Ddim ar Gael
         create_user_role: Creu Rôl
         demote_user: Diraddio Defnyddiwr
@@ -210,14 +211,17 @@ cy:
         destroy_email_domain_block: Dileu Rhwystr Parth E-bost
         destroy_instance: Clirio Parth
         destroy_ip_block: Dileu rheol IP
+        destroy_relay: Dileu Cyfnewidiad
         destroy_status: Dileu Postiad
         destroy_unavailable_domain: Dileu Parth Ddim ar Gael
         destroy_user_role: Dileu Rôl
         disable_2fa_user: Diffodd 2FA
         disable_custom_emoji: Analluogi Emoji Addasedig
+        disable_relay: Analluogi Cyfnewidiad
         disable_sign_in_token_auth_user: Analluogi Dilysu Tocyn E-bost Defnyddiwr
         disable_user: Analluogi Defnyddiwr
         enable_custom_emoji: Galluogi Emoji Addasedig
+        enable_relay: Galluogi Cyfnewidiad
         enable_sign_in_token_auth_user: Galluogi Dilysu Tocyn E-bost Defnyddiwr
         enable_user: Galluogi Defnyddiwr
         memorialize_account: Cofadeilio Cyfrif
@@ -259,6 +263,7 @@ cy:
         create_domain_block_html: Mae %{name} wedi rhwystro parth %{target}
         create_email_domain_block_html: Mae %{name} wedi rhwystro parth e-bost %{target}
         create_ip_block_html: Mae %{name} wedi creu rheol ar gyfer IP %{target}
+        create_relay_html: Creodd %{name} gyfnewidiad %{target}
         create_unavailable_domain_html: Mae %{name} wedi stopio danfon i barth %{target}
         create_user_role_html: Mae %{name} wedi creu rôl %{target}
         demote_user_html: Mae %{name} wedi israddio defnyddiwr %{target}
@@ -270,14 +275,17 @@ cy:
         destroy_email_domain_block_html: Mae %{name} wedi dad-rwystro parth e-bost %{target}
         destroy_instance_html: Mae %{name} wedi dileu parth %{target}
         destroy_ip_block_html: Mae %{name} dileu rheol ar gyfer IP %{target}
+        destroy_relay_html: Dileodd %{name} y cyfnewidiad %{target}
         destroy_status_html: Mae %{name} wedi tynnu postiad gan %{target}
         destroy_unavailable_domain_html: Mae %{name} wedi ailddechrau anfon i barth %{target}
         destroy_user_role_html: Mae %{name} wedi dileu rôl %{target}
         disable_2fa_user_html: Mae %{name} wedi analluogi gofyniad dau ffactor ar gyfer defnyddiwr %{target}
         disable_custom_emoji_html: Mae %{name} wedi analluogi emoji %{target}
+        disable_relay_html: Analluogodd %{name} y cyfnewidiad %{target}
         disable_sign_in_token_auth_user_html: Mae %{name} wedi analluogi dilysiad tocyn e-bost %{target}
         disable_user_html: Mae %{name} wedi analluogi mewngofnodi defnyddiwr %{target}
         enable_custom_emoji_html: Mae %{name} wedi analluogi emoji %{target}
+        enable_relay_html: Galluogodd %{name} y cyfnewidiad %{target}
         enable_sign_in_token_auth_user_html: Mae %{name} wedi galluogi dilysiad tocyn e-bost %{target}
         enable_user_html: Mae %{name} wedi galluogi mewngofnodi defnyddiwr %{target}
         memorialize_account_html: Newidiodd %{name} gyfrif %{target} i dudalen memoriam
diff --git a/config/locales/devise.lv.yml b/config/locales/devise.lv.yml
index 4470c8109e..5aaa23a731 100644
--- a/config/locales/devise.lv.yml
+++ b/config/locales/devise.lv.yml
@@ -14,7 +14,7 @@ lv:
       not_found_in_database: Nederīga %{authentication_keys} vai parole.
       omniauth_user_creation_failure: Kļūda šīs identitātes konta izveidošanā.
       pending: Tavs konts joprojām tiek pārskatīts.
-      timeout: Sesijair beigusies. Lūgums vēlreiz pieteikties, lai turpinātu.
+      timeout: Sesija ir beigusies. Lūgums vēlreiz pieteikties, lai turpinātu.
       unauthenticated: Lai turpinātu, jāpiesakās vai jāreģistrējas.
       unconfirmed: Lai turpinātu, jāapliecina sava e-pasta adrese.
     mailer:
@@ -90,13 +90,13 @@ lv:
       no_token: Tu nevari piekļūt šai lapai, ja neesi saņēmis paroles atiestatīšanas e-pasta ziņojumu. Ja ienāci no paroles atiestatīšanas e-pasta, lūdzu, pārliecinies, vai izmanto visu norādīto URL.
       send_instructions: Ja tava e-pasta adrese ir mūsu datu bāzē, pēc dažām minūtēm uz savu e-pasta adresi saņemsi paroles atkopšanas saiti. Lūdzu, pārbaudi spama mapi, ja neesi saņēmis šo e-pastu.
       send_paranoid_instructions: Ja tava e-pasta adrese ir mūsu datu bāzē, pēc dažām minūtēm uz savu e-pasta adresi saņemsi paroles atkopšanas saiti. Lūdzu, pārbaudi spama mapi, ja neesi saņēmis šo e-pastu.
-      updated: Tava parole tika veiksmīgi nomainīta. Tu tagad esi pieteicies.
+      updated: Tava parole tika veiksmīgi nomainīta. Tagad esi pieteicies.
       updated_not_active: Tava parole ir veiksmīgi nomainīta.
     registrations:
       destroyed: Visu labu! Tavs konts ir veiksmīgi atcelts. Mēs ceram tevi drīz atkal redzēt.
       signed_up: Laipni lūdzam! Tu esi veiksmīgi reģistrējies.
-      signed_up_but_inactive: Tava reģistrācija bija veiksmīga. Tomēr mēs nevarējām tevi pierakstīt, jo tavs konts vēl nav aktivizēts.
-      signed_up_but_locked: Tava reģistrācija bija veiksmīga. Tomēr mēs nevarējām tevi pierakstīt, jo tavs konts ir bloķēts.
+      signed_up_but_inactive: Tava reģistrācija bija veiksmīga. Tomēr mēs nevarējām Tevi pieteikt, jo Tavs konts vēl nav aktivizēts.
+      signed_up_but_locked: Tava reģistrācija bija veiksmīga. Tomēr mēs nevarējām Tevi pieteikt, jo Tavs konts ir slēgts.
       signed_up_but_pending: Uz tavu e-pasta adresi ir nosūtīts ziņojums ar apstiprinājuma saiti. Pēc noklikšķināšanas uz saites mēs izskatīsim tavu pieteikumu. Tu tiksi informēts, ja tas tiks apstiprināts.
       signed_up_but_unconfirmed: Uz tavu e-pasta adresi ir nosūtīts ziņojums ar apstiprinājuma saiti. Lūdzu, seko saitei, lai aktivizētu savu kontu. Lūdzu, pārbaudi spama mapi, ja neesi saņēmis šo e-pastu.
       update_needs_confirmation: Tu veiksmīgi atjaunināji savu kontu, taču mums ir jāverificē teva jaunā e-pasta adrese. Lūdzu, pārbaudi savu e-pastu un seko apstiprinājuma saitei, lai apstiprinātu savu jauno e-pasta adresi. Lūdzu, pārbaudi spama mapi, ja neesi saņēmis šo e-pastu.
@@ -111,7 +111,7 @@ lv:
       unlocked: Konts tika veiksmīgi atbloķēts. Lūgums pieteikties, lai turpinātu.
   errors:
     messages:
-      already_confirmed: jau tika apstiprināts, lūdzu, mēģini pierakstīties
+      already_confirmed: jau tika apstiprināts, lūgums mēģināt pieteikties
       confirmation_period_expired: jāapstiprina %{period} laikā, lūdzu, pieprasi jaunu
       expired: ir beidzies derīguma termiņš, lūdzu, pieprasi jaunu
       not_found: nav atrasts
diff --git a/config/locales/eo.yml b/config/locales/eo.yml
index b5287d9e2a..194b2c17b8 100644
--- a/config/locales/eo.yml
+++ b/config/locales/eo.yml
@@ -73,7 +73,7 @@ eo:
       enable_sign_in_token_auth: Ebligu retpoŝtan ĵeton-aŭtentikigon
       enabled: Ebligita
       enabled_msg: Sukcese malfrostigis konton de %{username}
-      followers: Sekvantoj
+      followers: Sekvoj
       follows: Sekvatoj
       header: Kapa bildo
       inbox_url: Enira URL
@@ -187,6 +187,7 @@ eo:
         create_domain_block: Krei Blokadon De Domajno
         create_email_domain_block: Krei retpoŝtan domajnan blokon
         create_ip_block: Krei IP-regulon
+        create_relay: Krei Relajson
         create_unavailable_domain: Krei Nehaveblan Domajnon
         create_user_role: Krei Rolon
         demote_user: Malpromocii Uzanton
@@ -198,13 +199,18 @@ eo:
         destroy_email_domain_block: Forigi retpoŝtan domajnan blokon
         destroy_instance: Forigi Domajnon
         destroy_ip_block: Forigi IP-regulon
+        destroy_relay: Forigi Relajson
         destroy_status: Forigi Afiŝon
         destroy_unavailable_domain: Forigi Nehaveblan Domajnon
         destroy_user_role: Detrui Rolon
         disable_2fa_user: Malebligi 2FA
         disable_custom_emoji: Malebligi proprajn emoĝiojn
+        disable_relay: Malebligi Relajson
+        disable_sign_in_token_auth_user: Malebligi aŭtentigon per retpoŝta ĵetono por la uzanto
         disable_user: Neebligi la uzanton
         enable_custom_emoji: Ebligi Propran Emoĝion
+        enable_relay: Ebligi Relajson
+        enable_sign_in_token_auth_user: Ebligi aŭtentigon per retpoŝta ĵetono por la uzanto
         enable_user: Ebligi uzanton
         memorialize_account: Memorigu Konton
         promote_user: Promocii Uzanton
@@ -245,6 +251,7 @@ eo:
         create_domain_block_html: "%{name} blokis domajnon %{target}"
         create_email_domain_block_html: "%{name} blokis retpoŝtan domajnon %{target}"
         create_ip_block_html: "%{name} kreis regulon por IP %{target}"
+        create_relay_html: "%{name} kreis relajson %{target}"
         create_unavailable_domain_html: "%{name} ĉesis sendon al domajno %{target}"
         create_user_role_html: "%{name} kreis rolon de %{target}"
         demote_user_html: "%{name} degradis uzanton %{target}"
@@ -256,13 +263,18 @@ eo:
         destroy_email_domain_block_html: "%{name} malblokis retpoŝtan domajnon %{target}"
         destroy_instance_html: "%{name} forigis domajnon %{target}"
         destroy_ip_block_html: "%{name} forigis regulon por IP %{target}"
+        destroy_relay_html: "%{name} forigis la relajson %{target}"
         destroy_status_html: "%{name} forigis mesaĝojn de %{target}"
         destroy_unavailable_domain_html: "%{name} restartigis sendon al domajno %{target}"
         destroy_user_role_html: "%{name} forigis rolon de %{target}"
         disable_2fa_user_html: "%{name} malebligis dufaktoran aŭtentigon por uzanto %{target}"
         disable_custom_emoji_html: "%{name} malebligis la emoĝion %{target}"
+        disable_relay_html: "%{name} malebligis la relajson %{target}"
+        disable_sign_in_token_auth_user_html: "%{name} malebligis la aŭtentigon de retpoŝta ĵetono por %{target}"
         disable_user_html: "%{name} malebligis ensaluton por uzanto %{target}"
         enable_custom_emoji_html: "%{name} ebligis la emoĝion %{target}"
+        enable_relay_html: "%{name} ebligis la relajson %{target}"
+        enable_sign_in_token_auth_user_html: "%{name} ebligis la aŭtentigon de retpoŝta ĵetono por %{target}"
         enable_user_html: "%{name} ebligis ensaluton por uzanto %{target}"
         memorialize_account_html: "%{name} ŝanĝis la konton de %{target} al memora paĝo"
         promote_user_html: "%{name} plirangigis uzanton %{target}"
@@ -270,6 +282,7 @@ eo:
         reject_user_html: "%{name} malakceptis registriĝon de %{target}"
         remove_avatar_user_html: "%{name} forigis la profilbildon de %{target}"
         reopen_report_html: "%{name} remalfermis signalon %{target}"
+        resend_user_html: "%{name} resendis konfirman retmesaĝon por %{target}"
         reset_password_user_html: "%{name} restarigis la pasvorton de la uzanto %{target}"
         resolve_report_html: "%{name} solvis raporton %{target}"
         sensitive_account_html: "%{name} markis audovidaĵon de %{target} kiel tiklan"
@@ -440,6 +453,7 @@ eo:
         create: Aldoni domajnon
         resolve: Solvi domajnon
         title: Bloki novan retpoŝtan domajnon
+      no_email_domain_block_selected: Neniuj domajn blokoj ŝanĝiĝis ĉar nenio estis elektita
       not_permitted: Ne permesita
       resolved_through_html: Solvis tra %{domain}
       title: Blokis retpoŝtajn domajnojn
@@ -467,6 +481,8 @@ eo:
       title: Rekomendoj de sekvado
       unsuppress: Regajni sekvorekomendon
     instances:
+      audit_log:
+        title: Novaj Protokoloj Pri Ekzamenoj
       availability:
         description_html:
           one: Se sendo la domajno malsukcesis por <strong>%{count} dio</strong>, ne estas sendprovo plu escepte <em>de</em> la dojmano.
@@ -1054,6 +1070,7 @@ eo:
       awaiting_review_title: Via registriĝo estas reviziita
       clicking_this_link: alklakante ĉi tiun ligilon
       login_link: ensaluti
+      proceed_to_login_html: Vi nun povas iri al %{login_link}.
       registration_complete: Via registriĝo sur %{domain} nun finiĝis!
       welcome_title: Bonvenon, %{name}!
       wrong_email_hint: Se tiu retadreso ne estas ĝusta, vi povas ŝanĝi ĝin en kontagordoj.
@@ -1329,6 +1346,7 @@ eo:
       unconfirmed: Nekonfirmita
     status: Stato
     success: Viaj datumoj estis sukcese alŝutitaj kaj estos traktitaj kiel planite
+    time_started: Komencis je
     titles:
       following: Importado de sekvaj kontoj
       lists: Importi listojn
@@ -1375,6 +1393,7 @@ eo:
     authentication_methods:
       otp: 2-faktora autentigprogramaro
       password: pasvorto
+      sign_in_token: retpoŝta sekureca kodo
       webauthn: sekurecaj ŝlosiloj
     description_html: Se vi vidas nerekonitan agon, eble ŝanĝu vian pasvorton.
     empty: Neniu autentighistorio disponebla
@@ -1385,6 +1404,9 @@ eo:
     unsubscribe:
       action: Jes, malabonu
       complete: Malabonita
+      emails:
+        notification_emails:
+          follow_request: retpoŝtajn petoj de sekvado
       title: Malaboni
   media_attachments:
     validations:
@@ -1725,6 +1747,7 @@ eo:
       default: "%Y.%b.%d, %H:%M"
       month: "%b %Y"
       time: "%H:%M"
+      with_time_zone: "%b %d, %Y, %H:%M %Z"
   translation:
     errors:
       quota_exceeded: La tutservila uzkvoto por la tradukservo estas superita.
@@ -1805,6 +1828,7 @@ eo:
       apps_ios_action: Elŝutu ĉe la App Store
       apps_step: Elŝutu niajn oficialajn aplikaĵojn.
       apps_title: Aplikaĵoj de Mastodon
+      checklist_title: Bonvenan Markolisto
       edit_profile_action: Agordi
       edit_profile_title: Agordi vian profilon
       explanation: Jen kelkaj konsiloj por helpi vin komenci
diff --git a/config/locales/hu.yml b/config/locales/hu.yml
index da4ff78dc4..56d41daf86 100644
--- a/config/locales/hu.yml
+++ b/config/locales/hu.yml
@@ -579,21 +579,21 @@ hu:
     relationships:
       title: "%{acct} kapcsolatai"
     relays:
-      add_new: Új relé hozzáadása
+      add_new: Új továbbító hozzáadása
       delete: Törlés
-      description_html: A <strong>föderációs relé</strong> egy olyan köztes szerver, mely nagy mennyiségű nyilvános bejegyzést cserél az erre feliratkozó vagy erre publikáló szerverek között. <strong>Ezzel segíthetsz kis és közepes szervereknek tartalmat megtalálni a föderációban</strong>, mely egyébként csak akkor válna lehetővé, ha a saját felhasználóik más szervereken lévő fiókokat követnének.
+      description_html: A <strong>föderációs továbbító</strong> egy olyan köztes kiszolgáló, mely nagy mennyiségű nyilvános bejegyzést cserél az erre feliratkozó vagy erre publikáló kiszolgálók között. <strong>Ezzel segíthetsz kis és közepes kiszolgálóknak megtalálni a tartalmakat a föderációban</strong>, melyek egyébként csak akkor válnának lehetővé, ha a saját felhasználóik más kiszolgálókon lévő fiókokat követnének.
       disable: Kikapcsolás
       disabled: Kikapcsolva
       enable: Bekapcsolás
-      enable_hint: Ha bekapcsolod, a szerver minden nyilvános bejegyzésre feliratkozik ezen a relén, valamint az összes nyilvános bejegyzést elküldi ennek.
+      enable_hint: Ha bekapcsolod, a kiszolgáló minden nyilvános bejegyzésre feliratkozik ezen a továbbítón, valamint az összes nyilvános bejegyzést elküldi ennek.
       enabled: Bekapcsolva
-      inbox_url: Relé URL
-      pending: Várakozás a relé jóváhagyására
+      inbox_url: Továbbító URL
+      pending: Várakozás a továbbító jóváhagyására
       save_and_enable: Mentés és engedélyezés
-      setup: Relé kapcsolat felállítása
-      signatures_not_enabled: A relék nem fognak megfelelően működni, amíg a biztonságos mód vagy a korlátozott föderációs mód engedélyezett
+      setup: Továbbító kapcsolat felállítása
+      signatures_not_enabled: A továbbítók nem fognak megfelelően működni, amíg a biztonságos mód vagy a korlátozott föderációs mód engedélyezett
       status: Állapot
-      title: Relék
+      title: Továbbítók
     report_notes:
       created_msg: Bejelentési feljegyzés létrehozva!
       destroyed_msg: Bejelentési feljegyzés törölve!
diff --git a/config/locales/lv.yml b/config/locales/lv.yml
index d793c8e196..33b357b837 100644
--- a/config/locales/lv.yml
+++ b/config/locales/lv.yml
@@ -293,7 +293,7 @@ lv:
       empty: Žurnāli nav atrasti.
       filter_by_action: Filtrēt pēc darbības
       filter_by_user: Filtrēt pēc lietotāja
-      title: Auditācijas pieraksti
+      title: Audita žurnāls
       unavailable_instance: "(domēna vārds nav pieejams)"
     announcements:
       destroyed_msg: Paziņojums ir veiksmīgi izdzēsts!
@@ -596,7 +596,7 @@ lv:
           one: "%{count} piezīme"
           other: "%{count} piezīmes"
           zero: "%{count} piezīmju"
-      action_log: Auditācijas pieraksti
+      action_log: Audita žurnāls
       action_taken_by: Veiktā darbība
       actions:
         delete_description_html: Raksti, par kurām ziņots, tiks dzēsti, un tiks reģistrēts brīdinājums, lai palīdzētu tev izvērst turpmākos pārkāpumus saistībā ar to pašu kontu.
@@ -875,6 +875,7 @@ lv:
         message_html: Rindā(s) %{value} nedarbojas neviens Sidekiq process. Lūdzu, pārskati savu Sidekiq konfigurāciju
       software_version_check:
         action: Skatīt pieejamos atjauninājumus
+        message_html: Pieejams Mastodon atjauninājums.
       software_version_critical_check:
         action: Skatīt pieejamos atjauninājumus
         message_html: Ir pieejams kritisks Mastodon atjauninājums. Lūdzu, atjaunini to pēc iespējas ātrāk.
@@ -1132,7 +1133,7 @@ lv:
       title: Pārbaudi savu iesūtni
     sign_in:
       preamble_html: Jāpiesakās ar saviem <strong>%{domain}</strong> piekļuves datiem. Ja konts tiek mitināts citā serverī, šeit nevarēs pieteikties.
-      title: Pierakstīties %{domain}
+      title: Pieteikties %{domain}
     sign_up:
       manual_review: Reģistrācijas domēnā %{domain} manuāli pārbauda mūsu moderatori. Lai palīdzētu mums apstrādāt tavu reģistrāciju, uzraksti mazliet par sevi un to, kāpēc vēlies kontu %{domain}.
       preamble: Ar kontu šajā Mastodon serverī varēsi sekot jebkuram citam tīklā esošam cilvēkam neatkarīgi no tā, kur tiek mitināts viņa konts.
@@ -1418,13 +1419,20 @@ lv:
       webauthn: drošības atslēgas
     description_html: Ja pamani darbības, kuras neatpazīsti, jāapsver iespēja nomainīt savu paroli un iespējot divpakāpju autentifikāciju.
     empty: Nav pieejama autentifikācijas vēsture
-    failed_sign_in_html: Neizdevies pierakstīšanās mēģinājums ar %{method} no %{ip} (%{browser})
-    successful_sign_in_html: Veiksmīga pierakstīšanās ar %{method} no %{ip} (%{browser})
+    failed_sign_in_html: Neizdevies pieteikšanās mēģinājums ar %{method} no %{ip} (%{browser})
+    successful_sign_in_html: Veiksmīga pieteikšanās ar %{method} no %{ip} (%{browser})
     title: Autentifikācijas vēsture
   mail_subscriptions:
     unsubscribe:
       action: Jā, atcelt abonēšanu
       complete: Anulēts
+      emails:
+        notification_emails:
+          favourite: izlases paziņojumu e-pasta ziņojumi
+          follow: sekošanas paziņojumu e-pasta ziņojumi
+          follow_request: sekošanas pieprasījumu e-pasta ziņojumi
+          mention: pieminēšanas paziņojumu e-pasta ziņojumi
+          reblog: pastiprinājumu paziņojumu e-pasta ziņojumi
       title: Atcelt abonēšanu
   media_attachments:
     validations:
@@ -1656,6 +1664,7 @@ lv:
     delete: Konta dzēšana
     development: Izstrāde
     edit_profile: Labot profilu
+    export: Izgūt
     featured_tags: Piedāvātie tēmturi
     import: Imports
     import_and_export: Imports un eksports
@@ -1802,11 +1811,11 @@ lv:
       title: Arhīva līdzņemšana
     suspicious_sign_in:
       change_password: mainīt paroli
-      details: 'Šeit ir detalizēta informācija par pierakstīšanos:'
-      explanation: Esam konstatējuši pierakstīšanos tavā kontā no jaunas IP adreses.
+      details: 'Šeit ir pieteikšanās izvērsums:'
+      explanation: Esam noteikuši pieteikšanos Tavā kontā no jaunas IP adreses.
       further_actions_html: Ja tas nebiji tu, iesakām nekavējoties %{action} un iespējot divu faktoru autentifikāciju, lai tavs konts būtu drošībā.
       subject: Tavam kontam ir piekļūts no jaunas IP adreses
-      title: Jauna pierakstīšanās
+      title: Jauna pieteikšanās
     warning:
       appeal: Iesniegt apelāciju
       appeal_description: Ja uzskatāt, ka tā ir kļūda, varat iesniegt apelāciju %{instance} darbiniekiem.
diff --git a/config/locales/simple_form.cy.yml b/config/locales/simple_form.cy.yml
index 5f3ac2818c..6c21683b07 100644
--- a/config/locales/simple_form.cy.yml
+++ b/config/locales/simple_form.cy.yml
@@ -3,13 +3,14 @@ cy:
   simple_form:
     hints:
       account:
-        attribution_domains_as_text: Un i bob llinell. Yn amddiffyn rhag cydnabyddiaethau ffug.
+        attribution_domains_as_text: Un i bob llinell. Yn amddiffyn rhag priodoli ffug.
         discoverable: Mae'n bosibl y bydd eich postiadau cyhoeddus a'ch proffil yn cael sylw neu'n cael eu hargymell mewn gwahanol feysydd o Mastodon ac efallai y bydd eich proffil yn cael ei awgrymu i ddefnyddwyr eraill.
         display_name: Eich enw llawn neu'ch enw hwyl.
         fields: Eich tudalen cartref, rhagenwau, oed, neu unrhyw beth.
         indexable: Mae'n bosib y bydd eich postiadau cyhoeddus yn ymddangos yng nghanlyniadau chwilio ar Mastodon. Mae'n bosibl y bydd pobl sydd wedi rhyngweithio â'ch postiadau yn dal i allu eu chwilio.
         note: 'Gallwch @grybwyll pobl eraill neu #hashnodau.'
         show_collections: Bydd pobl yn gallu pori trwy'r rhai rydych yn eu dilyn a'ch dilynwyr. Bydd y bobl rydych chi'n eu dilyn yn gweld eich bod chi'n eu dilyn beth bynnag.
+        unlocked: Bydd pobl yn gallu eich dilyn heb ofyn am gymeradwyaeth. Dad-diciwch os ydych am adolygu ceisiadau i'ch dilyn a dewis a ydych am dderbyn neu wrthod dilynwyr newydd.
       account_alias:
         acct: Rhowch enwdefnyddiwr@parth y cyfrif y hoffech chi symud ohono
       account_migration:
diff --git a/config/locales/simple_form.hu.yml b/config/locales/simple_form.hu.yml
index 230965fe87..60922b06b5 100644
--- a/config/locales/simple_form.hu.yml
+++ b/config/locales/simple_form.hu.yml
@@ -48,7 +48,7 @@ hu:
         digest: Csak hosszú távollét esetén küldődik és csak ha személyes üzenetet kaptál távollétedben
         email: Kapsz egy megerősítő e-mailt
         header: WEBP, PNG, GIF vagy JPG. Legfeljebb %{size}. Át lesz méretezve %{dimensions} képpontosra.
-        inbox_url: Másold ki a használandó relé szerver kezdőoldalának URL-jét
+        inbox_url: Másold ki a használandó továbbító kiszolgáló kezdőoldalának URL-jét
         irreversible: A kiszűrt bejegyzések visszafordíthatatlanul eltűnnek, a szűrő későbbi törlése esetén is
         locale: A felhasználói felület, e-mailek, push üzenetek nyelve
         password: Legalább 8 karakter
@@ -195,7 +195,7 @@ hu:
         fields: Profil metaadatai
         header: Fejléc
         honeypot: "%{label} (ne töltsd ki)"
-        inbox_url: Relé inbox-hoz tartozó URL
+        inbox_url: Továbbító inbox-hoz tartozó URL
         irreversible: Eldobás elrejtés helyett
         locale: Felhasználói felület nyelve
         max_uses: Hányszor használható
diff --git a/config/locales/simple_form.lv.yml b/config/locales/simple_form.lv.yml
index da8dac3c22..2f4a05dca4 100644
--- a/config/locales/simple_form.lv.yml
+++ b/config/locales/simple_form.lv.yml
@@ -10,6 +10,7 @@ lv:
         indexable: Tavi publiskie ieraksti var tikt parādīti Mastodon meklēšanas iznākumā. Cilvēki, kuri ir mijiedarbojušies ar Taviem ierakstiem, var tos meklēt neatkarīgi no tā.
         note: 'Tu vari @minēt citus cilvēkus vai #mirkļbirkas.'
         show_collections: Cilvēki varēs pārlūkot Tavus sekotājus un sekojamos. Cilvēki, kuriem Tu seko, redzēs, ka Tu seko viņiem neatkarīgi no tā.
+        unlocked: Cilvēki varēs Tev sekot bez apstiprinājuma pieprasīšanas. Jānoņem atzīme, ja vēlies pārskatīt sekošanas pieprasījumus un izvēlēties, vai apstiprināt vai noraidīt jaunus sekotājus.
       account_alias:
         acct: Norādi konta lietotājvārdu@domēnu, no kura vēlies pārvākties
       account_migration:
@@ -88,7 +89,7 @@ lv:
         media_cache_retention_period: Informācijas nesēju datnes no ierakstiem, kurus ir veikuši attālie lietotāji, tiek kešoti šajā serverī. Kad ir iestatīta apstiprinoša vērtība, informācijas nesēji tiks izdzēsti pēc norādītā dienu skaita. Ja informācijas nesēju dati tiks pieprasīti pēc tam, kad tie tika izdzēsti, tie tiks atkārtoti lejupielādēti, ja avota saturs joprojām būs pieejams. Saišu priekšskatījuma karšu vaicājumu biežuma ierobežojumu dēļ ir ieteicams iestatīt šo vērtību vismaz 14 dienas vai saišu priekšskatījuma kartes netiks atjauninātas pēc pieprasījuma pirms tā laika.
         peers_api_enabled: Domēna vārdu saraksts, ar kuriem šis serveris ir saskāries fediversā. Šeit nav iekļauti dati par to, vai tu veic federāciju ar noteiktu serveri, tikai tavs serveris par to zina. To izmanto dienesti, kas apkopo statistiku par federāciju vispārīgā nozīmē.
         profile_directory: Profilu direktorijā ir uzskaitīti visi lietotāji, kuri ir izvēlējušies būt atklājami.
-        require_invite_text: 'Ja pierakstīšanai nepieciešama manuāla apstiprināšana, izdari tā, lai teksta: “Kāpēc vēlaties pievienoties?” ievade ir obligāta, nevis opcionāla'
+        require_invite_text: Ja nepieciešama pašrocīga apstiprināšana, lai pierakstītos, teksta “Kāpēc vēlies pievienoties?” ievade jāpadara par nepieciešamu, nevis izvēles
         site_contact_email: Kā cilvēki var sazināties ar tevi par juridiskiem vai atbalsta jautājumiem.
         site_contact_username: Tagad cilvēki var tevi sasniegt Mastodon.
         site_extended_description: Jebkura papildu informācija, kas var būt noderīga apmeklētājiem un lietotājiem. Var strukturēt ar Markdown sintaksi.
@@ -338,5 +339,5 @@ lv:
       text: nepieciešams
     title:
       sessions:
-        webauthn: Lai pierakstītos, izmanto vienu no savām drošības atslēgām
+        webauthn: Lai pieteiktos, jāizmanto viena no savām drošības atslēgām
     'yes': Jā

From 0838cf1e0576cbcb8df1f9a1a57d42abb51f866c Mon Sep 17 00:00:00 2001
From: Claire <claire.github-309c@sitedethib.com>
Date: Fri, 15 Nov 2024 14:37:45 +0100
Subject: [PATCH 16/44] Fix domain attribution field having autocorrect and
 autocapitalize enabled (#32903)

---
 app/views/settings/verifications/show.html.haml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/views/settings/verifications/show.html.haml b/app/views/settings/verifications/show.html.haml
index 4def10e595..a93ffcebed 100644
--- a/app/views/settings/verifications/show.html.haml
+++ b/app/views/settings/verifications/show.html.haml
@@ -65,7 +65,7 @@
   %p.lead= t('author_attribution.then_instructions')
 
   .fields-group
-    = f.input :attribution_domains_as_text, as: :text, wrapper: :with_block_label, input_html: { placeholder: "example1.com\nexample2.com\nexample3.com", rows: 4 }
+    = f.input :attribution_domains_as_text, as: :text, wrapper: :with_block_label, input_html: { placeholder: "example1.com\nexample2.com\nexample3.com", rows: 4, autocapitalize: 'none', autocorrect: 'off' }
 
   .actions
     = f.button :button, t('generic.save_changes'), type: :submit

From f1ef7b5b433b392956469874392acb146bfc6c57 Mon Sep 17 00:00:00 2001
From: Claire <claire.github-309c@sitedethib.com>
Date: Fri, 15 Nov 2024 16:35:30 +0100
Subject: [PATCH 17/44] Fix uploading higher-than-wide GIF profile picture with
 libvips enabled (#32911)

---
 lib/paperclip/vips_lazy_thumbnail.rb            |   1 +
 spec/fixtures/files/avatar-high.gif             | Bin 0 -> 75006 bytes
 .../examples/models/concerns/account_avatar.rb  |   9 ++++++++-
 3 files changed, 9 insertions(+), 1 deletion(-)
 create mode 100644 spec/fixtures/files/avatar-high.gif

diff --git a/lib/paperclip/vips_lazy_thumbnail.rb b/lib/paperclip/vips_lazy_thumbnail.rb
index 4764b04af8..fea4b86064 100644
--- a/lib/paperclip/vips_lazy_thumbnail.rb
+++ b/lib/paperclip/vips_lazy_thumbnail.rb
@@ -52,6 +52,7 @@ module Paperclip
         # implement. If cropping ever becomes necessary for other situations, this will
         # need to be expanded.
         crop_width = crop_height = [target_width, target_height].min if @target_geometry&.square?
+        crop_width = crop_height = "'min(iw,ih)'" if crop_width == 'ih'
 
         filter = begin
           if @crop
diff --git a/spec/fixtures/files/avatar-high.gif b/spec/fixtures/files/avatar-high.gif
new file mode 100644
index 0000000000000000000000000000000000000000..7639f2c507ee72beb745a2ab0677590eb9eb7459
GIT binary patch
literal 75006
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
R<)|tCn~-dxRhj_-06QCBN&^4@

literal 0
HcmV?d00001

diff --git a/spec/support/examples/models/concerns/account_avatar.rb b/spec/support/examples/models/concerns/account_avatar.rb
index 232f51fa3c..c6cc4e75a5 100644
--- a/spec/support/examples/models/concerns/account_avatar.rb
+++ b/spec/support/examples/models/concerns/account_avatar.rb
@@ -2,13 +2,20 @@
 
 RSpec.shared_examples 'AccountAvatar' do |fabricator|
   describe 'static avatars', :attachment_processing do
-    describe 'when GIF' do
+    describe 'with a square GIF' do
       it 'creates a png static style' do
         account = Fabricate(fabricator, avatar: attachment_fixture('avatar.gif'))
         expect(account.avatar_static_url).to_not eq account.avatar_original_url
       end
     end
 
+    describe 'with a higher-than-wide GIF' do
+      it 'creates a png static style' do
+        account = Fabricate(fabricator, avatar: attachment_fixture('avatar-high.gif'))
+        expect(account.avatar_static_url).to_not eq account.avatar_original_url
+      end
+    end
+
     describe 'when non-GIF' do
       it 'does not create extra static style' do
         account = Fabricate(fabricator, avatar: attachment_fixture('attachment.jpg'))

From 34d7c9edaea46eb139eac6703f0750f45d4303ed Mon Sep 17 00:00:00 2001
From: Shlee <github@shl.ee>
Date: Fri, 15 Nov 2024 15:37:30 +0000
Subject: [PATCH 18/44] Rails 7+: primary_abstract_class recommendation
 (#32909)

---
 app/models/application_record.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/models/application_record.rb b/app/models/application_record.rb
index 299aad6340..24e9d6aeba 100644
--- a/app/models/application_record.rb
+++ b/app/models/application_record.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class ApplicationRecord < ActiveRecord::Base
-  self.abstract_class = true
+  primary_abstract_class
 
   include Remotable
 

From 297ce9ef4474c80e10043db7cc61b4fc331c68c1 Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Fri, 15 Nov 2024 10:49:26 -0500
Subject: [PATCH 19/44] Move body class to shared partial for web app
 controller concern views (#31797)

---
 app/controllers/concerns/web_app_controller_concern.rb | 5 -----
 app/views/shared/_web_app.html.haml                    | 1 +
 spec/system/about_spec.rb                              | 1 +
 spec/system/home_spec.rb                               | 2 ++
 spec/system/privacy_spec.rb                            | 1 +
 spec/system/tags_spec.rb                               | 1 +
 6 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/app/controllers/concerns/web_app_controller_concern.rb b/app/controllers/concerns/web_app_controller_concern.rb
index 9485ecda49..249bb20a25 100644
--- a/app/controllers/concerns/web_app_controller_concern.rb
+++ b/app/controllers/concerns/web_app_controller_concern.rb
@@ -7,7 +7,6 @@ module WebAppControllerConcern
     vary_by 'Accept, Accept-Language, Cookie'
 
     before_action :redirect_unauthenticated_to_permalinks!
-    before_action :set_app_body_class
 
     content_security_policy do |p|
       policy = ContentSecurityPolicy.new
@@ -24,10 +23,6 @@ module WebAppControllerConcern
     !(ENV['ONE_CLICK_SSO_LOGIN'] == 'true' && ENV['OMNIAUTH_ONLY'] == 'true' && Devise.omniauth_providers.length == 1) && current_user.nil?
   end
 
-  def set_app_body_class
-    @body_classes = 'app-body'
-  end
-
   def redirect_unauthenticated_to_permalinks!
     return if user_signed_in? && current_account.moved_to_account_id.nil?
 
diff --git a/app/views/shared/_web_app.html.haml b/app/views/shared/_web_app.html.haml
index 89d6ee567d..4f9a20a9f4 100644
--- a/app/views/shared/_web_app.html.haml
+++ b/app/views/shared/_web_app.html.haml
@@ -1,3 +1,4 @@
+- content_for :body_classes, 'app-body'
 - content_for :header_tags do
   - if user_signed_in?
     = preload_pack_asset 'features/compose.js'
diff --git a/spec/system/about_spec.rb b/spec/system/about_spec.rb
index f832802f91..d7fd7f51a1 100644
--- a/spec/system/about_spec.rb
+++ b/spec/system/about_spec.rb
@@ -8,5 +8,6 @@ RSpec.describe 'About page' do
 
     expect(page)
       .to have_css('noscript', text: /Mastodon/)
+      .and have_css('body', class: 'app-body')
   end
 end
diff --git a/spec/system/home_spec.rb b/spec/system/home_spec.rb
index c1ce4e1726..0838b3d8e7 100644
--- a/spec/system/home_spec.rb
+++ b/spec/system/home_spec.rb
@@ -11,6 +11,7 @@ RSpec.describe 'Home page' do
 
       expect(page)
         .to have_css('noscript', text: /Mastodon/)
+        .and have_css('body', class: 'app-body')
     end
   end
 
@@ -20,6 +21,7 @@ RSpec.describe 'Home page' do
 
       expect(page)
         .to have_css('noscript', text: /Mastodon/)
+        .and have_css('body', class: 'app-body')
     end
   end
 end
diff --git a/spec/system/privacy_spec.rb b/spec/system/privacy_spec.rb
index 631440ebb2..f2e4d5a993 100644
--- a/spec/system/privacy_spec.rb
+++ b/spec/system/privacy_spec.rb
@@ -8,5 +8,6 @@ RSpec.describe 'Privacy policy page' do
 
     expect(page)
       .to have_css('noscript', text: /Mastodon/)
+      .and have_css('body', class: 'app-body')
   end
 end
diff --git a/spec/system/tags_spec.rb b/spec/system/tags_spec.rb
index f39c6bf0d8..9da5768c7f 100644
--- a/spec/system/tags_spec.rb
+++ b/spec/system/tags_spec.rb
@@ -13,6 +13,7 @@ RSpec.describe 'Tags' do
 
       expect(page)
         .to have_css('noscript', text: /Mastodon/)
+        .and have_css('body', class: 'app-body')
         .and have_private_cache_control
     end
   end

From 319109029d8eb8b851874b3c80ced3536ba81f29 Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Fri, 15 Nov 2024 10:52:37 -0500
Subject: [PATCH 20/44] Fix logic in "last used at per application" oauth token
 list (#32912)

---
 .../authorized_applications_controller.rb     |  8 +------
 app/models/user.rb                            |  9 ++++++++
 spec/models/user_spec.rb                      | 23 +++++++++++++++++++
 3 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/app/controllers/oauth/authorized_applications_controller.rb b/app/controllers/oauth/authorized_applications_controller.rb
index 267409a9ce..9e541e5e3c 100644
--- a/app/controllers/oauth/authorized_applications_controller.rb
+++ b/app/controllers/oauth/authorized_applications_controller.rb
@@ -35,12 +35,6 @@ class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio
   end
 
   def set_last_used_at_by_app
-    @last_used_at_by_app = Doorkeeper::AccessToken
-                           .select('DISTINCT ON (application_id) application_id, last_used_at')
-                           .where(resource_owner_id: current_resource_owner.id)
-                           .where.not(last_used_at: nil)
-                           .order(application_id: :desc, last_used_at: :desc)
-                           .pluck(:application_id, :last_used_at)
-                           .to_h
+    @last_used_at_by_app = current_resource_owner.applications_last_used
   end
 end
diff --git a/app/models/user.rb b/app/models/user.rb
index f717dcd860..be9ebac699 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -280,6 +280,15 @@ class User < ApplicationRecord
     save!
   end
 
+  def applications_last_used
+    Doorkeeper::AccessToken
+      .where(resource_owner_id: id)
+      .where.not(last_used_at: nil)
+      .group(:application_id)
+      .maximum(:last_used_at)
+      .to_h
+  end
+
   def token_for_app(app)
     return nil if app.nil? || app.owner != self
 
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 4393be5a4e..9a5a070d25 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -598,4 +598,27 @@ RSpec.describe User do
       end
     end
   end
+
+  describe '#applications_last_used' do
+    let!(:user) { Fabricate(:user) }
+
+    let!(:never_used_application) { Fabricate :application, owner: user }
+    let!(:application_one) { Fabricate :application, owner: user }
+    let!(:application_two) { Fabricate :application, owner: user }
+
+    before do
+      _other_user_token = Fabricate :access_token, last_used_at: 3.days.ago
+      _never_used_token = Fabricate :access_token, application: never_used_application, resource_owner_id: user.id, last_used_at: nil
+      _app_one_old_token = Fabricate :access_token, application: application_one, resource_owner_id: user.id, last_used_at: 5.days.ago
+      _app_one_new_token = Fabricate :access_token, application: application_one, resource_owner_id: user.id, last_used_at: 1.day.ago
+      _never_used_token = Fabricate :access_token, application: application_two, resource_owner_id: user.id, last_used_at: 5.days.ago
+    end
+
+    it 'returns a hash of unique applications with last used values' do
+      expect(user.applications_last_used)
+        .to include(application_one.id => be_within(1.0).of(1.day.ago))
+        .and include(application_two.id => be_within(1.0).of(5.days.ago))
+        .and not_include(never_used_application.id)
+    end
+  end
 end

From 54a7c1898e36cda393dc79cde4d44b53e0a5299a Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Fri, 15 Nov 2024 15:55:10 +0000
Subject: [PATCH 21/44] Update dependency uuid to v11 (#32676)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
 streaming/package.json |  2 +-
 yarn.lock              | 12 ++++++------
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/streaming/package.json b/streaming/package.json
index 585c4be4e1..380f1c429d 100644
--- a/streaming/package.json
+++ b/streaming/package.json
@@ -27,7 +27,7 @@
     "pino": "^9.0.0",
     "pino-http": "^10.0.0",
     "prom-client": "^15.0.0",
-    "uuid": "^10.0.0",
+    "uuid": "^11.0.0",
     "ws": "^8.12.1"
   },
   "devDependencies": {
diff --git a/yarn.lock b/yarn.lock
index 7fd68ac8c1..1f9ff3426b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3027,7 +3027,7 @@ __metadata:
     prom-client: "npm:^15.0.0"
     typescript: "npm:^5.0.4"
     utf-8-validate: "npm:^6.0.3"
-    uuid: "npm:^10.0.0"
+    uuid: "npm:^11.0.0"
     ws: "npm:^8.12.1"
   dependenciesMeta:
     bufferutil:
@@ -17680,12 +17680,12 @@ __metadata:
   languageName: node
   linkType: hard
 
-"uuid@npm:^10.0.0":
-  version: 10.0.0
-  resolution: "uuid@npm:10.0.0"
+"uuid@npm:^11.0.0":
+  version: 11.0.1
+  resolution: "uuid@npm:11.0.1"
   bin:
-    uuid: dist/bin/uuid
-  checksum: 10c0/eab18c27fe4ab9fb9709a5d5f40119b45f2ec8314f8d4cf12ce27e4c6f4ffa4a6321dc7db6c515068fa373c075b49691ba969f0010bf37f44c37ca40cd6bf7fe
+    uuid: dist/esm/bin/uuid
+  checksum: 10c0/cd5a1d7eccfd6da80382ec88cfa28b68dce2c1c1402228b813fc0065ab8b29d20594cffeb67d850bc166ade677a6c35741072bd9dd0cc7d565c1fe8eca14ef22
   languageName: node
   linkType: hard
 

From 7bd7705f591692f9df0346f025a30ef8eda25ae1 Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Fri, 15 Nov 2024 11:07:26 -0500
Subject: [PATCH 22/44] Combine shared-setup examples across
 `spec/controllers/auth/*` specs (#32906)

---
 .../auth/challenges_controller_spec.rb        |  32 ++---
 .../auth/confirmations_controller_spec.rb     |  25 ++--
 .../auth/passwords_controller_spec.rb         |  53 ++++---
 .../auth/registrations_controller_spec.rb     | 135 +++++++++---------
 4 files changed, 121 insertions(+), 124 deletions(-)

diff --git a/spec/controllers/auth/challenges_controller_spec.rb b/spec/controllers/auth/challenges_controller_spec.rb
index 56fdfa61b5..3c9d2a5964 100644
--- a/spec/controllers/auth/challenges_controller_spec.rb
+++ b/spec/controllers/auth/challenges_controller_spec.rb
@@ -8,9 +8,7 @@ RSpec.describe Auth::ChallengesController do
   let(:password) { 'foobar12345' }
   let(:user) { Fabricate(:user, password: password) }
 
-  before do
-    sign_in user
-  end
+  before { sign_in user }
 
   describe 'POST #create' do
     let(:return_to) { edit_user_registration_path }
@@ -18,28 +16,24 @@ RSpec.describe Auth::ChallengesController do
     context 'with correct password' do
       before { post :create, params: { form_challenge: { return_to: return_to, current_password: password } } }
 
-      it 'redirects back' do
-        expect(response).to redirect_to(return_to)
-      end
-
-      it 'sets session' do
-        expect(session[:challenge_passed_at]).to_not be_nil
+      it 'redirects back and sets challenge passed at in session' do
+        expect(response)
+          .to redirect_to(return_to)
+        expect(session[:challenge_passed_at])
+          .to_not be_nil
       end
     end
 
     context 'with incorrect password' do
       before { post :create, params: { form_challenge: { return_to: return_to, current_password: 'hhfggjjd562' } } }
 
-      it 'renders challenge' do
-        expect(response).to render_template('auth/challenges/new')
-      end
-
-      it 'displays error' do
-        expect(response.body).to include 'Invalid password'
-      end
-
-      it 'does not set session' do
-        expect(session[:challenge_passed_at]).to be_nil
+      it 'renders challenge, displays error, does not set session' do
+        expect(response)
+          .to render_template('auth/challenges/new')
+        expect(response.body)
+          .to include 'Invalid password'
+        expect(session[:challenge_passed_at])
+          .to be_nil
       end
     end
   end
diff --git a/spec/controllers/auth/confirmations_controller_spec.rb b/spec/controllers/auth/confirmations_controller_spec.rb
index a5b212e660..09a178f0e8 100644
--- a/spec/controllers/auth/confirmations_controller_spec.rb
+++ b/spec/controllers/auth/confirmations_controller_spec.rb
@@ -23,12 +23,11 @@ RSpec.describe Auth::ConfirmationsController do
         get :show, params: { confirmation_token: 'foobar' }
       end
 
-      it 'redirects to login' do
-        expect(response).to redirect_to(new_user_session_path)
-      end
-
-      it 'queues up bootstrapping of home timeline' do
-        expect(BootstrapTimelineWorker).to have_received(:perform_async).with(user.account_id)
+      it 'redirects to login and queues worker' do
+        expect(response)
+          .to redirect_to(new_user_session_path)
+        expect(BootstrapTimelineWorker)
+          .to have_received(:perform_async).with(user.account_id)
       end
     end
 
@@ -88,13 +87,13 @@ RSpec.describe Auth::ConfirmationsController do
         get :show, params: { confirmation_token: 'foobar' }
       end
 
-      it 'redirects to login and confirms email' do
-        expect(response).to redirect_to(new_user_session_path)
-        expect(user.reload.unconfirmed_email).to be_nil
-      end
-
-      it 'does not queue up bootstrapping of home timeline' do
-        expect(BootstrapTimelineWorker).to_not have_received(:perform_async)
+      it 'redirects to login, confirms email, does not queue worker' do
+        expect(response)
+          .to redirect_to(new_user_session_path)
+        expect(user.reload.unconfirmed_email)
+          .to be_nil
+        expect(BootstrapTimelineWorker)
+          .to_not have_received(:perform_async)
       end
     end
   end
diff --git a/spec/controllers/auth/passwords_controller_spec.rb b/spec/controllers/auth/passwords_controller_spec.rb
index 9ccbb9e494..90095ac4b8 100644
--- a/spec/controllers/auth/passwords_controller_spec.rb
+++ b/spec/controllers/auth/passwords_controller_spec.rb
@@ -57,29 +57,30 @@ RSpec.describe Auth::PasswordsController do
         post :update, params: { user: { password: password, password_confirmation: password, reset_password_token: token } }
       end
 
-      it 'redirect to sign in' do
-        expect(response).to redirect_to '/auth/sign_in'
-      end
+      it 'resets the password' do
+        expect(response)
+          .to redirect_to '/auth/sign_in'
 
-      it 'changes password' do
-        this_user = User.find(user.id)
+        # Change password
+        expect(User.find(user.id))
+          .to be_present
+          .and be_valid_password(password)
 
-        expect(this_user).to_not be_nil
-        expect(this_user.valid_password?(password)).to be true
-      end
+        # Deactivate session
+        expect(user.session_activations.count)
+          .to eq 0
+        expect { session_activation.reload }
+          .to raise_error(ActiveRecord::RecordNotFound)
 
-      it 'deactivates all sessions' do
-        expect(user.session_activations.count).to eq 0
-        expect { session_activation.reload }.to raise_error(ActiveRecord::RecordNotFound)
-      end
+        # Revoke tokens
+        expect(Doorkeeper::AccessToken.active_for(user).count)
+          .to eq 0
 
-      it 'revokes all access tokens' do
-        expect(Doorkeeper::AccessToken.active_for(user).count).to eq 0
-      end
-
-      it 'removes push subscriptions' do
-        expect(Web::PushSubscription.where(user: user).or(Web::PushSubscription.where(access_token: access_token)).count).to eq 0
-        expect { web_push_subscription.reload }.to raise_error(ActiveRecord::RecordNotFound)
+        # Remove push subs
+        expect(Web::PushSubscription.where(user: user).or(Web::PushSubscription.where(access_token: access_token)).count)
+          .to eq 0
+        expect { web_push_subscription.reload }
+          .to raise_error(ActiveRecord::RecordNotFound)
       end
     end
 
@@ -88,15 +89,13 @@ RSpec.describe Auth::PasswordsController do
         post :update, params: { user: { password: password, password_confirmation: password, reset_password_token: 'some_invalid_value' } }
       end
 
-      it 'renders reset password' do
-        expect(response).to render_template(:new)
-      end
+      it 'renders reset password and retains password' do
+        expect(response)
+          .to render_template(:new)
 
-      it 'retains password' do
-        this_user = User.find(user.id)
-
-        expect(this_user).to_not be_nil
-        expect(this_user.external_or_valid_password?(user.password)).to be true
+        expect(User.find(user.id))
+          .to be_present
+          .and be_external_or_valid_password(user.password)
       end
     end
   end
diff --git a/spec/controllers/auth/registrations_controller_spec.rb b/spec/controllers/auth/registrations_controller_spec.rb
index d1542128e7..739cb455e8 100644
--- a/spec/controllers/auth/registrations_controller_spec.rb
+++ b/spec/controllers/auth/registrations_controller_spec.rb
@@ -6,25 +6,33 @@ RSpec.describe Auth::RegistrationsController do
   render_views
 
   shared_examples 'checks for enabled registrations' do |path|
-    it 'redirects if it is in single user mode while it is open for registration' do
-      Fabricate(:account)
-      Setting.registrations_mode = 'open'
-      allow(Rails.configuration.x).to receive(:single_user_mode).and_return(true)
+    context 'when in single user mode and open for registration' do
+      before do
+        Setting.registrations_mode = 'open'
+        allow(Rails.configuration.x).to receive(:single_user_mode).and_return(true)
+      end
 
-      get path
+      it 'redirects to root' do
+        Fabricate(:account)
+        get path
 
-      expect(response).to redirect_to '/'
-      expect(Rails.configuration.x).to have_received(:single_user_mode)
+        expect(response).to redirect_to '/'
+        expect(Rails.configuration.x).to have_received(:single_user_mode)
+      end
     end
 
-    it 'redirects if it is not open for registration while it is not in single user mode' do
-      Setting.registrations_mode = 'none'
-      allow(Rails.configuration.x).to receive(:single_user_mode).and_return(false)
+    context 'when registrations closed and not in single user mode' do
+      before do
+        Setting.registrations_mode = 'none'
+        allow(Rails.configuration.x).to receive(:single_user_mode).and_return(false)
+      end
 
-      get path
+      it 'redirects to root' do
+        get path
 
-      expect(response).to redirect_to '/'
-      expect(Rails.configuration.x).to have_received(:single_user_mode)
+        expect(response).to redirect_to '/'
+        expect(Rails.configuration.x).to have_received(:single_user_mode)
+      end
     end
   end
 
@@ -35,12 +43,12 @@ RSpec.describe Auth::RegistrationsController do
       get :edit
     end
 
-    it 'returns http success' do
-      expect(response).to have_http_status(200)
-    end
+    it 'returns http success and cache headers' do
+      expect(response)
+        .to have_http_status(200)
 
-    it 'returns private cache control header' do
-      expect(response.headers['Cache-Control']).to include('private, no-store')
+      expect(response.headers['Cache-Control'])
+        .to include('private, no-store')
     end
   end
 
@@ -53,14 +61,13 @@ RSpec.describe Auth::RegistrationsController do
       sign_in(user, scope: :user)
     end
 
-    it 'returns http success' do
+    it 'returns http success and cache headers' do
       put :update
-      expect(response).to have_http_status(200)
-    end
 
-    it 'returns private cache control headers' do
-      put :update
-      expect(response.headers['Cache-Control']).to include('private, no-store')
+      expect(response)
+        .to have_http_status(200)
+      expect(response.headers['Cache-Control'])
+        .to include('private, no-store')
     end
 
     it 'can update the user email' do
@@ -174,16 +181,14 @@ RSpec.describe Auth::RegistrationsController do
         post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', agreement: 'true' } }
       end
 
-      it 'redirects to setup' do
+      it 'redirects to setup and creates user' do
         subject
-        expect(response).to redirect_to auth_setup_path
-      end
 
-      it 'creates user' do
-        subject
-        user = User.find_by(email: 'test@example.com')
-        expect(user).to_not be_nil
-        expect(user.locale).to eq(accept_language)
+        expect(response)
+          .to redirect_to auth_setup_path
+        expect(User.find_by(email: 'test@example.com'))
+          .to be_present
+          .and have_attributes(locale: eq(accept_language))
       end
     end
 
@@ -254,17 +259,18 @@ RSpec.describe Auth::RegistrationsController do
         post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', agreement: 'true' } }
       end
 
-      it 'redirects to setup' do
+      it 'redirects to setup and creates user' do
         subject
-        expect(response).to redirect_to auth_setup_path
-      end
 
-      it 'creates user' do
-        subject
-        user = User.find_by(email: 'test@example.com')
-        expect(user).to_not be_nil
-        expect(user.locale).to eq(accept_language)
-        expect(user.approved).to be(false)
+        expect(response)
+          .to redirect_to auth_setup_path
+
+        expect(User.find_by(email: 'test@example.com'))
+          .to be_present
+          .and have_attributes(
+            locale: eq(accept_language),
+            approved: be(false)
+          )
       end
     end
 
@@ -276,17 +282,17 @@ RSpec.describe Auth::RegistrationsController do
         post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', invite_code: invite.code, agreement: 'true' } }
       end
 
-      it 'redirects to setup' do
+      it 'redirects to setup and creates user' do
         subject
-        expect(response).to redirect_to auth_setup_path
-      end
 
-      it 'creates user' do
-        subject
-        user = User.find_by(email: 'test@example.com')
-        expect(user).to_not be_nil
-        expect(user.locale).to eq(accept_language)
-        expect(user.approved).to be(false)
+        expect(response).to redirect_to auth_setup_path
+
+        expect(User.find_by(email: 'test@example.com'))
+          .to be_present
+          .and have_attributes(
+            locale: eq(accept_language),
+            approved: be(false)
+          )
       end
     end
 
@@ -300,17 +306,17 @@ RSpec.describe Auth::RegistrationsController do
         post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', invite_code: invite.code, agreement: 'true' } }
       end
 
-      it 'redirects to setup' do
+      it 'redirects to setup and creates user' do
         subject
-        expect(response).to redirect_to auth_setup_path
-      end
 
-      it 'creates user' do
-        subject
-        user = User.find_by(email: 'test@example.com')
-        expect(user).to_not be_nil
-        expect(user.locale).to eq(accept_language)
-        expect(user.approved).to be(true)
+        expect(response).to redirect_to auth_setup_path
+
+        expect(User.find_by(email: 'test@example.com'))
+          .to be_present
+          .and have_attributes(
+            locale: eq(accept_language),
+            approved: be(true)
+          )
       end
     end
 
@@ -348,12 +354,11 @@ RSpec.describe Auth::RegistrationsController do
       delete :destroy
     end
 
-    it 'returns http not found' do
-      expect(response).to have_http_status(404)
-    end
-
-    it 'does not delete user' do
-      expect(User.find(user.id)).to_not be_nil
+    it 'returns http not found and keeps user' do
+      expect(response)
+        .to have_http_status(404)
+      expect(User.find(user.id))
+        .to_not be_nil
     end
   end
 end

From 9d3fcc3546df1cef5652ea29e370a86cb87d7a21 Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Fri, 15 Nov 2024 11:10:20 -0500
Subject: [PATCH 23/44] Remove unused failure action in api/base controller
 spec (#32905)

---
 spec/controllers/api/base_controller_spec.rb | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/spec/controllers/api/base_controller_spec.rb b/spec/controllers/api/base_controller_spec.rb
index 1e0e7c8f4d..bd4073dfaf 100644
--- a/spec/controllers/api/base_controller_spec.rb
+++ b/spec/controllers/api/base_controller_spec.rb
@@ -7,10 +7,6 @@ RSpec.describe Api::BaseController do
     def success
       head 200
     end
-
-    def failure
-      FakeService.new
-    end
   end
 
   it 'returns private cache control headers by default' do

From 44d92fa4f6aac5c45ad358287af48cd879f5665e Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Fri, 15 Nov 2024 17:15:44 +0100
Subject: [PATCH 24/44] Update dependency uuid to v11.0.3 (#32913)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
 yarn.lock | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/yarn.lock b/yarn.lock
index 1f9ff3426b..aaecae7a2a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -17681,11 +17681,11 @@ __metadata:
   linkType: hard
 
 "uuid@npm:^11.0.0":
-  version: 11.0.1
-  resolution: "uuid@npm:11.0.1"
+  version: 11.0.3
+  resolution: "uuid@npm:11.0.3"
   bin:
     uuid: dist/esm/bin/uuid
-  checksum: 10c0/cd5a1d7eccfd6da80382ec88cfa28b68dce2c1c1402228b813fc0065ab8b29d20594cffeb67d850bc166ade677a6c35741072bd9dd0cc7d565c1fe8eca14ef22
+  checksum: 10c0/cee762fc76d949a2ff9205770334699e0043d52bb766472593a25f150077c9deed821230251ea3d6ab3943a5ea137d2826678797f1d5f6754c7ce5ce27e9f7a6
   languageName: node
   linkType: hard
 

From a1ac2a73fffa2a8e1b3aa71041fd01c1587e0d5f Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Sat, 16 Nov 2024 15:48:10 -0500
Subject: [PATCH 25/44] Remove remnants of embed views (#32419)

---
 app/helpers/statuses_helper.rb                | 11 ------
 app/views/admin/reports/_status.html.haml     |  2 +-
 .../filters/statuses/_status_filter.html.haml |  2 +-
 spec/helpers/accounts_helper_spec.rb          | 35 ++-----------------
 spec/helpers/statuses_helper_spec.rb          | 24 -------------
 5 files changed, 4 insertions(+), 70 deletions(-)

diff --git a/app/helpers/statuses_helper.rb b/app/helpers/statuses_helper.rb
index 9bbb03fd82..16b9d3fb53 100644
--- a/app/helpers/statuses_helper.rb
+++ b/app/helpers/statuses_helper.rb
@@ -1,9 +1,6 @@
 # frozen_string_literal: true
 
 module StatusesHelper
-  EMBEDDED_CONTROLLER = 'statuses'
-  EMBEDDED_ACTION = 'embed'
-
   VISIBLITY_ICONS = {
     public: 'globe',
     unlisted: 'lock_open',
@@ -60,18 +57,10 @@ module StatusesHelper
     components.compact_blank.join("\n\n")
   end
 
-  def stream_link_target
-    embedded_view? ? '_blank' : nil
-  end
-
   def visibility_icon(status)
     VISIBLITY_ICONS[status.visibility.to_sym]
   end
 
-  def embedded_view?
-    params[:controller] == EMBEDDED_CONTROLLER && params[:action] == EMBEDDED_ACTION
-  end
-
   def prefers_autoplay?
     ActiveModel::Type::Boolean.new.cast(params[:autoplay]) || current_user&.setting_auto_play_gif
   end
diff --git a/app/views/admin/reports/_status.html.haml b/app/views/admin/reports/_status.html.haml
index 3a35fdd272..bd688a1a5d 100644
--- a/app/views/admin/reports/_status.html.haml
+++ b/app/views/admin/reports/_status.html.haml
@@ -44,7 +44,7 @@
         = t("statuses.visibilities.#{status.visibility}")
         ·
 
-        = link_to ActivityPub::TagManager.instance.url_for(status.proper), class: 'detailed-status__link', target: stream_link_target, rel: 'noopener noreferrer' do
+        = link_to ActivityPub::TagManager.instance.url_for(status.proper), class: 'detailed-status__link', rel: 'noopener noreferrer' do
           = t('admin.statuses.view_publicly')
 
         - if status.proper.sensitive?
diff --git a/app/views/filters/statuses/_status_filter.html.haml b/app/views/filters/statuses/_status_filter.html.haml
index d0d04638d2..3476869e60 100644
--- a/app/views/filters/statuses/_status_filter.html.haml
+++ b/app/views/filters/statuses/_status_filter.html.haml
@@ -23,7 +23,7 @@
         = image_tag(status.account.avatar.url, width: 15, height: 15, alt: '', class: 'avatar')
         .username= status.account.acct
       ·
-      = link_to ActivityPub::TagManager.instance.url_for(status), class: 'detailed-status__datetime', target: stream_link_target, rel: 'noopener noreferrer' do
+      = link_to ActivityPub::TagManager.instance.url_for(status), class: 'detailed-status__datetime', rel: 'noopener noreferrer' do
         %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
       - if status.edited?
         ·
diff --git a/spec/helpers/accounts_helper_spec.rb b/spec/helpers/accounts_helper_spec.rb
index 2c949cde69..8526482362 100644
--- a/spec/helpers/accounts_helper_spec.rb
+++ b/spec/helpers/accounts_helper_spec.rb
@@ -3,16 +3,6 @@
 require 'rails_helper'
 
 RSpec.describe AccountsHelper do
-  def set_not_embedded_view
-    params[:controller] = "not_#{StatusesHelper::EMBEDDED_CONTROLLER}"
-    params[:action] = "not_#{StatusesHelper::EMBEDDED_ACTION}"
-  end
-
-  def set_embedded_view
-    params[:controller] = StatusesHelper::EMBEDDED_CONTROLLER
-    params[:action] = StatusesHelper::EMBEDDED_ACTION
-  end
-
   describe '#display_name' do
     it 'uses the display name when it exists' do
       account = Account.new(display_name: 'Display', username: 'Username')
@@ -28,9 +18,8 @@ RSpec.describe AccountsHelper do
   end
 
   describe '#acct' do
-    it 'is fully qualified for embedded local accounts' do
+    it 'is fully qualified for local accounts' do
       allow(Rails.configuration.x).to receive(:local_domain).and_return('local_domain')
-      set_embedded_view
       account = Account.new(domain: nil, username: 'user')
 
       acct = helper.acct(account)
@@ -38,32 +27,12 @@ RSpec.describe AccountsHelper do
       expect(acct).to eq '@user@local_domain'
     end
 
-    it 'is fully qualified for embedded foreign accounts' do
-      set_embedded_view
+    it 'is fully qualified for remote accounts' do
       account = Account.new(domain: 'foreign_server.com', username: 'user')
 
       acct = helper.acct(account)
 
       expect(acct).to eq '@user@foreign_server.com'
     end
-
-    it 'is fully qualified for non embedded foreign accounts' do
-      set_not_embedded_view
-      account = Account.new(domain: 'foreign_server.com', username: 'user')
-
-      acct = helper.acct(account)
-
-      expect(acct).to eq '@user@foreign_server.com'
-    end
-
-    it 'is fully qualified for non embedded local accounts' do
-      allow(Rails.configuration.x).to receive(:local_domain).and_return('local_domain')
-      set_not_embedded_view
-      account = Account.new(domain: nil, username: 'user')
-
-      acct = helper.acct(account)
-
-      expect(acct).to eq '@user@local_domain'
-    end
   end
 end
diff --git a/spec/helpers/statuses_helper_spec.rb b/spec/helpers/statuses_helper_spec.rb
index edd3e8f2f7..07ad72eda9 100644
--- a/spec/helpers/statuses_helper_spec.rb
+++ b/spec/helpers/statuses_helper_spec.rb
@@ -77,28 +77,4 @@ RSpec.describe StatusesHelper do
       end
     end
   end
-
-  describe '#stream_link_target' do
-    it 'returns nil if it is not an embedded view' do
-      set_not_embedded_view
-
-      expect(helper.stream_link_target).to be_nil
-    end
-
-    it 'returns _blank if it is an embedded view' do
-      set_embedded_view
-
-      expect(helper.stream_link_target).to eq '_blank'
-    end
-  end
-
-  def set_not_embedded_view
-    params[:controller] = "not_#{StatusesHelper::EMBEDDED_CONTROLLER}"
-    params[:action] = "not_#{StatusesHelper::EMBEDDED_ACTION}"
-  end
-
-  def set_embedded_view
-    params[:controller] = StatusesHelper::EMBEDDED_CONTROLLER
-    params[:action] = StatusesHelper::EMBEDDED_ACTION
-  end
 end

From 1c6f53e70f3eb59e2870a55c9f271524ff6115a4 Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Mon, 18 Nov 2024 03:07:18 -0500
Subject: [PATCH 26/44] Use `with_options` blocks in `Associations` concern
 (#32840)

---
 app/models/concerns/account/associations.rb | 101 +++++++++-----------
 1 file changed, 47 insertions(+), 54 deletions(-)

diff --git a/app/models/concerns/account/associations.rb b/app/models/concerns/account/associations.rb
index 637e785953..4e29235b6b 100644
--- a/app/models/concerns/account/associations.rb
+++ b/app/models/concerns/account/associations.rb
@@ -4,75 +4,68 @@ module Account::Associations
   extend ActiveSupport::Concern
 
   included do
-    # Local users
-    has_one :user, inverse_of: :account, dependent: :destroy
+    # Core associations
+    with_options dependent: :destroy do
+      # Association where account owns record
+      with_options inverse_of: :account do
+        has_many :account_moderation_notes
+        has_many :account_pins
+        has_many :account_warnings
+        has_many :aliases, class_name: 'AccountAlias'
+        has_many :bookmarks
+        has_many :conversations, class_name: 'AccountConversation'
+        has_many :custom_filters
+        has_many :favourites
+        has_many :featured_tags, -> { includes(:tag) }
+        has_many :list_accounts
+        has_many :media_attachments
+        has_many :mentions
+        has_many :migrations, class_name: 'AccountMigration'
+        has_many :notification_permissions
+        has_many :notification_requests
+        has_many :notifications
+        has_many :owned_lists, class_name: 'List'
+        has_many :polls
+        has_many :report_notes
+        has_many :reports
+        has_many :scheduled_statuses
+        has_many :status_pins
+        has_many :statuses
 
-    # Timelines
-    has_many :statuses, inverse_of: :account, dependent: :destroy
-    has_many :favourites, inverse_of: :account, dependent: :destroy
-    has_many :bookmarks, inverse_of: :account, dependent: :destroy
-    has_many :mentions, inverse_of: :account, dependent: :destroy
-    has_many :conversations, class_name: 'AccountConversation', dependent: :destroy, inverse_of: :account
-    has_many :scheduled_statuses, inverse_of: :account, dependent: :destroy
+        has_one :deletion_request, class_name: 'AccountDeletionRequest'
+        has_one :follow_recommendation_suppression
+        has_one :notification_policy
+        has_one :statuses_cleanup_policy, class_name: 'AccountStatusesCleanupPolicy'
+        has_one :user
+      end
 
-    # Notifications
-    has_many :notifications, inverse_of: :account, dependent: :destroy
-    has_one :notification_policy, inverse_of: :account, dependent: :destroy
-    has_many :notification_permissions, inverse_of: :account, dependent: :destroy
-    has_many :notification_requests, inverse_of: :account, dependent: :destroy
+      # Association where account is targeted by record
+      with_options foreign_key: :target_account_id, inverse_of: :target_account do
+        has_many :strikes, class_name: 'AccountWarning'
+        has_many :targeted_moderation_notes, class_name: 'AccountModerationNote'
+        has_many :targeted_reports, class_name: 'Report'
+      end
+    end
 
-    # Pinned statuses
-    has_many :status_pins, inverse_of: :account, dependent: :destroy
+    # Status records pinned by the account
     has_many :pinned_statuses, -> { reorder('status_pins.created_at DESC') }, through: :status_pins, class_name: 'Status', source: :status
 
-    # Endorsements
-    has_many :account_pins, inverse_of: :account, dependent: :destroy
+    # Account records endorsed (pinned) by the account
     has_many :endorsed_accounts, through: :account_pins, class_name: 'Account', source: :target_account
 
-    # Media
-    has_many :media_attachments, dependent: :destroy
-    has_many :polls, dependent: :destroy
-
-    # Report relationships
-    has_many :reports, dependent: :destroy, inverse_of: :account
-    has_many :targeted_reports, class_name: 'Report', foreign_key: :target_account_id, dependent: :destroy, inverse_of: :target_account
-
-    has_many :report_notes, dependent: :destroy
-    has_many :custom_filters, inverse_of: :account, dependent: :destroy
-
-    # Moderation notes
-    has_many :account_moderation_notes, dependent: :destroy, inverse_of: :account
-    has_many :targeted_moderation_notes, class_name: 'AccountModerationNote', foreign_key: :target_account_id, dependent: :destroy, inverse_of: :target_account
-    has_many :account_warnings, dependent: :destroy, inverse_of: :account
-    has_many :strikes, class_name: 'AccountWarning', foreign_key: :target_account_id, dependent: :destroy, inverse_of: :target_account
-
-    # Lists (that the account is on, not owned by the account)
-    has_many :list_accounts, inverse_of: :account, dependent: :destroy
+    # List records the account has been added to (not owned by the account)
     has_many :lists, through: :list_accounts
 
-    # Lists (owned by the account)
-    has_many :owned_lists, class_name: 'List', dependent: :destroy, inverse_of: :account
-
-    # Account migrations
+    # Account record where account has been migrated
     belongs_to :moved_to_account, class_name: 'Account', optional: true
-    has_many :migrations, class_name: 'AccountMigration', dependent: :destroy, inverse_of: :account
-    has_many :aliases, class_name: 'AccountAlias', dependent: :destroy, inverse_of: :account
 
-    # Hashtags
+    # Tag records applied to account
     has_and_belongs_to_many :tags # rubocop:disable Rails/HasAndBelongsToMany
-    has_many :featured_tags, -> { includes(:tag) }, dependent: :destroy, inverse_of: :account
 
-    # Account deletion requests
-    has_one :deletion_request, class_name: 'AccountDeletionRequest', inverse_of: :account, dependent: :destroy
-
-    # Follow recommendations
+    # FollowRecommendation for account (surfaced via view)
     has_one :follow_recommendation, inverse_of: :account, dependent: nil
-    has_one :follow_recommendation_suppression, inverse_of: :account, dependent: :destroy
 
-    # Account statuses cleanup policy
-    has_one :statuses_cleanup_policy, class_name: 'AccountStatusesCleanupPolicy', inverse_of: :account, dependent: :destroy
-
-    # Imports
+    # BulkImport records owned by account
     has_many :bulk_imports, inverse_of: :account, dependent: :delete_all
   end
 end

From bcf5d30e01b711b86505f9eeae067dea08e03b41 Mon Sep 17 00:00:00 2001
From: Renaud Chaput <renchap@gmail.com>
Date: Mon, 18 Nov 2024 09:41:09 +0100
Subject: [PATCH 27/44] Add OpenTelemetry VCS attributes (#32904)

---
 .github/workflows/build-container-image.yml |   1 +
 Dockerfile                                  | 307 ++++++++++----------
 config/initializers/opentelemetry.rb        |   7 +
 lib/mastodon/version.rb                     |   4 +
 4 files changed, 167 insertions(+), 152 deletions(-)

diff --git a/.github/workflows/build-container-image.yml b/.github/workflows/build-container-image.yml
index 03a0f5bf37..6204319a63 100644
--- a/.github/workflows/build-container-image.yml
+++ b/.github/workflows/build-container-image.yml
@@ -92,6 +92,7 @@ jobs:
           build-args: |
             MASTODON_VERSION_PRERELEASE=${{ inputs.version_prerelease }}
             MASTODON_VERSION_METADATA=${{ inputs.version_metadata }}
+            SOURCE_COMMIT=${{ github.sha }}
           platforms: ${{ inputs.platforms }}
           provenance: false
           builder: ${{ steps.buildx.outputs.name || steps.buildx-native.outputs.name }}
diff --git a/Dockerfile b/Dockerfile
index a6c7d46b57..c91f10de0f 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -29,6 +29,8 @@ FROM docker.io/ruby:${RUBY_VERSION}-slim-${DEBIAN_VERSION} AS ruby
 ARG MASTODON_VERSION_PRERELEASE=""
 # Append build metadata or fork information to version.rb [--build-arg MASTODON_VERSION_METADATA="pr-123456"]
 ARG MASTODON_VERSION_METADATA=""
+# Will be available as Mastodon::Version.source_commit
+ARG SOURCE_COMMIT=""
 
 # Allow Ruby on Rails to serve static files
 # See: https://docs.joinmastodon.org/admin/config/#rails_serve_static_files
@@ -45,30 +47,31 @@ ARG GID="991"
 
 # Apply Mastodon build options based on options above
 ENV \
-# Apply Mastodon version information
+  # Apply Mastodon version information
   MASTODON_VERSION_PRERELEASE="${MASTODON_VERSION_PRERELEASE}" \
   MASTODON_VERSION_METADATA="${MASTODON_VERSION_METADATA}" \
-# Apply Mastodon static files and YJIT options
+  SOURCE_COMMIT="${SOURCE_COMMIT}" \
+  # Apply Mastodon static files and YJIT options
   RAILS_SERVE_STATIC_FILES=${RAILS_SERVE_STATIC_FILES} \
   RUBY_YJIT_ENABLE=${RUBY_YJIT_ENABLE} \
-# Apply timezone
+  # Apply timezone
   TZ=${TZ}
 
 ENV \
-# Configure the IP to bind Mastodon to when serving traffic
+  # Configure the IP to bind Mastodon to when serving traffic
   BIND="0.0.0.0" \
-# Use production settings for Yarn, Node and related nodejs based tools
+  # Use production settings for Yarn, Node and related nodejs based tools
   NODE_ENV="production" \
-# Use production settings for Ruby on Rails
+  # Use production settings for Ruby on Rails
   RAILS_ENV="production" \
-# Add Ruby and Mastodon installation to the PATH
+  # Add Ruby and Mastodon installation to the PATH
   DEBIAN_FRONTEND="noninteractive" \
   PATH="${PATH}:/opt/ruby/bin:/opt/mastodon/bin" \
-# Optimize jemalloc 5.x performance
+  # Optimize jemalloc 5.x performance
   MALLOC_CONF="narenas:2,background_thread:true,thp:never,dirty_decay_ms:1000,muzzy_decay_ms:0" \
-# Enable libvips, should not be changed
+  # Enable libvips, should not be changed
   MASTODON_USE_LIBVIPS=true \
-# Sidekiq will touch tmp/sidekiq_process_has_started_and_will_begin_processing_jobs to indicate it is ready. This can be used for a readiness check in Kubernetes
+  # Sidekiq will touch tmp/sidekiq_process_has_started_and_will_begin_processing_jobs to indicate it is ready. This can be used for a readiness check in Kubernetes
   MASTODON_SIDEKIQ_READY_FILENAME=sidekiq_process_has_started_and_will_begin_processing_jobs
 
 # Set default shell used for running commands
@@ -79,14 +82,14 @@ ARG TARGETPLATFORM
 RUN echo "Target platform is $TARGETPLATFORM"
 
 RUN \
-# Remove automatic apt cache Docker cleanup scripts
+  # Remove automatic apt cache Docker cleanup scripts
   rm -f /etc/apt/apt.conf.d/docker-clean; \
-# Sets timezone
+  # Sets timezone
   echo "${TZ}" > /etc/localtime; \
-# Creates mastodon user/group and sets home directory
+  # Creates mastodon user/group and sets home directory
   groupadd -g "${GID}" mastodon; \
   useradd -l -u "${UID}" -g "${GID}" -m -d /opt/mastodon mastodon; \
-# Creates /mastodon symlink to /opt/mastodon
+  # Creates /mastodon symlink to /opt/mastodon
   ln -s /opt/mastodon /mastodon;
 
 # Set /opt/mastodon as working directory
@@ -94,28 +97,28 @@ WORKDIR /opt/mastodon
 
 # hadolint ignore=DL3008,DL3005
 RUN \
-# Mount Apt cache and lib directories from Docker buildx caches
---mount=type=cache,id=apt-cache-${TARGETPLATFORM},target=/var/cache/apt,sharing=locked \
---mount=type=cache,id=apt-lib-${TARGETPLATFORM},target=/var/lib/apt,sharing=locked \
-# Apt update & upgrade to check for security updates to Debian image
+  # Mount Apt cache and lib directories from Docker buildx caches
+  --mount=type=cache,id=apt-cache-${TARGETPLATFORM},target=/var/cache/apt,sharing=locked \
+  --mount=type=cache,id=apt-lib-${TARGETPLATFORM},target=/var/lib/apt,sharing=locked \
+  # Apt update & upgrade to check for security updates to Debian image
   apt-get update; \
   apt-get dist-upgrade -yq; \
-# Install jemalloc, curl and other necessary components
+  # Install jemalloc, curl and other necessary components
   apt-get install -y --no-install-recommends \
-    curl \
-    file \
-    libjemalloc2 \
-    patchelf \
-    procps \
-    tini \
-    tzdata \
-    wget \
+  curl \
+  file \
+  libjemalloc2 \
+  patchelf \
+  procps \
+  tini \
+  tzdata \
+  wget \
   ; \
-# Patch Ruby to use jemalloc
+  # Patch Ruby to use jemalloc
   patchelf --add-needed libjemalloc.so.2 /usr/local/bin/ruby; \
-# Discard patchelf after use
+  # Discard patchelf after use
   apt-get purge -y \
-    patchelf \
+  patchelf \
   ;
 
 # Create temporary build layer from base image
@@ -132,56 +135,56 @@ ARG TARGETPLATFORM
 
 # hadolint ignore=DL3008
 RUN \
-# Mount Apt cache and lib directories from Docker buildx caches
---mount=type=cache,id=apt-cache-${TARGETPLATFORM},target=/var/cache/apt,sharing=locked \
---mount=type=cache,id=apt-lib-${TARGETPLATFORM},target=/var/lib/apt,sharing=locked \
-# Install build tools and bundler dependencies from APT
+  # Mount Apt cache and lib directories from Docker buildx caches
+  --mount=type=cache,id=apt-cache-${TARGETPLATFORM},target=/var/cache/apt,sharing=locked \
+  --mount=type=cache,id=apt-lib-${TARGETPLATFORM},target=/var/lib/apt,sharing=locked \
+  # Install build tools and bundler dependencies from APT
   apt-get install -y --no-install-recommends \
-    autoconf \
-    automake \
-    build-essential \
-    cmake \
-    git \
-    libgdbm-dev \
-    libglib2.0-dev \
-    libgmp-dev \
-    libicu-dev \
-    libidn-dev \
-    libpq-dev \
-    libssl-dev \
-    libtool \
-    meson \
-    nasm \
-    pkg-config \
-    shared-mime-info \
-    xz-utils \
-	# libvips components
-    libcgif-dev \
-    libexif-dev \
-    libexpat1-dev \
-    libgirepository1.0-dev \
-    libheif-dev \
-    libimagequant-dev \
-    libjpeg62-turbo-dev \
-    liblcms2-dev \
-    liborc-dev \
-    libspng-dev \
-    libtiff-dev \
-    libwebp-dev \
+  autoconf \
+  automake \
+  build-essential \
+  cmake \
+  git \
+  libgdbm-dev \
+  libglib2.0-dev \
+  libgmp-dev \
+  libicu-dev \
+  libidn-dev \
+  libpq-dev \
+  libssl-dev \
+  libtool \
+  meson \
+  nasm \
+  pkg-config \
+  shared-mime-info \
+  xz-utils \
+  # libvips components
+  libcgif-dev \
+  libexif-dev \
+  libexpat1-dev \
+  libgirepository1.0-dev \
+  libheif-dev \
+  libimagequant-dev \
+  libjpeg62-turbo-dev \
+  liblcms2-dev \
+  liborc-dev \
+  libspng-dev \
+  libtiff-dev \
+  libwebp-dev \
   # ffmpeg components
-    libdav1d-dev \
-    liblzma-dev \
-    libmp3lame-dev \
-    libopus-dev \
-    libsnappy-dev \
-    libvorbis-dev \
-    libvpx-dev \
-    libx264-dev \
-    libx265-dev \
+  libdav1d-dev \
+  liblzma-dev \
+  libmp3lame-dev \
+  libopus-dev \
+  libsnappy-dev \
+  libvorbis-dev \
+  libvpx-dev \
+  libx264-dev \
+  libx265-dev \
   ;
 
 RUN \
-# Configure Corepack
+  # Configure Corepack
   rm /usr/local/bin/yarn*; \
   corepack enable; \
   corepack prepare --activate;
@@ -228,28 +231,28 @@ WORKDIR /usr/local/ffmpeg/src/ffmpeg-${FFMPEG_VERSION}
 # Configure and compile ffmpeg
 RUN \
   ./configure \
-    --prefix=/usr/local/ffmpeg \
-    --toolchain=hardened \
-    --disable-debug \
-    --disable-devices \
-    --disable-doc \
-    --disable-ffplay \
-    --disable-network \
-    --disable-static \
-    --enable-ffmpeg \
-    --enable-ffprobe \
-    --enable-gpl \
-    --enable-libdav1d \
-    --enable-libmp3lame \
-    --enable-libopus \
-    --enable-libsnappy \
-    --enable-libvorbis \
-    --enable-libvpx \
-    --enable-libwebp \
-    --enable-libx264 \
-    --enable-libx265 \
-    --enable-shared \
-    --enable-version3 \
+  --prefix=/usr/local/ffmpeg \
+  --toolchain=hardened \
+  --disable-debug \
+  --disable-devices \
+  --disable-doc \
+  --disable-ffplay \
+  --disable-network \
+  --disable-static \
+  --enable-ffmpeg \
+  --enable-ffprobe \
+  --enable-gpl \
+  --enable-libdav1d \
+  --enable-libmp3lame \
+  --enable-libopus \
+  --enable-libsnappy \
+  --enable-libvorbis \
+  --enable-libvpx \
+  --enable-libwebp \
+  --enable-libx264 \
+  --enable-libx265 \
+  --enable-shared \
+  --enable-version3 \
   ; \
   make -j$(nproc); \
   make install;
@@ -263,17 +266,17 @@ ARG TARGETPLATFORM
 COPY Gemfile* /opt/mastodon/
 
 RUN \
-# Mount Ruby Gem caches
---mount=type=cache,id=gem-cache-${TARGETPLATFORM},target=/usr/local/bundle/cache/,sharing=locked \
-# Configure bundle to prevent changes to Gemfile and Gemfile.lock
+  # Mount Ruby Gem caches
+  --mount=type=cache,id=gem-cache-${TARGETPLATFORM},target=/usr/local/bundle/cache/,sharing=locked \
+  # Configure bundle to prevent changes to Gemfile and Gemfile.lock
   bundle config set --global frozen "true"; \
-# Configure bundle to not cache downloaded Gems
+  # Configure bundle to not cache downloaded Gems
   bundle config set --global cache_all "false"; \
-# Configure bundle to only process production Gems
+  # Configure bundle to only process production Gems
   bundle config set --local without "development test"; \
-# Configure bundle to not warn about root user
+  # Configure bundle to not warn about root user
   bundle config set silence_root_warning "true"; \
-# Download and install required Gems
+  # Download and install required Gems
   bundle install -j"$(nproc)";
 
 # Create temporary node specific build layer from build layer
@@ -288,9 +291,9 @@ COPY .yarn /opt/mastodon/.yarn
 
 # hadolint ignore=DL3008
 RUN \
---mount=type=cache,id=corepack-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/corepack,sharing=locked \
---mount=type=cache,id=yarn-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/yarn,sharing=locked \
-# Install Node packages
+  --mount=type=cache,id=corepack-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/corepack,sharing=locked \
+  --mount=type=cache,id=yarn-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/yarn,sharing=locked \
+  # Install Node packages
   yarn workspaces focus --production @mastodon/mastodon;
 
 # Create temporary assets build layer from build layer
@@ -311,10 +314,10 @@ ARG TARGETPLATFORM
 
 RUN \
   ldconfig; \
-# Use Ruby on Rails to create Mastodon assets
+  # Use Ruby on Rails to create Mastodon assets
   SECRET_KEY_BASE_DUMMY=1 \
   bundle exec rails assets:precompile; \
-# Cleanup temporary files
+  # Cleanup temporary files
   rm -fr /opt/mastodon/tmp;
 
 # Prep final Mastodon Ruby layer
@@ -324,49 +327,49 @@ ARG TARGETPLATFORM
 
 # hadolint ignore=DL3008
 RUN \
-# Mount Apt cache and lib directories from Docker buildx caches
---mount=type=cache,id=apt-cache-${TARGETPLATFORM},target=/var/cache/apt,sharing=locked \
---mount=type=cache,id=apt-lib-${TARGETPLATFORM},target=/var/lib/apt,sharing=locked \
-# Mount Corepack and Yarn caches from Docker buildx caches
---mount=type=cache,id=corepack-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/corepack,sharing=locked \
---mount=type=cache,id=yarn-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/yarn,sharing=locked \
-# Apt update install non-dev versions of necessary components
+  # Mount Apt cache and lib directories from Docker buildx caches
+  --mount=type=cache,id=apt-cache-${TARGETPLATFORM},target=/var/cache/apt,sharing=locked \
+  --mount=type=cache,id=apt-lib-${TARGETPLATFORM},target=/var/lib/apt,sharing=locked \
+  # Mount Corepack and Yarn caches from Docker buildx caches
+  --mount=type=cache,id=corepack-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/corepack,sharing=locked \
+  --mount=type=cache,id=yarn-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/yarn,sharing=locked \
+  # Apt update install non-dev versions of necessary components
   apt-get install -y --no-install-recommends \
-    libexpat1 \
-    libglib2.0-0 \
-    libicu72 \
-    libidn12 \
-    libpq5 \
-    libreadline8 \
-    libssl3 \
-    libyaml-0-2 \
+  libexpat1 \
+  libglib2.0-0 \
+  libicu72 \
+  libidn12 \
+  libpq5 \
+  libreadline8 \
+  libssl3 \
+  libyaml-0-2 \
   # libvips components
-    libcgif0 \
-    libexif12 \
-    libheif1 \
-    libimagequant0 \
-    libjpeg62-turbo \
-    liblcms2-2 \
-    liborc-0.4-0 \
-    libspng0 \
-    libtiff6 \
-    libwebp7 \
-    libwebpdemux2 \
-    libwebpmux3 \
+  libcgif0 \
+  libexif12 \
+  libheif1 \
+  libimagequant0 \
+  libjpeg62-turbo \
+  liblcms2-2 \
+  liborc-0.4-0 \
+  libspng0 \
+  libtiff6 \
+  libwebp7 \
+  libwebpdemux2 \
+  libwebpmux3 \
   # ffmpeg components
-    libdav1d6 \
-    libmp3lame0 \
-    libopencore-amrnb0 \
-    libopencore-amrwb0 \
-    libopus0 \
-    libsnappy1v5 \
-    libtheora0 \
-    libvorbis0a \
-    libvorbisenc2 \
-    libvorbisfile3 \
-    libvpx7 \
-    libx264-164 \
-    libx265-199 \
+  libdav1d6 \
+  libmp3lame0 \
+  libopencore-amrnb0 \
+  libopencore-amrwb0 \
+  libopus0 \
+  libsnappy1v5 \
+  libtheora0 \
+  libvorbis0a \
+  libvorbisenc2 \
+  libvorbisfile3 \
+  libvpx7 \
+  libx264-164 \
+  libx265-199 \
   ;
 
 # Copy Mastodon sources into final layer
@@ -386,7 +389,7 @@ COPY --from=ffmpeg /usr/local/ffmpeg/lib /usr/local/lib
 
 RUN \
   ldconfig; \
-# Smoketest media processors
+  # Smoketest media processors
   vips -v; \
   ffmpeg -version; \
   ffprobe -version;
@@ -396,10 +399,10 @@ RUN \
   bundle exec bootsnap precompile --gemfile app/ lib/;
 
 RUN \
-# Pre-create and chown system volume to Mastodon user
+  # Pre-create and chown system volume to Mastodon user
   mkdir -p /opt/mastodon/public/system; \
   chown mastodon:mastodon /opt/mastodon/public/system; \
-# Set Mastodon user as owner of tmp folder
+  # Set Mastodon user as owner of tmp folder
   chown -R mastodon:mastodon /opt/mastodon/tmp;
 
 # Set the running user for resulting container
diff --git a/config/initializers/opentelemetry.rb b/config/initializers/opentelemetry.rb
index 8edce03b90..a40cd4e4c5 100644
--- a/config/initializers/opentelemetry.rb
+++ b/config/initializers/opentelemetry.rb
@@ -65,6 +65,13 @@ if ENV.keys.any? { |name| name.match?(/OTEL_.*_ENDPOINT/) }
                         "#{prefix}#{separator}#{$PROGRAM_NAME.split('/').last}"
                       end
     c.service_version = Mastodon::Version.to_s
+
+    if Mastodon::Version.source_commit.present?
+      c.resource = OpenTelemetry::SDK::Resources::Resource.create(
+        'vcs.repository.ref.revision' => Mastodon::Version.source_commit,
+        'vcs.repository.url.full' => Mastodon::Version.source_base_url
+      )
+    end
   end
 end
 
diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb
index 88aa515296..f132c3a548 100644
--- a/lib/mastodon/version.rb
+++ b/lib/mastodon/version.rb
@@ -70,6 +70,10 @@ module Mastodon
       end
     end
 
+    def source_commit
+      ENV.fetch('SOURCE_COMMIT', nil)
+    end
+
     def user_agent
       @user_agent ||= "Mastodon/#{Version} (#{HTTP::Request::USER_AGENT}; +http#{Rails.configuration.x.use_https ? 's' : ''}://#{Rails.configuration.x.web_domain}/)"
     end

From 60801ab9140c5bcce3a3336d3ed46ccfbf3ab129 Mon Sep 17 00:00:00 2001
From: Jeong Arm <kjwonmail@gmail.com>
Date: Mon, 18 Nov 2024 03:48:27 -0500
Subject: [PATCH 28/44] Add missing autofocus on boost modal (#32953)

---
 app/javascript/mastodon/features/ui/components/boost_modal.tsx | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/app/javascript/mastodon/features/ui/components/boost_modal.tsx b/app/javascript/mastodon/features/ui/components/boost_modal.tsx
index cdf7138d49..72a28a01f9 100644
--- a/app/javascript/mastodon/features/ui/components/boost_modal.tsx
+++ b/app/javascript/mastodon/features/ui/components/boost_modal.tsx
@@ -128,6 +128,8 @@ export const BoostModal: React.FC<{
                 ? messages.cancel_reblog
                 : messages.reblog,
             )}
+            /* eslint-disable-next-line jsx-a11y/no-autofocus -- We are in the modal */
+            autoFocus
           />
         </div>
       </div>

From 5b68f4b070dd2d569d854ecc3854a2610fb61866 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Mon, 18 Nov 2024 09:56:19 +0100
Subject: [PATCH 29/44] Update libretranslate/libretranslate Docker tag to
 v1.6.2 (#32951)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
 .devcontainer/compose.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.devcontainer/compose.yaml b/.devcontainer/compose.yaml
index 5c7263c874..705d26e0ab 100644
--- a/.devcontainer/compose.yaml
+++ b/.devcontainer/compose.yaml
@@ -69,7 +69,7 @@ services:
         hard: -1
 
   libretranslate:
-    image: libretranslate/libretranslate:v1.6.1
+    image: libretranslate/libretranslate:v1.6.2
     restart: unless-stopped
     volumes:
       - lt-data:/home/libretranslate/.local

From 49a12a2df9d87321de9a13a5f4e4527bcd9bf69c Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Mon, 18 Nov 2024 08:57:37 +0000
Subject: [PATCH 30/44] Update dependency @formatjs/cli to v6.3.11 (#32950)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
 yarn.lock | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/yarn.lock b/yarn.lock
index aaecae7a2a..20d00347b8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2232,8 +2232,8 @@ __metadata:
   linkType: hard
 
 "@formatjs/cli@npm:^6.1.1":
-  version: 6.3.8
-  resolution: "@formatjs/cli@npm:6.3.8"
+  version: 6.3.11
+  resolution: "@formatjs/cli@npm:6.3.11"
   peerDependencies:
     "@glimmer/env": ^0.1.7
     "@glimmer/reference": ^0.91.1 || ^0.92.0
@@ -2262,7 +2262,7 @@ __metadata:
       optional: true
   bin:
     formatjs: bin/formatjs
-  checksum: 10c0/61fb0e56a2da26befad5ca6ff5a8bcf9c383d22634cf288f3cab5661bece7686e6f064adaa500954b37726a7745c73134b459d115d52c931b76d68d998c7b22d
+  checksum: 10c0/31d5fac85314e97591c4c6a4793abf1d9c6fbf790fbbea779b2a4c0f742f1859804f290e77be06d128274468e44bc27992196aacb4cb6f2fbd141755ca79a98d
   languageName: node
   linkType: hard
 

From 02985aae691d23086aa2512974996a1a51999b7c Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
 <41898282+github-actions[bot]@users.noreply.github.com>
Date: Mon, 18 Nov 2024 10:20:37 +0100
Subject: [PATCH 31/44] New Crowdin Translations (automated) (#32927)

Co-authored-by: GitHub Actions <noreply@github.com>
---
 app/javascript/mastodon/locales/bg.json    |   4 +
 app/javascript/mastodon/locales/de.json    |   2 +-
 app/javascript/mastodon/locales/fi.json    |   3 +-
 app/javascript/mastodon/locales/ga.json    |   1 +
 app/javascript/mastodon/locales/he.json    |   1 +
 app/javascript/mastodon/locales/ia.json    |  28 +++
 app/javascript/mastodon/locales/lv.json    |   8 +
 app/javascript/mastodon/locales/nn.json    |   1 +
 app/javascript/mastodon/locales/sk.json    |   6 +
 app/javascript/mastodon/locales/sl.json    |   8 +
 app/javascript/mastodon/locales/tr.json    |   4 +-
 app/javascript/mastodon/locales/zh-CN.json | 112 +++++------
 config/locales/activerecord.zh-CN.yml      |  10 +-
 config/locales/an.yml                      |   1 -
 config/locales/ar.yml                      |   1 -
 config/locales/be.yml                      |   1 -
 config/locales/bg.yml                      |   1 -
 config/locales/br.yml                      |   2 +-
 config/locales/ca.yml                      |   1 -
 config/locales/ckb.yml                     |   1 -
 config/locales/co.yml                      |   1 -
 config/locales/cs.yml                      |   1 -
 config/locales/cy.yml                      |   1 -
 config/locales/da.yml                      |   6 +
 config/locales/de.yml                      |  14 +-
 config/locales/devise.zh-CN.yml            |   6 +-
 config/locales/doorkeeper.ia.yml           |   2 +
 config/locales/doorkeeper.zh-CN.yml        |  10 +-
 config/locales/el.yml                      |   1 -
 config/locales/en-GB.yml                   |   1 -
 config/locales/eo.yml                      |   1 -
 config/locales/es-AR.yml                   |  16 +-
 config/locales/es-MX.yml                   |  16 +-
 config/locales/es.yml                      |  44 +++--
 config/locales/et.yml                      |   1 -
 config/locales/eu.yml                      |   1 -
 config/locales/fa.yml                      |   1 -
 config/locales/fi.yml                      |   8 +-
 config/locales/fo.yml                      |   8 +-
 config/locales/fr-CA.yml                   |   1 -
 config/locales/fr.yml                      |   1 -
 config/locales/fy.yml                      |   1 -
 config/locales/ga.yml                      |  16 +-
 config/locales/gd.yml                      |   1 -
 config/locales/gl.yml                      |   6 +
 config/locales/he.yml                      |  16 +-
 config/locales/hu.yml                      |   1 -
 config/locales/hy.yml                      |   1 -
 config/locales/ia.yml                      |  21 +-
 config/locales/id.yml                      |   1 -
 config/locales/ie.yml                      |   1 -
 config/locales/io.yml                      |   1 -
 config/locales/is.yml                      |   8 +-
 config/locales/it.yml                      |   8 +-
 config/locales/ja.yml                      |  16 +-
 config/locales/ka.yml                      |   1 -
 config/locales/kab.yml                     |   1 -
 config/locales/kk.yml                      |   1 -
 config/locales/ko.yml                      |   6 +
 config/locales/ku.yml                      |   1 -
 config/locales/lad.yml                     |   1 -
 config/locales/lt.yml                      |   8 +-
 config/locales/lv.yml                      |   1 -
 config/locales/ms.yml                      |   1 -
 config/locales/my.yml                      |   1 -
 config/locales/nl.yml                      |   6 +-
 config/locales/nn.yml                      |   8 +-
 config/locales/no.yml                      |   1 -
 config/locales/oc.yml                      |   1 -
 config/locales/pl.yml                      |   1 -
 config/locales/pt-BR.yml                   |  13 ++
 config/locales/pt-PT.yml                   |   1 -
 config/locales/ru.yml                      |   1 -
 config/locales/sc.yml                      |   1 -
 config/locales/sco.yml                     |   1 -
 config/locales/si.yml                      |   1 -
 config/locales/simple_form.ga.yml          |   1 +
 config/locales/simple_form.ia.yml          |   5 +
 config/locales/simple_form.pt-BR.yml       |   1 +
 config/locales/simple_form.zh-CN.yml       |  34 ++--
 config/locales/sk.yml                      |   1 -
 config/locales/sl.yml                      |   1 -
 config/locales/sq.yml                      |   8 +-
 config/locales/sr-Latn.yml                 |   1 -
 config/locales/sr.yml                      |   1 -
 config/locales/sv.yml                      |   5 +
 config/locales/th.yml                      |   1 -
 config/locales/tr.yml                      |   8 +-
 config/locales/uk.yml                      |   1 -
 config/locales/vi.yml                      |   8 +-
 config/locales/zh-CN.yml                   | 212 +++++++++++----------
 config/locales/zh-HK.yml                   |   1 -
 config/locales/zh-TW.yml                   |   8 +-
 93 files changed, 511 insertions(+), 278 deletions(-)

diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json
index 44482f6c96..8f99992f33 100644
--- a/app/javascript/mastodon/locales/bg.json
+++ b/app/javascript/mastodon/locales/bg.json
@@ -93,10 +93,14 @@
   "annual_report.summary.archetype.replier": "Социална пеперуда",
   "annual_report.summary.followers.followers": "последователи",
   "annual_report.summary.followers.total": "{count} общо",
+  "annual_report.summary.here_it_is": "Ето преглед на вашата {year} година:",
   "annual_report.summary.highlighted_post.by_favourites": "най-правено като любима публикация",
+  "annual_report.summary.highlighted_post.by_replies": "публикации с най-много отговори",
+  "annual_report.summary.highlighted_post.possessive": "на {name}",
   "annual_report.summary.most_used_app.most_used_app": "най-употребявано приложение",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "най-употребяван хаштаг",
   "annual_report.summary.new_posts.new_posts": "нови публикации",
+  "annual_report.summary.percentile.text": "<topLabel>Това ви слага най-отгоре</topLabel><percentage></percentage><bottomLabel>сред потребителите на Mastodon.</bottomLabel>",
   "annual_report.summary.thanks": "Благодарим, че сте част от Mastodon!",
   "attachments_list.unprocessed": "(необработено)",
   "audio.hide": "Скриване на звука",
diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json
index bd24ccd48f..f692681387 100644
--- a/app/javascript/mastodon/locales/de.json
+++ b/app/javascript/mastodon/locales/de.json
@@ -101,7 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "{name}",
   "annual_report.summary.most_used_app.most_used_app": "am häufigsten verwendete App",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "am häufigsten verwendeter Hashtag",
-  "annual_report.summary.most_used_hashtag.none": "Kein",
+  "annual_report.summary.most_used_hashtag.none": "Keiner",
   "annual_report.summary.new_posts.new_posts": "neue Beiträge",
   "annual_report.summary.percentile.text": "<topLabel>Damit gehörst du zu den obersten</topLabel><percentage></percentage><bottomLabel>der Mastodon-Nutzer*innen.</bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "Wir werden Bernie nichts verraten.",
diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json
index 2763c39168..2c0aacc535 100644
--- a/app/javascript/mastodon/locales/fi.json
+++ b/app/javascript/mastodon/locales/fi.json
@@ -38,7 +38,7 @@
   "account.following": "Seuratut",
   "account.following_counter": "{count, plural, one {{counter} seurattu} other {{counter} seurattua}}",
   "account.follows.empty": "Tämä käyttäjä ei vielä seuraa ketään.",
-  "account.go_to_profile": "Mene profiiliin",
+  "account.go_to_profile": "Siirry profiiliin",
   "account.hide_reblogs": "Piilota käyttäjän @{name} tehostukset",
   "account.in_memoriam": "Muistoissamme.",
   "account.joined_short": "Liittynyt",
@@ -101,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "Käyttäjän {name}",
   "annual_report.summary.most_used_app.most_used_app": "käytetyin sovellus",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "käytetyin aihetunniste",
+  "annual_report.summary.most_used_hashtag.none": "Ei mitään",
   "annual_report.summary.new_posts.new_posts": "uutta julkaisua",
   "annual_report.summary.percentile.text": "<topLabel>Olet osa huippujoukkoa, johon kuuluu</topLabel><percentage></percentage><bottomLabel>Mastodon-käyttäjistä.</bottomLabel>",
   "annual_report.summary.thanks": "Kiitos, että olet osa Mastodonia!",
diff --git a/app/javascript/mastodon/locales/ga.json b/app/javascript/mastodon/locales/ga.json
index 3181d7978e..137a7c591f 100644
--- a/app/javascript/mastodon/locales/ga.json
+++ b/app/javascript/mastodon/locales/ga.json
@@ -101,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "{name}'s",
   "annual_report.summary.most_used_app.most_used_app": "aip is mó a úsáidtear",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "hashtag is mó a úsáidtear",
+  "annual_report.summary.most_used_hashtag.none": "Dada",
   "annual_report.summary.new_posts.new_posts": "postanna nua",
   "annual_report.summary.percentile.text": "<topLabel>Cuireann sé sin i mbarr</topLabel><percentage></percentage><bottomLabel> úsáideoirí Mastodon.</bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "Ní inseoidh muid do Bernie.",
diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json
index 48ea869dd2..52d61b737b 100644
--- a/app/javascript/mastodon/locales/he.json
+++ b/app/javascript/mastodon/locales/he.json
@@ -101,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "של {name}",
   "annual_report.summary.most_used_app.most_used_app": "היישומון שהכי בשימוש",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "התג בשימוש הרב ביותר",
+  "annual_report.summary.most_used_hashtag.none": "אף אחד",
   "annual_report.summary.new_posts.new_posts": "הודעות חדשות",
   "annual_report.summary.percentile.text": "<topLabel>ממקם אותך באחוזון </topLabel><percentage></percentage><bottomLabel>של משמשי מסטודון.</bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "לא נגלה לברני.",
diff --git a/app/javascript/mastodon/locales/ia.json b/app/javascript/mastodon/locales/ia.json
index e41d390a3f..402829817f 100644
--- a/app/javascript/mastodon/locales/ia.json
+++ b/app/javascript/mastodon/locales/ia.json
@@ -87,6 +87,25 @@
   "alert.unexpected.title": "Ups!",
   "alt_text_badge.title": "Texto alt",
   "announcement.announcement": "Annuncio",
+  "annual_report.summary.archetype.booster": "Le impulsator",
+  "annual_report.summary.archetype.lurker": "Le lector",
+  "annual_report.summary.archetype.oracle": "Le oraculo",
+  "annual_report.summary.archetype.pollster": "Le sondagista",
+  "annual_report.summary.archetype.replier": "Le responditor",
+  "annual_report.summary.followers.followers": "sequitores",
+  "annual_report.summary.followers.total": "{count} in total",
+  "annual_report.summary.here_it_is": "Ecce tu summario de {year}:",
+  "annual_report.summary.highlighted_post.by_favourites": "message le plus favorite",
+  "annual_report.summary.highlighted_post.by_reblogs": "message le plus impulsate",
+  "annual_report.summary.highlighted_post.by_replies": "message le plus respondite",
+  "annual_report.summary.highlighted_post.possessive": "{name}, ecce tu…",
+  "annual_report.summary.most_used_app.most_used_app": "application le plus usate",
+  "annual_report.summary.most_used_hashtag.most_used_hashtag": "hashtag le plus usate",
+  "annual_report.summary.most_used_hashtag.none": "Necun",
+  "annual_report.summary.new_posts.new_posts": "nove messages",
+  "annual_report.summary.percentile.text": "<topLabel>Isto te pone in le prime</topLabel><percentage></percentage><bottomLabel>del usatores de Mastodon.</bottomLabel>",
+  "annual_report.summary.percentile.we_wont_tell_bernie": "Tu es un primo inter pares.",
+  "annual_report.summary.thanks": "Gratias pro facer parte de Mastodon!",
   "attachments_list.unprocessed": "(non processate)",
   "audio.hide": "Celar audio",
   "block_modal.remote_users_caveat": "Nos demandera al servitor {domain} de respectar tu decision. Nonobstante, le conformitate non es garantite perque alcun servitores pote tractar le blocadas de maniera differente. Le messages public pote esser totevia visibile pro le usatores non authenticate.",
@@ -158,6 +177,7 @@
   "compose_form.poll.duration": "Durata del sondage",
   "compose_form.poll.multiple": "Selection multiple",
   "compose_form.poll.option_placeholder": "Option {number}",
+  "compose_form.poll.single": "Option singule",
   "compose_form.poll.switch_to_multiple": "Cambiar le sondage pro permitter selectiones multiple",
   "compose_form.poll.switch_to_single": "Cambiar le sondage pro permitter selection singule",
   "compose_form.poll.type": "Stilo",
@@ -196,6 +216,7 @@
   "confirmations.unfollow.title": "Cessar de sequer le usator?",
   "content_warning.hide": "Celar le message",
   "content_warning.show": "Monstrar in omne caso",
+  "content_warning.show_more": "Monstrar plus",
   "conversation.delete": "Deler conversation",
   "conversation.mark_as_read": "Marcar como legite",
   "conversation.open": "Vider conversation",
@@ -304,6 +325,7 @@
   "filter_modal.select_filter.subtitle": "Usa un categoria existente o crea un nove",
   "filter_modal.select_filter.title": "Filtrar iste message",
   "filter_modal.title.status": "Filtrar un message",
+  "filter_warning.matches_filter": "Corresponde al filtro “<span>{title}</span>”",
   "filtered_notifications_banner.pending_requests": "De {count, plural, =0 {nemo} one {un persona} other {# personas}} que tu pote cognoscer",
   "filtered_notifications_banner.title": "Notificationes filtrate",
   "firehose.all": "Toto",
@@ -383,6 +405,7 @@
   "interaction_modal.description.follow": "Con un conto sur Mastodon, tu pote sequer {name} e reciper su messages in tu fluxo de initio.",
   "interaction_modal.description.reblog": "Con un conto sur Mastodon, tu pote impulsar iste message pro condivider lo con tu proprie sequitores.",
   "interaction_modal.description.reply": "Con un conto sur Mastodon, tu pote responder a iste message.",
+  "interaction_modal.description.vote": "Con un conto sur Mastodon, tu pote votar in iste sondage.",
   "interaction_modal.login.action": "Porta me a casa",
   "interaction_modal.login.prompt": "Dominio de tu servitor, p.ex. mastodon.social",
   "interaction_modal.no_account_yet": "Non sur Mstodon?",
@@ -394,6 +417,7 @@
   "interaction_modal.title.follow": "Sequer {name}",
   "interaction_modal.title.reblog": "Impulsar le message de {name}",
   "interaction_modal.title.reply": "Responder al message de {name}",
+  "interaction_modal.title.vote": "Votar in le sondage de {name}",
   "intervals.full.days": "{number, plural, one {# die} other {# dies}}",
   "intervals.full.hours": "{number, plural, one {# hora} other {# horas}}",
   "intervals.full.minutes": "{number, plural, one {# minuta} other {# minutas}}",
@@ -503,9 +527,12 @@
   "notification.admin.report_statuses_other": "{name} ha reportate {target}",
   "notification.admin.sign_up": "{name} se ha inscribite",
   "notification.admin.sign_up.name_and_others": "{name} e {count, plural, one {# altere usator} other {altere # usatores}} se inscribeva",
+  "notification.annual_report.message": "Tu summario #Wrapstodon pro {year} attende! Revela le momentos saliente e memorabile de tu anno sur Mastodon!",
+  "notification.annual_report.view": "Visitar summario #Wrapstodon",
   "notification.favourite": "{name} ha marcate tu message como favorite",
   "notification.favourite.name_and_others_with_link": "{name} e <a>{count, plural, one {# altere} other {# alteres}}</a> favoriva tu message",
   "notification.follow": "{name} te ha sequite",
+  "notification.follow.name_and_others": "{name} e <a>{count, plural, one {# other} other {# alteres}}</a> te ha sequite",
   "notification.follow_request": "{name} ha requestate de sequer te",
   "notification.follow_request.name_and_others": "{name} e {count, plural, one {# altere} other {# alteres}} ha demandate de sequer te",
   "notification.label.mention": "Mention",
@@ -564,6 +591,7 @@
   "notifications.column_settings.filter_bar.category": "Barra de filtro rapide",
   "notifications.column_settings.follow": "Nove sequitores:",
   "notifications.column_settings.follow_request": "Nove requestas de sequimento:",
+  "notifications.column_settings.group": "Gruppo",
   "notifications.column_settings.mention": "Mentiones:",
   "notifications.column_settings.poll": "Resultatos del sondage:",
   "notifications.column_settings.push": "Notificationes push",
diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json
index f6053b2e09..d6fcb34828 100644
--- a/app/javascript/mastodon/locales/lv.json
+++ b/app/javascript/mastodon/locales/lv.json
@@ -89,6 +89,10 @@
   "annual_report.summary.followers.followers": "sekotāji",
   "annual_report.summary.followers.total": "pavisam {count}",
   "annual_report.summary.here_it_is": "Šeit ir {year}. gada pārskats:",
+  "annual_report.summary.highlighted_post.possessive": "{name}",
+  "annual_report.summary.most_used_app.most_used_app": "visizmantotākā lietotne",
+  "annual_report.summary.most_used_hashtag.most_used_hashtag": "visizmantotākais tēmturis",
+  "annual_report.summary.most_used_hashtag.none": "Nav",
   "annual_report.summary.new_posts.new_posts": "jauni ieraksti",
   "attachments_list.unprocessed": "(neapstrādāti)",
   "audio.hide": "Slēpt audio",
@@ -329,7 +333,11 @@
   "hashtag.follow": "Sekot tēmturim",
   "hashtag.unfollow": "Pārstāt sekot tēmturim",
   "hashtags.and_other": "… un {count, plural, other {vēl #}}",
+  "hints.profiles.see_more_followers": "Skatīt vairāk sekotāju {domain}",
+  "hints.profiles.see_more_follows": "Skatīt vairāk sekojumu {domain}",
+  "hints.profiles.see_more_posts": "Skatīt vairāk ierakstu {domain}",
   "hints.threads.replies_may_be_missing": "Var trūkt atbildes no citiem serveriem.",
+  "hints.threads.see_more": "Skatīt vairāk atbilžu {domain}",
   "home.column_settings.show_reblogs": "Rādīt pastiprinātos ierakstus",
   "home.column_settings.show_replies": "Rādīt atbildes",
   "home.hide_announcements": "Slēpt paziņojumus",
diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json
index b45ff90585..85d19c4f93 100644
--- a/app/javascript/mastodon/locales/nn.json
+++ b/app/javascript/mastodon/locales/nn.json
@@ -101,6 +101,7 @@
   "annual_report.summary.highlighted_post.possessive": "som {name} laga",
   "annual_report.summary.most_used_app.most_used_app": "mest brukte app",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "mest brukte emneknagg",
+  "annual_report.summary.most_used_hashtag.none": "Ingen",
   "annual_report.summary.new_posts.new_posts": "nye innlegg",
   "annual_report.summary.percentile.text": "<topLabel>Du er av dei</topLabel><percentage></percentage><bottomLabel>ivrigaste Mastodon-brukarane.</bottomLabel>",
   "annual_report.summary.percentile.we_wont_tell_bernie": "Ikkje eit ord til pressa.",
diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json
index 8a01263eb2..1ecbaaffdd 100644
--- a/app/javascript/mastodon/locales/sk.json
+++ b/app/javascript/mastodon/locales/sk.json
@@ -348,6 +348,8 @@
   "hashtag.follow": "Sledovať hashtag",
   "hashtag.unfollow": "Prestať sledovať hashtag",
   "hashtags.and_other": "…a {count, plural, other {# ďalších}}",
+  "hints.profiles.see_more_posts": "Pozri viac príspevkov na {domain}",
+  "hints.threads.replies_may_be_missing": "Odpovede z ostatných serverov môžu chýbať.",
   "hints.threads.see_more": "Pozri viac odpovedí na {domain}",
   "home.column_settings.show_reblogs": "Zobraziť zdieľania",
   "home.column_settings.show_replies": "Zobraziť odpovede",
@@ -360,6 +362,10 @@
   "ignore_notifications_modal.filter_to_act_users": "Stále budeš môcť akceptovať, odmietnuť, alebo nahlásiť užívateľov",
   "ignore_notifications_modal.filter_to_avoid_confusion": "Triedenie pomáha vyvarovať sa možnému zmäteniu",
   "ignore_notifications_modal.ignore": "Ignoruj upozornenia",
+  "ignore_notifications_modal.new_accounts_title": "Nevšímať si oznámenia z nových účtov?",
+  "ignore_notifications_modal.not_followers_title": "Nevšímať si oznámenia od ľudí, ktorí ťa nenasledujú?",
+  "ignore_notifications_modal.not_following_title": "Nevšímať si oznámenia od ľudí, ktorých nenasleduješ?",
+  "ignore_notifications_modal.private_mentions_title": "Nevšímať si oznámenia o nevyžiadaných súkromných spomínaniach?",
   "interaction_modal.description.favourite": "S účtom na Mastodone môžete tento príspevok ohviezdičkovať, tak dať autorovi vedieť, že sa vám páči, a uložiť si ho na neskôr.",
   "interaction_modal.description.follow": "S účtom na Mastodone môžete {name} sledovať a vidieť ich príspevky vo svojom domovskom kanáli.",
   "interaction_modal.description.reblog": "S účtom na Mastodone môžete tento príspevok zdeľať so svojimi sledovateľmi.",
diff --git a/app/javascript/mastodon/locales/sl.json b/app/javascript/mastodon/locales/sl.json
index 32626b80f9..3690c612b7 100644
--- a/app/javascript/mastodon/locales/sl.json
+++ b/app/javascript/mastodon/locales/sl.json
@@ -86,6 +86,8 @@
   "alert.unexpected.message": "Zgodila se je nepričakovana napaka.",
   "alert.unexpected.title": "Ojoj!",
   "announcement.announcement": "Obvestilo",
+  "annual_report.summary.most_used_hashtag.none": "Brez",
+  "annual_report.summary.new_posts.new_posts": "nove objave",
   "attachments_list.unprocessed": "(neobdelano)",
   "audio.hide": "Skrij zvok",
   "block_modal.remote_users_caveat": "Od strežnika {domain} bomo zahtevali, da spoštuje vašo odločitev. Izpolnjevanje zahteve ni zagotovljeno, ker nekateri strežniki blokiranja obravnavajo drugače. Javne objave bodo morda še vedno vidne neprijavljenim uporabnikom.",
@@ -433,6 +435,7 @@
   "lists.subheading": "Vaši seznami",
   "load_pending": "{count, plural, one {# nov element} two {# nova elementa} few {# novi elementi} other {# novih elementov}}",
   "loading_indicator.label": "Nalaganje …",
+  "media_gallery.hide": "Skrij",
   "moved_to_account_banner.text": "Vaš račun {disabledAccount} je trenutno onemogočen, ker ste se prestavili na {movedToAccount}.",
   "mute_modal.hide_from_notifications": "Skrijte se pred obvestili",
   "mute_modal.hide_options": "Skrij možnosti",
@@ -444,6 +447,7 @@
   "mute_modal.you_wont_see_mentions": "Objav, ki jih omenjajo, ne boste videli.",
   "mute_modal.you_wont_see_posts": "Še vedno vidijo vaše objave, vi pa ne njihovih.",
   "navigation_bar.about": "O Mastodonu",
+  "navigation_bar.administration": "Upravljanje",
   "navigation_bar.advanced_interface": "Odpri v naprednem spletnem vmesniku",
   "navigation_bar.blocks": "Blokirani uporabniki",
   "navigation_bar.bookmarks": "Zaznamki",
@@ -478,10 +482,12 @@
   "notification.favourite": "{name} je vzljubil/a vašo objavo",
   "notification.follow": "{name} vam sledi",
   "notification.follow_request": "{name} vam želi slediti",
+  "notification.label.mention": "Omemba",
   "notification.label.private_mention": "Zasebna omemba",
   "notification.label.private_reply": "Zasebni odgovor",
   "notification.label.reply": "Odgovori",
   "notification.mention": "Omemba",
+  "notification.mentioned_you": "{name} vas je omenil/a",
   "notification.moderation-warning.learn_more": "Več o tem",
   "notification.moderation_warning": "Prejeli ste opozorilo moderatorjev",
   "notification.moderation_warning.action_delete_statuses": "Nekatere vaše objave so odstranjene.",
@@ -502,6 +508,7 @@
   "notification.status": "{name} je pravkar objavil/a",
   "notification.update": "{name} je uredil(a) objavo",
   "notification_requests.accept": "Sprejmi",
+  "notification_requests.confirm_accept_multiple.title": "Ali želite sprejeti zahteve za obvestila?",
   "notification_requests.confirm_dismiss_multiple.title": "Želite opustiti zahteve za obvestila?",
   "notification_requests.dismiss": "Zavrni",
   "notification_requests.edit_selection": "Uredi",
@@ -740,6 +747,7 @@
   "status.edit": "Uredi",
   "status.edited": "Zadnje urejanje {date}",
   "status.edited_x_times": "Urejeno {count, plural, one {#-krat} two {#-krat} few {#-krat} other {#-krat}}",
+  "status.embed": "Pridobite kodo za vgradnjo",
   "status.favourite": "Priljubljen_a",
   "status.favourites": "{count, plural, one {priljubitev} two {priljubitvi} few {priljubitve} other {priljubitev}}",
   "status.filter": "Filtriraj to objavo",
diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json
index ece97614ad..061f9c6c28 100644
--- a/app/javascript/mastodon/locales/tr.json
+++ b/app/javascript/mastodon/locales/tr.json
@@ -81,7 +81,7 @@
   "admin.impact_report.instance_followers": "Kullanıcılarımızın kaybedeceği takipçiler",
   "admin.impact_report.instance_follows": "Kullanıcılarının kaybedeceği takipçiler",
   "admin.impact_report.title": "Etki özeti",
-  "alert.rate_limited.message": "Lütfen {retry_time, time, medium} saatinden sonra tekrar deneyin.",
+  "alert.rate_limited.message": "Lütfen sonra tekrar deneyin {retry_time, time, medium}.",
   "alert.rate_limited.title": "Aşırı istek gönderildi",
   "alert.unexpected.message": "Beklenmedik bir hata oluştu.",
   "alert.unexpected.title": "Hay aksi!",
@@ -358,7 +358,7 @@
   "footer.privacy_policy": "Gizlilik politikası",
   "footer.source_code": "Kaynak kodu görüntüle",
   "footer.status": "Durum",
-  "generic.saved": "Kaydedildi",
+  "generic.saved": "Kaydet",
   "getting_started.heading": "Başlarken",
   "hashtag.column_header.tag_mode.all": "ve {additional}",
   "hashtag.column_header.tag_mode.any": "ya da {additional}",
diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json
index 887410dd51..cc0f0b9341 100644
--- a/app/javascript/mastodon/locales/zh-CN.json
+++ b/app/javascript/mastodon/locales/zh-CN.json
@@ -89,7 +89,7 @@
   "announcement.announcement": "公告",
   "annual_report.summary.archetype.booster": "潮流捕手",
   "annual_report.summary.archetype.lurker": "吃瓜群众",
-  "annual_report.summary.archetype.oracle": "预言家",
+  "annual_report.summary.archetype.oracle": "无所不在",
   "annual_report.summary.archetype.pollster": "投票狂魔",
   "annual_report.summary.archetype.replier": "评论区原住民",
   "annual_report.summary.followers.followers": "关注者",
@@ -102,13 +102,13 @@
   "annual_report.summary.most_used_app.most_used_app": "最常用的应用",
   "annual_report.summary.most_used_hashtag.most_used_hashtag": "最常用的话题",
   "annual_report.summary.most_used_hashtag.none": "无",
-  "annual_report.summary.new_posts.new_posts": "新发嘟",
+  "annual_report.summary.new_posts.new_posts": "新嘟嘟",
   "annual_report.summary.percentile.text": "<topLabel>这使你跻身 Mastodon 用户的前</topLabel><percentage></percentage><bottomLabel></bottomLabel>",
-  "annual_report.summary.percentile.we_wont_tell_bernie": "我们打死也不会告诉Bernie。",
+  "annual_report.summary.percentile.we_wont_tell_bernie": "我们打死也不会告诉扣税国王的(他知道的话要来收你发嘟税了)。",
   "annual_report.summary.thanks": "感谢你这一年与 Mastodon 一路同行!",
   "attachments_list.unprocessed": "(未处理)",
   "audio.hide": "隐藏音频",
-  "block_modal.remote_users_caveat": "我们将要求服务器 {domain} 尊重您的决定。然而,我们无法保证对方一定遵从,因为某些服务器可能会以不同的方案处理屏蔽操作。公开嘟文仍然可能对未登录的用户可见。",
+  "block_modal.remote_users_caveat": "我们将要求服务器 {domain} 尊重你的决定。然而,我们无法保证对方一定遵从,因为某些服务器可能会以不同的方案处理屏蔽操作。公开嘟文仍然可能对未登录的用户可见。",
   "block_modal.show_less": "隐藏",
   "block_modal.show_more": "显示更多",
   "block_modal.they_cant_mention": "他们不能提及或关注你。",
@@ -132,7 +132,7 @@
   "bundle_modal_error.message": "载入这个组件时发生了错误。",
   "bundle_modal_error.retry": "重试",
   "closed_registrations.other_server_instructions": "基于 Mastodon 去中心化的特性,你可以在其它服务器上创建账号并继续与此服务器互动。",
-  "closed_registrations_modal.description": "您目前无法在 {domain} 上创建账户,但请注意,使用 Mastodon 并非需要专门在 {domain} 上注册账户。",
+  "closed_registrations_modal.description": "你目前无法在 {domain} 上创建账户,但请注意,使用 Mastodon 并非需要专门在 {domain} 上注册账户。",
   "closed_registrations_modal.find_another_server": "查找其他服务器",
   "closed_registrations_modal.preamble": "Mastodon 是去中心化的,所以无论在哪个实例创建账号,都可以关注本服务器上的账号并与之交流。 或者你还可以自己搭建实例!",
   "closed_registrations_modal.title": "注册 Mastodon 账号",
@@ -161,8 +161,8 @@
   "column_header.unpin": "取消置顶",
   "column_subheading.settings": "设置",
   "community.column_settings.local_only": "仅限本站",
-  "community.column_settings.media_only": "仅限媒体",
-  "community.column_settings.remote_only": "仅限外部",
+  "community.column_settings.media_only": "仅媒体",
+  "community.column_settings.remote_only": "仅外站",
   "compose.language.change": "更改语言",
   "compose.language.search": "搜索语言...",
   "compose.published.body": "嘟文已发布。",
@@ -180,11 +180,11 @@
   "compose_form.poll.single": "单选",
   "compose_form.poll.switch_to_multiple": "将投票改为多选",
   "compose_form.poll.switch_to_single": "将投票改为单选",
-  "compose_form.poll.type": "样式",
+  "compose_form.poll.type": "类型",
   "compose_form.publish": "发布",
-  "compose_form.publish_form": "发布",
+  "compose_form.publish_form": "新嘟文",
   "compose_form.reply": "回复",
-  "compose_form.save_changes": "更新",
+  "compose_form.save_changes": "更改",
   "compose_form.spoiler.marked": "移除内容警告",
   "compose_form.spoiler.unmarked": "添加内容警告",
   "compose_form.spoiler_placeholder": "内容警告 (可选)",
@@ -197,7 +197,7 @@
   "confirmations.delete_list.message": "确定永久删除这个列表吗?",
   "confirmations.delete_list.title": "确认删除列表?",
   "confirmations.discard_edit_media.confirm": "丢弃",
-  "confirmations.discard_edit_media.message": "您还有未保存的媒体描述或预览修改,仍要丢弃吗?",
+  "confirmations.discard_edit_media.message": "你还有未保存的媒体描述或预览修改,仍要丢弃吗?",
   "confirmations.edit.confirm": "编辑",
   "confirmations.edit.message": "编辑此消息将会覆盖当前正在撰写的信息。仍要继续吗?",
   "confirmations.edit.title": "确认覆盖嘟文?",
@@ -229,7 +229,7 @@
   "directory.new_arrivals": "新来者",
   "directory.recently_active": "最近活跃",
   "disabled_account_banner.account_settings": "账号设置",
-  "disabled_account_banner.text": "您的账号 {disabledAccount} 目前已被禁用。",
+  "disabled_account_banner.text": "你的账号 {disabledAccount} 目前已被禁用。",
   "dismissable_banner.community_timeline": "这些是来自 {domain} 用户的最新公开嘟文。",
   "dismissable_banner.dismiss": "忽略",
   "dismissable_banner.explore_links": "这些新闻故事正被本站和分布式网络上其他站点的用户谈论。",
@@ -264,7 +264,7 @@
   "emoji_button.clear": "清除",
   "emoji_button.custom": "自定义",
   "emoji_button.flags": "旗帜",
-  "emoji_button.food": "食物和饮料",
+  "emoji_button.food": "食物与饮料",
   "emoji_button.label": "插入表情符号",
   "emoji_button.nature": "自然",
   "emoji_button.not_found": "未找到匹配的表情符号",
@@ -288,13 +288,13 @@
   "empty_column.favourited_statuses": "你没有喜欢过任何嘟文。喜欢过的嘟文会显示在这里。",
   "empty_column.favourites": "没有人喜欢过这条嘟文。如果有人喜欢了,就会显示在这里。",
   "empty_column.follow_requests": "你还没有收到任何关注请求。当你收到一个关注请求时,它会出现在这里。",
-  "empty_column.followed_tags": "您还没有关注任何话题标签。 当您关注后,它们会出现在这里。",
+  "empty_column.followed_tags": "你还没有关注任何话题标签。 当你关注后,它们会出现在这里。",
   "empty_column.hashtag": "这个话题标签下暂时没有内容。",
   "empty_column.home": "你的主页时间线是空的!快去关注更多人吧。 {suggestions}",
   "empty_column.list": "列表中还没有任何内容。当列表成员发布新嘟文时,它们将出现在这里。",
   "empty_column.lists": "你还没有创建过列表。你创建的列表会在这里显示。",
   "empty_column.mutes": "你没有隐藏任何用户。",
-  "empty_column.notification_requests": "都看完了!这里没有任何未读通知。当收到新的通知时,它们将根据您的设置显示在这里。",
+  "empty_column.notification_requests": "都看完了!这里没有任何未读通知。当收到新的通知时,它们将根据你的设置显示在这里。",
   "empty_column.notifications": "你还没有收到过任何通知,快和其他用户互动吧。",
   "empty_column.public": "这里什么都没有!写一些公开的嘟文,或者关注其他服务器的用户后,这里就会有嘟文出现了",
   "error.unexpected_crash.explanation": "此页面无法正确显示,这可能是因为我们的代码中有错误,也可能是因为浏览器兼容问题。",
@@ -333,7 +333,7 @@
   "firehose.remote": "其他服务器",
   "follow_request.authorize": "同意",
   "follow_request.reject": "拒绝",
-  "follow_requests.unlocked_explanation": "尽管你没有锁嘟,但是 {domain} 的工作人员认为你也许会想手动审核审核这些账号的关注请求。",
+  "follow_requests.unlocked_explanation": "尽管你没有锁嘟,但是 {domain} 的站务人员认为你也许会想手动审核审核这些账号的关注请求。",
   "follow_suggestions.curated_suggestion": "站务人员精选",
   "follow_suggestions.dismiss": "不再显示",
   "follow_suggestions.featured_longer": "由 {domain} 管理团队精选",
@@ -354,7 +354,7 @@
   "footer.directory": "用户目录",
   "footer.get_app": "获取应用",
   "footer.invite": "邀请",
-  "footer.keyboard_shortcuts": "快捷键列表",
+  "footer.keyboard_shortcuts": "快捷键",
   "footer.privacy_policy": "隐私政策",
   "footer.source_code": "查看源代码",
   "footer.status": "状态",
@@ -401,18 +401,18 @@
   "ignore_notifications_modal.not_followers_title": "是否忽略未关注你的人的通知?",
   "ignore_notifications_modal.not_following_title": "是否忽略你未关注的人的通知?",
   "ignore_notifications_modal.private_mentions_title": "是否忽略不请自来的私下提及?",
-  "interaction_modal.description.favourite": "只需一个 Mastodon 账号,即可喜欢这条嘟文,对嘟文的作者展示您欣赏的态度,并保存嘟文以供日后使用。",
+  "interaction_modal.description.favourite": "只需一个 Mastodon 账号,即可喜欢这条嘟文,对嘟文的作者展示你欣赏的态度,并保存嘟文以供日后使用。",
   "interaction_modal.description.follow": "拥有一个 Mastodon 账号,你就可以关注 {name} 并在自己的主页上接收对方的新嘟文。",
   "interaction_modal.description.reblog": "拥有一个 Mastodon 账号,你就可以向自己的关注者们转发此嘟文。",
   "interaction_modal.description.reply": "拥有一个 Mastodon 账号,你就可以回复此嘟文。",
   "interaction_modal.description.vote": "拥有一个 Mastodon 账号,你就可以参与此投票。",
   "interaction_modal.login.action": "转到主页",
-  "interaction_modal.login.prompt": "您所入驻的服务器域名,如:mastodon.social",
+  "interaction_modal.login.prompt": "你所入驻的服务器域名,如:mastodon.social",
   "interaction_modal.no_account_yet": "不在 Mastodon 上?",
   "interaction_modal.on_another_server": "在另一服务器",
   "interaction_modal.on_this_server": "在此服务器",
-  "interaction_modal.sign_in": "您尚未登录此服务器,您的账号托管在哪?",
-  "interaction_modal.sign_in_hint": "提示:这是您注册的网站,如果您不记得了,请在邮箱的收件箱中查找欢迎邮件。您还可以输入完整的用户名!(例如 @Mastodon@mastodon.social)",
+  "interaction_modal.sign_in": "你尚未登录此服务器,你的账号托管在哪?",
+  "interaction_modal.sign_in_hint": "提示:这是你注册的网站,如果你不记得了,请在邮箱的收件箱中查找欢迎邮件。你还可以输入完整的用户名!(例如 @Mastodon@mastodon.social)",
   "interaction_modal.title.favourite": "喜欢 {name} 的嘟文",
   "interaction_modal.title.follow": "关注 {name}",
   "interaction_modal.title.reblog": "转发 {name} 的嘟文",
@@ -424,8 +424,8 @@
   "keyboard_shortcuts.back": "返回上一页",
   "keyboard_shortcuts.blocked": "打开被屏蔽用户列表",
   "keyboard_shortcuts.boost": "转嘟",
-  "keyboard_shortcuts.column": "选择某栏",
-  "keyboard_shortcuts.compose": "选择输入框",
+  "keyboard_shortcuts.column": "选中某栏",
+  "keyboard_shortcuts.compose": "选中输入框",
   "keyboard_shortcuts.description": "说明",
   "keyboard_shortcuts.direct": "打开私下提及栏",
   "keyboard_shortcuts.down": "在列表中让光标下移",
@@ -447,7 +447,7 @@
   "keyboard_shortcuts.profile": "打开作者的个人资料",
   "keyboard_shortcuts.reply": "回复嘟文",
   "keyboard_shortcuts.requests": "打开关注请求列表",
-  "keyboard_shortcuts.search": "选择搜索框",
+  "keyboard_shortcuts.search": "选中搜索框",
   "keyboard_shortcuts.spoilers": "显示或隐藏被折叠的正文",
   "keyboard_shortcuts.start": "打开“开始使用”栏",
   "keyboard_shortcuts.toggle_hidden": "显示或隐藏被折叠的正文",
@@ -473,16 +473,16 @@
   "lists.exclusive": "在主页中隐藏这些嘟文",
   "lists.new.create": "新建列表",
   "lists.new.title_placeholder": "新列表的标题",
-  "lists.replies_policy.followed": "任何被关注的用户",
+  "lists.replies_policy.followed": "所有我关注的用户",
   "lists.replies_policy.list": "列表成员",
-  "lists.replies_policy.none": "无人",
+  "lists.replies_policy.none": "不显示",
   "lists.replies_policy.title": "显示回复:",
   "lists.search": "搜索你关注的人",
   "lists.subheading": "你的列表",
   "load_pending": "{count} 项",
   "loading_indicator.label": "加载中…",
   "media_gallery.hide": "隐藏",
-  "moved_to_account_banner.text": "您的账号 {disabledAccount} 已禁用,因为您已迁移到 {movedToAccount}。",
+  "moved_to_account_banner.text": "你的账号 {disabledAccount} 已禁用,因为你已迁移到 {movedToAccount}。",
   "mute_modal.hide_from_notifications": "从通知中隐藏",
   "mute_modal.hide_options": "隐藏选项",
   "mute_modal.indefinite": "直到我取消隐藏他们",
@@ -507,19 +507,19 @@
   "navigation_bar.filters": "忽略的关键词",
   "navigation_bar.follow_requests": "关注请求",
   "navigation_bar.followed_tags": "关注的话题标签",
-  "navigation_bar.follows_and_followers": "关注和粉丝",
+  "navigation_bar.follows_and_followers": "关注与关注者",
   "navigation_bar.lists": "列表",
   "navigation_bar.logout": "退出登录",
-  "navigation_bar.moderation": "运营",
+  "navigation_bar.moderation": "审核",
   "navigation_bar.mutes": "已隐藏的用户",
   "navigation_bar.opened_in_classic_interface": "嘟文、账户和其他特定页面默认在经典网页界面中打开。",
   "navigation_bar.personal": "个人",
   "navigation_bar.pins": "置顶嘟文",
-  "navigation_bar.preferences": "首选项",
+  "navigation_bar.preferences": "偏好设置",
   "navigation_bar.public_timeline": "跨站公共时间轴",
   "navigation_bar.search": "搜索",
   "navigation_bar.security": "安全",
-  "not_signed_in_indicator.not_signed_in": "您需要登录才能访问此资源。",
+  "not_signed_in_indicator.not_signed_in": "你需要登录才能访问此资源。",
   "notification.admin.report": "{name} 举报了 {target}",
   "notification.admin.report_account": "{name} 举报了来自 {target} 的 {count, plural, other {# 条嘟文}},原因为 {category}",
   "notification.admin.report_account_other": "{name} 举报了来自 {target} 的 {count, plural, other {# 条嘟文}}",
@@ -528,10 +528,10 @@
   "notification.admin.sign_up": "{name} 注册了",
   "notification.admin.sign_up.name_and_others": "{name} 和 {count, plural, other {另外 # 人}}注册了",
   "notification.annual_report.message": "你的 {year} #Wrapstodon 年度回顾来啦!快来看看这一年你在 Mastodon 上的精彩瞬间!",
-  "notification.annual_report.view": "查看 #Wrapstodon",
+  "notification.annual_report.view": "查看 #Wrapstodon 年度回顾",
   "notification.favourite": "{name} 喜欢了你的嘟文",
   "notification.favourite.name_and_others_with_link": "{name} 和 <a>{count, plural, other {另外 # 人}}</a> 喜欢了你的嘟文",
-  "notification.follow": "{name} 开始关注你",
+  "notification.follow": "{name} 关注了你",
   "notification.follow.name_and_others": "{name} 和 <a>{count, plural, other {另外 # 人}}</a> 关注了你",
   "notification.follow_request": "{name} 向你发送了关注请求",
   "notification.follow_request.name_and_others": "{name} 和 {count, plural, other {另外 # 人}} 向你发送了关注请求",
@@ -569,7 +569,7 @@
   "notification_requests.confirm_dismiss_multiple.button": "{count, plural, other {拒绝请求}}",
   "notification_requests.confirm_dismiss_multiple.message": "你将要拒绝 {count, plural, other {# 个通知请求}}。你将无法再轻易访问{count, plural, other {它们}}。是否继续?",
   "notification_requests.confirm_dismiss_multiple.title": "是否拒绝通知请求?",
-  "notification_requests.dismiss": "拒绝",
+  "notification_requests.dismiss": "忽略",
   "notification_requests.dismiss_multiple": "{count, plural, other {拒绝 # 个请求…}}",
   "notification_requests.edit_selection": "编辑",
   "notification_requests.exit_selection": "完成",
@@ -597,7 +597,7 @@
   "notifications.column_settings.push": "推送通知",
   "notifications.column_settings.reblog": "转嘟:",
   "notifications.column_settings.show": "在通知栏显示",
-  "notifications.column_settings.sound": "播放音效",
+  "notifications.column_settings.sound": "播放提示音",
   "notifications.column_settings.status": "新嘟文:",
   "notifications.column_settings.unread_notifications.category": "未读通知",
   "notifications.column_settings.unread_notifications.highlight": "高亮显示未读通知",
@@ -630,7 +630,7 @@
   "notifications.policy.filter_not_following_hint": "直到你手动批准",
   "notifications.policy.filter_not_following_title": "你没有关注的人",
   "notifications.policy.filter_private_mentions_hint": "过滤通知,除非通知是在回复提及你自己的内容,或发送者是你关注的人",
-  "notifications.policy.filter_private_mentions_title": "不请自来的提及",
+  "notifications.policy.filter_private_mentions_title": "不请自来的私下提及",
   "notifications.policy.title": "管理来自 … 的通知",
   "notifications_permission_banner.enable": "启用桌面通知",
   "notifications_permission_banner.how_to_control": "启用桌面通知以在 Mastodon 未打开时接收通知。你可以通过交互通过上面的 {icon} 按钮来精细控制可以发送桌面通知的交互类型。",
@@ -640,9 +640,9 @@
   "onboarding.actions.go_to_explore": "看看有什么新鲜事",
   "onboarding.actions.go_to_home": "转到主页动态",
   "onboarding.compose.template": "你好 #Mastodon!",
-  "onboarding.follows.empty": "很抱歉,现在无法显示任何结果。您可以尝试使用搜索或浏览探索页面来查找要关注的人,或稍后再试。",
+  "onboarding.follows.empty": "很抱歉,现在无法显示任何结果。你可以尝试使用搜索或浏览探索页面来查找要关注的人,或稍后再试。",
   "onboarding.follows.lead": "你管理你自己的家庭饲料。你关注的人越多,它将越活跃和有趣。 这些配置文件可能是一个很好的起点——你可以随时取消关注它们!",
-  "onboarding.follows.title": "定制您的主页动态",
+  "onboarding.follows.title": "定制你的主页动态",
   "onboarding.profile.discoverable": "让我的资料卡可被他人发现",
   "onboarding.profile.discoverable_hint": "当你选择在 Mastodon 上启用发现功能时,你的嘟文可能会出现在搜索结果和热门中,你的账户可能会被推荐给与你兴趣相似的人。",
   "onboarding.profile.display_name": "昵称",
@@ -653,28 +653,28 @@
   "onboarding.profile.save_and_continue": "保存并继续",
   "onboarding.profile.title": "设置个人资料",
   "onboarding.profile.upload_avatar": "上传头像",
-  "onboarding.profile.upload_header": "上传资料卡头图",
+  "onboarding.profile.upload_header": "上传个人资料背景横幅",
   "onboarding.share.lead": "让人们知道他们如何在Mastodon找到你!",
   "onboarding.share.message": "我是来自 #Mastodon 的 {username}!请在 {url} 关注我。",
   "onboarding.share.next_steps": "可能的下一步:",
   "onboarding.share.title": "分享你的个人资料",
-  "onboarding.start.lead": "你的新 Mastodon 帐户已准备好。下面是如何最大限度地利用它:",
+  "onboarding.start.lead": "你的新 Mastodon 账户已准备好。下面是如何最大限度地利用它:",
   "onboarding.start.skip": "想要在前面跳过吗?",
   "onboarding.start.title": "你已经成功了!",
   "onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.",
-  "onboarding.steps.follow_people.title": "定制您的主页动态",
+  "onboarding.steps.follow_people.title": "定制你的主页动态",
   "onboarding.steps.publish_status.body": "向世界问声好吧。",
   "onboarding.steps.publish_status.title": "发布你的第一篇嘟文",
   "onboarding.steps.setup_profile.body": "Others are more likely to interact with you with a filled out profile.",
   "onboarding.steps.setup_profile.title": "自定义你的个人资料",
-  "onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!",
+  "onboarding.steps.share_profile.body": "让你的朋友知道怎样在 Mastodon 找到你",
   "onboarding.steps.share_profile.title": "分享你的个人资料",
   "onboarding.tips.2fa": "<strong>你知道吗?</strong>你可以在账户设置中配置双因素认证来保护账户安全。可以使用你选择的任何 TOTP 应用,无需电话号码!",
   "onboarding.tips.accounts_from_other_servers": "<strong>你知道吗?</strong> 既然Mastodon是去中心化的,你所看到的一些账户将被托管在你以外的服务器上。 但你可以无缝地与他们交互!他们的服务器在他们的用户名的后半部分!",
-  "onboarding.tips.migration": "<strong>您知道吗?</strong> 如果你觉得你喜欢 {domain} 不是您未来的一个伟大的服务器选择。 您可以移动到另一个 Mastodon 服务器而不失去您的关注者。 您甚至可以主持您自己的服务器!",
-  "onboarding.tips.verification": "<strong>您知道吗?</strong> 您可以通过在自己的网站上放置一个链接到您的 Mastodon 个人资料并将网站添加到您的个人资料来验证您的帐户。 无需收费或文书工作!",
+  "onboarding.tips.migration": "<strong>你知道吗?</strong>如果你将来觉得 {domain} 不再符合您的需求,你可以在保留现有关注者的情况下迁移至其他 Mastodon 服务器。你甚至可以部署自己的服务器!",
+  "onboarding.tips.verification": "<strong>你知道吗?</strong> 你可以通过在自己的网站上放置一个链接到你的 Mastodon 个人资料并将网站添加到你的个人资料来验证你的账户。 无需收费或文书工作!",
   "password_confirmation.exceeds_maxlength": "密码确认超过最大密码长度",
-  "password_confirmation.mismatching": "密码确认不匹配",
+  "password_confirmation.mismatching": "确认密码与密码不一致。",
   "picture_in_picture.restore": "恢复",
   "poll.closed": "已关闭",
   "poll.refresh": "刷新",
@@ -687,9 +687,9 @@
   "poll_button.add_poll": "发起投票",
   "poll_button.remove_poll": "移除投票",
   "privacy.change": "设置嘟文的可见范围",
-  "privacy.direct.long": "帖子中提到的每个人",
+  "privacy.direct.long": "嘟文中提到的每个人",
   "privacy.direct.short": "特定的人",
-  "privacy.private.long": "仅限您的关注者",
+  "privacy.private.long": "仅限你的关注者",
   "privacy.private.short": "关注者",
   "privacy.public.long": "所有 Mastodon 内外的人",
   "privacy.public.short": "公开",
@@ -745,12 +745,12 @@
   "report.reasons.violation": "违反服务器规则",
   "report.reasons.violation_description": "你清楚它违反了特定的规则",
   "report.rules.subtitle": "选择所有适用选项",
-  "report.rules.title": "哪些规则被违反了?",
+  "report.rules.title": "违反了哪些规则?",
   "report.statuses.subtitle": "选择所有适用选项",
   "report.statuses.title": "是否有任何嘟文可以支持这一报告?",
   "report.submit": "提交",
   "report.target": "举报 {target}",
-  "report.thanks.take_action": "以下是您控制您在 Mastodon 上能看到哪些内容的选项:",
+  "report.thanks.take_action": "以下是你控制你在 Mastodon 上能看到哪些内容的选项:",
   "report.thanks.take_action_actionable": "在我们审阅这个问题时,你可以对 @{name} 采取行动",
   "report.thanks.title": "不想看到这个内容?",
   "report.thanks.title_actionable": "感谢提交举报,我们将会进行处理。",
@@ -780,7 +780,7 @@
   "search_popout.options": "搜索选项",
   "search_popout.quick_actions": "快捷操作",
   "search_popout.recent": "最近搜索",
-  "search_popout.specific_date": "指定日期",
+  "search_popout.specific_date": "具体日期",
   "search_popout.user": "用户",
   "search_results.accounts": "用户",
   "search_results.all": "全部",
@@ -789,7 +789,7 @@
   "search_results.see_all": "查看全部",
   "search_results.statuses": "嘟文",
   "search_results.title": "搜索 {q}",
-  "server_banner.about_active_users": "过去 30 天内使用此服务器的人(每月活跃用户)",
+  "server_banner.about_active_users": "过去 30 天内使用此服务器的人(月活跃用户)",
   "server_banner.active_users": "活跃用户",
   "server_banner.administered_by": "本站管理员:",
   "server_banner.is_one_of_many": "{domain} 是可用于参与联邦宇宙的众多独立 Mastodon 服务器之一。",
@@ -814,7 +814,7 @@
   "status.direct_indicator": "私下提及",
   "status.edit": "编辑",
   "status.edited": "最后编辑于 {date}",
-  "status.edited_x_times": "共编辑 {count, plural, one {{count} 次} other {{count} 次}}",
+  "status.edited_x_times": "共编辑 {count, plural, other {{count} 次}}",
   "status.embed": "获取嵌入代码",
   "status.favourite": "喜欢",
   "status.favourites": "{count, plural, other {次喜欢}}",
@@ -834,7 +834,7 @@
   "status.pinned": "置顶嘟文",
   "status.read_more": "查看更多",
   "status.reblog": "转嘟",
-  "status.reblog_private": "转嘟(可见者不变)",
+  "status.reblog_private": "以相同可见性转嘟",
   "status.reblogged_by": "{name} 转嘟了",
   "status.reblogs": "{count, plural, other {次转嘟}}",
   "status.reblogs.empty": "没有人转嘟过此条嘟文。如果有人转嘟了,就会显示在这里。",
@@ -856,7 +856,7 @@
   "status.uncached_media_warning": "预览不可用",
   "status.unmute_conversation": "恢复此对话的通知提醒",
   "status.unpin": "在个人资料页面取消置顶",
-  "subscribed_languages.lead": "更改此选择后,仅选定语言的嘟文会出现在您的主页和列表时间轴上。选择「无」将接收所有语言的嘟文。",
+  "subscribed_languages.lead": "更改此选择后,仅选定语言的嘟文会出现在你的主页和列表时间轴上。选择「无」将接收所有语言的嘟文。",
   "subscribed_languages.save": "保存更改",
   "subscribed_languages.target": "更改 {target} 的订阅语言",
   "tabs_bar.home": "主页",
@@ -886,7 +886,7 @@
   "upload_form.edit": "编辑",
   "upload_form.thumbnail": "更改缩略图",
   "upload_form.video_description": "为听障人士和视障人士添加文字描述",
-  "upload_modal.analyzing_picture": "分析图片…",
+  "upload_modal.analyzing_picture": "正在分析图片…",
   "upload_modal.apply": "应用",
   "upload_modal.applying": "正在应用…",
   "upload_modal.choose_image": "选择图像",
@@ -908,5 +908,5 @@
   "video.mute": "静音",
   "video.pause": "暂停",
   "video.play": "播放",
-  "video.unmute": "解除禁音"
+  "video.unmute": "取消静音"
 }
diff --git a/config/locales/activerecord.zh-CN.yml b/config/locales/activerecord.zh-CN.yml
index a4edf294a3..f620158361 100644
--- a/config/locales/activerecord.zh-CN.yml
+++ b/config/locales/activerecord.zh-CN.yml
@@ -49,16 +49,16 @@ zh-CN:
               blocked: 使用了被封禁的电子邮件提供商
               unreachable: 似乎不存在
             role_id:
-              elevated: 不能高于您当前的身份
+              elevated: 不能高于你现在的身份
         user_role:
           attributes:
             permissions_as_keys:
               dangerous: 包含对基本角色不安全的权限
-              elevated: 不能包含您当前身份未有的权限
-              own_role: 无法以您当前的身份更改
+              elevated: 不能包含你当前身份未有的权限
+              own_role: 无权以你当前的身份更改
             position:
-              elevated: 不能高于您当前的角色
-              own_role: 无法以您当前的身份更改
+              elevated: 不能高于你当前的角色
+              own_role: 无权以你当前的身份更改
         webhook:
           attributes:
             events:
diff --git a/config/locales/an.yml b/config/locales/an.yml
index 43f8d358cc..f941651438 100644
--- a/config/locales/an.yml
+++ b/config/locales/an.yml
@@ -723,7 +723,6 @@ an:
       original_status: Publicación orichinal
       reblogs: Impulsos
       status_changed: Publicación cambiada
-      title: Estau d'as cuentas - @%{name}
       trending: En tendencia
       visibility: Visibilidat
       with_media: Con multimedia
diff --git a/config/locales/ar.yml b/config/locales/ar.yml
index bbc481a137..832f60795f 100644
--- a/config/locales/ar.yml
+++ b/config/locales/ar.yml
@@ -847,7 +847,6 @@ ar:
       original_status: المنشور الأصلي
       reblogs: المعاد تدوينها
       status_changed: عُدّل المنشور
-      title: منشورات الحساب - @%{name}
       trending: المتداولة
       visibility: مدى الظهور
       with_media: تحتوي على وسائط
diff --git a/config/locales/be.yml b/config/locales/be.yml
index c59233eb8b..c97547b8b9 100644
--- a/config/locales/be.yml
+++ b/config/locales/be.yml
@@ -856,7 +856,6 @@ be:
       original_status: Зыходны допіс
       reblogs: Рэпосты
       status_changed: Допіс зменены
-      title: Допісы уліковага запісу - @%{name}
       trending: Папулярныя
       visibility: Бачнасць
       with_media: З медыя
diff --git a/config/locales/bg.yml b/config/locales/bg.yml
index 2c5edf0b13..5688a44f91 100644
--- a/config/locales/bg.yml
+++ b/config/locales/bg.yml
@@ -807,7 +807,6 @@ bg:
       original_status: Първообразна публикация
       reblogs: Блогване пак
       status_changed: Публикацията променена
-      title: Публикации на акаунта - @%{name}
       trending: Изгряващи
       visibility: Видимост
       with_media: С мултимедия
diff --git a/config/locales/br.yml b/config/locales/br.yml
index 098b20934f..fbe91fcbd7 100644
--- a/config/locales/br.yml
+++ b/config/locales/br.yml
@@ -263,7 +263,7 @@ br:
       original_status: Toud orin
       reblogs: Skignadennoù
       status_changed: Toud kemmet
-      title: Toudoù ar gont - @%{name}
+      status_title: Embannadenn gant @%{name}
       visibility: Gwelusted
       with_media: Gant mediaoù
     strikes:
diff --git a/config/locales/ca.yml b/config/locales/ca.yml
index 970fd99fff..b1af2d95d4 100644
--- a/config/locales/ca.yml
+++ b/config/locales/ca.yml
@@ -841,7 +841,6 @@ ca:
       original_status: Publicació original
       reblogs: Impulsos
       status_changed: Publicació canviada
-      title: Estats del compte - @%{name}
       trending: Tendència
       visibility: Visibilitat
       with_media: Amb contingut multimèdia
diff --git a/config/locales/ckb.yml b/config/locales/ckb.yml
index 6e1b11379c..cfee624e36 100644
--- a/config/locales/ckb.yml
+++ b/config/locales/ckb.yml
@@ -520,7 +520,6 @@ ckb:
       media:
         title: میدیا
       no_status_selected: هیچ دۆخیک نەگۆڕاوە وەک ئەوەی هیچ بارێک دەستنیشان نەکراوە
-      title: دۆخی ئەژمێر - @%{name}
       with_media: بە میدیا
     tags:
       review: پێداچوونەوەی دۆخ
diff --git a/config/locales/co.yml b/config/locales/co.yml
index b81427e833..39d9e9157e 100644
--- a/config/locales/co.yml
+++ b/config/locales/co.yml
@@ -459,7 +459,6 @@ co:
       media:
         title: Media
       no_status_selected: I statuti ùn sò micca stati mudificati perchè manc'unu era selezziunatu
-      title: Statuti di u contu - @%{name}
       with_media: Cù media
     system_checks:
       rules_check:
diff --git a/config/locales/cs.yml b/config/locales/cs.yml
index f5f7f4d731..19a6372224 100644
--- a/config/locales/cs.yml
+++ b/config/locales/cs.yml
@@ -826,7 +826,6 @@ cs:
       original_status: Původní příspěvek
       reblogs: Boosty
       status_changed: Příspěvek změněn
-      title: Příspěvky účtu - @%{name}
       trending: Populární
       visibility: Viditelnost
       with_media: S médii
diff --git a/config/locales/cy.yml b/config/locales/cy.yml
index f479f0f0a0..0daa793f97 100644
--- a/config/locales/cy.yml
+++ b/config/locales/cy.yml
@@ -897,7 +897,6 @@ cy:
       original_status: Postiad gwreiddiol
       reblogs: Ailflogiadau
       status_changed: Postiad wedi'i newid
-      title: Postiadau cyfrif - @%{name}
       trending: Yn trendio
       visibility: Gwelededd
       with_media: Gyda chyfryngau
diff --git a/config/locales/da.yml b/config/locales/da.yml
index e157af9cc2..3a82278b93 100644
--- a/config/locales/da.yml
+++ b/config/locales/da.yml
@@ -826,8 +826,10 @@ da:
       back_to_account: Retur til kontoside
       back_to_report: Retur til anmeldelsesside
       batch:
+        add_to_report: 'Føj til rapporten #%{id}'
         remove_from_report: Fjern fra anmeldelse
         report: Anmeldelse
+      contents: Indhold
       deleted: Slettet
       favourites: Favoritter
       history: Versionshistorik
@@ -836,13 +838,17 @@ da:
       media:
         title: Medier
       metadata: Metadata
+      no_history: Dette indlæg er ikke blevet redigeret
       no_status_selected: Ingen indlæg ændret (ingen valgt)
       open: Åbn indlæg
       original_status: Oprindeligt indlæg
       reblogs: Genblogninger
+      replied_to_html: Besvarede %{acct_link}
       status_changed: Indlæg ændret
+      status_title: Indlæg fra @%{name}
       title: Kontoindlæg - @%{name}
       trending: Populære
+      view_publicly: Vis offentligt
       visibility: Synlighed
       with_media: Med medier
     strikes:
diff --git a/config/locales/de.yml b/config/locales/de.yml
index e3ee03264e..26ccc8f3ee 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -427,9 +427,9 @@ de:
       not_permitted: Du bist nicht berechtigt, diese Aktion durchzuführen
       obfuscate: Domain-Name verschleiern
       obfuscate_hint: Den Domain-Namen öffentlich nur teilweise bekannt geben, sofern die Liste der Domain-Beschränkungen aktiviert ist
-      private_comment: Interne bzw. nicht-öffentliche Notiz
+      private_comment: Nicht-öffentliche Notiz
       private_comment_hint: Kommentar zu dieser Domain-Beschränkung für die interne Nutzung durch die Moderator*innen.
-      public_comment: Öffentliche Notiz
+      public_comment: Öffentliche Begründung
       public_comment_hint: Öffentlicher Hinweis zu dieser Domain-Beschränkung, sofern das Veröffentlichen von Sperrlisten grundsätzlich aktiviert ist.
       reject_media: Mediendateien ablehnen
       reject_media_hint: Entfernt lokal gespeicherte Mediendateien und verhindert deren künftiges Herunterladen. Für Sperren irrelevant
@@ -502,7 +502,7 @@ de:
       by_domain: Domain
       confirm_purge: Möchtest du die Daten von dieser Domain wirklich für immer löschen?
       content_policies:
-        comment: Interne Notiz
+        comment: Nicht-öffentliche Notiz
         description_html: Du kannst Inhaltsrichtlinien definieren, die auf alle Konten dieser Domain und einer ihrer Subdomains angewendet werden.
         limited_federation_mode_description_html: Du kannst auswählen, ob du eine Föderation mit dieser Domain erlaubst.
         policies:
@@ -826,8 +826,10 @@ de:
       back_to_account: Zurück zum Konto
       back_to_report: Zurück zur Seite mit den Meldungen
       batch:
+        add_to_report: Der Meldung Nr. %{id} hinzufügen
         remove_from_report: Von der Meldung entfernen
         report: Meldung
+      contents: Inhalte
       deleted: Gelöscht
       favourites: Favoriten
       history: Versionsverlauf
@@ -836,13 +838,17 @@ de:
       media:
         title: Medien
       metadata: Metadaten
+      no_history: Der Beitrag wurde nicht bearbeitet
       no_status_selected: Keine Beiträge wurden geändert, weil keine ausgewählt wurden
       open: Beitrag öffnen
       original_status: Ursprünglicher Beitrag
       reblogs: Geteilte Beiträge
+      replied_to_html: Antwortete %{acct_link}
       status_changed: Beitrag bearbeitet
-      title: Beiträge des Kontos - @%{name}
+      status_title: Beitrag von @%{name}
+      title: Beiträge des Kontos – @%{name}
       trending: Trends
+      view_publicly: Öffentlich anzeigen
       visibility: Sichtbarkeit
       with_media: Mit Medien
     strikes:
diff --git a/config/locales/devise.zh-CN.yml b/config/locales/devise.zh-CN.yml
index 86e78c1b18..1b5f364d08 100644
--- a/config/locales/devise.zh-CN.yml
+++ b/config/locales/devise.zh-CN.yml
@@ -9,7 +9,7 @@ zh-CN:
       already_authenticated: 你已登录。
       inactive: 你还没有激活账户。
       invalid: "%{authentication_keys} 无效或密码错误。"
-      last_attempt: 你只有最后一次尝试机会,若未通过,帐号将被锁定。
+      last_attempt: 你只有最后一次尝试机会,若未通过,账号将被锁定。
       locked: 你的账户已被锁定。
       not_found_in_database: "%{authentication_keys}或密码错误。"
       omniauth_user_creation_failure: 为此身份创建账户时出错。
@@ -33,7 +33,7 @@ zh-CN:
         title: 新邮箱地址
       password_change:
         explanation: 你的账户密码已更改。
-        extra: 如果你并没有申请更改密码,那似乎有人已经入侵你的帐户。请立即更改你的密码;如果你已经无法访问你的帐户,请联系服务器的管理员获取帮助。
+        extra: 如果你并没有申请更改密码,那似乎有人已经入侵你的账户。请立即更改你的密码;如果你已经无法访问你的账户,请联系服务器的管理员获取帮助。
         subject: Mastodon:密码已被更改
         title: 密码已被重置
       reconfirmation_instructions:
@@ -66,7 +66,7 @@ zh-CN:
         subject: Mastodon:账户解锁信息
       webauthn_credential:
         added:
-          explanation: 以下安全密钥已添加到你的帐户
+          explanation: 以下安全密钥已添加到你的账户
           subject: Mastodon:新的安全密钥
           title: 已添加一个新的安全密钥
         deleted:
diff --git a/config/locales/doorkeeper.ia.yml b/config/locales/doorkeeper.ia.yml
index 6bf5e38506..efde9be9c0 100644
--- a/config/locales/doorkeeper.ia.yml
+++ b/config/locales/doorkeeper.ia.yml
@@ -60,6 +60,7 @@ ia:
       error:
         title: Un error ha occurrite
       new:
+        prompt_html: "%{client_name} vole haber le permission de acceder a tu conto. <strong>Solmente approba iste requesta si tu recognosce e confide in iste fonte.</strong>"
         review_permissions: Revider permissiones
         title: Autorisation necessari
       show:
@@ -82,6 +83,7 @@ ia:
         access_denied: Le proprietario del ressource o servitor de autorisation ha refusate le requesta.
         credential_flow_not_configured: Le processo de credentiales de contrasigno del proprietario del ressource ha fallite perque Doorkeeper.configure.resource_owner_from_credentials non es configurate.
         invalid_client: Le authentication del cliente ha fallite perque le cliente es incognite, necun authentication de cliente es includite, o le methodo de authentication non es supportate.
+        invalid_code_challenge_method: Le methodo de defia de codice debe esser S256. Le methodo simple (plain) non es supportate.
         invalid_grant: Le concession de autorisation fornite es invalide, expirate, revocate, non corresponde al URI de redirection usate in le requesta de autorisation, o ha essite emittite a un altere cliente.
         invalid_redirect_uri: Le URI de redirection includite non es valide.
         invalid_request:
diff --git a/config/locales/doorkeeper.zh-CN.yml b/config/locales/doorkeeper.zh-CN.yml
index 08f9885894..848b0d6b6c 100644
--- a/config/locales/doorkeeper.zh-CN.yml
+++ b/config/locales/doorkeeper.zh-CN.yml
@@ -60,7 +60,7 @@ zh-CN:
       error:
         title: 发生错误
       new:
-        prompt_html: "%{client_name} 请求获得访问您账户的权限。 <strong>请在确保自己了解并信任此来源后再批准该请求。</strong>"
+        prompt_html: "%{client_name} 请求获得访问你账户的权限。 <strong>请在确保自己了解并信任此来源后再批准该请求。</strong>"
         review_permissions: 检查权限
         title: 需要授权
       show:
@@ -85,7 +85,7 @@ zh-CN:
         invalid_client: 由于应用信息未知、未提交认证信息或使用了不支持的认证方式,认证失败
         invalid_code_challenge_method: 代码验证方法必须是 S256,不支持明文。
         invalid_grant: 授权方式无效、过期或已被撤销、与授权请求中的回调地址不一致,或使用了其他应用的回调地址
-        invalid_redirect_uri: 无效的登录回调地址
+        invalid_redirect_uri: 登录回调地址无效。
         invalid_request:
           missing_param: 缺少必需的参数:%{value}
           request_not_authorized: 请求需要被授权。授权请求所需的参数缺失或无效。
@@ -123,14 +123,14 @@ zh-CN:
         admin/accounts: 账号管理
         admin/all: 所有管理功能
         admin/reports: 举报管理
-        all: 完全访问您的Mastodon账户
+        all: 完全访问你的Mastodon账户
         blocks: 屏蔽
         bookmarks: 书签
         conversations: 会话
         crypto: 端到端加密
         favourites: 喜欢
         filters: 过滤器
-        follow: 关注者,隐藏与屏蔽
+        follow: 关注,隐藏与屏蔽
         follows: 关注
         lists: 列表
         media: 媒体文件
@@ -163,7 +163,7 @@ zh-CN:
       admin:write:domain_allows: 在域上执行管理操作
       admin:write:domain_blocks: 在域块上执行管理操作
       admin:write:email_domain_blocks: 对已屏蔽邮箱域名执行管理操作
-      admin:write:ip_blocks: 在 IP 块上执行管理操作
+      admin:write:ip_blocks: 针对 IP 段执行管理操作
       admin:write:reports: 对举报执行管理操作
       crypto: 使用端到端加密
       follow: 关注或屏蔽用户
diff --git a/config/locales/el.yml b/config/locales/el.yml
index 26b0ec00a2..98ef5f18b7 100644
--- a/config/locales/el.yml
+++ b/config/locales/el.yml
@@ -817,7 +817,6 @@ el:
       original_status: Αρχική ανάρτηση
       reblogs: Αναδημοσιεύσεις
       status_changed: Η ανάρτηση άλλαξε
-      title: Καταστάσεις λογαριασμού - @%{name}
       trending: Τάσεις
       visibility: Ορατότητα
       with_media: Με πολυμέσα
diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml
index e22ed62051..76a16aa9db 100644
--- a/config/locales/en-GB.yml
+++ b/config/locales/en-GB.yml
@@ -832,7 +832,6 @@ en-GB:
       original_status: Original post
       reblogs: Reblogs
       status_changed: Post changed
-      title: Account posts - @%{name}
       trending: Trending
       visibility: Visibility
       with_media: With media
diff --git a/config/locales/eo.yml b/config/locales/eo.yml
index 194b2c17b8..120df142b7 100644
--- a/config/locales/eo.yml
+++ b/config/locales/eo.yml
@@ -830,7 +830,6 @@ eo:
       original_status: Originala afiŝo
       reblogs: Reblogaĵoj
       status_changed: Afiŝo ŝanĝiĝis
-      title: Afiŝoj de la konto - @%{name}
       trending: Popularaĵoj
       visibility: Videbleco
       with_media: Kun aŭdovidaĵoj
diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml
index 6dc9d99f37..09163c2e4a 100644
--- a/config/locales/es-AR.yml
+++ b/config/locales/es-AR.yml
@@ -187,6 +187,7 @@ es-AR:
         create_domain_block: Crear bloqueo de dominio
         create_email_domain_block: Crear bloqueo de dominio de correo electrónico
         create_ip_block: Crear regla de dirección IP
+        create_relay: Crear Relé
         create_unavailable_domain: Crear dominio no disponible
         create_user_role: Crear rol
         demote_user: Descender usuario
@@ -198,14 +199,17 @@ es-AR:
         destroy_email_domain_block: Eliminar bloqueo de dominio de correo electrónico
         destroy_instance: Purgar dominio
         destroy_ip_block: Eliminar regla de dirección IP
+        destroy_relay: Eliminar Relé
         destroy_status: Eliminar mensaje
         destroy_unavailable_domain: Eliminar dominio no disponible
         destroy_user_role: Destruir rol
         disable_2fa_user: Deshabilitar 2FA
         disable_custom_emoji: Deshabilitar emoji personalizado
+        disable_relay: Desactivar Relé
         disable_sign_in_token_auth_user: Deshabilitar autenticación de token por correo electrónico para el usuario
         disable_user: Deshabilitar usuario
         enable_custom_emoji: Habilitar emoji personalizado
+        enable_relay: Activar Relé
         enable_sign_in_token_auth_user: Habilitar autenticación de token por correo electrónico para el usuario
         enable_user: Habilitar usuario
         memorialize_account: Convertir en cuenta conmemorativa
@@ -247,6 +251,7 @@ es-AR:
         create_domain_block_html: "%{name} bloqueó el dominio %{target}"
         create_email_domain_block_html: "%{name} bloqueó el dominio de correo electrónico %{target}"
         create_ip_block_html: "%{name} creó la regla para la dirección IP %{target}"
+        create_relay_html: "%{name} creó un relé %{target}"
         create_unavailable_domain_html: "%{name} detuvo la entrega al dominio %{target}"
         create_user_role_html: "%{name} creó el rol %{target}"
         demote_user_html: "%{name} bajó de nivel al usuario %{target}"
@@ -258,14 +263,17 @@ es-AR:
         destroy_email_domain_block_html: "%{name} desbloqueó el dominio de correo electrónico %{target}"
         destroy_instance_html: "%{name} purgó el dominio %{target}"
         destroy_ip_block_html: "%{name} eliminó la regla para la dirección IP %{target}"
+        destroy_relay_html: "%{name} eliminó el relé %{target}"
         destroy_status_html: "%{name} eliminó el mensaje de %{target}"
         destroy_unavailable_domain_html: "%{name} reanudó la entrega al dominio %{target}"
         destroy_user_role_html: "%{name} eliminó el rol %{target}"
         disable_2fa_user_html: "%{name} deshabilitó el requerimiento de dos factores para el usuario %{target}"
         disable_custom_emoji_html: "%{name} deshabilitó el emoji %{target}"
+        disable_relay_html: "%{name} desactivó el relé %{target}"
         disable_sign_in_token_auth_user_html: "%{name} deshabilitó la autenticación de token por correo electrónico para %{target}"
         disable_user_html: "%{name} deshabilitó el inicio de sesión para el usuario %{target}"
         enable_custom_emoji_html: "%{name} habilitó el emoji %{target}"
+        enable_relay_html: "%{name} activó el relé %{target}"
         enable_sign_in_token_auth_user_html: "%{name} habilitó la autenticación de token por correo electrónico para %{target}"
         enable_user_html: "%{name} habilitó el inicio de sesión para el usuario %{target}"
         memorialize_account_html: "%{name} convirtió la cuenta de %{target} en una cuenta conmemorativa"
@@ -818,8 +826,10 @@ es-AR:
       back_to_account: Volver a la página de la cuenta
       back_to_report: Volver a la página de la denuncia
       batch:
+        add_to_report: 'Añadir al informe #%{id}'
         remove_from_report: Quitar de la denuncia
         report: Denunciar
+      contents: Contenidos
       deleted: Eliminado
       favourites: Favoritos
       history: Historial de versiones
@@ -828,13 +838,17 @@ es-AR:
       media:
         title: Medios
       metadata: Metadatos
+      no_history: Esta publicación no ha sido editada
       no_status_selected: No se cambió ningún mensaje, ya que ninguno fue seleccionado
       open: Abrir mensaje
       original_status: Mensaje original
       reblogs: Adhesiones
+      replied_to_html: Respondió a %{acct_link}
       status_changed: Mensaje cambiado
-      title: Mensajes de la cuenta - @%{name}
+      status_title: Publicación de @%{name}
+      title: Publicaciones de la cuenta - @%{name}
       trending: En tendencia
+      view_publicly: Ver públicamente
       visibility: Visibilidad
       with_media: Con medios
     strikes:
diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml
index 7e6570f068..53557c091a 100644
--- a/config/locales/es-MX.yml
+++ b/config/locales/es-MX.yml
@@ -187,6 +187,7 @@ es-MX:
         create_domain_block: Crear Bloqueo de Dominio
         create_email_domain_block: Crear bloqueo de dominio de correo electrónico
         create_ip_block: Crear regla IP
+        create_relay: Crear Relé
         create_unavailable_domain: Crear Dominio No Disponible
         create_user_role: Crear rol
         demote_user: Degradar Usuario
@@ -198,14 +199,17 @@ es-MX:
         destroy_email_domain_block: Eliminar bloqueo de dominio de correo electrónico
         destroy_instance: Purgar dominio
         destroy_ip_block: Eliminar regla IP
+        destroy_relay: Eliminar Relé
         destroy_status: Eliminar Estado
         destroy_unavailable_domain: Eliminar Dominio No Disponible
         destroy_user_role: Destruir Rol
         disable_2fa_user: Deshabilitar 2FA
         disable_custom_emoji: Deshabilitar Emoji Personalizado
+        disable_relay: Desactivar Relé
         disable_sign_in_token_auth_user: Deshabilitar la autenticación por token de correo electrónico para el usuario
         disable_user: Deshabilitar Usuario
         enable_custom_emoji: Habilitar Emoji Personalizado
+        enable_relay: Activar Relé
         enable_sign_in_token_auth_user: Habilitar la autenticación por token de correo electrónico para el usuario
         enable_user: Habilitar Usuario
         memorialize_account: Transformar en Cuenta Conmemorativa
@@ -247,6 +251,7 @@ es-MX:
         create_domain_block_html: "%{name} bloqueó el dominio %{target}"
         create_email_domain_block_html: "%{name} bloqueó el dominio de correo electrónico %{target}"
         create_ip_block_html: "%{name} creó una regla para la IP %{target}"
+        create_relay_html: "%{name} creó un relé %{target}"
         create_unavailable_domain_html: "%{name} detuvo las entregas al dominio %{target}"
         create_user_role_html: "%{name} creó el rol %{target}"
         demote_user_html: "%{name} degradó al usuario %{target}"
@@ -258,14 +263,17 @@ es-MX:
         destroy_email_domain_block_html: "%{name} desbloqueó el dominio de correo electrónico %{target}"
         destroy_instance_html: "%{name} purgó el dominio %{target}"
         destroy_ip_block_html: "%{name} eliminó una regla para la IP %{target}"
+        destroy_relay_html: "%{name} eliminó el relé %{target}"
         destroy_status_html: "%{name} eliminó el estado por %{target}"
         destroy_unavailable_domain_html: "%{name} reanudó las entregas al dominio %{target}"
         destroy_user_role_html: "%{name} eliminó el rol %{target}"
         disable_2fa_user_html: "%{name} desactivó el requisito de dos factores para el usuario %{target}"
         disable_custom_emoji_html: "%{name} desactivó el emoji %{target}"
+        disable_relay_html: "%{name} desactivó el relé %{target}"
         disable_sign_in_token_auth_user_html: "%{name} desactivó la autenticación por token de correo electrónico para %{target}"
         disable_user_html: "%{name} deshabilitó el inicio de sesión para el usuario %{target}"
         enable_custom_emoji_html: "%{name} activó el emoji %{target}"
+        enable_relay_html: "%{name} activó el relé %{target}"
         enable_sign_in_token_auth_user_html: "%{name} activó autenticación por token de correo electrónico para %{target}"
         enable_user_html: "%{name} habilitó el inicio de sesión para el usuario %{target}"
         memorialize_account_html: "%{name} convirtió la cuenta de %{target} en una página in memoriam"
@@ -818,8 +826,10 @@ es-MX:
       back_to_account: Volver a la cuenta
       back_to_report: Volver a la página de reporte
       batch:
+        add_to_report: 'Añadir al informe #%{id}'
         remove_from_report: Eliminar del reporte
         report: Reportar
+      contents: Contenidos
       deleted: Eliminado
       favourites: Favoritos
       history: Historial de versiones
@@ -828,13 +838,17 @@ es-MX:
       media:
         title: Multimedia
       metadata: Metadatos
+      no_history: Esta publicación no ha sido editada
       no_status_selected: No se cambió ningún estado al no seleccionar ninguno
       open: Abrir publicación
       original_status: Publicación original
       reblogs: Impulsos
+      replied_to_html: Respondió a %{acct_link}
       status_changed: Publicación cambiada
-      title: Estado de las cuentas - @%{name}
+      status_title: Publicación de @%{name}
+      title: Publicaciones de la cuenta - @%{name}
       trending: En tendencia
+      view_publicly: Ver públicamente
       visibility: Visibilidad
       with_media: Con multimedia
     strikes:
diff --git a/config/locales/es.yml b/config/locales/es.yml
index 32abd9420d..22123e4309 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -57,7 +57,7 @@ es:
       confirming: Confirmando
       custom: Personalizado
       delete: Eliminar datos
-      deleted: Borrado
+      deleted: Eliminado
       demote: Degradar
       destroyed_msg: Los datos de %{username} están ahora en cola para ser eliminados inminentemente
       disable: Deshabilitar
@@ -116,7 +116,7 @@ es:
       protocol: Protocolo
       public: Público
       push_subscription_expires: Expiración de la suscripción PuSH
-      redownload: Refrescar avatar
+      redownload: Refrescar perfil
       redownloaded_msg: Se actualizó correctamente el perfil de %{username} desde el origen
       reject: Rechazar
       rejected_msg: La solicitud de registro de %{username} ha sido rechazada con éxito
@@ -187,6 +187,7 @@ es:
         create_domain_block: Crear Bloqueo de Dominio
         create_email_domain_block: Crear Bloqueo de Dominio de Correo Electrónico
         create_ip_block: Crear regla IP
+        create_relay: Crear Relé
         create_unavailable_domain: Crear Dominio No Disponible
         create_user_role: Crear Rol
         demote_user: Degradar Usuario
@@ -198,14 +199,17 @@ es:
         destroy_email_domain_block: Eliminar Bloqueo de Dominio de Correo Electrónico
         destroy_instance: Purgar Dominio
         destroy_ip_block: Eliminar regla IP
+        destroy_relay: Eliminar Relé
         destroy_status: Eliminar Publicación
         destroy_unavailable_domain: Eliminar Dominio No Disponible
         destroy_user_role: Destruir Rol
         disable_2fa_user: Deshabilitar 2FA
         disable_custom_emoji: Deshabilitar Emoji Personalizado
+        disable_relay: Desactivar Relé
         disable_sign_in_token_auth_user: Deshabilitar la Autenticación por Token de Correo Electrónico para el Usuario
         disable_user: Deshabilitar Usuario
         enable_custom_emoji: Habilitar Emoji Personalizado
+        enable_relay: Activar Relé
         enable_sign_in_token_auth_user: Habilitar la Autenticación por Token de Correo Electrónico para el Usuario
         enable_user: Habilitar Usuario
         memorialize_account: Transformar en Cuenta Conmemorativa
@@ -247,6 +251,7 @@ es:
         create_domain_block_html: "%{name} bloqueó el dominio %{target}"
         create_email_domain_block_html: "%{name} bloqueó el dominio de correo electrónico %{target}"
         create_ip_block_html: "%{name} creó una regla para la IP %{target}"
+        create_relay_html: "%{name} creó un relé %{target}"
         create_unavailable_domain_html: "%{name} detuvo las entregas al dominio %{target}"
         create_user_role_html: "%{name} creó el rol %{target}"
         demote_user_html: "%{name} degradó al usuario %{target}"
@@ -258,14 +263,17 @@ es:
         destroy_email_domain_block_html: "%{name} desbloqueó el dominio de correo electrónico %{target}"
         destroy_instance_html: "%{name} purgó el dominio %{target}"
         destroy_ip_block_html: "%{name} eliminó una regla para la IP %{target}"
+        destroy_relay_html: "%{name} eliminó el relé %{target}"
         destroy_status_html: "%{name} eliminó la publicación de %{target}"
         destroy_unavailable_domain_html: "%{name} reanudó las entregas al dominio %{target}"
         destroy_user_role_html: "%{name} eliminó el rol %{target}"
         disable_2fa_user_html: "%{name} desactivó el requisito de dos factores para el usuario %{target}"
         disable_custom_emoji_html: "%{name} desactivó el emoji %{target}"
+        disable_relay_html: "%{name} desactivó el relé %{target}"
         disable_sign_in_token_auth_user_html: "%{name} ha deshabilitado la autenticación por token de correo electrónico para %{target}"
         disable_user_html: "%{name} deshabilitó el inicio de sesión para el usuario %{target}"
         enable_custom_emoji_html: "%{name} activó el emoji %{target}"
+        enable_relay_html: "%{name} activó el relé %{target}"
         enable_sign_in_token_auth_user_html: "%{name} ha habilitado la autenticación por token de correo electrónico para %{target}"
         enable_user_html: "%{name} habilitó el inicio de sesión para el usuario %{target}"
         memorialize_account_html: "%{name} convirtió la cuenta de %{target} en una página in memoriam"
@@ -566,7 +574,7 @@ es:
         '94670856': 3 años
       new:
         title: Crear nueva regla IP
-      no_ip_block_selected: No se han cambiado reglas IP ya que no se ha seleccionado ninguna
+      no_ip_block_selected: No se han cambiado reglas IP, ya que no se ha seleccionado ninguna
       title: Reglas IP
     relationships:
       title: Relaciones de %{acct}
@@ -818,8 +826,10 @@ es:
       back_to_account: Volver a la cuenta
       back_to_report: Volver a la página del reporte
       batch:
+        add_to_report: 'Añadir al informe #%{id}'
         remove_from_report: Eliminar del reporte
         report: Reporte
+      contents: Contenidos
       deleted: Eliminado
       favourites: Favoritos
       history: Historial de versiones
@@ -828,13 +838,17 @@ es:
       media:
         title: Multimedia
       metadata: Metadatos
+      no_history: Esta publicación no ha sido editada
       no_status_selected: No se cambió ninguna publicación al no seleccionar ninguna
       open: Abrir publicación
       original_status: Publicación original
       reblogs: Impulsos
+      replied_to_html: Respondió a %{acct_link}
       status_changed: Publicación cambiada
+      status_title: Publicación de @%{name}
       title: Publicaciones de la cuenta - @%{name}
       trending: En tendencia
+      view_publicly: Ver públicamente
       visibility: Visibilidad
       with_media: Con multimedia
     strikes:
@@ -910,7 +924,7 @@ es:
       review: Estado de revisión
       search: Buscar
       title: Etiquetas
-      updated_msg: Hashtags actualizados exitosamente
+      updated_msg: La configuración de etiquetas se actualizó correctamente
     title: Administración
     trends:
       allow: Permitir
@@ -1109,7 +1123,7 @@ es:
     didnt_get_confirmation: "¿No recibiste un enlace de confirmación?"
     dont_have_your_security_key: "¿No tienes tu clave de seguridad?"
     forgot_password: "¿Olvidaste tu contraseña?"
-    invalid_reset_password_token: El token de reinicio de contraseña es inválido o expiró. Por favor pide uno nuevo.
+    invalid_reset_password_token: El token de restablecimiento de contraseña no es válido o ha expirado. Por favor solicita uno nuevo.
     link_to_otp: Introduce un código de dos factores desde tu teléfono o un código de recuperación
     link_to_webauth: Utilice su dispositivo de clave de seguridad
     log_in_with: Iniciar sesión con
@@ -1258,7 +1272,7 @@ es:
     '422':
       content: Verificación de seguridad fallida. ¿Estás bloqueando algunas cookies?
       title: Verificación de seguridad fallida
-    '429': Asfixiado
+    '429': Demasiadas solicitudes
     '500':
       content: Lo sentimos, algo ha funcionado mal por nuestra parte.
       title: Esta página no es correcta
@@ -1446,7 +1460,7 @@ es:
       '604800': 1 semana
       '86400': 1 día
     expires_in_prompt: Nunca
-    generate: Generar
+    generate: Generar enlace de invitación
     invalid: Esta invitación no es válida
     invited_by: 'Fuiste invitado por:'
     max_uses:
@@ -1489,12 +1503,12 @@ es:
       title: Cancelar suscripición
   media_attachments:
     validations:
-      images_and_video: No se puede adjuntar un video a unapublicación que ya contenga imágenes
+      images_and_video: No se puede adjuntar un video a una publicación que ya contenga imágenes
       not_found: Archivos multimedia %{ids} no encontrados, o ya se encuentran adjuntos a otra publicación
       not_ready: No se pueden adjuntar archivos que no se han terminado de procesar. ¡Inténtalo de nuevo en un momento!
       too_many: No se pueden adjuntar más de 4 archivos
   migrations:
-    acct: username@domain de la nueva cuenta
+    acct: Movido a
     cancel: Cancelar redireccionamiento
     cancel_explanation: Al cancelar el redireccionamiento se reactivará tu cuenta actual, pero no recuperarás los seguidores que hayan sido trasladados a la otra cuenta.
     cancelled_msg: El redireccionamiento se ha cancelado correctamente.
@@ -1729,7 +1743,7 @@ es:
     migrate: Migración de cuenta
     notifications: Notificaciones por correo electrónico
     preferences: Preferencias
-    profile: Perfil
+    profile: Perfil público
     relationships: Siguiendo y seguidores
     severed_relationships: Relaciones cortadas
     statuses_cleanup: Eliminación automática de publicaciones
@@ -1773,11 +1787,11 @@ es:
       direct: Las publicaciones que son visibles solo para los usuarios mencionados no pueden fijarse
       limit: Ya has fijado el número máximo de publicaciones
       ownership: La publicación de otra persona no puede fijarse
-      reblog: Un boost no puede fijarse
+      reblog: Una publicación impulsada no puede fijarse
     title: "%{name}: «%{quote}»"
     visibilities:
       direct: Directa
-      private: Sólo mostrar a seguidores
+      private: Solo seguidores
       private_long: Solo mostrar a tus seguidores
       public: Pública
       public_long: Todos pueden ver
@@ -1826,8 +1840,8 @@ es:
   tags:
     does_not_match_previous_name: no coincide con el nombre anterior
   themes:
-    contrast: Alto contraste
-    default: Mastodon
+    contrast: Mastodon (alto contraste)
+    default: Mastodon (oscuro)
     mastodon-light: Mastodon (claro)
     system: Automático (usar tema del sistema)
   time:
@@ -1847,7 +1861,7 @@ es:
     edit: Editar
     enabled: La autenticación de dos factores está activada
     enabled_success: Verificación de dos factores activada exitosamente
-    generate_recovery_codes: generar códigos de recuperación
+    generate_recovery_codes: Generar códigos de recuperación
     lost_recovery_codes: Los códigos de recuperación te permiten obtener acceso a tu cuenta si pierdes tu teléfono. Si has perdido tus códigos de recuperación, puedes regenerarlos aquí. Tus viejos códigos de recuperación se harán inválidos.
     methods: Métodos de autenticación de doble factor
     otp: Aplicación de autenticación
diff --git a/config/locales/et.yml b/config/locales/et.yml
index f8a4f7f69e..40db2eede0 100644
--- a/config/locales/et.yml
+++ b/config/locales/et.yml
@@ -833,7 +833,6 @@ et:
       original_status: Algne postitus
       reblogs: Jagamised
       status_changed: Muudetud postitus
-      title: Konto postitused - @%{name}
       trending: Populaarne
       visibility: Nähtavus
       with_media: Meediaga
diff --git a/config/locales/eu.yml b/config/locales/eu.yml
index a764e88bac..dc064ebc7b 100644
--- a/config/locales/eu.yml
+++ b/config/locales/eu.yml
@@ -793,7 +793,6 @@ eu:
       original_status: Jatorrizko bidalketa
       reblogs: Bultzadak
       status_changed: Bidalketa aldatuta
-      title: Kontuaren bidalketak - @%{name}
       trending: Joera
       visibility: Ikusgaitasuna
       with_media: Multimediarekin
diff --git a/config/locales/fa.yml b/config/locales/fa.yml
index 38daf70d29..7cb0714c28 100644
--- a/config/locales/fa.yml
+++ b/config/locales/fa.yml
@@ -741,7 +741,6 @@ fa:
       original_status: فرستهٔ اصلی
       reblogs: تقویت‌ها
       status_changed: فرسته تغییر کرد
-      title: "@%{name} - نوشته‌های حساب"
       trending: پرطرفدار
       visibility: نمایانی
       with_media: دارای عکس یا ویدیو
diff --git a/config/locales/fi.yml b/config/locales/fi.yml
index efdfdfed04..d7755d23b8 100644
--- a/config/locales/fi.yml
+++ b/config/locales/fi.yml
@@ -826,8 +826,10 @@ fi:
       back_to_account: Takaisin tilin sivulle
       back_to_report: Takaisin raporttisivulle
       batch:
+        add_to_report: Lisää raporttiin nro %{id}
         remove_from_report: Poista raportista
         report: Raportti
+      contents: Sisältö
       deleted: Poistettu
       favourites: Suosikit
       history: Versiohistoria
@@ -836,13 +838,17 @@ fi:
       media:
         title: Media
       metadata: Metadata
+      no_history: Tätä julkaisua ei ole muokattu
       no_status_selected: Julkaisuja ei muutettu, koska yhtään ei ollut valittuna
       open: Avaa julkaisu
       original_status: Alkuperäinen julkaisu
       reblogs: Edelleen jako
+      replied_to_html: Vastaus käyttäjälle %{acct_link}
       status_changed: Julkaisua muutettu
-      title: Tilin tilat - @%{name}
+      status_title: Julkaisu käyttäjältä @%{name}
+      title: Tilin julkaisut - @%{name}
       trending: Suosituttua
+      view_publicly: Näytä julkisesti
       visibility: Näkyvyys
       with_media: Sisältää mediaa
     strikes:
diff --git a/config/locales/fo.yml b/config/locales/fo.yml
index 8dab61c267..502c027b5d 100644
--- a/config/locales/fo.yml
+++ b/config/locales/fo.yml
@@ -826,8 +826,10 @@ fo:
       back_to_account: Aftur til kontusíðu
       back_to_report: Aftur til meldingarsíðu
       batch:
+        add_to_report: 'Legg afturat melding #%{id}'
         remove_from_report: Strika frá melding
         report: Melding
+      contents: Innihald
       deleted: Strikað
       favourites: Dámdir postar
       history: Útgávusøga
@@ -836,13 +838,17 @@ fo:
       media:
         title: Miðlar
       metadata: Metadátur
+      no_history: Hesin posturin er ikki broyttur
       no_status_selected: Eingir postar vóru broyttir, tí eingir vóru valdir
       open: Lat post upp
       original_status: Upprunapostur
       reblogs: Endurbloggar
+      replied_to_html: Svaraði %{acct_link}
       status_changed: Postur broyttur
-      title: Postar hjá kontu - @%{name}
+      status_title: Postar hjá @%{name}
+      title: Kontupostar - @%{name}
       trending: Vælumtókt
+      view_publicly: Vís fyri øllum
       visibility: Sýni
       with_media: Við miðli
     strikes:
diff --git a/config/locales/fr-CA.yml b/config/locales/fr-CA.yml
index bb0501d0e3..9c2bf3398e 100644
--- a/config/locales/fr-CA.yml
+++ b/config/locales/fr-CA.yml
@@ -836,7 +836,6 @@ fr-CA:
       original_status: Message original
       reblogs: Partages
       status_changed: Publication modifiée
-      title: Messages du compte - @%{name}
       trending: Tendances
       visibility: Visibilité
       with_media: Avec médias
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index 0c35dea62a..650147eb5d 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -836,7 +836,6 @@ fr:
       original_status: Message original
       reblogs: Partages
       status_changed: Publication modifiée
-      title: Messages du compte - @%{name}
       trending: Tendances
       visibility: Visibilité
       with_media: Avec médias
diff --git a/config/locales/fy.yml b/config/locales/fy.yml
index 8a4f519e0c..24be51d9d7 100644
--- a/config/locales/fy.yml
+++ b/config/locales/fy.yml
@@ -833,7 +833,6 @@ fy:
       original_status: Oarspronklik berjocht
       reblogs: Boosts
       status_changed: Berjocht wizige
-      title: Accountberjochten - @%{name}
       trending: Trending
       visibility: Sichtberheid
       with_media: Mei media
diff --git a/config/locales/ga.yml b/config/locales/ga.yml
index 67461f3c2a..deb9986691 100644
--- a/config/locales/ga.yml
+++ b/config/locales/ga.yml
@@ -196,6 +196,7 @@ ga:
         create_domain_block: Cruthaigh Bloc Fearainn
         create_email_domain_block: Cruthaigh Bloc Fearainn Ríomhphoist
         create_ip_block: Cruthaigh riail IP
+        create_relay: Cruthaigh Leaschraolacháin
         create_unavailable_domain: Cruthaigh Fearann ​​Gan Fáil
         create_user_role: Cruthaigh Ról
         demote_user: Ísligh úsáideoir
@@ -207,14 +208,17 @@ ga:
         destroy_email_domain_block: Scrios Bloc Fearainn Ríomhphoist
         destroy_instance: Fearann ​​Purge
         destroy_ip_block: Scrios riail IP
+        destroy_relay: Scrios Leaschraolacháin
         destroy_status: Scrios Postáil
         destroy_unavailable_domain: Scrios Fearann ​​Gan Fáil
         destroy_user_role: Scrios ról
         disable_2fa_user: Díchumasaigh 2FA
         disable_custom_emoji: Díchumasaigh Emoji Saincheaptha
+        disable_relay: Díchumasaigh Leaschraolacháin
         disable_sign_in_token_auth_user: Díchumasaigh Fíordheimhniú Comhartha Ríomhphoist don Úsáideoir
         disable_user: Díchumasaigh Úsáideoir
         enable_custom_emoji: Cumasaigh Emoji Saincheaptha
+        enable_relay: Cumasaigh Leaschraolacháin
         enable_sign_in_token_auth_user: Cumasaigh Fíordheimhniú Comhartha Ríomhphoist don Úsáideoir
         enable_user: Cumasaigh Úsáideoir
         memorialize_account: Cuntas Cuimhneacháin
@@ -256,6 +260,7 @@ ga:
         create_domain_block_html: "%{name} fearann ​​bactha %{target}"
         create_email_domain_block_html: Chuir %{name} fearann ​​ríomhphoist bactha %{target}
         create_ip_block_html: Chruthaigh %{name} riail don IP %{target}
+        create_relay_html: Chruthaigh %{name} athsheoladh %{target}
         create_unavailable_domain_html: Chuir %{name} deireadh leis an seachadadh chuig fearann ​​%{target}
         create_user_role_html: Chruthaigh %{name} %{target} ról
         demote_user_html: "%{name} úsáideoir scriosta %{target}"
@@ -267,14 +272,17 @@ ga:
         destroy_email_domain_block_html: "%{name} fearann ​​ríomhphoist díchoiscthe %{target}"
         destroy_instance_html: Glanadh %{name} fearann ​​%{target}
         destroy_ip_block_html: "%{name} scriosta riail le haghaidh IP %{target}"
+        destroy_relay_html: Scrios %{name} an athsheoladh %{target}
         destroy_status_html: Bhain %{name} postáil le %{target}
         destroy_unavailable_domain_html: D'athchrom %{name} ar an seachadadh chuig fearann ​​%{target}
         destroy_user_role_html: Scrios %{name} ról %{target}
         disable_2fa_user_html: Dhíchumasaigh %{name} riachtanas dhá fhachtóir don úsáideoir %{target}
         disable_custom_emoji_html: Dhíchumasaigh %{name} emoji %{target}
+        disable_relay_html: Dhíchumasaigh %{name} an athsheoladh %{target}
         disable_sign_in_token_auth_user_html: Dhíchumasaigh %{name} fíordheimhniú comhartha ríomhphoist le haghaidh %{target}
         disable_user_html: "%{name} logáil isteach díchumasaithe d'úsáideoir %{target}"
         enable_custom_emoji_html: "%{name} emoji cumasaithe %{target}"
+        enable_relay_html: Chuir %{name} an sealaíocht %{target} ar chumas
         enable_sign_in_token_auth_user_html: Chuir %{name} fíordheimhniú comhartha ríomhphoist ar chumas %{target}
         enable_user_html: "%{name} logáil isteach cumasaithe don úsáideoir %{target}"
         memorialize_account_html: Rinne %{name} cuntas %{target} a iompú ina leathanach cuimhneacháin
@@ -860,8 +868,10 @@ ga:
       back_to_account: Ar ais go leathanach cuntais
       back_to_report: Ar ais go leathanach tuairisce
       batch:
+        add_to_report: 'Cuir leis an tuairisc # %{id}'
         remove_from_report: Bain den tuairisc
         report: Tuairisc
+      contents: Ábhar
       deleted: Scriosta
       favourites: Toghanna
       history: Stair leagan
@@ -870,13 +880,17 @@ ga:
       media:
         title: Meáin
       metadata: Meiteashonraí
+      no_history: Níl an postáil seo curtha in eagar
       no_status_selected: Níor athraíodh aon phostáil mar níor roghnaíodh ceann ar bith
       open: Oscail postáil
       original_status: Bunphostáil
       reblogs: Athbhlaganna
+      replied_to_html: D'fhreagair %{acct_link}
       status_changed: Athraíodh postáil
-      title: Poist chuntais - @%{name}
+      status_title: Postáil le @ %{name}
+      title: Postálacha cuntais - @%{name}
       trending: Ag treochtáil
+      view_publicly: Féach go poiblí
       visibility: Infheictheacht
       with_media: Le meáin
     strikes:
diff --git a/config/locales/gd.yml b/config/locales/gd.yml
index 89198bd514..78f4516cfc 100644
--- a/config/locales/gd.yml
+++ b/config/locales/gd.yml
@@ -861,7 +861,6 @@ gd:
       original_status: Am post tùsail
       reblogs: Brosnachaidhean
       status_changed: Post air atharrachadh
-      title: Postaichean a’ chunntais - @%{name}
       trending: A’ treandadh
       visibility: Faicsinneachd
       with_media: Le meadhanan riutha
diff --git a/config/locales/gl.yml b/config/locales/gl.yml
index 0f3420a7f3..feda673621 100644
--- a/config/locales/gl.yml
+++ b/config/locales/gl.yml
@@ -826,8 +826,10 @@ gl:
       back_to_account: Volver a páxina da conta
       back_to_report: Volver a denuncias
       batch:
+        add_to_report: 'Engadir á denuncia #%{id}'
         remove_from_report: Eliminar da denuncia
         report: Denuncia
+      contents: Contidos
       deleted: Eliminado
       favourites: Favoritas
       history: Historial de versións
@@ -836,13 +838,17 @@ gl:
       media:
         title: Medios
       metadata: Metadatos
+      no_history: Esta publicación foi editada
       no_status_selected: Non se cambiou ningunha publicación xa que ningunha foi seleccionada
       open: Abrir publicación
       original_status: Publicación orixinal
       reblogs: Promocións
+      replied_to_html: Respondeu a %{acct_link}
       status_changed: Publicación editada
+      status_title: Publicación de @%{name}
       title: Publicacións da conta - @%{name}
       trending: Popular
+      view_publicly: Ver publicamente
       visibility: Visibilidade
       with_media: con medios
     strikes:
diff --git a/config/locales/he.yml b/config/locales/he.yml
index 59dc09799d..5243cf4768 100644
--- a/config/locales/he.yml
+++ b/config/locales/he.yml
@@ -193,6 +193,7 @@ he:
         create_domain_block: יצירת דומיין חסום
         create_email_domain_block: יצירת חסימת דומיין דוא"ל
         create_ip_block: יצירת כלל IP
+        create_relay: יצירת ממסר
         create_unavailable_domain: יצירת דומיין בלתי זמין
         create_user_role: יצירת תפקיד
         demote_user: הורדת משתמש בדרגה
@@ -204,14 +205,17 @@ he:
         destroy_email_domain_block: מחיקת חסימת דומיין דוא"ל
         destroy_instance: טיהור דומיין
         destroy_ip_block: מחיקת כלל IP
+        destroy_relay: מחיקת ממסר
         destroy_status: מחיקת הודעה
         destroy_unavailable_domain: מחיקת דומיין בלתי זמין
         destroy_user_role: מחיקת תפקיד
         disable_2fa_user: השעיית זיהוי דו-גורמי
         disable_custom_emoji: השעיית אמוג'י מיוחד
+        disable_relay: השבתת ממסר
         disable_sign_in_token_auth_user: השעיית אסימון הזדהות בדוא"ל של משתמש
         disable_user: השעיית משתמש
         enable_custom_emoji: הפעלת אמוג'י מיוחד
+        enable_relay: החייאת ממסר
         enable_sign_in_token_auth_user: הפעלת אסימון הזדהות בדוא"ל של משתמש
         enable_user: אפשור משתמש
         memorialize_account: הנצחת חשבון
@@ -253,6 +257,7 @@ he:
         create_domain_block_html: "%{name} חסם/ה את הדומיין %{target}"
         create_email_domain_block_html: '%{name} חסם/ה את דומיין הדוא"ל %{target}'
         create_ip_block_html: "%{name} יצר/ה כלל עבור IP %{target}"
+        create_relay_html: "%{name} יצרו את הממסר %{target}"
         create_unavailable_domain_html: "%{name} הפסיק/ה משלוח לדומיין %{target}"
         create_user_role_html: "%{name} יצר את התפקיד של %{target}"
         demote_user_html: "%{name} הוריד/ה בדרגה את המשתמש %{target}"
@@ -264,14 +269,17 @@ he:
         destroy_email_domain_block_html: '%{name} הסיר/ה חסימה מדומיין הדוא"ל %{target}'
         destroy_instance_html: "%{name} טיהר/ה את הדומיין %{target}"
         destroy_ip_block_html: "%{name} מחק/ה את הכלל עבור IP %{target}"
+        destroy_relay_html: "%{name} מחקו את הממסר %{target}"
         destroy_status_html: ההודעה של %{target} הוסרה ע"י %{name}
         destroy_unavailable_domain_html: "%{name} התחיל/ה מחדש משלוח לדומיין %{target}"
         destroy_user_role_html: "%{name} ביטל את התפקיד של %{target}"
         disable_2fa_user_html: "%{name} ביטל/ה את הדרישה לאימות דו-גורמי למשתמש %{target}"
         disable_custom_emoji_html: "%{name} השבית/ה את האמוג'י %{target}"
+        disable_relay_html: "%{name} השביתו את הממסר %{target}"
         disable_sign_in_token_auth_user_html: '%{name} השבית/ה את האימות בעזרת אסימון דוא"ל עבור %{target}'
         disable_user_html: "%{name} חסם/ה כניסה מהמשתמש/ת %{target}"
         enable_custom_emoji_html: "%{name} אפשר/ה את האמוג'י %{target}"
+        enable_relay_html: "%{name} החיו את הממסר %{target}"
         enable_sign_in_token_auth_user_html: '%{name} אפשר/ה אימות בעזרת אסימון דוא"ל עבור %{target}'
         enable_user_html: "%{name} אפשר/ה כניסה עבור המשתמש %{target}"
         memorialize_account_html: "%{name} הפך/ה את חשבונו של %{target} לדף הנצחה"
@@ -846,8 +854,10 @@ he:
       back_to_account: חזרה לדף החשבון
       back_to_report: חזרה לעמוד הדיווח
       batch:
+        add_to_report: להוסיף לדו"ח מספר %{id}
         remove_from_report: הסרה מהדיווח
         report: דווח
+      contents: תוכן
       deleted: מחוקים
       favourites: חיבובים
       history: היסטורית גרסאות
@@ -856,13 +866,17 @@ he:
       media:
         title: מדיה
       metadata: נתוני-מטא
+      no_history: הודעה זו לא נערכה
       no_status_selected: לא בוצעו שינויים בהודעות שכן לא נבחרו כאלו
       open: פתח הודעה
       original_status: הודעה מקורית
       reblogs: שיתופים
+      replied_to_html: בתגובה לחשבון %{acct_link}
       status_changed: הודעה שונתה
-      title: הודעות החשבון - @%{name}
+      status_title: פרסום מאת @%{name}
+      title: פרסומי החשבון - @%{name}
       trending: נושאים חמים
+      view_publicly: צפיה בפומבי
       visibility: נראות
       with_media: עם מדיה
     strikes:
diff --git a/config/locales/hu.yml b/config/locales/hu.yml
index 56d41daf86..f23711d403 100644
--- a/config/locales/hu.yml
+++ b/config/locales/hu.yml
@@ -841,7 +841,6 @@ hu:
       original_status: Eredeti bejegyzés
       reblogs: Megosztások
       status_changed: A bejegyzés megváltozott
-      title: Fiók bejegyzései - @%{name}
       trending: Felkapott
       visibility: Láthatóság
       with_media: Médiával
diff --git a/config/locales/hy.yml b/config/locales/hy.yml
index d8cf2a97ba..3b4aaf3629 100644
--- a/config/locales/hy.yml
+++ b/config/locales/hy.yml
@@ -402,7 +402,6 @@ hy:
       deleted: Ջնջված է
       media:
         title: Մեդիա
-      title: Օգտատիրոջ գրառումները - @%{name}
       with_media: Մեդիայի հետ
     tags:
       review: Վերանայել գրառումը
diff --git a/config/locales/ia.yml b/config/locales/ia.yml
index 1398ae51d4..54401b1c5a 100644
--- a/config/locales/ia.yml
+++ b/config/locales/ia.yml
@@ -187,6 +187,7 @@ ia:
         create_domain_block: Crear blocada de dominio
         create_email_domain_block: Crear blocada de dominio de e-mail
         create_ip_block: Crear un regula IP
+        create_relay: Crear repetitor
         create_unavailable_domain: Crear dominio indisponibile
         create_user_role: Crear un rolo
         demote_user: Degradar usator
@@ -198,14 +199,17 @@ ia:
         destroy_email_domain_block: Deler blocada de dominio de e-mail
         destroy_instance: Purgar dominio
         destroy_ip_block: Deler le regula IP
+        destroy_relay: Deler repetitor
         destroy_status: Deler message
         destroy_unavailable_domain: Deler dominio indisponibile
         destroy_user_role: Destruer rolo
         disable_2fa_user: Disactivar A2F
         disable_custom_emoji: Disactivar emoji personalisate
+        disable_relay: Disactivar repetitor
         disable_sign_in_token_auth_user: Disactivar le authentication per token de e-mail pro le usator
         disable_user: Disactivar le usator
         enable_custom_emoji: Activar emoji personalisate
+        enable_relay: Activar repetitor
         enable_sign_in_token_auth_user: Activar le authentication per token de e-mail pro le usator
         enable_user: Activar le usator
         memorialize_account: Converter conto in memorial
@@ -247,6 +251,7 @@ ia:
         create_domain_block_html: "%{name} blocava dominio %{target}"
         create_email_domain_block_html: "%{name} blocava le dominio de e-mail %{target}"
         create_ip_block_html: "%{name} creava regula pro IP %{target}"
+        create_relay_html: "%{name} ha create un repetitor %{target}"
         create_unavailable_domain_html: "%{name} stoppava livration al dominio %{target}"
         create_user_role_html: "%{name} creava rolo de %{target}"
         demote_user_html: "%{name} degradava usator %{target}"
@@ -258,14 +263,17 @@ ia:
         destroy_email_domain_block_html: "%{name} disblocava le dominio de e-mail %{target}"
         destroy_instance_html: "%{name} purgava le dominio %{target}"
         destroy_ip_block_html: "%{name} deleva le regula pro IP %{target}"
+        destroy_relay_html: "%{name} ha delite le repetitor %{target}"
         destroy_status_html: "%{name} removeva un message de %{target}"
         destroy_unavailable_domain_html: "%{name} reprendeva le livration al dominio %{target}"
         destroy_user_role_html: "%{name} deleva le rolo %{target}"
         disable_2fa_user_html: "%{name} disactivava le authentication a duo factores pro le usator %{target}"
         disable_custom_emoji_html: "%{name} disactivava le emoji %{target}"
+        disable_relay_html: "%{name} ha disactivate le repetitor %{target}"
         disable_sign_in_token_auth_user_html: "%{name} disactivava le authentication per token de e-mail pro %{target}"
         disable_user_html: "%{name} disactivava le apertura de session pro le usator %{target}"
         enable_custom_emoji_html: "%{name} activava le emoji %{target}"
+        enable_relay_html: "%{name} ha activate le repetitor %{target}"
         enable_sign_in_token_auth_user_html: "%{name} activava le authentication per token de e-mail pro %{target}"
         enable_user_html: "%{name} activava le apertura de session pro le usator %{target}"
         memorialize_account_html: "%{name} converteva le conto de %{target} in un pagina commemorative"
@@ -818,8 +826,10 @@ ia:
       back_to_account: Retornar al pagina del conto
       back_to_report: Retro al pagina de reporto
       batch:
+        add_to_report: 'Adder al reporto #%{id}'
         remove_from_report: Remover del reporto
         report: Reporto
+      contents: Contento
       deleted: Delite
       favourites: Favorites
       history: Historia de versiones
@@ -828,13 +838,17 @@ ia:
       media:
         title: Multimedia
       metadata: Metadatos
+      no_history: Iste message non ha essite modificate
       no_status_selected: Necun message ha essite cambiate perque necun ha essite seligite
       open: Aperir message
       original_status: Message original
       reblogs: Republicationes
+      replied_to_html: Respondite a %{acct_link}
       status_changed: Message cambiate
-      title: Messages del conto - @%{name}
+      status_title: Message de @%{name}
+      title: Messages del conto – @%{name}
       trending: Tendentias
+      view_publicly: Vider publicamente
       visibility: Visibilitate
       with_media: Con multimedia
     strikes:
@@ -1118,7 +1132,7 @@ ia:
     migrate_account: Migrar a un altere conto
     migrate_account_html: Si tu vole rediriger iste conto a un altere, tu pote <a href="%{path}">configurar lo hic</a>.
     or_log_in_with: O aperi session con
-    privacy_policy_agreement_html: Io ha legite e accepta le <a href="<a href="%{privacy_policy_path}" target="_blank">politica de confidentialitate</a>
+    privacy_policy_agreement_html: Io ha legite e accepta le <a href="%{privacy_policy_path}" target="_blank">politica de confidentialitate</a>
     progress:
       confirm: Confirmar e-mail
       details: Tu detalios
@@ -1166,8 +1180,11 @@ ia:
     use_security_key: Usar clave de securitate
   author_attribution:
     example_title: Texto de exemplo
+    hint_html: Scribe tu articulos de novas o de blog foras de Mastodon? Controla le maniera in que tu recipe attribution quando on los condivide sur Mastodon.
+    instructions: 'Assecura te que iste codice appare in le HTML de tu articulo:'
     more_from_html: Plus de %{name}
     s_blog: Blog de %{name}
+    then_instructions: Postea, adde le nomine de dominio del publication in le campo sequente.
     title: Attribution de autor
   challenge:
     confirm: Continuar
diff --git a/config/locales/id.yml b/config/locales/id.yml
index 9c31daf420..34b690828d 100644
--- a/config/locales/id.yml
+++ b/config/locales/id.yml
@@ -711,7 +711,6 @@ id:
       original_status: Kiriman asli
       reblogs: Reblog
       status_changed: Kiriman diubah
-      title: Status akun - @%{name}
       trending: Sedang tren
       visibility: Visibilitas
       with_media: Dengan media
diff --git a/config/locales/ie.yml b/config/locales/ie.yml
index d7df83ef69..f006f2c8ad 100644
--- a/config/locales/ie.yml
+++ b/config/locales/ie.yml
@@ -791,7 +791,6 @@ ie:
       original_status: Original posta
       reblogs: Boosts
       status_changed: Posta modificat
-      title: Postas del conto - @%{name}
       trending: Populari
       visibility: Visibilitá
       with_media: Con medie
diff --git a/config/locales/io.yml b/config/locales/io.yml
index 1ff5d98bf2..83c92484ff 100644
--- a/config/locales/io.yml
+++ b/config/locales/io.yml
@@ -779,7 +779,6 @@ io:
       original_status: Originala posto
       reblogs: Dissemi
       status_changed: Posto chanjita
-      title: Kontoposti - @%{name}
       trending: Populara
       visibility: Videbleso
       with_media: Kun medii
diff --git a/config/locales/is.yml b/config/locales/is.yml
index 9ba29f2af0..cad01257fd 100644
--- a/config/locales/is.yml
+++ b/config/locales/is.yml
@@ -828,8 +828,10 @@ is:
       back_to_account: Fara aftur á síðu notandaaðgangsins
       back_to_report: Til baka á kærusíðu
       batch:
+        add_to_report: 'Bæta við skýrslu #%{id}'
         remove_from_report: Fjarlægja úr kæru
         report: Kæra
+      contents: Efni
       deleted: Eytt
       favourites: Eftirlæti
       history: Útgáfuferill
@@ -838,13 +840,17 @@ is:
       media:
         title: Myndefni
       metadata: Lýsigögn
+      no_history: Færslunni hefur ekki verið breytt
       no_status_selected: Engum færslum var breytt þar sem engar voru valdar
       open: Opna færslu
       original_status: Upprunaleg færsla
       reblogs: Endurbirtingar
+      replied_to_html: Svaraði til %{acct_link}
       status_changed: Færslu breytt
-      title: Færslur notandaaðgangs - @%{name}
+      status_title: Færsla frá @%{name}
+      title: Færslur notanda - @%{name}
       trending: Vinsælt
+      view_publicly: Skoða opinberlega
       visibility: Sýnileiki
       with_media: Með myndefni
     strikes:
diff --git a/config/locales/it.yml b/config/locales/it.yml
index 08e224ad94..4c083fd006 100644
--- a/config/locales/it.yml
+++ b/config/locales/it.yml
@@ -818,8 +818,10 @@ it:
       back_to_account: Torna alla pagina dell'account
       back_to_report: Torna alla pagina del report
       batch:
+        add_to_report: 'Aggiungi alla segnalazione #%{id}'
         remove_from_report: Rimuovi dal report
         report: Rapporto
+      contents: Contenuti
       deleted: Cancellato
       favourites: Preferiti
       history: Cronologia delle versioni
@@ -828,13 +830,17 @@ it:
       media:
         title: Media
       metadata: Metadati
+      no_history: Questo post non è stato modificato
       no_status_selected: Nessun status è stato modificato perché nessuno era stato selezionato
       open: Apri il post
       original_status: Post originale
       reblogs: Condivisioni
+      replied_to_html: Risposta a %{acct_link}
       status_changed: Post modificato
-      title: Gli status dell'account - @%{name}
+      status_title: Post di @%{name}
+      title: Post dell'account - @%{name}
       trending: Di tendenza
+      view_publicly: Visualizza pubblicamente
       visibility: Visibilità
       with_media: con media
     strikes:
diff --git a/config/locales/ja.yml b/config/locales/ja.yml
index 76152c3744..810de2b227 100644
--- a/config/locales/ja.yml
+++ b/config/locales/ja.yml
@@ -184,6 +184,7 @@ ja:
         create_domain_block: ドメインブロックを作成
         create_email_domain_block: メールドメインブロックを作成
         create_ip_block: IPルールを作成
+        create_relay: リレーの追加
         create_unavailable_domain: 配送できないドメインを作成
         create_user_role: ロールを作成
         demote_user: ユーザーを降格
@@ -195,14 +196,17 @@ ja:
         destroy_email_domain_block: メールドメインブロックを削除
         destroy_instance: ドメインをブロックする
         destroy_ip_block: IPルールを削除
+        destroy_relay: リレーの削除
         destroy_status: 投稿を削除
         destroy_unavailable_domain: 配送できないドメインを削除
         destroy_user_role: ロールを削除
         disable_2fa_user: 二要素認証を無効化
         disable_custom_emoji: カスタム絵文字を無効化
+        disable_relay: リレーの無効化
         disable_sign_in_token_auth_user: ユーザのメールトークン認証を無効化
         disable_user: ユーザーを無効化
         enable_custom_emoji: カスタム絵文字を有効化
+        enable_relay: リレーの有効化
         enable_sign_in_token_auth_user: ユーザのメールトークン認証を有効化
         enable_user: ユーザーを有効化
         memorialize_account: 追悼アカウント化
@@ -244,6 +248,7 @@ ja:
         create_domain_block_html: "%{name}さんがドメイン %{target}をブロックしました"
         create_email_domain_block_html: "%{name} さんがメールドメイン %{target} をブロックしました"
         create_ip_block_html: "%{name}さんがIP %{target}のルールを作成しました"
+        create_relay_html: "%{name} さんがリレー %{target} を追加しました"
         create_unavailable_domain_html: "%{name}がドメイン %{target}への配送を停止しました"
         create_user_role_html: "%{name}さんがロール『%{target}』を作成しました"
         demote_user_html: "%{name}さんが%{target}さんを降格しました"
@@ -252,17 +257,20 @@ ja:
         destroy_custom_emoji_html: "%{name}さんがカスタム絵文字『%{target}』を削除しました"
         destroy_domain_allow_html: "%{name}さんが%{target}の連合許可を外しました"
         destroy_domain_block_html: "%{name}さんがドメイン %{target}のブロックを外しました"
-        destroy_email_domain_block_html: "%{name} がメールドメイン %{target} のブロックを外しました"
+        destroy_email_domain_block_html: "%{name} さんがメールドメイン %{target} のブロックを外しました"
         destroy_instance_html: "%{name}さんがドメイン %{target}をブロックしました"
         destroy_ip_block_html: "%{name}さんが IP %{target}のルールを削除しました"
+        destroy_relay_html: "%{name} さんがリレー %{target} を削除しました"
         destroy_status_html: "%{name}さんが%{target}さんの投稿を削除しました"
         destroy_unavailable_domain_html: "%{name}がドメイン %{target}への配送を再開しました"
         destroy_user_role_html: "%{name}さんがロール『%{target}』を削除しました"
         disable_2fa_user_html: "%{name}さんが%{target}さんの二要素認証を無効化しました"
         disable_custom_emoji_html: "%{name}さんがカスタム絵文字 %{target}を無効化しました"
+        disable_relay_html: "%{name} さんがリレー %{target} を無効にしました"
         disable_sign_in_token_auth_user_html: "%{name} が %{target} のメールトークン認証を無効化しました"
         disable_user_html: "%{name}さんが%{target}さんのログインを無効化しました"
         enable_custom_emoji_html: "%{name}さんがカスタム絵文字 %{target}を有効化しました"
+        enable_relay_html: "%{name} さんがリレー %{target} を有効にしました"
         enable_sign_in_token_auth_user_html: "%{name} が %{target} のメールトークン認証を有効化しました"
         enable_user_html: "%{name}さんが%{target}さんのログインを有効化しました"
         memorialize_account_html: "%{name}さんが%{target}さんを追悼アカウントページに登録しました"
@@ -804,8 +812,10 @@ ja:
       back_to_account: アカウントページに戻る
       back_to_report: 通報ページに戻る
       batch:
+        add_to_report: 'レポート #%{id} に追加'
         remove_from_report: 通報から削除
         report: 通報
+      contents: 投稿内容
       deleted: 削除済み
       favourites: お気に入り
       history: 更新履歴
@@ -814,13 +824,17 @@ ja:
       media:
         title: メディア
       metadata: メタデータ
+      no_history: この投稿は編集されていません
       no_status_selected: 何も選択されていないため、変更されていません
       open: 投稿を開く
       original_status: オリジナルの投稿
       reblogs: ブースト
+      replied_to_html: "%{acct_link}さんへの返信"
       status_changed: 投稿を変更しました
+      status_title: "@%{name} の投稿"
       title: 投稿一覧 - @%{name}
       trending: トレンド
+      view_publicly: 元の投稿を開く
       visibility: 公開範囲
       with_media: メディアあり
     strikes:
diff --git a/config/locales/ka.yml b/config/locales/ka.yml
index 93f7a39dc3..f3178be8d3 100644
--- a/config/locales/ka.yml
+++ b/config/locales/ka.yml
@@ -190,7 +190,6 @@ ka:
       media:
         title: მედია
       no_status_selected: სატუსები არ შეცვლილა, რადგან არცერთი არ მონიშნულა
-      title: ანგარიშის სტატუსები - @%{name}
       with_media: მედიით
     title: ადმინისტრაცია
   admin_mailer:
diff --git a/config/locales/kab.yml b/config/locales/kab.yml
index c74540cfbf..1f5c5ded79 100644
--- a/config/locales/kab.yml
+++ b/config/locales/kab.yml
@@ -419,7 +419,6 @@ kab:
       media:
         title: Amidya
       open: Ldi tasuffeɣt
-      title: Tisuffaɣ n umiḍan - @%{name}
       trending: Ayen mucaɛen
       visibility: Abani
       with_media: S umidya
diff --git a/config/locales/kk.yml b/config/locales/kk.yml
index 4b9cef245e..7ab33b3134 100644
--- a/config/locales/kk.yml
+++ b/config/locales/kk.yml
@@ -285,7 +285,6 @@ kk:
       media:
         title: Медиa
       no_status_selected: Бірде-бір статус өзгерген жоқ, себебі ештеңе таңдалмады
-      title: Аккаунт статустары - @%{name}
       with_media: Медиамен
     tags:
       review: Статусты көрсету
diff --git a/config/locales/ko.yml b/config/locales/ko.yml
index 36a13397d0..3394433758 100644
--- a/config/locales/ko.yml
+++ b/config/locales/ko.yml
@@ -814,8 +814,10 @@ ko:
       back_to_account: 계정으로 돌아가기
       back_to_report: 신고 페이지로 돌아가기
       batch:
+        add_to_report: '신고 #%{id}에 추가'
         remove_from_report: 신고에서 제거
         report: 신고
+      contents: 내용
       deleted: 삭제됨
       favourites: 좋아요
       history: 버전 이력
@@ -824,13 +826,17 @@ ko:
       media:
         title: 미디어
       metadata: 메타데이터
+      no_history: 이 게시물은 수정되지 않았습니다
       no_status_selected: 아무 것도 선택 되지 않아 어떤 게시물도 바뀌지 않았습니다
       open: 게시물 열기
       original_status: 원본 게시물
       reblogs: 리블로그
+      replied_to_html: "%{acct_link} 님에게 답장"
       status_changed: 게시물 변경됨
+      status_title: "@%{name} 님의 게시물"
       title: 계정 게시물 - @%{name}
       trending: 유행 중
+      view_publicly: 공개시점으로 보기
       visibility: 공개 설정
       with_media: 미디어 있음
     strikes:
diff --git a/config/locales/ku.yml b/config/locales/ku.yml
index 54188d2514..5337610992 100644
--- a/config/locales/ku.yml
+++ b/config/locales/ku.yml
@@ -720,7 +720,6 @@ ku:
       original_status: Şandiyê resen
       reblogs: Ji nû ve nivîsandin
       status_changed: Şandî hate guhertin
-      title: Şandiyên ajimêr - @%{name}
       trending: Rojev
       visibility: Xuyabarî
       with_media: Bi medya yê re
diff --git a/config/locales/lad.yml b/config/locales/lad.yml
index 3b33888c71..2612ae2131 100644
--- a/config/locales/lad.yml
+++ b/config/locales/lad.yml
@@ -825,7 +825,6 @@ lad:
       original_status: Publikasyon orijinala
       reblogs: Repartajasyones
       status_changed: Publikasyon trokada
-      title: Publikasyones del kuento - @%{name}
       trending: Trendes
       visibility: Vizivilita
       with_media: Kon multimedia
diff --git a/config/locales/lt.yml b/config/locales/lt.yml
index 3519cb5b32..65bd4456ae 100644
--- a/config/locales/lt.yml
+++ b/config/locales/lt.yml
@@ -589,7 +589,9 @@ lt:
       back_to_account: Grįžti į paskyros puslapį
       back_to_report: Grįžti į ataskaitos puslapį
       batch:
+        add_to_report: 'Pridėti į ataskaitą #%{id}'
         remove_from_report: Pašalinti iš ataskaitos
+      contents: Turinys
       deleted: Ištrinta
       favourites: Mėgstami
       history: Versijų istorija
@@ -598,11 +600,15 @@ lt:
       media:
         title: Medija
       metadata: Metaduomenys
+      no_history: Šis įrašas nebuvo redaguotas
       no_status_selected: Jokie įrašai nebuvo pakeisti, nes nė vienas buvo pasirinktas
       open: Atidaryti įrašą
       original_status: Originalus įrašas
-      title: Paskyros statusai - @%{name}
+      replied_to_html: Atsakyta į %{acct_link}
+      status_title: Paskelbė @%{name}
+      title: Paskyros įrašai – @%{name}
       trending: Tendencinga
+      view_publicly: Peržiūrėti viešai
       with_media: Su medija
     system_checks:
       database_schema_check:
diff --git a/config/locales/lv.yml b/config/locales/lv.yml
index 33b357b837..1ced1bb7d0 100644
--- a/config/locales/lv.yml
+++ b/config/locales/lv.yml
@@ -830,7 +830,6 @@ lv:
       original_status: Oriģinālā ziņa
       reblogs: Reblogi
       status_changed: Ziņa mainīta
-      title: Konta ziņas - @%{name}
       trending: Aktuāli
       visibility: Redzamība
       with_media: Ar multividi
diff --git a/config/locales/ms.yml b/config/locales/ms.yml
index 76f914dd16..948ad56a54 100644
--- a/config/locales/ms.yml
+++ b/config/locales/ms.yml
@@ -768,7 +768,6 @@ ms:
       original_status: Hantaran asal
       reblogs: Ulang siar
       status_changed: Hantaran diubah
-      title: Hantaran akaun - @%{name}
       trending: Sohor kini
       visibility: Visibiliti
       with_media: Dengan media
diff --git a/config/locales/my.yml b/config/locales/my.yml
index b238abb051..4428843855 100644
--- a/config/locales/my.yml
+++ b/config/locales/my.yml
@@ -764,7 +764,6 @@ my:
       original_status: မူရင်းပို့စ်
       reblogs: Reblog များ
       status_changed: ပို့စ်ပြောင်းပြီးပါပြီ
-      title: "@%{name} - အကောင့်ပို့စ်များ"
       trending: လက်ရှိခေတ်စားနေခြင်း
       visibility: မြင်နိုင်မှု
       with_media: မီဒီယာနှင့်အတူ
diff --git a/config/locales/nl.yml b/config/locales/nl.yml
index d4a88b3bea..048214eca3 100644
--- a/config/locales/nl.yml
+++ b/config/locales/nl.yml
@@ -818,8 +818,10 @@ nl:
       back_to_account: Terug naar accountpagina
       back_to_report: Terug naar de rapportage
       batch:
+        add_to_report: 'Toevoegen aan rapport #%{id}'
         remove_from_report: Uit de rapportage verwijderen
         report: Rapportage
+      contents: Inhoud
       deleted: Verwijderd
       favourites: Favorieten
       history: Versiegeschiedenis
@@ -828,12 +830,14 @@ nl:
       media:
         title: Media
       metadata: Metagegevens
+      no_history: Dit bericht is niet bewerkt
       no_status_selected: Er werden geen berichten gewijzigd, omdat er geen enkele werd geselecteerd
       open: Bericht tonen
       original_status: Oorspronkelijk bericht
       reblogs: Boosts
       status_changed: Bericht veranderd
-      title: Berichten van account - @%{name}
+      status_title: Bericht van @%{name}
+      title: Accountberichten - @%{name}
       trending: Trending
       visibility: Zichtbaarheid
       with_media: Met media
diff --git a/config/locales/nn.yml b/config/locales/nn.yml
index e04c0168f2..dbb8b6c693 100644
--- a/config/locales/nn.yml
+++ b/config/locales/nn.yml
@@ -826,8 +826,10 @@ nn:
       back_to_account: Tilbake til kontosida
       back_to_report: Attende til rapporteringssida
       batch:
+        add_to_report: 'Legg til rapport #%{id}'
         remove_from_report: Fjern fra rapport
         report: Rapport
+      contents: Innhald
       deleted: Sletta
       favourites: Favorittar
       history: Versjonshistorikk
@@ -836,13 +838,17 @@ nn:
       media:
         title: Media
       metadata: Metadata
+      no_history: Dette innlegget har ikkje blitt redigert
       no_status_selected: Ingen statusar vart endra sidan ingen vart valde
       open: Opne innlegg
       original_status: Opprinnelig innlegg
       reblogs: Framhevingar
+      replied_to_html: Svarte %{acct_link}
       status_changed: Innlegg endret
-      title: Kontostatusar - @%{name}
+      status_title: Innlegg av @%{name}
+      title: Kontoinnlegg - @%{name}
       trending: Populært
+      view_publicly: Vis offentleg
       visibility: Synlighet
       with_media: Med media
     strikes:
diff --git a/config/locales/no.yml b/config/locales/no.yml
index 408fdd5ae1..8bf5daad0e 100644
--- a/config/locales/no.yml
+++ b/config/locales/no.yml
@@ -786,7 +786,6 @@
       original_status: Opprinnelig innlegg
       reblogs: Fremheve
       status_changed: Innlegg endret
-      title: Kontostatuser - @%{name}
       trending: Populært
       visibility: Synlighet
       with_media: Med media
diff --git a/config/locales/oc.yml b/config/locales/oc.yml
index 5130977cb3..5dec5ebb77 100644
--- a/config/locales/oc.yml
+++ b/config/locales/oc.yml
@@ -401,7 +401,6 @@ oc:
       media:
         title: Mèdia
       no_status_selected: Cap d’estatut pas cambiat estant que cap èra pas seleccionat
-      title: Estatuts del compte - @%{name}
       visibility: Visibilitat
       with_media: Amb mèdia
     system_checks:
diff --git a/config/locales/pl.yml b/config/locales/pl.yml
index c5d63e1d73..48a881a61b 100644
--- a/config/locales/pl.yml
+++ b/config/locales/pl.yml
@@ -861,7 +861,6 @@ pl:
       original_status: Oryginalny post
       reblogs: Podbicia
       status_changed: Post zmieniony
-      title: Wpisy konta - @%{name}
       trending: Popularne
       visibility: Widoczność
       with_media: Z zawartością multimedialną
diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml
index c5a0f3764a..537dee5f74 100644
--- a/config/locales/pt-BR.yml
+++ b/config/locales/pt-BR.yml
@@ -826,8 +826,10 @@ pt-BR:
       back_to_account: Voltar para página da conta
       back_to_report: Voltar às denúncias
       batch:
+        add_to_report: 'Adicionar à denúncia #%{id}'
         remove_from_report: Remover da denúncia
         report: Denunciar
+      contents: Conteúdos
       deleted: Excluídos
       favourites: Favoritos
       history: Histórico de versões
@@ -836,13 +838,17 @@ pt-BR:
       media:
         title: Mídia
       metadata: Metadados
+      no_history: Esta publicação não foi editada
       no_status_selected: Nenhuma publicação foi modificada porque nenhuma estava selecionada
       open: Publicação aberta
       original_status: Publicação original
       reblogs: Reblogs
+      replied_to_html: Respondeu à %{acct_link}
       status_changed: Publicação alterada
+      status_title: Publicação de @%{name}
       title: Publicações da conta - @%{name}
       trending: Em alta
+      view_publicly: Ver publicamente
       visibility: Visibilidade
       with_media: Com mídia
     strikes:
@@ -1377,9 +1383,16 @@ pt-BR:
       overwrite: Sobrescrever
       overwrite_long: Substituir os registros atuais com os novos
     overwrite_preambles:
+      blocking_html:
+        one: Você está prestes a <strong>trocar seu bloco de listas</strong> com mais de <strong>%{count} conta</strong> de <strong>%{filename}</strong>.
+        other: Você está prestes a <strong>substituir sua lista de blocos</strong> com mais de <strong>%{count} contas</strong> de <strong>%{filename}</strong>.
       bookmarks_html:
         one: Você está prestes a <strong>substituir seus salvos</strong> por até <strong>%{count} publicação</strong> de <strong>%{filename}</strong>.
         other: Você está prestes a <strong>substituir seus salvos</strong> por até <strong>%{count} publicações</strong> de <strong>%{filename}</strong>.
+    preambles:
+      muting_html:
+        one: Você está prestes a <strong>silenciar</strong> <strong>%{count}  conta</strong> de <strong>%{filename}</strong>.
+        other: Você está prestes a <strong>silenciar</strong> mais de <strong>%{count} contas</strong> de <strong>%{filename}</strong>.
     preface: Você pode importar dados que você exportou de outro servidor, como a lista de pessoas que você segue ou bloqueou.
     recent_imports: Importações recentes
     states:
diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml
index ff80948848..cceceb0534 100644
--- a/config/locales/pt-PT.yml
+++ b/config/locales/pt-PT.yml
@@ -832,7 +832,6 @@ pt-PT:
       original_status: Publicação original
       reblogs: Re-publicacões
       status_changed: Publicação alterada
-      title: Estado das contas - @%{name}
       trending: Em tendência
       visibility: Visibilidade
       with_media: Com media
diff --git a/config/locales/ru.yml b/config/locales/ru.yml
index 09d89cef9d..d9bf96c625 100644
--- a/config/locales/ru.yml
+++ b/config/locales/ru.yml
@@ -869,7 +869,6 @@ ru:
       original_status: Оригинальный пост
       reblogs: Продвинули
       status_changed: Пост изменен
-      title: Посты пользователя - @%{name}
       trending: Популярное
       visibility: Видимость
       with_media: С файлами
diff --git a/config/locales/sc.yml b/config/locales/sc.yml
index 09f8ba0e0e..38ede0a72c 100644
--- a/config/locales/sc.yml
+++ b/config/locales/sc.yml
@@ -582,7 +582,6 @@ sc:
       open: Aberi sa publicatzione
       original_status: Publicatzione originale
       status_changed: Publicatzione modificada
-      title: Istados de su contu - @%{name}
       trending: Populares
       visibility: Visibilidade
       with_media: Cun elementos multimediales
diff --git a/config/locales/sco.yml b/config/locales/sco.yml
index 55e0603d45..ff3a730b17 100644
--- a/config/locales/sco.yml
+++ b/config/locales/sco.yml
@@ -713,7 +713,6 @@ sco:
       original_status: Original post
       reblogs: Reblogs
       status_changed: Post chynged
-      title: Accoont posts - @%{name}
       trending: Trendin
       visibility: Visibility
       with_media: Wi media
diff --git a/config/locales/si.yml b/config/locales/si.yml
index b0eb1d3b0c..cd4abf6451 100644
--- a/config/locales/si.yml
+++ b/config/locales/si.yml
@@ -607,7 +607,6 @@ si:
       open: ලිපිය අරින්න
       original_status: මුල් ලිපිය
       status_changed: ලිපිය සංශෝධිතයි
-      title: ගිණුමේ ලිපි - @%{name}
       trending: නැගී එන
       with_media: මාධ්‍ය සමඟ
     strikes:
diff --git a/config/locales/simple_form.ga.yml b/config/locales/simple_form.ga.yml
index 62d59235bf..f8257a9da9 100644
--- a/config/locales/simple_form.ga.yml
+++ b/config/locales/simple_form.ga.yml
@@ -10,6 +10,7 @@ ga:
         indexable: Seans go mbeidh do phostálacha poiblí le feiceáil sna torthaí cuardaigh ar Mastodon. Seans go mbeidh daoine a d’idirghníomhaigh le do phostálacha in ann iad a chuardach beag beann ar.
         note: 'Is féidir leat @trá a dhéanamh ar dhaoine eile nó #hashtags.'
         show_collections: Beidh daoine in ann brabhsáil trí do seo a leanas agus do leanúna. Feicfidh na daoine a leanann tú go leanann tú iad beag beann ar.
+        unlocked: Beidh daoine in ann tú a leanúint gan cead a iarraidh. Díthiceáil an dteastaíonn uait athbhreithniú a dhéanamh ar iarratais leantacha agus roghnaigh cé acu an nglacfaidh nó an diúltóidh tú do leantóirí nua.
       account_alias:
         acct: Sonraigh ainm@fearann don chuntas ar mhaith leat aistriú uaidh
       account_migration:
diff --git a/config/locales/simple_form.ia.yml b/config/locales/simple_form.ia.yml
index 5ac75aafb1..1a405980c0 100644
--- a/config/locales/simple_form.ia.yml
+++ b/config/locales/simple_form.ia.yml
@@ -3,12 +3,14 @@ ia:
   simple_form:
     hints:
       account:
+        attribution_domains_as_text: Un per linea. Protege contra false attributiones.
         discoverable: Tu messages public e tu profilo pote esser mittite in evidentia o recommendate in varie areas de Mastodon e tu profilo pote esser suggerite a altere usatores.
         display_name: Tu prenomine e nomine de familia o tu pseudonymo.
         fields: Tu pagina principal, pronomines, etate, tote lo que tu vole.
         indexable: Tu messages public pote apparer in le resultatos de recerca sur Mastodon. Le personas qui ha interagite con tu messages pote cercar los in omne caso.
         note: 'Tu pote @mentionar altere personas o #hashtags.'
         show_collections: Le gente potera percurrer le listas de personas que tu seque e qui te seque. Le personas que tu seque videra que tu les seque in omne caso.
+        unlocked: Le personas potera sequer te sin requestar approbation. Dismarca si tu vole revider le requestas de sequimento e seliger si acceptar o rejectar nove sequitores.
       account_alias:
         acct: Specifica le nomine_de_usator@dominio del conto desde le qual tu vole migrar
       account_migration:
@@ -129,6 +131,7 @@ ia:
         name: Tu pote solmente cambiar le litteras inter majusculas e minusculas, per exemplo, pro render lo plus legibile
       user:
         chosen_languages: Si marcate, solo le messages in le linguas seligite sera monstrate in chronologias public
+        role: Le rolo controla qual permissos le usator ha.
       user_role:
         color: Color a esser usate pro le rolo in omne parte del UI, como RGB in formato hexadecimal
         highlighted: Iste rende le rolo publicamente visibile
@@ -141,6 +144,7 @@ ia:
         url: Ubi le eventos essera inviate
     labels:
       account:
+        attribution_domains_as_text: Sitos web autorisate a accreditar te
         discoverable: Evidentiar le profilo e messages in le algorithmos de discoperta
         fields:
           name: Etiquetta
@@ -209,6 +213,7 @@ ia:
         setting_default_privacy: Confidentialitate del messages
         setting_default_sensitive: Sempre marcar le medios cmo sensbile
         setting_delete_modal: Monstrar le dialogo de confirmation ante deler un message
+        setting_disable_hover_cards: Disactivar le previsualisation de profilos al passar del mus
         setting_disable_swiping: Disactivar le movimentos per glissamento
         setting_display_media: Visualisation de medios
         setting_display_media_default: Predefinite
diff --git a/config/locales/simple_form.pt-BR.yml b/config/locales/simple_form.pt-BR.yml
index 0c6be63aaa..fca59515f0 100644
--- a/config/locales/simple_form.pt-BR.yml
+++ b/config/locales/simple_form.pt-BR.yml
@@ -10,6 +10,7 @@ pt-BR:
         indexable: Suas publicações públicas podem aparecer nos resultados da pesquisa em Mastodon. As pessoas que interagiram com suas publicações podem conseguir pesquisá-las independentemente disso.
         note: 'Você pode @mencionar outras pessoas ou #hashtags.'
         show_collections: As pessoas poderão navegar entre os seus seguidores e seguidores. As pessoas que você segue verão que você as segue independentemente disso.
+        unlocked: As pessoas poderão seguir você sem solicitar aprovação. Desmarque caso você queira revisar as solicitações de seguidor e escolha se queira aceitar ou rejeitar novos seguidores.
       account_alias:
         acct: Especifique o usuário@domínio de onde veio
       account_migration:
diff --git a/config/locales/simple_form.zh-CN.yml b/config/locales/simple_form.zh-CN.yml
index 5f98d73be6..0b7edae913 100644
--- a/config/locales/simple_form.zh-CN.yml
+++ b/config/locales/simple_form.zh-CN.yml
@@ -4,12 +4,12 @@ zh-CN:
     hints:
       account:
         attribution_domains_as_text: 每行一个域名。这样就可以保护作品免受虚假署名。
-        discoverable: 您的公开嘟文和个人资料可能会在 Mastodon 的多个位置展示,您的个人资料可能会被推荐给其他用户。
+        discoverable: 你的公开嘟文和个人资料可能会在 Mastodon 的多个位置展示,你的个人资料可能会被推荐给其他用户。
         display_name: 你的全名或昵称。
         fields: 你的主页、人称代词、年龄,以及任何你想要添加的内容。
-        indexable: 您的公开嘟文会出现在 Mastodon 的搜索结果中。无论是否勾选,与您的嘟文有过交互的人都可能通过搜索找到它们。
-        note: '你可以提及 @其他人 或 #标签 。'
-        show_collections: 人们将能够浏览您的关注和追随者。您关注的人会看到您关注他们。
+        indexable: 你的公开嘟文会出现在 Mastodon 的搜索结果中。无论是否勾选,与你的嘟文有过交互的人都可能通过搜索找到它们。
+        note: '你可以提及 @其他人 或 #话题标签 。'
+        show_collections: 人们将能够浏览你的关注和追随者。你关注的人会看到你关注他们。
         unlocked: 人们将能够在不请求批准的情况下关注你。如果你希望审核关注请求并选择接受或拒绝新的关注者,请取消勾选此项。
       account_alias:
         acct: 指定你想要迁移过来的原账号:用户名@站点域名
@@ -62,7 +62,7 @@ zh-CN:
         setting_display_media_show_all: 始终显示媒体
         setting_use_blurhash: 渐变是基于模糊后的隐藏内容生成的
         setting_use_pending_items: 关闭自动滚动更新,时间轴会在点击后更新
-        username: 您只能使用字母、数字和下划线
+        username: 你只能使用字母、数字和下划线
         whole_word: 如果关键词只包含字母和数字,将只在词语完全匹配时才会应用
       domain_allow:
         domain: 该站点将能够从该服务器上拉取数据,并处理和存储收到的数据。
@@ -87,7 +87,7 @@ zh-CN:
         favicon: WEBP、PNG、GIF 或 JPG。使用自定义图标覆盖 Mastodon 的默认图标。
         mascot: 覆盖高级网页界面中的绘图形象。
         media_cache_retention_period: 来自外站用户嘟文的媒体文件将被缓存到你的实例上。当该值被设为正值时,缓存的媒体文件将在指定天数后被清除。如果媒体文件在被清除后重新被请求,且源站内容仍然可用,它将被重新下载。由于链接预览卡拉取第三方站点的频率受到限制,建议将此值设置为至少 14 天,如果小于该值,链接预览卡将不会按需更新。
-        peers_api_enabled: 此服务器在联邦宇宙中遇到的域名列表。 这里不包含关于您是否与给定服务器联合的数据,只是您的服务器知道它。 这由收集一般意义上的联邦统计信息的服务使用。
+        peers_api_enabled: 此服务器在联邦宇宙中遇到的实例列表。 此处不包含关于您是否与给定服务器联合的数据,只是您的服务器知道它。 这由收集一般意义上的联邦统计信息的服务使用。
         profile_directory: 个人资料目录会列出所有选择可被发现的用户。
         require_invite_text: 当注册需要手动批准时,将“你为什么想要加入?”设为必填项
         site_contact_email: 他人需要询恰法务或支持信息时的联络方式
@@ -125,7 +125,7 @@ zh-CN:
         otp: 输入你手机应用上生成的双因素认证代码,或者任意一个恢复代码:
         webauthn: 如果是 USB 密钥,请确保将其插入,如有必要,请点击它。
       settings:
-        indexable: 您的个人资料页面可能会出现在Google、Bing等搜索结果中。
+        indexable: 你的个人资料页面可能会出现在Google、Bing等搜索结果中。
         show_application: 无论如何,你始终可以看到是哪个应用发布了你的嘟文。
       tag:
         name: 你只能改变字母的大小写,让它更易读
@@ -257,7 +257,7 @@ zh-CN:
         peers_api_enabled: 在API中公开的已知实例的服务器的列表
         profile_directory: 启用用户目录
         registrations_mode: 谁可以注册
-        require_invite_text: 注册前需要提供理由
+        require_invite_text: 注册时需要提供理由
         show_domain_blocks: 显示域名屏蔽列表
         show_domain_blocks_rationale: 显示域名屏蔽原因
         site_contact_email: 联系邮箱
@@ -292,13 +292,13 @@ zh-CN:
       notification_emails:
         appeal: 有人对审核结果提出申诉
         digest: 发送摘要邮件
-        favourite: 当有用户喜欢了我的嘟文时,发送电子邮件提醒我
-        follow: 有用户关注我时
-        follow_request: 有用户向我发送关注请求时
-        mention: 有用户提及我时
-        pending_account: 有账号需要审核时
-        reblog: 有用户转嘟我的嘟文时
-        report: 新举报已提交
+        favourite: 有用户喜欢了我的嘟文
+        follow: 有人关注了我
+        follow_request: 有人向我发送了关注请求
+        mention: 有人提到了我
+        pending_account: 有账号需要审核
+        reblog: 有人转嘟了我的嘟文
+        report: 有人提交了新举报
         software_updates:
           all: 通知所有更新
           critical: 仅在有关键更新时通知
@@ -328,8 +328,8 @@ zh-CN:
         position: 优先级
       webhook:
         events: 已启用事件
-        template: 载荷模板
-        url: 对端 URL
+        template: Payload 模板
+        url: 端点 URL
     'no': 否
     not_recommended: 不推荐
     overridden: 已覆盖
diff --git a/config/locales/sk.yml b/config/locales/sk.yml
index d576bf0382..c946b8abf1 100644
--- a/config/locales/sk.yml
+++ b/config/locales/sk.yml
@@ -684,7 +684,6 @@ sk:
       open: Otvor príspevok
       original_status: Pôvodný príspevok
       status_changed: Príspevok bol zmenený
-      title: Príspevky na účte - @%{name}
       trending: Populárne
       visibility: Viditeľnosť
       with_media: S médiami
diff --git a/config/locales/sl.yml b/config/locales/sl.yml
index 6ae239d69f..909b89e5a9 100644
--- a/config/locales/sl.yml
+++ b/config/locales/sl.yml
@@ -853,7 +853,6 @@ sl:
       original_status: Izvorna objava
       reblogs: Ponovljeni blogi
       status_changed: Objava spremenjena
-      title: Objave računa - @%{name}
       trending: V trendu
       visibility: Vidnost
       with_media: Z mediji
diff --git a/config/locales/sq.yml b/config/locales/sq.yml
index b1e2a4f61e..e9247ef365 100644
--- a/config/locales/sq.yml
+++ b/config/locales/sq.yml
@@ -823,8 +823,10 @@ sq:
       back_to_account: Mbrapsht te faqja e llogarisë
       back_to_report: Mbrapsht te faqja e raportimit
       batch:
+        add_to_report: 'Shtoje te raportimi #%{id}'
         remove_from_report: Hiqe prej raportimit
         report: Raportojeni
+      contents: Lëndë
       deleted: E fshirë
       favourites: Të parapëlqyer
       history: Historik versioni
@@ -833,13 +835,17 @@ sq:
       media:
         title: Media
       metadata: Tejtëdhëna
+      no_history: Ky postim s’është përpunuar
       no_status_selected: S’u ndryshua ndonjë gjendje, ngaqë s’u përzgjodh ndonjë e tillë
       open: Hape postimin
       original_status: Postim origjinal
       reblogs: Riblogime
+      replied_to_html: Iu përgjigj %{acct_link}
       status_changed: Postimi ndryshoi
-      title: Gjendje llogarish - @%{name}
+      status_title: Postim nga @%{name}
+      title: Postime llogarie - @%{name}
       trending: Në modë
+      view_publicly: Shiheni publikisht
       visibility: Dukshmëri
       with_media: Me media
     strikes:
diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml
index 76a0f8afe9..0b3043c47b 100644
--- a/config/locales/sr-Latn.yml
+++ b/config/locales/sr-Latn.yml
@@ -807,7 +807,6 @@ sr-Latn:
       original_status: Originalna objava
       reblogs: Deljenja
       status_changed: Objava promenjena
-      title: Statusi naloga - @%{name}
       trending: U trendu
       visibility: Vidljivost
       with_media: Sa multimedijom
diff --git a/config/locales/sr.yml b/config/locales/sr.yml
index 6a75316c23..e077a40eee 100644
--- a/config/locales/sr.yml
+++ b/config/locales/sr.yml
@@ -837,7 +837,6 @@ sr:
       original_status: Оригинална објава
       reblogs: Дељења
       status_changed: Објава промењена
-      title: Статуси налога - @%{name}
       trending: У тренду
       visibility: Видљивост
       with_media: Са мултимедијом
diff --git a/config/locales/sv.yml b/config/locales/sv.yml
index 11b37f8bfc..c48b45b2e8 100644
--- a/config/locales/sv.yml
+++ b/config/locales/sv.yml
@@ -826,8 +826,10 @@ sv:
       back_to_account: Tillbaka till kontosidan
       back_to_report: Tillbaka till rapportsidan
       batch:
+        add_to_report: 'Lägg till i rapport #%{id}'
         remove_from_report: Ta bort från rapport
         report: Rapportera
+      contents: Innehåll
       deleted: Raderad
       favourites: Favoriter
       history: Versionshistorik
@@ -836,13 +838,16 @@ sv:
       media:
         title: Media
       metadata: Metadata
+      no_history: Detta inlägg har inte redigerats
       no_status_selected: Inga inlägg ändrades eftersom inga valdes
       open: Öppna inlägg
       original_status: Ursprungligt inlägg
       reblogs: Ombloggningar
       status_changed: Inlägg ändrat
+      status_title: Inlägg av @%{name}
       title: Kontoinlägg - @%{name}
       trending: Trendande
+      view_publicly: Visa offentligt
       visibility: Synlighet
       with_media: Med media
     strikes:
diff --git a/config/locales/th.yml b/config/locales/th.yml
index 32f2b30292..5178506bab 100644
--- a/config/locales/th.yml
+++ b/config/locales/th.yml
@@ -819,7 +819,6 @@ th:
       original_status: โพสต์ดั้งเดิม
       reblogs: การดัน
       status_changed: เปลี่ยนโพสต์แล้ว
-      title: โพสต์ของบัญชี - @%{name}
       trending: กำลังนิยม
       visibility: การมองเห็น
       with_media: มีสื่อ
diff --git a/config/locales/tr.yml b/config/locales/tr.yml
index 2eafed1b47..a0002070c6 100644
--- a/config/locales/tr.yml
+++ b/config/locales/tr.yml
@@ -826,8 +826,10 @@ tr:
       back_to_account: Hesap sayfasına geri dön
       back_to_report: Bildirim sayfasına geri dön
       batch:
+        add_to_report: 'Rapora ekle #%{id}'
         remove_from_report: Bildirimden kaldır
         report: Bildirim
+      contents: İçerikler
       deleted: Silindi
       favourites: Favoriler
       history: Sürüm geçmişi
@@ -836,13 +838,17 @@ tr:
       media:
         title: Medya
       metadata: Üstveri
+      no_history: Bu gönderi düzenlenmemiş
       no_status_selected: Hiçbiri seçilmediğinden hiçbir durum değiştirilmedi
       open: Gönderiyi aç
       original_status: Özgün gönderi
       reblogs: Yeniden Paylaşımlar
+      replied_to_html: Yanıtladı %{acct_link}
       status_changed: Gönderi değişti
-      title: Hesap durumları - @%{name}
+      status_title: Gönderen @%{name}
+      title: Hesap gönderileri - @%{name}
       trending: Öne çıkanlar
+      view_publicly: Herkese Açık Görüntüle
       visibility: Görünürlük
       with_media: Medya ile
     strikes:
diff --git a/config/locales/uk.yml b/config/locales/uk.yml
index 7ea76b2a75..68ca10c0cc 100644
--- a/config/locales/uk.yml
+++ b/config/locales/uk.yml
@@ -861,7 +861,6 @@ uk:
       original_status: Оригінальний допис
       reblogs: Поширення
       status_changed: Допис змінено
-      title: Дописи облікових записів - @%{name}
       trending: Популярне
       visibility: Видимість
       with_media: З медіа
diff --git a/config/locales/vi.yml b/config/locales/vi.yml
index 71c4357f2f..acc69f96cd 100644
--- a/config/locales/vi.yml
+++ b/config/locales/vi.yml
@@ -812,8 +812,10 @@ vi:
       back_to_account: Quay lại trang tài khoản
       back_to_report: Quay lại trang báo cáo
       batch:
+        add_to_report: 'Thêm vào báo cáo #%{id}'
         remove_from_report: Xóa khỏi báo cáo
         report: Báo cáo
+      contents: Nội dung
       deleted: Đã xóa
       favourites: Lượt thích
       history: Lịch sử phiên bản
@@ -822,13 +824,17 @@ vi:
       media:
         title: Media
       metadata: Metadata
+      no_history: Tút này chưa được chỉnh sửa
       no_status_selected: Bạn chưa chọn bất kỳ tút nào
       open: Mở tút
       original_status: Tút gốc
       reblogs: Lượt đăng lại
+      replied_to_html: Trả lời đến %{acct_link}
       status_changed: Tút đã sửa
-      title: Tất cả tút - @%{name}
+      status_title: Đăng bởi @%{name}
+      title: Tút từ tài khoản - @%{name}
       trending: Xu hướng
+      view_publicly: Xem công khai
       visibility: Hiển thị
       with_media: Có media
     strikes:
diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml
index cae0efee57..7dc0f3d949 100644
--- a/config/locales/zh-CN.yml
+++ b/config/locales/zh-CN.yml
@@ -10,7 +10,7 @@ zh-CN:
     followers:
       other: 关注者
     following: 正在关注
-    instance_actor_flash: 该账号用来代表虚拟角色,并不代表个人用户,仅代表服务器本身。该账号用于达成互联之目的,不应该被停用。
+    instance_actor_flash: 该账号用来代表虚拟角色,并不代表个人用户,仅代表服务器本身。该账号用于联合目的,不应该被停用。
     last_active: 最近活动
     link_verified_on: 此链接的所有权已在 %{date} 检查
     nothing_here: 空空如也!
@@ -24,7 +24,7 @@ zh-CN:
     account_actions:
       action: 执行操作
       already_silenced: 此账户已受限。
-      already_suspended: 此帐户已被封禁。
+      already_suspended: 此账户已被封禁。
       title: 在 %{acct} 上执行管理操作
     account_moderation_notes:
       create: 新建记录
@@ -86,9 +86,9 @@ zh-CN:
         title: 位置
       login_status: 登录状态
       media_attachments: 媒体文件
-      memorialize: 设置为追悼账户
-      memorialized: 被悼念
-      memorialized_msg: 成功将 %{username} 转换为悼念账号
+      memorialize: 设为追悼账户
+      memorialized: 已设为追悼账户
+      memorialized_msg: 成功将 %{username} 转换为追悼账户
       moderation:
         active: 活跃
         all: 全部
@@ -98,8 +98,8 @@ zh-CN:
         suspended: 已封禁
         title: 管理
       moderation_notes: 管理记录
-      most_recent_activity: 最后一次活跃的时间
-      most_recent_ip: 最后一次活跃的 IP 地址
+      most_recent_activity: 最后活跃时间
+      most_recent_ip: 最后活跃IP
       no_account_selected: 因为没有选中任何账号,所以没有更改
       no_limits_imposed: 无限制
       no_role_assigned: 未定角色
@@ -167,7 +167,7 @@ zh-CN:
       view_domain: 查看域名摘要
       warn: 警告
       web: 站内页面
-      whitelisted: 允许跨站交互
+      whitelisted: 允许联合
     action_logs:
       action_types:
         approve_appeal: 批准申诉
@@ -209,7 +209,7 @@ zh-CN:
         enable_relay: 启用中继站
         enable_sign_in_token_auth_user: 为用户启用邮件令牌身份验证
         enable_user: 启用用户
-        memorialize_account: 将账户设为追悼模式
+        memorialize_account: 设为追悼账户
         promote_user: 给用户升任
         reject_appeal: 驳回申诉
         reject_user: 拒绝用户
@@ -244,7 +244,7 @@ zh-CN:
         create_announcement_html: "%{name} 创建了新公告 %{target}"
         create_canonical_email_block_html: "%{name} 封禁了 hash 为 %{target} 的邮箱地址"
         create_custom_emoji_html: "%{name} 添加了新的自定义表情 %{target}"
-        create_domain_allow_html: "%{name} 允许了和域名 %{target} 的跨站交互"
+        create_domain_allow_html: "%{name} 允许了与实例 %{target} 的联合"
         create_domain_block_html: "%{name} 屏蔽了域名 %{target}"
         create_email_domain_block_html: "%{name} 封禁了邮箱域名 %{target}"
         create_ip_block_html: "%{name} 为 IP %{target} 创建了规则"
@@ -255,7 +255,7 @@ zh-CN:
         destroy_announcement_html: "%{name} 删除了公告 %{target}"
         destroy_canonical_email_block_html: "%{name} 解封了 hash 为 %{target} 的邮箱地址"
         destroy_custom_emoji_html: "%{name} 删除了自定义表情 %{target}"
-        destroy_domain_allow_html: "%{name} 拒绝了和 %{target} 跨站交互"
+        destroy_domain_allow_html: "%{name} 拒绝了与实例 %{target} 的联合"
         destroy_domain_block_html: "%{name} 解除了对域名 %{target} 的屏蔽"
         destroy_email_domain_block_html: "%{name} 解封了邮箱域名 %{target}"
         destroy_instance_html: "%{name} 删除了实例 %{target}"
@@ -301,7 +301,7 @@ zh-CN:
       empty: 没有找到日志
       filter_by_action: 根据行为过滤
       filter_by_user: 根据用户过滤
-      title: 运营日志
+      title: 审核日志
       unavailable_instance: "(域名不可用)"
     announcements:
       destroyed_msg: 公告已删除!
@@ -337,7 +337,7 @@ zh-CN:
       emoji: 表情
       enable: 启用
       enabled: 已启用
-      enabled_msg: 表情启用成功
+      enabled_msg: 已成功启用此表情
       image_hint: 最大 %{size} 的 PNG 或 GIF
       list: 列表
       listed: 已显示
@@ -350,7 +350,7 @@ zh-CN:
       shortcode_hint: 至少 2 个字符,只能使用字母、数字和下划线
       title: 自定义表情
       uncategorized: 未分类
-      unlist: 不公开
+      unlist: 隐藏
       unlisted: 已隐藏
       update_failed_msg: 表情更新失败
       updated_msg: 表情更新成功!
@@ -370,24 +370,24 @@ zh-CN:
       pending_users_html:
         other: "<strong>%{count}</strong> 个待处理用户"
       resolved_reports: 已处理的举报
-      software: 软件
+      software: 软件信息
       sources: 注册来源
       space: 存储使用情况
       title: 信息面板
       top_languages: 最活跃的语言
       top_servers: 最活跃的服务器
-      website: 网页端
+      website: 网站
     disputes:
       appeals:
-        empty: 没有发现申诉。
+        empty: 未找到申诉。
         title: 申诉
     domain_allows:
-      add_new: 允许和域名跨站交互
-      created_msg: 域名已被允许跨站交互
-      destroyed_msg: 域名已被禁止跨站交互
+      add_new: 允许与此实例联合
+      created_msg: 实例已被允许联合
+      destroyed_msg: 实例已被禁止联合
       export: 导出
       import: 导入
-      undo: 不允许和该域名跨站交互
+      undo: 禁止与此实例联合
     domain_blocks:
       add_new: 添加新屏蔽域名
       confirm_suspension:
@@ -403,15 +403,15 @@ zh-CN:
       destroyed_msg: 域名屏蔽已撤销
       domain: 域名
       edit: 编辑域名屏蔽
-      existing_domain_block: 您已经对 %{name} 设置了更严格的限制。
+      existing_domain_block: 你已经对 %{name} 设置了更严格的限制。
       existing_domain_block_html: 你已经对 %{name} 施加了更严格的限制,你需要先 <a href="%{unblock_url}">解封</a>。
       export: 导出
       import: 导入
       new:
         create: 添加屏蔽
-        hint: 域名屏蔽不会阻止该域名下的帐户进入本站的数据库,但是会对来自这个域名的帐户自动进行预先设置的管理操作。
+        hint: 域名屏蔽不会阻止该域名下的账户进入本站的数据库,但是会对来自这个域名的账户自动进行预先设置的管理操作。
         severity:
-          desc_html: 选择<strong>隐藏</strong>会将该域名下帐户发送的嘟文设置为仅关注者可见;选择<strong>封禁</strong>会将该域名下帐户发送的嘟文、媒体文件以及个人资料数据从本实例上删除;如果你只是想拒绝接收来自该域名的任何媒体文件,请选择<strong>无</strong>。
+          desc_html: 选择<strong>隐藏</strong>会将该域名下账户发送的嘟文设置为仅关注者可见;选择<strong>封禁</strong>会将该域名下账户发送的嘟文、媒体文件以及个人资料数据从本实例上删除;如果你只是想拒绝接收来自该域名的任何媒体文件,请选择<strong>无</strong>。
           noop: 无
           silence: 隐藏
           suspend: 封禁
@@ -456,9 +456,9 @@ zh-CN:
       no_file: 没有选择文件
     export_domain_blocks:
       import:
-        description_html: 您即将导入域名列表,如果您不是此域名列表的作者,请仔细检查核对。
+        description_html: 你即将导入域名列表,如果你不是此域名列表的作者,请仔细检查核对。
         existing_relationships_warning: 现有的关注关系
-        private_comment_description_html: 为了帮助您追踪域名列表来源,导入的域名列表将被添加如下的私人注释:<q>%{comment}</q>
+        private_comment_description_html: 为了帮助你追踪域名列表来源,导入的域名列表将被添加如下的私人注释:<q>%{comment}</q>
         private_comment_template: 从 %{source} 导入 %{date}
         title: 导入域名列表
       invalid_domain_block: 由于以下错误,一个或多个域名屏蔽被跳过: %{error}
@@ -494,7 +494,7 @@ zh-CN:
       content_policies:
         comment: 内部备注
         description_html: 你可以设置应用于此域名所有账号和其所有子域名的内容策略。
-        limited_federation_mode_description_html: 您可以选择是否允许与该联邦联合。
+        limited_federation_mode_description_html: 你可以选择是否允许与此实例联合。
         policies:
           reject_media: 拒收媒体
           reject_reports: 拒收举报
@@ -529,7 +529,7 @@ zh-CN:
       moderation:
         all: 全部
         limited: 受限的
-        title: 运营
+        title: 审核
       private_comment: 私密评论
       public_comment: 公开评论
       purge: 删除
@@ -543,7 +543,7 @@ zh-CN:
       totals_time_period_hint_html: 下方显示的总数来自全部历史数据。
       unknown_instance: 此服务器上目前没有此域名的记录。
     invites:
-      deactivate_all: 撤销所有邀请链接
+      deactivate_all: 全部停用
       filter:
         all: 全部
         available: 可用
@@ -563,7 +563,7 @@ zh-CN:
         '94670856': 3年
       new:
         title: 创建新 IP 规则
-      no_ip_block_selected: 因为没有 IP 规则被选中,所以没有更改
+      no_ip_block_selected: 未选中任何 IP 规则,所以没有更改
       title: IP 规则
     relationships:
       title: "%{acct} 的关系"
@@ -580,7 +580,7 @@ zh-CN:
       pending: 等待中继站的确认
       save_and_enable: 保存并启用
       setup: 设置中继连接
-      signatures_not_enabled: 安全模式或限联模式启用时,中继将不会正常工作
+      signatures_not_enabled: 安全模式或白名单模式启用时,中继站可能将不会正常工作
       status: 状态
       title: 中继站
     report_notes:
@@ -597,10 +597,10 @@ zh-CN:
         mark_as_sensitive_description_html: 被举报的嘟文将被标记为敏感,同时该账号将被标记一次处罚,以供未来同一账号再次违规时参考。
         other_description_html: 查看更多控制该账号行为的选项,并自定义编写与被举报账号的通信。
         resolve_description_html: 不会对被举报账号采取任何动作,举报将被关闭,也不会留下处罚记录。
-        silence_description_html: 只有关注或手工搜索此账号才能查看其资料,将严重限制其触达范围。可随时撤销。关闭针对此帐户的所有举报。
-        suspend_description_html: 该帐户及其所有内容将无法访问并最终被删除,且无法与该帐户进行互动。 在 30 天内可随时撤销。关闭针对此帐户的所有举报。
+        silence_description_html: 只有关注或手工搜索此账号才能查看其资料,将严重限制其触达范围。可随时撤销。关闭针对此账户的所有举报。
+        suspend_description_html: 该账户及其所有内容将无法访问并最终被删除,且无法与该账户进行互动。 在 30 天内可随时撤销。关闭针对此账户的所有举报。
       actions_description_html: 决定采取何种措施处理此举报。如果对被举报账号采取惩罚性措施,将向其发送一封电子邮件通知。但若选中<strong>垃圾信息</strong>类别则不会发送通知。
-      actions_description_remote_html: 决定采取何种行动来解决此举报。 这只会影响<strong>您的</strong>服务器如何与该远程帐户的通信并处理其内容。
+      actions_description_remote_html: 决定采取何种行动来解决此举报。 这只会影响<strong>你的</strong>服务器如何与该远程账户的通信并处理其内容。
       actions_no_posts: 该举报没有相关嘟文可供删除
       add_to_report: 增加更多举报内容
       already_suspended_badges:
@@ -622,7 +622,7 @@ zh-CN:
       delete_and_resolve: 删除嘟文
       forwarded: 已转发
       forwarded_replies_explanation: 该举报来自外站用户,涉及外站内容。之所以转发给你,是因为被举报的内容是对你站点一位用户的回复。
-      forwarded_to: 转发举报至 %{domain}
+      forwarded_to: 转发举报到 %{domain}
       mark_as_resolved: 标记为已处理
       mark_as_sensitive: 标记为敏感内容
       mark_as_unresolved: 标记为未处理
@@ -630,7 +630,7 @@ zh-CN:
       notes:
         create: 添加记录
         create_and_resolve: 添加记录并标记为“已处理”
-        create_and_unresolve: 添加记录并重开
+        create_and_unresolve: 添加备注并重新打开
         delete: 删除
         placeholder: 描述已经执行的操作,或其他任何相关的跟进情况…
         title: 备注
@@ -651,10 +651,10 @@ zh-CN:
       statuses_description_html: 在与该账号的通信中将引用违规内容
       summary:
         action_preambles:
-          delete_html: 您即将<strong>删除</strong> <strong>@%{acct}</strong> 的一些嘟文。 这将:
-          mark_as_sensitive_html: 您即将 <strong>标记</strong> <strong>@%{acct}</strong> 的帖一些子为 <strong>敏感</strong>。这将:
-          silence_html: 您即将<strong>限制</strong> <strong>@%{acct}</strong> 的帐户。 这将:
-          suspend_html: 您即将<strong>暂停</strong> <strong>@%{acct}</strong> 的帐户。 这将:
+          delete_html: 你即将<strong>删除</strong> <strong>@%{acct}</strong> 的一些嘟文。 这将:
+          mark_as_sensitive_html: 你即将 <strong>标记</strong> <strong>@%{acct}</strong> 的帖一些子为 <strong>敏感</strong>。这将:
+          silence_html: 你即将<strong>限制</strong> <strong>@%{acct}</strong> 的账户。 这将:
+          suspend_html: 你即将<strong>暂停</strong> <strong>@%{acct}</strong> 的账户。 这将:
         actions:
           delete_html: 删除违规嘟文
           mark_as_sensitive_html: 将违规嘟文的媒体标记为敏感
@@ -664,7 +664,7 @@ zh-CN:
         close_reports_html: 将针对 <strong>@%{acct}</strong> 的<strong>所有</strong> 报告标记为已解决
         delete_data_html: 从现在起 30 天后删除 <strong>@%{acct}</strong> 的个人资料和内容,除非他们同时解除暂停。
         preview_preamble_html: "<strong>@%{acct}</strong> 将收到包含以下内容的警告:"
-        record_strike_html: 记录一次针对 <strong>@%{acct}</strong> 的警示,以帮助您在这个帐户上的未来违规事件中得到重视。
+        record_strike_html: 记录一次针对 <strong>@%{acct}</strong> 的警示,以帮助你在这个账户上的未来违规事件中得到重视。
         send_email_html: 向 <strong>@%{acct}</strong> 发送警告邮件
         warning_placeholder: 可选的补充理由,以说明调整的情况。
       target_origin: 被举报账号的来源
@@ -685,7 +685,7 @@ zh-CN:
         moderation: 监察
         special: 特殊
       delete: 刪除
-      description_html: 使用 <strong>用户角色</strong>,您可以自定义您的用户可以访问的功能和区域。
+      description_html: 使用 <strong>用户角色</strong>,你可以自定义你的用户可以访问的功能和区域。
       edit: 编辑 '%{name}' 角色
       everyone: 默认权限
       everyone_full_description_html: 这是影响到 <strong>所有用户</strong>的<strong>基础角色</strong>,包括未指定角色的用户。 其他所有的角色都继承着它的权限。
@@ -706,7 +706,7 @@ zh-CN:
         manage_blocks_description: 允许用户屏蔽邮箱提供商和IP地址
         manage_custom_emojis: 管理自定义表情
         manage_custom_emojis_description: 允许用户管理服务器上的自定义表情
-        manage_federation: 管理邦联
+        manage_federation: 管理联合
         manage_federation_description: 允许用户屏蔽或允许同其他域名的邦联,并控制消息投递能力
         manage_invites: 管理邀请
         manage_invites_description: 允许用户浏览和停用邀请链接
@@ -743,7 +743,7 @@ zh-CN:
     settings:
       about:
         manage_rules: 管理服务器规则
-        preamble: 提供此服务器如何运营、资金状况等的深入信息。
+        preamble: 提供此服务器如何运营、审核及资金状况等详细信息。
         rules_hint: 有一个专门区域用于显示用户需要遵守的规则。
         title: 关于本站
       appearance:
@@ -774,7 +774,7 @@ zh-CN:
       domain_blocks:
         all: 对所有人
         disabled: 不对任何人
-        users: 对本地已登录用户
+        users: 对已登录的本站用户
       registrations:
         moderation_recommandation: 在向所有人开放注册之前,请确保你拥有一个人手足够且反应迅速的管理团队!
         preamble: 控制谁可以在你的服务器上创建账号。
@@ -789,7 +789,7 @@ zh-CN:
         authorized_fetch: 需要跨站认证
         authorized_fetch_hint: 要求外站请求通过验证能够使用户级别与服务器级别的封锁更为严格。然而,这将带来额外的性能负担、减少回复触达范围、并可能导致与一些联邦宇宙服务的兼容性问题。此外,这并不能阻止他人针对性地获取公开嘟文与账户。
         authorized_fetch_overridden_hint: 由于此设置被环境变量覆盖,目前无法更改。
-        federation_authentication: 强制跨站认证
+        federation_authentication: 联合时强制要求身份验证
       title: 服务器设置
     site_uploads:
       delete: 删除已上传的文件
@@ -809,11 +809,13 @@ zh-CN:
     statuses:
       account: 作者
       application: 应用
-      back_to_account: 返回帐户信息页
+      back_to_account: 返回账户信息页
       back_to_report: 返回举报页
       batch:
+        add_to_report: '添加到举报 #%{id}'
         remove_from_report: 从报告中移除
         report: 举报
+      contents: 内容
       deleted: 已删除
       favourites: 喜欢
       history: 版本历史记录
@@ -822,13 +824,17 @@ zh-CN:
       media:
         title: 媒体文件
       metadata: 元数据
+      no_history: 此嘟文没有编辑历史
       no_status_selected: 因为没有嘟文被选中,所以没有更改
       open: 展开嘟文
       original_status: 原始嘟文
       reblogs: 转发
+      replied_to_html: 回复给 %{acct_link}
       status_changed: 嘟文已编辑
-      title: 帐户嘟文 - @%{name}
+      status_title: "@%{name} 的嘟文"
+      title: 该账号的嘟文 - @%{name}
       trending: 当前热门
+      view_publicly: 以公开身份查看
       visibility: 可见性
       with_media: 含有媒体文件
     strikes:
@@ -960,7 +966,7 @@ zh-CN:
           tag_languages_dimension: 语言排行
           tag_servers_dimension: 服务器排行
           tag_servers_measure: 不同服务器
-          tag_uses_measure: 总使用
+          tag_uses_measure: 总使用次数
         description_html: 这些是当前此服务器可见嘟文中大量出现的标签。它可以帮助用户发现其他人正关注的话题。在获得批准前不会公开显示任何标签。
         listable: 可被推荐
         no_tag_selected: 因为没有选中任何标签,所以没有更改
@@ -980,17 +986,17 @@ zh-CN:
     warning_presets:
       add_new: 添加新条目
       delete: 删除
-      edit_preset: 编辑预置警告
+      edit_preset: 编辑预设警告
       empty: 你尚未定义任何警告预设。
       title: 预设警告
     webhooks:
-      add_new: 新增对端
+      add_new: 新增端点
       delete: 删除
       description_html: "<strong>Webhook</strong> 使 Mastodon 能够推送 <strong>关于所选事件的实时通知</strong> 到你自己的应用程序,进而由你的应用程序<strong>自动触发反应</strong>。"
       disable: 禁用
       disabled: 已禁用
       edit: 编辑对端
-      empty: 你尚未配置任何 Webhook 对端。
+      empty: 你尚未配置任何 Webhook 端点。
       enable: 启用
       enabled: 活跃
       enabled_events:
@@ -1043,14 +1049,14 @@ zh-CN:
   aliases:
     add_new: 创建别名
     created_msg: 成功创建了一个新别名。你现在可以从旧账户开始迁移了。
-    deleted_msg: 成功移除别名。已经无法从该帐户移动到此帐户了。
-    empty: 你没有设置别名
+    deleted_msg: 成功移除别名。已经无法从该账户移动到此账户了。
+    empty: 你没有设置别名。
     hint_html: 如果你想从另一个账号迁移到这里,可以先在这里创建一个别名。要把旧账号的关注者迁移过来,这一步是必须的。设置别名的操作是<strong>无害且可撤销的</strong>。<strong>账号迁移的操作会从旧账号发起</strong>。
     remove: 取消关联别名
   appearance:
     advanced_web_interface: 高级 Web 界面
-    advanced_web_interface_hint: 如果你想使用整个屏幕宽度,高级 web 界面允许您配置多个不同的栏目,可以同时看到更多的信息:主页、通知、跨站时间轴、任意数量的列表和话题标签。
-    animations_and_accessibility: 动画和访问选项
+    advanced_web_interface_hint: 如果你想使用整个屏幕宽度,高级 web 界面允许你配置多个不同的栏目,可以同时看到更多的信息:主页、通知、跨站时间轴、任意数量的列表和话题标签。
+    animations_and_accessibility: 动画与可访问性
     confirmation_dialogs: 确认对话框
     discovery: 发现
     localization:
@@ -1090,8 +1096,8 @@ zh-CN:
       registration_complete: 你在 %{domain} 上的注册现已完成!
       welcome_title: 欢迎你,%{name}!
       wrong_email_hint: 如果该邮箱地址不正确,你可以在账户设置中进行更改。
-    delete_account: 删除帐户
-    delete_account_html: 如果你想删除你的帐户,请<a href="%{path}">点击这里继续</a>。你需要确认你的操作。
+    delete_account: 删除账户
+    delete_account_html: 如果你想删除你的账户,请<a href="%{path}">点击这里继续</a>。你需要确认你的操作。
     description:
       prefix_invited_by_user: "@%{name} 邀请你加入这个Mastodon服务器!"
       prefix_sign_up: 现在就注册 Mastodon!
@@ -1111,8 +1117,8 @@ zh-CN:
     privacy_policy_agreement_html: 我已阅读并同意 <a href="%{privacy_policy_path}" target="_blank">隐私政策</a>
     progress:
       confirm: 确认邮箱
-      details: 您的详情
-      review: 我们的复审
+      details: 你的详情
+      review: 我们的审核
       rules: 接受规则
     providers:
       cas: CAS
@@ -1128,21 +1134,21 @@ zh-CN:
       preamble: 这些由 %{domain} 监察员设置和执行。
       preamble_invited: 在你继续之前,请考虑 %{domain} 的管理员设定的基本规则。
       title: 一些基本规则。
-      title_invited: 您已经被邀请。
+      title_invited: 你已经被邀请。
     security: 账户安全
     set_new_password: 设置新密码
     setup:
       email_below_hint_html: 请检查你的垃圾邮件文件夹,或请求再发送一次。如果你的邮箱地址不正确,你可以更正它。
-      email_settings_hint_html: 请点击我们发送给 %{email} 地址中的确认链接。我在这儿等着您。
+      email_settings_hint_html: 请点击我们发送给 %{email} 地址中的确认链接。我在这儿等着你。
       link_not_received: 没有收到链接?
       new_confirmation_instructions_sent: 你将在几分钟内收到一封带有确认链接的新邮件!
       title: 请检查你的收件箱
     sign_in:
-      preamble_html: 使用您在 <strong>%{domain}</strong> 的账户和密码登录。如果您的账户托管在其他的服务器上,您将无法在此登录。
+      preamble_html: 使用你在 <strong>%{domain}</strong> 的账户和密码登录。如果你的账户托管在其他的服务器上,你将无法在此登录。
       title: 登录到 %{domain}
     sign_up:
-      manual_review: 您在 %{domain} 上的注册需要经由管理人员手动审核。 为了帮助我们处理您的注册,请稍微介绍一下您为什么想在 %{domain} 上注册。
-      preamble: 有了这个Mastodon服务器上的账户,您就可以关注Mastodon网络上的任何其他人,无论他们的账户在哪里。
+      manual_review: 你在 %{domain} 上的注册需要经由管理人员手动审核。 为了帮助我们处理你的注册,请稍微介绍一下你为什么想在 %{domain} 上注册。
+      preamble: 有了这个Mastodon服务器上的账户,你就可以关注Mastodon网络上的任何其他人,无论他们的账户在哪里。
       title: 让我们在 %{domain} 上开始。
     status:
       account_status: 账户状态
@@ -1157,7 +1163,7 @@ zh-CN:
   author_attribution:
     example_title: 示例文本
     hint_html: 你是否在 Mastodon 之外撰写新闻或博客文章?控制它们被分享到 Mastodon 时的署名方式。
-    instructions: 请确保将这段代码放在您文章的 HTML 中:
+    instructions: 请确保将这段代码放在你文章的 HTML 中:
     more_from_html: 来自 %{name} 的更多内容
     s_blog: "%{name} 的博客"
     then_instructions: 然后,在下面的文本框中添加你用于发布文章的域名。
@@ -1218,7 +1224,7 @@ zh-CN:
       approve_appeal: 批准申诉
       associated_report: 相关举报
       created_at: 日期
-      description_html: 这些是针对您的账户采取的行动和警告,已经由 %{instance} 的工作人员发送给您。
+      description_html: 这些是针对你的账户采取的行动和警告,已经由 %{instance} 的工作人员发送给你。
       recipient: 发送至
       reject_appeal: 驳回申诉
       status: '嘟文 #%{id}'
@@ -1237,7 +1243,7 @@ zh-CN:
       your_appeal_rejected: 你的申诉已被驳回
   edit_profile:
     basic_information: 基本信息
-    hint_html: "<strong>自定义公开资料和嘟文旁边显示的内容。</strong>当您填写完整的个人资料并设置了头像时,其他人更有可能关注您并与您互动。"
+    hint_html: "<strong>自定义公开资料和嘟文旁边显示的内容。</strong>当你填写完整的个人资料并设置了头像时,其他人更有可能关注你并与你互动。"
     other: 其他
   errors:
     '400': 你提交的请求无效或格式不正确。
@@ -1275,7 +1281,7 @@ zh-CN:
   featured_tags:
     add_new: 添加新条目
     errors:
-      limit: 您所推荐的话题标签数已达上限
+      limit: 你所推荐的话题标签数已达上限
     hint_html: "<strong>什么是精选话题标签?</strong> 它们被显示在你的公开个人资料中的突出位置,人们可以在这些标签下浏览你的公共嘟文。 它们是跟踪创作或长期项目的进度的重要工具。"
   filters:
     contexts:
@@ -1321,7 +1327,7 @@ zh-CN:
     all_items_on_page_selected_html:
       other: 此页面上的所有 <strong>%{count}</strong> 项目已被选中。
     all_matching_items_selected_html:
-      other: 所有 <strong>%{count}</strong> 匹配您搜索的项目都已被选中。
+      other: 所有 <strong>%{count}</strong> 匹配你搜索的项目都已被选中。
     cancel: 取消
     changes_saved_msg: 更改保存成功!
     confirm: 确认
@@ -1332,7 +1338,7 @@ zh-CN:
     order_by: 排序方式
     save_changes: 保存更改
     select_all_matching_items:
-      other: 选择匹配您搜索的所有 %{count} 个项目。
+      other: 选择匹配你搜索的所有 %{count} 个项目。
     today: 今天
     validation_errors:
       other: 出错啦!检查一下下面 %{count} 处出错的地方吧
@@ -1353,7 +1359,7 @@ zh-CN:
       overwrite_long: 将当前记录替换为新记录
     overwrite_preambles:
       blocking_html:
-        other: 你即将使用来自 <strong>%{filename}</strong> 的最多 <strong>%{count} 个</strong>帐户<strong>替换你的屏蔽列表</strong>。
+        other: 你即将使用来自 <strong>%{filename}</strong> 的最多 <strong>%{count} 个</strong>账户<strong>替换你的屏蔽列表</strong>。
       bookmarks_html:
         other: 你即将使用来自 <strong>%{filename}</strong> 的最多 <strong>%{count} 条</strong>嘟文<strong>替换你的书签</strong>。
       domain_blocking_html:
@@ -1363,7 +1369,7 @@ zh-CN:
       lists_html:
         other: 你即将使用来自 <strong>%{filename}</strong> 的内容<strong>替换你的列表</strong>。最多将会有 <strong>%{count} 个账户</strong> 被添加到新列表。
       muting_html:
-        other: 你即将使用来自 <strong>%{filename}</strong> 的最多 <strong>%{count} 个</strong>帐户<strong>替换你的已隐藏账户列表</strong>。
+        other: 你即将使用来自 <strong>%{filename}</strong> 的最多 <strong>%{count} 个</strong>账户<strong>替换你的已隐藏账户列表</strong>。
     preambles:
       blocking_html:
         other: 你即将<strong>屏蔽</strong>来自 <strong>%{filename}</strong> 的最多 <strong>%{count} 个账号</strong>。
@@ -1397,7 +1403,7 @@ zh-CN:
     type: 导入类型
     type_groups:
       constructive: 关注和书签
-      destructive: 屏蔽和隐藏
+      destructive: 屏蔽与隐藏
     types:
       blocking: 屏蔽列表
       bookmarks: 书签
@@ -1430,14 +1436,14 @@ zh-CN:
     title: 邀请用户
   lists:
     errors:
-      limit: 您已达到列表数量的上限
+      limit: 你已达到列表数量的上限
   login_activities:
     authentication_methods:
       otp: 双因素认证应用
       password: 密码
       sign_in_token: 邮件安全码
       webauthn: 安全密钥
-    description_html: 如有您无法识别的活动,请考虑更改密码并启用双因素认证。
+    description_html: 如有你无法识别的活动,请考虑更改密码并启用双因素认证。
     empty: 没有可用的认证记录
     failed_sign_in_html: 失败的 %{method} 登录尝试,来自 %{ip} (%{browser})
     successful_sign_in_html: 通过 %{method} 成功登录,来自 %{ip} (%{browser})
@@ -1495,7 +1501,7 @@ zh-CN:
       other_data: 不会自动移动其它数据
       redirect: 在收到一个跳转通知后,你当前的账号资料将会更新,并被排除在搜索范围外
   moderation:
-    title: 运营
+    title: 审核
   move_handler:
     carry_blocks_over_text: 这个用户迁移自你屏蔽过的 %{acct}
     carry_mutes_over_text: 这个用户由你隐藏过的 %{acct} 迁移而来
@@ -1523,7 +1529,7 @@ zh-CN:
       title: 新的关注请求
     mention:
       action: 回复
-      body: "%{name} 在嘟文中提到了你:"
+      body: "%{name} 提到了你:"
       subject: "%{name} 提到了你"
       title: 新的提及
     poll:
@@ -1585,7 +1591,7 @@ zh-CN:
     privacy: 隐私
     privacy_hint_html: 控制你愿意向他人透露多少信息。通过浏览他人的关注列表和查看他们发嘟所用的应用,人们可以发现有趣的用户和酷炫的应用,但你可能更喜欢将其隐藏起来。
     reach: 范围
-    reach_hint_html: 控制您是否希望被新人发现和关注。您是否希望您的嘟文出现在“探索”页面上?您是否希望其他人在关注推荐中看到您?您是想自动接受所有新粉丝,还是对每个粉丝都进行仔细的筛选?
+    reach_hint_html: 控制你是否希望被新人发现和关注。你是否希望你的嘟文出现在“探索”页面上?你是否希望其他人在关注推荐中看到你?你是想自动接受所有新粉丝,还是对每个粉丝都进行仔细的筛选?
     search: 搜索
     search_hint_html: 控制你希望被找到的方式。你想让人们通过你公开发布的内容来找到你吗?当在网络上搜索时,你是否希望Mastodon之外的人能够找到你的个人资料?请注意,我们无法保证完全排除所有搜索引擎对公开信息的索引。
     title: 隐私与可达性
@@ -1593,16 +1599,16 @@ zh-CN:
     title: 隐私政策
   reactions:
     errors:
-      limit_reached: 互动种类的限制
-      unrecognized_emoji: 不是一个可识别的表情
+      limit_reached: 回应种类个数超过限制
+      unrecognized_emoji: 不是一个可被识别的表情
   redirects:
     prompt: 如果你信任此链接,请单击以继续跳转。
     title: 你正在离开 %{instance} 。
   relationships:
     activity: 账号活动
-    confirm_follow_selected_followers: 您确定想要关注所选的关注者吗?
-    confirm_remove_selected_followers: 您确定想要取关所选的关注者吗?
-    confirm_remove_selected_follows: 您确定要删除选定的关注着吗?
+    confirm_follow_selected_followers: 你确定想要关注所选的关注者吗?
+    confirm_remove_selected_followers: 你确定想要取关所选的关注者吗?
+    confirm_remove_selected_follows: 您确定要删除选定的关注者吗?
     dormant: 休眠
     follow_failure: 无法关注选中的部分账户。
     follow_selected_followers: 关注选中的关注者
@@ -1649,12 +1655,12 @@ zh-CN:
       generic: 未知浏览器
       huawei_browser: 华为浏览器
       ie: IE 浏览器
-      micro_messenger: 微信
+      micro_messenger: MicroMessenger
       nokia: Nokia S40 Ovi 浏览器
       opera: 欧朋浏览器
       otter: Otter
       phantom_js: PhantomJS
-      qq: QQ浏览器
+      qq: QQ 浏览器
       safari: Safari
       uc_browser: UC 浏览器
       unknown_browser: 未知浏览器
@@ -1673,7 +1679,7 @@ zh-CN:
       ios: iOS
       kai_os: KaiOS
       linux: Linux
-      mac: Mac
+      mac: macOS
       unknown_platform: 未知平台
       windows: Windows
       windows_mobile: Windows Mobile
@@ -1695,15 +1701,15 @@ zh-CN:
     export: 导出
     featured_tags: 精选的话题标签
     import: 导入
-    import_and_export: 导入和导出
+    import_and_export: 导入与导出
     migrate: 账户迁移
     notifications: 邮件通知
-    preferences: 首选项
+    preferences: 偏好设置
     profile: 个人资料
     relationships: 关注管理
     severed_relationships: 已断开的关系
     statuses_cleanup: 自动删除嘟文
-    strikes: 操作记录
+    strikes: 管理处罚记录
     two_factor_authentication: 双因素认证
     webauthn_authentication: 安全密钥
   severed_relationships:
@@ -1737,7 +1743,7 @@ zh-CN:
     over_character_limit: 超过了 %{max} 字的限制
     pin_errors:
       direct: 仅对被提及的用户可见的帖子不能被置顶
-      limit: 你所固定的嘟文数量已达到上限
+      limit: 你置顶的嘟文数量已达上限
       ownership: 不能置顶别人的嘟文
       reblog: 不能置顶转嘟
     title: "%{name}:“%{quote}”"
@@ -1747,13 +1753,13 @@ zh-CN:
       private_long: 只有关注你的用户能看到
       public: 公开
       public_long: 所有人可见,并会出现在公共时间轴上
-      unlisted: 不公开
+      unlisted: 悄悄公开
       unlisted_long: 所有人可见,但不会出现在公共时间轴上
   statuses_cleanup:
     enabled: 自动删除旧嘟文
-    enabled_hint: 达到指定过期时间后自动删除您的嘟文,除非满足下列条件之一
+    enabled_hint: 达到指定过期时间后自动删除你的嘟文,除非满足下列条件之一
     exceptions: 例外
-    explanation: 删除嘟文是一个消耗系统资源的耗时操作,所以这个操作会在服务器空闲时完成。因此,您的嘟文可能会在达到过期阈值之后一段时间才会被删除。
+    explanation: 删除嘟文是一个消耗系统资源的耗时操作,所以这个操作会在服务器空闲时完成。因此,你的嘟文可能会在达到过期阈值之后一段时间才会被删除。
     ignore_favs: 取消喜欢
     ignore_reblogs: 忽略转嘟
     interaction_exceptions: 基于互动的例外
@@ -1792,10 +1798,10 @@ zh-CN:
   tags:
     does_not_match_previous_name: 和之前的名称不匹配
   themes:
-    contrast: Mastodon(高对比度)
-    default: Mastodon(暗色主题)
-    mastodon-light: Mastodon(亮色主题)
-    system: 自动切换(使用系统主题)
+    contrast: Mastodon (高对比度)
+    default: Mastodon (暗色)
+    mastodon-light: Mastodon (亮色)
+    system: 自动切换 (使用系统主题)
   time:
     formats:
       default: "%Y年%m月%d日 %H:%M"
@@ -1847,10 +1853,10 @@ zh-CN:
     suspicious_sign_in:
       change_password: 更改密码
       details: 以下是该次登录的详细信息:
-      explanation: 我们检测到有新 IP 地址登录了您的账号。
-      further_actions_html: 如果不是您本人操作,我们建议您立即 %{action} 并启用双因素认证,以确保账号安全。
-      subject: 已有新 IP 地址访问了您的账号
-      title: 新登录
+      explanation: 我们检测到有新 IP 地址登录了你的账号。
+      further_actions_html: 如果不是你本人操作,我们建议你立即 %{action} 并启用双因素认证,以确保账号安全。
+      subject: 已有新 IP 地址访问了你的账号
+      title: 一次新登录
     warning:
       appeal: 提交申诉
       appeal_description: 如果你认为此结果有误,可以向 %{instance} 的工作人员提交申诉。
@@ -1895,7 +1901,7 @@ zh-CN:
       explanation: 下面是几个小贴士,希望它们能帮到你
       feature_action: 了解更多
       feature_audience: Mastodon 为你提供了无需中间商即可管理受众的独特可能。Mastodon 可被部署在你自己的基础设施上,允许你关注其它任何 Mastodon 在线服务器的用户,或被任何其他在线 Mastodon 服务器的用户关注,并且不受你之外的任何人控制。
-      feature_audience_title: 放手去建立起你的受众
+      feature_audience_title: 自由吸引你的受众
       feature_control: 你最清楚你想在你自己的主页中看到什么动态。没有算法或广告浪费你的时间。你可以用一个账号关注任何 Mastodon 服务器上的任何人,并按时间顺序获得他们发布的嘟文,让你的互联网的角落更合自己的心意。
       feature_control_title: 掌控自己的时间线
       feature_creativity: Mastodon 支持音频、视频和图片、无障碍描述、投票、内容警告, 动画头像、自定义表情包、缩略图裁剪控制等功能,帮助你在网上尽情表达自己。无论你是要发布你的艺术作品、音乐还是播客,Mastodon 都能为你服务。
diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml
index 6f0a99a5b3..752c9b5cbf 100644
--- a/config/locales/zh-HK.yml
+++ b/config/locales/zh-HK.yml
@@ -777,7 +777,6 @@ zh-HK:
       original_status: 原始帖文
       reblogs: 轉發
       status_changed: 帖文已變更
-      title: 帳戶文章 - @%{name}
       trending: 熱門
       visibility: 可見性
       with_media: 含有媒體檔案
diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml
index ce6bd3e8f5..701ea0ea53 100644
--- a/config/locales/zh-TW.yml
+++ b/config/locales/zh-TW.yml
@@ -814,8 +814,10 @@ zh-TW:
       back_to_account: 返回帳號資訊頁面
       back_to_report: 回到檢舉報告頁面
       batch:
+        add_to_report: '新增至報告 #%{id}'
         remove_from_report: 自檢舉報告中移除
         report: 檢舉報告
+      contents: 內容
       deleted: 已刪除
       favourites: 最愛
       history: 版本紀錄
@@ -824,13 +826,17 @@ zh-TW:
       media:
         title: 媒體檔案
       metadata: 詮釋資料
+      no_history: 此嘟文未曾被編輯
       no_status_selected: 因未選取嘟文,所以什麼事都沒發生。
       open: 公開嘟文
       original_status: 原始嘟文
       reblogs: 轉嘟
+      replied_to_html: 回覆給 %{acct_link}
       status_changed: 嘟文已編輯
-      title: 帳號嘟文 - @%{name}
+      status_title: 由 @%{name} 發嘟
+      title: 嘟文帳號 - @%{name}
       trending: 熱門
+      view_publicly: 公開檢視
       visibility: 可見性
       with_media: 含有媒體檔案
     strikes:

From be413d67de3357ad7cd601970cb9884431edad9e Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Mon, 18 Nov 2024 04:22:09 -0500
Subject: [PATCH 32/44] `Form::Import` spec reduce factories (#32924)

---
 spec/models/form/import_spec.rb | 57 +++++++++------------------------
 1 file changed, 16 insertions(+), 41 deletions(-)

diff --git a/spec/models/form/import_spec.rb b/spec/models/form/import_spec.rb
index 22ffdfd877..e14ad6eca0 100644
--- a/spec/models/form/import_spec.rb
+++ b/spec/models/form/import_spec.rb
@@ -237,51 +237,26 @@ RSpec.describe Form::Import do
       let(:import_file) { file }
       let(:import_mode) { mode }
 
-      before do
-        subject.save
-      end
-
-      it 'creates the expected rows' do
-        expect(account.bulk_imports.first.rows.pluck(:data)).to match_array(expected_rows)
-      end
+      before { subject.save }
 
       context 'with a BulkImport' do
         let(:bulk_import) { account.bulk_imports.first }
 
-        it 'creates a non-nil bulk import' do
-          expect(bulk_import).to_not be_nil
-        end
-
-        it 'matches the subjects type' do
-          expect(bulk_import.type.to_sym).to eq subject.type.to_sym
-        end
-
-        it 'matches the subjects original filename' do
-          expect(bulk_import.original_filename).to eq subject.data.original_filename
-        end
-
-        it 'matches the subjects likely_mismatched? value' do
-          expect(bulk_import.likely_mismatched?).to eq subject.likely_mismatched?
-        end
-
-        it 'matches the subject overwrite value' do
-          expect(bulk_import.overwrite?).to eq !!subject.overwrite # rubocop:disable Style/DoubleNegation
-        end
-
-        it 'has zero processed items' do
-          expect(bulk_import.processed_items).to eq 0
-        end
-
-        it 'has zero imported items' do
-          expect(bulk_import.imported_items).to eq 0
-        end
-
-        it 'has a correct total_items value' do
-          expect(bulk_import.total_items).to eq bulk_import.rows.count
-        end
-
-        it 'defaults to unconfirmed true' do
-          expect(bulk_import.state_unconfirmed?).to be true
+        it 'creates a bulk import with correct values' do
+          expect(bulk_import)
+            .to be_present
+            .and have_attributes(
+              type: eq(subject.type),
+              original_filename: eq(subject.data.original_filename),
+              likely_mismatched?: eq(subject.likely_mismatched?),
+              overwrite?: eq(!!subject.overwrite), # rubocop:disable Style/DoubleNegation
+              processed_items: eq(0),
+              imported_items: eq(0),
+              total_items: eq(bulk_import.rows.count),
+              state_unconfirmed?: be(true)
+            )
+          expect(bulk_import.rows.pluck(:data))
+            .to match_array(expected_rows)
         end
       end
     end

From 16addf47c72ceb258e0cd020620407bb0e78f6af Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Mon, 18 Nov 2024 04:23:07 -0500
Subject: [PATCH 33/44] Reduce long lines in `relationships/show` view (#32922)

---
 app/views/relationships/show.html.haml | 28 ++++++++++++++++++++++----
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/app/views/relationships/show.html.haml b/app/views/relationships/show.html.haml
index 7478b8c5ce..b062a4f53d 100644
--- a/app/views/relationships/show.html.haml
+++ b/app/views/relationships/show.html.haml
@@ -42,13 +42,33 @@
       %label.batch-table__toolbar__select.batch-checkbox-all
         = check_box_tag :batch_checkbox_all, nil, false
       .batch-table__toolbar__actions
-        = f.button safe_join([material_symbol('person_add'), t('relationships.follow_selected_followers')]), name: :follow, class: 'table-action-link', type: :submit, data: { confirm: t('relationships.confirm_follow_selected_followers') } if followed_by_relationship? && !mutual_relationship?
+        - if followed_by_relationship? && !mutual_relationship?
+          = f.button safe_join([material_symbol('person_add'), t('relationships.follow_selected_followers')]),
+                     class: 'table-action-link',
+                     data: { confirm: t('relationships.confirm_follow_selected_followers') },
+                     name: :follow,
+                     type: :submit
 
-        = f.button safe_join([material_symbol('person_remove'), t('relationships.remove_selected_follows')]), name: :unfollow, class: 'table-action-link', type: :submit, data: { confirm: t('relationships.confirm_remove_selected_follows') } unless followed_by_relationship?
+        - unless followed_by_relationship?
+          = f.button safe_join([material_symbol('person_remove'), t('relationships.remove_selected_follows')]),
+                     class: 'table-action-link',
+                     data: { confirm: t('relationships.confirm_remove_selected_follows') },
+                     name: :unfollow,
+                     type: :submit
 
-        = f.button safe_join([material_symbol('delete'), t('relationships.remove_selected_followers')]), name: :remove_from_followers, class: 'table-action-link', type: :submit, data: { confirm: t('relationships.confirm_remove_selected_followers') } unless following_relationship?
+        - unless following_relationship?
+          = f.button safe_join([material_symbol('delete'), t('relationships.remove_selected_followers')]),
+                     class: 'table-action-link',
+                     data: { confirm: t('relationships.confirm_remove_selected_followers') },
+                     name: :remove_from_followers,
+                     type: :submit
 
-        = f.button safe_join([material_symbol('delete'), t('relationships.remove_selected_domains')]), name: :remove_domains_from_followers, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } if followed_by_relationship?
+        - if followed_by_relationship?
+          = f.button safe_join([material_symbol('delete'), t('relationships.remove_selected_domains')]),
+                     class: 'table-action-link',
+                     data: { confirm: t('admin.reports.are_you_sure') },
+                     name: :remove_domains_from_followers,
+                     type: :submit
     .batch-table__body
       - if @accounts.empty?
         = nothing_here 'nothing-here--under-tabs'

From c511cbcd6cdcaf7babce610db24db55498891ecc Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Mon, 18 Nov 2024 04:23:38 -0500
Subject: [PATCH 34/44] Extract constants for controller `LIMIT` queries
 (#32921)

---
 app/controllers/admin/instances_controller.rb                 | 4 +++-
 .../api/v1/featured_tags/suggestions_controller.rb            | 4 +++-
 app/controllers/settings/featured_tags_controller.rb          | 4 +++-
 app/controllers/settings/imports_controller.rb                | 4 +++-
 4 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/app/controllers/admin/instances_controller.rb b/app/controllers/admin/instances_controller.rb
index d7f88a71f3..a48c4773ed 100644
--- a/app/controllers/admin/instances_controller.rb
+++ b/app/controllers/admin/instances_controller.rb
@@ -5,6 +5,8 @@ module Admin
     before_action :set_instances, only: :index
     before_action :set_instance, except: :index
 
+    LOGS_LIMIT = 5
+
     def index
       authorize :instance, :index?
       preload_delivery_failures!
@@ -13,7 +15,7 @@ module Admin
     def show
       authorize :instance, :show?
       @time_period = (6.days.ago.to_date...Time.now.utc.to_date)
-      @action_logs = Admin::ActionLogFilter.new(target_domain: @instance.domain).results.limit(5)
+      @action_logs = Admin::ActionLogFilter.new(target_domain: @instance.domain).results.limit(LOGS_LIMIT)
     end
 
     def destroy
diff --git a/app/controllers/api/v1/featured_tags/suggestions_controller.rb b/app/controllers/api/v1/featured_tags/suggestions_controller.rb
index 9c72e4380d..d533b1af7b 100644
--- a/app/controllers/api/v1/featured_tags/suggestions_controller.rb
+++ b/app/controllers/api/v1/featured_tags/suggestions_controller.rb
@@ -5,6 +5,8 @@ class Api::V1::FeaturedTags::SuggestionsController < Api::BaseController
   before_action :require_user!
   before_action :set_recently_used_tags, only: :index
 
+  RECENT_TAGS_LIMIT = 10
+
   def index
     render json: @recently_used_tags, each_serializer: REST::TagSerializer, relationships: TagRelationshipsPresenter.new(@recently_used_tags, current_user&.account_id)
   end
@@ -12,6 +14,6 @@ class Api::V1::FeaturedTags::SuggestionsController < Api::BaseController
   private
 
   def set_recently_used_tags
-    @recently_used_tags = Tag.suggestions_for_account(current_account).limit(10)
+    @recently_used_tags = Tag.suggestions_for_account(current_account).limit(RECENT_TAGS_LIMIT)
   end
 end
diff --git a/app/controllers/settings/featured_tags_controller.rb b/app/controllers/settings/featured_tags_controller.rb
index 90c112e219..7e29dd1d29 100644
--- a/app/controllers/settings/featured_tags_controller.rb
+++ b/app/controllers/settings/featured_tags_controller.rb
@@ -5,6 +5,8 @@ class Settings::FeaturedTagsController < Settings::BaseController
   before_action :set_featured_tag, except: [:index, :create]
   before_action :set_recently_used_tags, only: :index
 
+  RECENT_TAGS_LIMIT = 10
+
   def index
     @featured_tag = FeaturedTag.new
   end
@@ -38,7 +40,7 @@ class Settings::FeaturedTagsController < Settings::BaseController
   end
 
   def set_recently_used_tags
-    @recently_used_tags = Tag.suggestions_for_account(current_account).limit(10)
+    @recently_used_tags = Tag.suggestions_for_account(current_account).limit(RECENT_TAGS_LIMIT)
   end
 
   def featured_tag_params
diff --git a/app/controllers/settings/imports_controller.rb b/app/controllers/settings/imports_controller.rb
index 569aa07c53..5346a448a3 100644
--- a/app/controllers/settings/imports_controller.rb
+++ b/app/controllers/settings/imports_controller.rb
@@ -24,6 +24,8 @@ class Settings::ImportsController < Settings::BaseController
     lists: false,
   }.freeze
 
+  RECENT_IMPORTS_LIMIT = 10
+
   def index
     @import = Form::Import.new(current_account: current_account)
   end
@@ -96,6 +98,6 @@ class Settings::ImportsController < Settings::BaseController
   end
 
   def set_recent_imports
-    @recent_imports = current_account.bulk_imports.reorder(id: :desc).limit(10)
+    @recent_imports = current_account.bulk_imports.reorder(id: :desc).limit(RECENT_IMPORTS_LIMIT)
   end
 end

From d8e907fae3a1dacf450595ccfdb2864c1e12f1c3 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Mon, 18 Nov 2024 09:25:11 +0000
Subject: [PATCH 35/44] Update dependency aws-sdk-s3 to v1.171.0 (#32901)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
 Gemfile.lock | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/Gemfile.lock b/Gemfile.lock
index 106fb0d0fd..c7ab4e66fe 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -97,8 +97,8 @@ GEM
     attr_required (1.0.2)
     awrence (1.2.1)
     aws-eventstream (1.3.0)
-    aws-partitions (1.1004.0)
-    aws-sdk-core (3.212.0)
+    aws-partitions (1.1008.0)
+    aws-sdk-core (3.213.0)
       aws-eventstream (~> 1, >= 1.3.0)
       aws-partitions (~> 1, >= 1.992.0)
       aws-sigv4 (~> 1.9)
@@ -106,7 +106,7 @@ GEM
     aws-sdk-kms (1.95.0)
       aws-sdk-core (~> 3, >= 3.210.0)
       aws-sigv4 (~> 1.5)
-    aws-sdk-s3 (1.170.1)
+    aws-sdk-s3 (1.171.0)
       aws-sdk-core (~> 3, >= 3.210.0)
       aws-sdk-kms (~> 1)
       aws-sigv4 (~> 1.5)

From 03ee08c2da6634fa1cf566580889e249181200ac Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Mon, 18 Nov 2024 04:31:25 -0500
Subject: [PATCH 36/44] Use `nil` instead of `false` for datetime value in spec
 (#32926)

---
 spec/models/concerns/account/sensitizes_spec.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/spec/models/concerns/account/sensitizes_spec.rb b/spec/models/concerns/account/sensitizes_spec.rb
index 3596c9a126..5416d40570 100644
--- a/spec/models/concerns/account/sensitizes_spec.rb
+++ b/spec/models/concerns/account/sensitizes_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Account::Sensitizes do
     describe '.sensitized' do
       let(:sensitized_account) { Fabricate :account, sensitized_at: 2.days.ago }
 
-      before { Fabricate :account, sensitized_at: false }
+      before { Fabricate :account, sensitized_at: nil }
 
       it 'returns an array of accounts who are sensitized' do
         expect(Account.sensitized)

From 9a46329fbda5926aefc8fdcd9c7a19a2f516885b Mon Sep 17 00:00:00 2001
From: Emelia Smith <ThisIsMissEm@users.noreply.github.com>
Date: Mon, 18 Nov 2024 10:34:34 +0100
Subject: [PATCH 37/44] Streaming: add development logging of database queries
 (#32945)

---
 streaming/database.js | 33 ++++++++++++++++++++++++++++++++-
 streaming/index.js    |  3 ++-
 2 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/streaming/database.js b/streaming/database.js
index 9f1d742143..60a3b34ef0 100644
--- a/streaming/database.js
+++ b/streaming/database.js
@@ -116,13 +116,44 @@ let pool;
 /**
  *
  * @param {pg.PoolConfig} config
+ * @param {string} environment
+ * @param {import('pino').Logger} logger
  * @returns {pg.Pool}
  */
-export function getPool(config) {
+export function getPool(config, environment, logger) {
   if (pool) {
     return pool;
   }
 
   pool = new pg.Pool(config);
+
+  // Setup logging on pool.query and client.query for checked out clients:
+  // This is taken from: https://node-postgres.com/guides/project-structure
+  if (environment === 'development') {
+    const logQuery = (originalQuery) => {
+      return async (queryTextOrConfig, values, ...rest) => {
+        const start = process.hrtime();
+
+        const result = await originalQuery.apply(pool, [queryTextOrConfig, values, ...rest]);
+
+        const duration = process.hrtime(start);
+        const durationInMs = (duration[0] * 1000000000 + duration[1]) / 1000000;
+
+        logger.debug({
+          query: queryTextOrConfig,
+          values,
+          duration: durationInMs
+        }, 'Executed database query');
+
+        return result;
+      };
+    };
+
+    pool.on('connect', (client) => {
+      const originalQuery = client.query.bind(client);
+      client.query = logQuery(originalQuery);
+    });
+  }
+
   return pool;
 }
diff --git a/streaming/index.js b/streaming/index.js
index 3e362f1860..e00da1bb83 100644
--- a/streaming/index.js
+++ b/streaming/index.js
@@ -101,7 +101,8 @@ const CHANNEL_NAMES = [
 ];
 
 const startServer = async () => {
-  const pgPool = Database.getPool(Database.configFromEnv(process.env, environment));
+  const pgConfig = Database.configFromEnv(process.env, environment);
+  const pgPool = Database.getPool(pgConfig, environment, logger);
 
   const metrics = setupMetrics(CHANNEL_NAMES, pgPool);
 

From 911d7dbbf6884d3a67a074a595a5c26c6b8b5434 Mon Sep 17 00:00:00 2001
From: Eugen Rochko <eugen@zeonfederated.com>
Date: Mon, 18 Nov 2024 10:37:01 +0100
Subject: [PATCH 38/44] Fix `min_id` and `max_id` causing error in search API
 (#32857)

---
 app/lib/search_query_transformer.rb       | 20 ++++++++------------
 lib/exceptions.rb                         |  1 -
 spec/lib/search_query_transformer_spec.rb |  2 +-
 3 files changed, 9 insertions(+), 14 deletions(-)

diff --git a/app/lib/search_query_transformer.rb b/app/lib/search_query_transformer.rb
index 1306ed12ed..59352c6e6e 100644
--- a/app/lib/search_query_transformer.rb
+++ b/app/lib/search_query_transformer.rb
@@ -144,6 +144,8 @@ class SearchQueryTransformer < Parslet::Transform
   end
 
   class PrefixClause
+    EPOCH_RE = /\A\d+\z/
+
     attr_reader :operator, :prefix, :term
 
     def initialize(prefix, operator, term, options = {})
@@ -168,15 +170,15 @@ class SearchQueryTransformer < Parslet::Transform
       when 'before'
         @filter = :created_at
         @type = :range
-        @term = { lt: TermValidator.validate_date!(term), time_zone: @options[:current_account]&.user_time_zone.presence || 'UTC' }
+        @term = { lt: date_from_term(term), time_zone: @options[:current_account]&.user_time_zone.presence || 'UTC' }
       when 'after'
         @filter = :created_at
         @type = :range
-        @term = { gt: TermValidator.validate_date!(term), time_zone: @options[:current_account]&.user_time_zone.presence || 'UTC' }
+        @term = { gt: date_from_term(term), time_zone: @options[:current_account]&.user_time_zone.presence || 'UTC' }
       when 'during'
         @filter = :created_at
         @type = :range
-        @term = { gte: TermValidator.validate_date!(term), lte: TermValidator.validate_date!(term), time_zone: @options[:current_account]&.user_time_zone.presence || 'UTC' }
+        @term = { gte: date_from_term(term), lte: date_from_term(term), time_zone: @options[:current_account]&.user_time_zone.presence || 'UTC' }
       when 'in'
         @operator = :flag
         @term = term
@@ -222,16 +224,10 @@ class SearchQueryTransformer < Parslet::Transform
 
       term
     end
-  end
 
-  class TermValidator
-    STRICT_DATE_REGEX = /\A\d{4}-\d{2}-\d{2}\z/ # yyyy-MM-dd
-    EPOCH_MILLIS_REGEX = /\A\d{1,19}\z/
-
-    def self.validate_date!(value)
-      return value if value.match?(STRICT_DATE_REGEX) || value.match?(EPOCH_MILLIS_REGEX)
-
-      raise Mastodon::FilterValidationError, "Invalid date #{value}"
+    def date_from_term(term)
+      DateTime.iso8601(term) unless term.match?(EPOCH_RE) # This will raise Date::Error if the date is invalid
+      term
     end
   end
 
diff --git a/lib/exceptions.rb b/lib/exceptions.rb
index 1910d37a13..135f8126a4 100644
--- a/lib/exceptions.rb
+++ b/lib/exceptions.rb
@@ -8,7 +8,6 @@ module Mastodon
   class LengthValidationError < ValidationError; end
   class DimensionsValidationError < ValidationError; end
   class StreamValidationError < ValidationError; end
-  class FilterValidationError < ValidationError; end
   class RaceConditionError < Error; end
   class RateLimitExceededError < Error; end
   class SyntaxError < Error; end
diff --git a/spec/lib/search_query_transformer_spec.rb b/spec/lib/search_query_transformer_spec.rb
index 9399f3503d..b677d88ed0 100644
--- a/spec/lib/search_query_transformer_spec.rb
+++ b/spec/lib/search_query_transformer_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe SearchQueryTransformer do
       let(:query) { "#{operator}:\"abc\"" }
 
       it 'raises an exception' do
-        expect { subject }.to raise_error(Mastodon::FilterValidationError, 'Invalid date abc')
+        expect { subject }.to raise_error(Date::Error)
       end
     end
   end

From c0c34d35e22e5ac9c87a5bffff5b02b06f772f3a Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Mon, 18 Nov 2024 04:57:16 -0500
Subject: [PATCH 39/44] Move self destruct check to `config_for` and add
 constant for verifier string (#32943)

---
 app/helpers/self_destruct_helper.rb       |  6 ++++--
 config/mastodon.yml                       |  1 +
 lib/mastodon/cli/federation.rb            |  2 +-
 spec/helpers/self_destruct_helper_spec.rb | 22 +++++++++++++---------
 4 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/app/helpers/self_destruct_helper.rb b/app/helpers/self_destruct_helper.rb
index 78557c25e5..f1927b1e04 100644
--- a/app/helpers/self_destruct_helper.rb
+++ b/app/helpers/self_destruct_helper.rb
@@ -1,9 +1,11 @@
 # frozen_string_literal: true
 
 module SelfDestructHelper
+  VERIFY_PURPOSE = 'self-destruct'
+
   def self.self_destruct?
-    value = ENV.fetch('SELF_DESTRUCT', nil)
-    value.present? && Rails.application.message_verifier('self-destruct').verify(value) == ENV['LOCAL_DOMAIN']
+    value = Rails.configuration.x.mastodon.self_destruct_value
+    value.present? && Rails.application.message_verifier(VERIFY_PURPOSE).verify(value) == ENV['LOCAL_DOMAIN']
   rescue ActiveSupport::MessageVerifier::InvalidSignature
     false
   end
diff --git a/config/mastodon.yml b/config/mastodon.yml
index 255213b4b7..2c09c59e0a 100644
--- a/config/mastodon.yml
+++ b/config/mastodon.yml
@@ -1,3 +1,4 @@
 ---
 shared:
+  self_destruct_value: <%= ENV.fetch('SELF_DESTRUCT', nil) %>
   software_update_url: <%= ENV.fetch('UPDATE_CHECK_URL', 'https://api.joinmastodon.org/update-check') %>
diff --git a/lib/mastodon/cli/federation.rb b/lib/mastodon/cli/federation.rb
index c738796557..f512bca358 100644
--- a/lib/mastodon/cli/federation.rb
+++ b/lib/mastodon/cli/federation.rb
@@ -76,7 +76,7 @@ module Mastodon::CLI
       def self_destruct_value
         Rails
           .application
-          .message_verifier('self-destruct')
+          .message_verifier(SelfDestructHelper::VERIFY_PURPOSE)
           .generate(Rails.configuration.x.local_domain)
       end
     end
diff --git a/spec/helpers/self_destruct_helper_spec.rb b/spec/helpers/self_destruct_helper_spec.rb
index 09d7347eee..dca1590764 100644
--- a/spec/helpers/self_destruct_helper_spec.rb
+++ b/spec/helpers/self_destruct_helper_spec.rb
@@ -3,19 +3,20 @@
 require 'rails_helper'
 
 RSpec.describe SelfDestructHelper do
-  describe 'self_destruct?' do
+  describe '#self_destruct?' do
+    before { Rails.configuration.x.mastodon.self_destruct_value = destruct_value }
+    after { Rails.configuration.x.mastodon.self_destruct_value = nil }
+
     context 'when SELF_DESTRUCT is unset' do
+      let(:destruct_value) { nil }
+
       it 'returns false' do
         expect(helper.self_destruct?).to be false
       end
     end
 
     context 'when SELF_DESTRUCT is set to an invalid value' do
-      around do |example|
-        ClimateControl.modify SELF_DESTRUCT: 'true' do
-          example.run
-        end
-      end
+      let(:destruct_value) { 'true' }
 
       it 'returns false' do
         expect(helper.self_destruct?).to be false
@@ -23,9 +24,10 @@ RSpec.describe SelfDestructHelper do
     end
 
     context 'when SELF_DESTRUCT is set to value signed for the wrong purpose' do
+      let(:destruct_value) { Rails.configuration.x.mastodon.self_destruct_value = Rails.application.message_verifier('foo').generate('example.com') }
+
       around do |example|
         ClimateControl.modify(
-          SELF_DESTRUCT: Rails.application.message_verifier('foo').generate('example.com'),
           LOCAL_DOMAIN: 'example.com'
         ) do
           example.run
@@ -38,9 +40,10 @@ RSpec.describe SelfDestructHelper do
     end
 
     context 'when SELF_DESTRUCT is set to value signed for the wrong domain' do
+      let(:destruct_value) { Rails.configuration.x.mastodon.self_destruct_value = Rails.application.message_verifier(described_class::VERIFY_PURPOSE).generate('foo.com') }
+
       around do |example|
         ClimateControl.modify(
-          SELF_DESTRUCT: Rails.application.message_verifier('self-destruct').generate('foo.com'),
           LOCAL_DOMAIN: 'example.com'
         ) do
           example.run
@@ -53,9 +56,10 @@ RSpec.describe SelfDestructHelper do
     end
 
     context 'when SELF_DESTRUCT is set to a correctly-signed value' do
+      let(:destruct_value) { Rails.configuration.x.mastodon.self_destruct_value = Rails.application.message_verifier(described_class::VERIFY_PURPOSE).generate('example.com') }
+
       around do |example|
         ClimateControl.modify(
-          SELF_DESTRUCT: Rails.application.message_verifier('self-destruct').generate('example.com'),
           LOCAL_DOMAIN: 'example.com'
         ) do
           example.run

From 3e44dca0b4d914886dbd4132d5eadd43c4be4304 Mon Sep 17 00:00:00 2001
From: "Andrew W. Lee" <wjldrew@gmail.com>
Date: Mon, 18 Nov 2024 06:40:02 -0800
Subject: [PATCH 40/44] Change dependency from annotate to annotaterb (#30232)

---
 .annotaterb.yml                     | 59 +++++++++++++++++++++++++++++
 Gemfile                             |  2 +-
 Gemfile.lock                        |  6 +--
 lib/tasks/annotate_rb.rake          | 10 +++++
 lib/tasks/auto_annotate_models.rake | 46 ----------------------
 5 files changed, 72 insertions(+), 51 deletions(-)
 create mode 100644 .annotaterb.yml
 create mode 100644 lib/tasks/annotate_rb.rake
 delete mode 100644 lib/tasks/auto_annotate_models.rake

diff --git a/.annotaterb.yml b/.annotaterb.yml
new file mode 100644
index 0000000000..df8e92b247
--- /dev/null
+++ b/.annotaterb.yml
@@ -0,0 +1,59 @@
+---
+:position: before
+:position_in_additional_file_patterns: before
+:position_in_class: before
+:position_in_factory: before
+:position_in_fixture: before
+:position_in_routes: before
+:position_in_serializer: before
+:position_in_test: before
+:classified_sort: true
+:exclude_controllers: true
+:exclude_factories: true
+:exclude_fixtures: true
+:exclude_helpers: true
+:exclude_scaffolds: true
+:exclude_serializers: true
+:exclude_sti_subclasses: true
+:exclude_tests: true
+:force: false
+:format_markdown: false
+:format_rdoc: false
+:format_yard: false
+:frozen: false
+:ignore_model_sub_dir: false
+:ignore_unknown_models: false
+:include_version: false
+:show_complete_foreign_keys: false
+:show_foreign_keys: false
+:show_indexes: false
+:simple_indexes: false
+:sort: false
+:timestamp: false
+:trace: false
+:with_comment: true
+:with_column_comments: true
+:with_table_comments: true
+:active_admin: false
+:command:
+:debug: false
+:hide_default_column_types: ''
+:hide_limit_column_types: 'integer,boolean'
+:ignore_columns:
+:ignore_routes:
+:models: true
+:routes: false
+:skip_on_db_migrate: false
+:target_action: :do_annotations
+:wrapper:
+:wrapper_close:
+:wrapper_open:
+:classes_default_to_s: []
+:additional_file_patterns: []
+:model_dir:
+  - app/models
+:require: []
+:root_dir:
+  - ''
+
+:show_check_constraints: false
diff --git a/Gemfile b/Gemfile
index 47506929b0..c8104d094e 100644
--- a/Gemfile
+++ b/Gemfile
@@ -172,7 +172,7 @@ group :development do
   gem 'rubocop-rspec_rails', require: false
 
   # Annotates modules with schema
-  gem 'annotate', '~> 3.2'
+  gem 'annotaterb', '~> 4.13'
 
   # Enhanced error message pages for development
   gem 'better_errors', '~> 2.9'
diff --git a/Gemfile.lock b/Gemfile.lock
index c7ab4e66fe..09017e3fa9 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -90,9 +90,7 @@ GEM
       public_suffix (>= 2.0.2, < 7.0)
     aes_key_wrap (1.1.0)
     android_key_attestation (0.3.0)
-    annotate (3.2.0)
-      activerecord (>= 3.2, < 8.0)
-      rake (>= 10.4, < 14.0)
+    annotaterb (4.13.0)
     ast (2.4.2)
     attr_required (1.0.2)
     awrence (1.2.1)
@@ -884,7 +882,7 @@ PLATFORMS
 DEPENDENCIES
   active_model_serializers (~> 0.10)
   addressable (~> 2.8)
-  annotate (~> 3.2)
+  annotaterb (~> 4.13)
   aws-sdk-s3 (~> 1.123)
   better_errors (~> 2.9)
   binding_of_caller (~> 1.0)
diff --git a/lib/tasks/annotate_rb.rake b/lib/tasks/annotate_rb.rake
new file mode 100644
index 0000000000..e8368b2e94
--- /dev/null
+++ b/lib/tasks/annotate_rb.rake
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+# This rake task was added by annotate_rb gem.
+
+# Can set `ANNOTATERB_SKIP_ON_DB_TASKS` to be anything to skip this
+if Rails.env.development? && ENV['ANNOTATERB_SKIP_ON_DB_TASKS'].nil?
+  require 'annotate_rb'
+
+  AnnotateRb::Core.load_rake_tasks
+end
diff --git a/lib/tasks/auto_annotate_models.rake b/lib/tasks/auto_annotate_models.rake
deleted file mode 100644
index 4b5997920a..0000000000
--- a/lib/tasks/auto_annotate_models.rake
+++ /dev/null
@@ -1,46 +0,0 @@
-# frozen_string_literal: true
-
-if Rails.env.development?
-  task :set_annotation_options do
-    Annotate.set_defaults(
-      'routes' => 'false',
-      'models' => 'true',
-      'position_in_routes' => 'before',
-      'position_in_class' => 'before',
-      'position_in_test' => 'before',
-      'position_in_fixture' => 'before',
-      'position_in_factory' => 'before',
-      'position_in_serializer' => 'before',
-      'show_foreign_keys' => 'false',
-      'show_indexes' => 'false',
-      'simple_indexes' => 'false',
-      'model_dir' => 'app/models',
-      'root_dir' => '',
-      'include_version' => 'false',
-      'require' => '',
-      'exclude_tests' => 'true',
-      'exclude_fixtures' => 'true',
-      'exclude_factories' => 'true',
-      'exclude_serializers' => 'true',
-      'exclude_scaffolds' => 'true',
-      'exclude_controllers' => 'true',
-      'exclude_helpers' => 'true',
-      'ignore_model_sub_dir' => 'false',
-      'ignore_columns' => nil,
-      'ignore_routes' => nil,
-      'ignore_unknown_models' => 'false',
-      'hide_limit_column_types' => 'integer,boolean',
-      'skip_on_db_migrate' => 'false',
-      'format_bare' => 'true',
-      'format_rdoc' => 'false',
-      'format_markdown' => 'false',
-      'sort' => 'false',
-      'force' => 'false',
-      'trace' => 'false',
-      'wrapper_open' => nil,
-      'wrapper_close' => nil
-    )
-  end
-
-  Annotate.load_tasks
-end

From 477412d62a9b90c83cc56fdfa12b3e5af1c1c0bc Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Mon, 18 Nov 2024 09:58:45 -0500
Subject: [PATCH 41/44] Use hash arguments to `select` when possible (Rails
 7.2) (#32917)

---
 .../api/v1/accounts/familiar_followers_controller.rb   |  2 +-
 app/lib/feed_manager.rb                                |  6 +++---
 app/lib/importer/statuses_index_importer.rb            |  2 +-
 app/models/status.rb                                   | 10 +++++-----
 4 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/app/controllers/api/v1/accounts/familiar_followers_controller.rb b/app/controllers/api/v1/accounts/familiar_followers_controller.rb
index a49eb2eb27..81f0a9ed0f 100644
--- a/app/controllers/api/v1/accounts/familiar_followers_controller.rb
+++ b/app/controllers/api/v1/accounts/familiar_followers_controller.rb
@@ -12,7 +12,7 @@ class Api::V1::Accounts::FamiliarFollowersController < Api::BaseController
   private
 
   def set_accounts
-    @accounts = Account.without_suspended.where(id: account_ids).select('id, hide_collections')
+    @accounts = Account.without_suspended.where(id: account_ids).select(:id, :hide_collections)
   end
 
   def familiar_followers
diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb
index 97cb25d58f..edd1162f4f 100644
--- a/app/lib/feed_manager.rb
+++ b/app/lib/feed_manager.rb
@@ -162,7 +162,7 @@ class FeedManager
     timeline_key        = key(:home, into_account.id)
     timeline_status_ids = redis.zrange(timeline_key, 0, -1)
 
-    from_account.statuses.select('id, reblog_of_id').where(id: timeline_status_ids).reorder(nil).find_each do |status|
+    from_account.statuses.select(:id, :reblog_of_id).where(id: timeline_status_ids).reorder(nil).find_each do |status|
       remove_from_feed(:home, into_account.id, status, aggregate_reblogs: into_account.user&.aggregates_reblogs?)
     end
   end
@@ -175,7 +175,7 @@ class FeedManager
     timeline_key        = key(:list, list.id)
     timeline_status_ids = redis.zrange(timeline_key, 0, -1)
 
-    from_account.statuses.select('id, reblog_of_id').where(id: timeline_status_ids).reorder(nil).find_each do |status|
+    from_account.statuses.select(:id, :reblog_of_id).where(id: timeline_status_ids).reorder(nil).find_each do |status|
       remove_from_feed(:list, list.id, status, aggregate_reblogs: list.account.user&.aggregates_reblogs?)
     end
   end
@@ -196,7 +196,7 @@ class FeedManager
                     .where.not(account: into_account.following)
                     .tagged_with_none(TagFollow.where(account: into_account).pluck(:tag_id))
 
-    scope.select('id, reblog_of_id').reorder(nil).find_each do |status|
+    scope.select(:id, :reblog_of_id).reorder(nil).find_each do |status|
       remove_from_feed(:home, into_account.id, status, aggregate_reblogs: into_account.user&.aggregates_reblogs?)
     end
   end
diff --git a/app/lib/importer/statuses_index_importer.rb b/app/lib/importer/statuses_index_importer.rb
index 1922f65f6d..5c8a9f28c8 100644
--- a/app/lib/importer/statuses_index_importer.rb
+++ b/app/lib/importer/statuses_index_importer.rb
@@ -71,7 +71,7 @@ class Importer::StatusesIndexImporter < Importer::BaseImporter
   end
 
   def local_votes_scope
-    Poll.joins(:votes).where(votes: { account: Account.local }).select('polls.id, polls.status_id')
+    Poll.joins(:votes).where(votes: { account: Account.local }).select(polls: [:id, :status_id])
   end
 
   def local_statuses_scope
diff --git a/app/models/status.rb b/app/models/status.rb
index c58de5114c..5a81b00773 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -356,23 +356,23 @@ class Status < ApplicationRecord
     end
 
     def favourites_map(status_ids, account_id)
-      Favourite.select('status_id').where(status_id: status_ids).where(account_id: account_id).each_with_object({}) { |f, h| h[f.status_id] = true }
+      Favourite.select(:status_id).where(status_id: status_ids).where(account_id: account_id).each_with_object({}) { |f, h| h[f.status_id] = true }
     end
 
     def bookmarks_map(status_ids, account_id)
-      Bookmark.select('status_id').where(status_id: status_ids).where(account_id: account_id).map { |f| [f.status_id, true] }.to_h
+      Bookmark.select(:status_id).where(status_id: status_ids).where(account_id: account_id).map { |f| [f.status_id, true] }.to_h
     end
 
     def reblogs_map(status_ids, account_id)
-      unscoped.select('reblog_of_id').where(reblog_of_id: status_ids).where(account_id: account_id).each_with_object({}) { |s, h| h[s.reblog_of_id] = true }
+      unscoped.select(:reblog_of_id).where(reblog_of_id: status_ids).where(account_id: account_id).each_with_object({}) { |s, h| h[s.reblog_of_id] = true }
     end
 
     def mutes_map(conversation_ids, account_id)
-      ConversationMute.select('conversation_id').where(conversation_id: conversation_ids).where(account_id: account_id).each_with_object({}) { |m, h| h[m.conversation_id] = true }
+      ConversationMute.select(:conversation_id).where(conversation_id: conversation_ids).where(account_id: account_id).each_with_object({}) { |m, h| h[m.conversation_id] = true }
     end
 
     def pins_map(status_ids, account_id)
-      StatusPin.select('status_id').where(status_id: status_ids).where(account_id: account_id).each_with_object({}) { |p, h| h[p.status_id] = true }
+      StatusPin.select(:status_id).where(status_id: status_ids).where(account_id: account_id).each_with_object({}) { |p, h| h[p.status_id] = true }
     end
 
     def from_text(text)

From da826fe959ad58a747023483fadd50c400f5d90f Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Mon, 18 Nov 2024 10:07:53 -0500
Subject: [PATCH 42/44] Use hash arguments to `order` when possible (Rails 7.2)
 (#32915)

---
 app/models/concerns/account/associations.rb |  2 +-
 app/models/concerns/account/interactions.rb | 12 ++++++------
 app/models/instance_filter.rb               |  4 ++--
 app/models/tag.rb                           |  4 ++--
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/app/models/concerns/account/associations.rb b/app/models/concerns/account/associations.rb
index 4e29235b6b..cafb2d151c 100644
--- a/app/models/concerns/account/associations.rb
+++ b/app/models/concerns/account/associations.rb
@@ -48,7 +48,7 @@ module Account::Associations
     end
 
     # Status records pinned by the account
-    has_many :pinned_statuses, -> { reorder('status_pins.created_at DESC') }, through: :status_pins, class_name: 'Status', source: :status
+    has_many :pinned_statuses, -> { reorder(status_pins: { created_at: :desc }) }, through: :status_pins, class_name: 'Status', source: :status
 
     # Account records endorsed (pinned) by the account
     has_many :endorsed_accounts, through: :account_pins, class_name: 'Account', source: :target_account
diff --git a/app/models/concerns/account/interactions.rb b/app/models/concerns/account/interactions.rb
index 536afba17f..6f6b8c16d0 100644
--- a/app/models/concerns/account/interactions.rb
+++ b/app/models/concerns/account/interactions.rb
@@ -80,8 +80,8 @@ module Account::Interactions
       has_many :passive_relationships, foreign_key: 'target_account_id', inverse_of: :target_account
     end
 
-    has_many :following, -> { order('follows.id desc') }, through: :active_relationships,  source: :target_account
-    has_many :followers, -> { order('follows.id desc') }, through: :passive_relationships, source: :account
+    has_many :following, -> { order(follows: { id: :desc }) }, through: :active_relationships,  source: :target_account
+    has_many :followers, -> { order(follows: { id: :desc }) }, through: :passive_relationships, source: :account
 
     with_options class_name: 'SeveredRelationship', dependent: :destroy do
       has_many :severed_relationships, foreign_key: 'local_account_id', inverse_of: :local_account
@@ -96,16 +96,16 @@ module Account::Interactions
       has_many :block_relationships, foreign_key: 'account_id', inverse_of: :account
       has_many :blocked_by_relationships, foreign_key: :target_account_id, inverse_of: :target_account
     end
-    has_many :blocking, -> { order('blocks.id desc') }, through: :block_relationships, source: :target_account
-    has_many :blocked_by, -> { order('blocks.id desc') }, through: :blocked_by_relationships, source: :account
+    has_many :blocking, -> { order(blocks: { id: :desc }) }, through: :block_relationships, source: :target_account
+    has_many :blocked_by, -> { order(blocks: { id: :desc }) }, through: :blocked_by_relationships, source: :account
 
     # Mute relationships
     with_options class_name: 'Mute', dependent: :destroy do
       has_many :mute_relationships, foreign_key: 'account_id', inverse_of: :account
       has_many :muted_by_relationships, foreign_key: :target_account_id, inverse_of: :target_account
     end
-    has_many :muting, -> { order('mutes.id desc') }, through: :mute_relationships, source: :target_account
-    has_many :muted_by, -> { order('mutes.id desc') }, through: :muted_by_relationships, source: :account
+    has_many :muting, -> { order(mutes: { id: :desc }) }, through: :mute_relationships, source: :target_account
+    has_many :muted_by, -> { order(mutes: { id: :desc }) }, through: :muted_by_relationships, source: :account
     has_many :conversation_mutes, dependent: :destroy
     has_many :domain_blocks, class_name: 'AccountDomainBlock', dependent: :destroy
     has_many :announcement_mutes, dependent: :destroy
diff --git a/app/models/instance_filter.rb b/app/models/instance_filter.rb
index 1d94c919f9..7e71640e52 100644
--- a/app/models/instance_filter.rb
+++ b/app/models/instance_filter.rb
@@ -28,9 +28,9 @@ class InstanceFilter
   def scope_for(key, value)
     case key.to_s
     when 'limited'
-      Instance.joins(:domain_block).reorder(Arel.sql('domain_blocks.id desc'))
+      Instance.joins(:domain_block).reorder(domain_blocks: { id: :desc })
     when 'allowed'
-      Instance.joins(:domain_allow).reorder(Arel.sql('domain_allows.id desc'))
+      Instance.joins(:domain_allow).reorder(domain_allows: { id: :desc })
     when 'by_domain'
       Instance.matches_domain(value)
     when 'availability'
diff --git a/app/models/tag.rb b/app/models/tag.rb
index 93210eb307..67fa9e5d3a 100644
--- a/app/models/tag.rb
+++ b/app/models/tag.rb
@@ -61,7 +61,7 @@ class Tag < ApplicationRecord
   scope :recently_used, lambda { |account|
                           joins(:statuses)
                             .where(statuses: { id: account.statuses.select(:id).limit(RECENT_STATUS_LIMIT) })
-                            .group(:id).order(Arel.sql('count(*) desc'))
+                            .group(:id).order(Arel.star.count.desc)
                         }
   scope :matches_name, ->(term) { where(arel_table[:name].lower.matches(arel_table.lower("#{sanitize_sql_like(Tag.normalize(term))}%"), nil, true)) } # Search with case-sensitive to use B-tree index
 
@@ -127,7 +127,7 @@ class Tag < ApplicationRecord
       query = query.merge(Tag.listable) if options[:exclude_unlistable]
       query = query.merge(matching_name(stripped_term).or(reviewed)) if options[:exclude_unreviewed]
 
-      query.order(Arel.sql('length(name) ASC, name ASC'))
+      query.order(Arel.sql('LENGTH(name)').asc, name: :asc)
            .limit(limit)
            .offset(offset)
     end

From 30a79865698b1fbef2b1a6e818ce6984db68d551 Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Mon, 18 Nov 2024 10:42:45 -0500
Subject: [PATCH 43/44] Add coverage for fixing the thing with the dates in the
 search area (#32958)

---
 spec/lib/search_query_transformer_spec.rb | 1 +
 1 file changed, 1 insertion(+)

diff --git a/spec/lib/search_query_transformer_spec.rb b/spec/lib/search_query_transformer_spec.rb
index b677d88ed0..b69e3afc9d 100644
--- a/spec/lib/search_query_transformer_spec.rb
+++ b/spec/lib/search_query_transformer_spec.rb
@@ -16,6 +16,7 @@ RSpec.describe SearchQueryTransformer do
       ['"2022-01-01"', '2022-01-01'],
       ['12345678', '12345678'],
       ['"12345678"', '12345678'],
+      ['"2024-10-31T23:47:20Z"', '2024-10-31T23:47:20Z'],
     ].each do |value, parsed|
       context "with #{operator}:#{value}" do
         let(:query) { "#{operator}:#{value}" }

From 295ad6f19a016b3f16e1201ffcbb1b3ad6b455a2 Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Mon, 18 Nov 2024 11:37:21 -0500
Subject: [PATCH 44/44] Prep work for coverage addition to
 `ActivityPub::DeliveryWorker` spec (#32944)

---
 .../activitypub/delivery_worker_spec.rb       | 41 ++++++++++++++-----
 1 file changed, 30 insertions(+), 11 deletions(-)

diff --git a/spec/workers/activitypub/delivery_worker_spec.rb b/spec/workers/activitypub/delivery_worker_spec.rb
index 3dfbef31a4..9e6805c68b 100644
--- a/spec/workers/activitypub/delivery_worker_spec.rb
+++ b/spec/workers/activitypub/delivery_worker_spec.rb
@@ -5,26 +5,45 @@ require 'rails_helper'
 RSpec.describe ActivityPub::DeliveryWorker do
   include RoutingHelper
 
-  subject { described_class.new }
-
-  let(:sender)  { Fabricate(:account) }
+  let(:sender) { Fabricate(:account) }
   let(:payload) { 'test' }
+  let(:url) { 'https://example.com/api' }
 
   before do
-    allow(sender).to receive(:remote_followers_hash).with('https://example.com/api').and_return('somehash')
+    allow(sender).to receive(:remote_followers_hash).with(url).and_return('somehash')
     allow(Account).to receive(:find).with(sender.id).and_return(sender)
   end
 
   describe 'perform' do
-    it 'performs a request' do
-      stub_request(:post, 'https://example.com/api').to_return(status: 200)
-      subject.perform(payload, sender.id, 'https://example.com/api', { synchronize_followers: true })
-      expect(a_request(:post, 'https://example.com/api').with(headers: { 'Collection-Synchronization' => "collectionId=\"#{account_followers_url(sender)}\", digest=\"somehash\", url=\"#{account_followers_synchronization_url(sender)}\"" })).to have_been_made.once
+    context 'with successful request' do
+      before { stub_request(:post, url).to_return(status: 200) }
+
+      it 'performs a request to synchronize collection' do
+        subject.perform(payload, sender.id, url, { synchronize_followers: true })
+
+        expect(request_to_url)
+          .to have_been_made.once
+      end
+
+      def request_to_url
+        a_request(:post, url)
+          .with(
+            headers: {
+              'Collection-Synchronization' => <<~VALUES.squish,
+                collectionId="#{account_followers_url(sender)}", digest="somehash", url="#{account_followers_synchronization_url(sender)}"
+              VALUES
+            }
+          )
+      end
     end
 
-    it 'raises when request fails' do
-      stub_request(:post, 'https://example.com/api').to_return(status: 500)
-      expect { subject.perform(payload, sender.id, 'https://example.com/api') }.to raise_error Mastodon::UnexpectedResponseError
+    context 'with failing request' do
+      before { stub_request(:post, url).to_return(status: 500) }
+
+      it 'raises error' do
+        expect { subject.perform(payload, sender.id, url) }
+          .to raise_error Mastodon::UnexpectedResponseError
+      end
     end
   end
 end