From fba838d61ad280e2a03dd937aa71637e7c0f166b Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Fri, 10 Nov 2023 13:45:19 +0100
Subject: [PATCH 1/5] Update dependency @material-symbols/svg-600 to ^0.14.0
 (#27803)

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

diff --git a/package.json b/package.json
index e8f7f02e0e..96bfb1571c 100644
--- a/package.json
+++ b/package.json
@@ -47,7 +47,7 @@
     "@formatjs/intl-pluralrules": "^5.2.2",
     "@gamestdio/websocket": "^0.3.2",
     "@github/webauthn-json": "^2.1.1",
-    "@material-symbols/svg-600": "^0.13.1",
+    "@material-symbols/svg-600": "^0.14.0",
     "@rails/ujs": "^7.1.1",
     "@reduxjs/toolkit": "^1.9.5",
     "@svgr/webpack": "^5.5.0",
diff --git a/yarn.lock b/yarn.lock
index 1b2bfe0598..4c70859d08 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -52,14 +52,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.22.9":
-  version: 7.23.2
-  resolution: "@babel/compat-data@npm:7.23.2"
-  checksum: 0397a08c3e491696cc1b12cf0879bf95fc550bfc6ef524d5a9452981aa0e192a958b2246debfb230fa22718fac473cc5a36616f89b1ad6e7e52055732cd374a1
-  languageName: node
-  linkType: hard
-
-"@babel/compat-data@npm:^7.23.3":
+"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.22.9, @babel/compat-data@npm:^7.23.3":
   version: 7.23.3
   resolution: "@babel/compat-data@npm:7.23.3"
   checksum: c6af331753c34ee8a5678bc94404320826cb56b1dda3efc1311ec8fb0774e78225132f3c1acc988440ace667f14a838e297a822692b95758aa63da406e1f97a1
@@ -89,19 +82,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@babel/generator@npm:^7.23.0, @babel/generator@npm:^7.7.2":
-  version: 7.23.0
-  resolution: "@babel/generator@npm:7.23.0"
-  dependencies:
-    "@babel/types": "npm:^7.23.0"
-    "@jridgewell/gen-mapping": "npm:^0.3.2"
-    "@jridgewell/trace-mapping": "npm:^0.3.17"
-    jsesc: "npm:^2.5.1"
-  checksum: b7d8727c574119b5ef06e5d5d0d8d939527d51537db4b08273caebb18f3f2b1d4517b874776085e161fd47d28f26b22c08e7f270b64f43b2afd4a60c5936d6cd
-  languageName: node
-  linkType: hard
-
-"@babel/generator@npm:^7.23.3":
+"@babel/generator@npm:^7.23.3, @babel/generator@npm:^7.7.2":
   version: 7.23.3
   resolution: "@babel/generator@npm:7.23.3"
   dependencies:
@@ -383,16 +364,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.22.15, @babel/parser@npm:^7.23.0":
-  version: 7.23.0
-  resolution: "@babel/parser@npm:7.23.0"
-  bin:
-    parser: ./bin/babel-parser.js
-  checksum: ab4ea9360ed4ba3c728c5a9bf33035103ebde20a7e943c4ae1d42becb02a313d731d12a93c795c5a19777031e4022e64b92a52262eda902522a1a18649826283
-  languageName: node
-  linkType: hard
-
-"@babel/parser@npm:^7.23.3":
+"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.22.15, @babel/parser@npm:^7.23.3":
   version: 7.23.3
   resolution: "@babel/parser@npm:7.23.3"
   bin:
@@ -556,18 +528,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@babel/plugin-syntax-jsx@npm:7, @babel/plugin-syntax-jsx@npm:^7.22.5, @babel/plugin-syntax-jsx@npm:^7.7.2":
-  version: 7.22.5
-  resolution: "@babel/plugin-syntax-jsx@npm:7.22.5"
-  dependencies:
-    "@babel/helper-plugin-utils": "npm:^7.22.5"
-  peerDependencies:
-    "@babel/core": ^7.0.0-0
-  checksum: b56ceaa9c6adc17fadfb48e1c801d07797195df2a581489e33c8034950e12e7778de6e1e70d6bcf7c5c7ada6222fe6bad5746187ab280df435f5a2799c8dd0d8
-  languageName: node
-  linkType: hard
-
-"@babel/plugin-syntax-jsx@npm:^7.23.3":
+"@babel/plugin-syntax-jsx@npm:7, @babel/plugin-syntax-jsx@npm:^7.22.5, @babel/plugin-syntax-jsx@npm:^7.23.3, @babel/plugin-syntax-jsx@npm:^7.7.2":
   version: 7.23.3
   resolution: "@babel/plugin-syntax-jsx@npm:7.23.3"
   dependencies:
@@ -666,7 +627,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@babel/plugin-syntax-typescript@npm:^7.23.3":
+"@babel/plugin-syntax-typescript@npm:^7.23.3, @babel/plugin-syntax-typescript@npm:^7.7.2":
   version: 7.23.3
   resolution: "@babel/plugin-syntax-typescript@npm:7.23.3"
   dependencies:
@@ -677,17 +638,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@babel/plugin-syntax-typescript@npm:^7.7.2":
-  version: 7.22.5
-  resolution: "@babel/plugin-syntax-typescript@npm:7.22.5"
-  dependencies:
-    "@babel/helper-plugin-utils": "npm:^7.22.5"
-  peerDependencies:
-    "@babel/core": ^7.0.0-0
-  checksum: 523a76627f17e67dc1999f4d7c7a71ed79e9f77f55a61cf05051101967ac23ec378ff0c93787b2cbd5d53720ad799658d796a649fa351682b2bf636f63b665a1
-  languageName: node
-  linkType: hard
-
 "@babel/plugin-syntax-unicode-sets-regex@npm:^7.18.6":
   version: 7.18.6
   resolution: "@babel/plugin-syntax-unicode-sets-regex@npm:7.18.6"
@@ -1552,25 +1502,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@babel/traverse@npm:7, @babel/traverse@npm:^7.23.2":
-  version: 7.23.2
-  resolution: "@babel/traverse@npm:7.23.2"
-  dependencies:
-    "@babel/code-frame": "npm:^7.22.13"
-    "@babel/generator": "npm:^7.23.0"
-    "@babel/helper-environment-visitor": "npm:^7.22.20"
-    "@babel/helper-function-name": "npm:^7.23.0"
-    "@babel/helper-hoist-variables": "npm:^7.22.5"
-    "@babel/helper-split-export-declaration": "npm:^7.22.6"
-    "@babel/parser": "npm:^7.23.0"
-    "@babel/types": "npm:^7.23.0"
-    debug: "npm:^4.1.0"
-    globals: "npm:^11.1.0"
-  checksum: d096c7c4bab9262a2f658298a3c630ae4a15a10755bb257ae91d5ab3e3b2877438934859c8d34018b7727379fe6b26c4fa2efc81cf4c462a7fe00caf79fa02ff
-  languageName: node
-  linkType: hard
-
-"@babel/traverse@npm:^7.23.3":
+"@babel/traverse@npm:7, @babel/traverse@npm:^7.23.2, @babel/traverse@npm:^7.23.3":
   version: 7.23.3
   resolution: "@babel/traverse@npm:7.23.3"
   dependencies:
@@ -1588,18 +1520,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@babel/types@npm:^7.0.0, @babel/types@npm:^7.0.0-beta.49, @babel/types@npm:^7.12.11, @babel/types@npm:^7.12.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.19, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3":
-  version: 7.23.0
-  resolution: "@babel/types@npm:7.23.0"
-  dependencies:
-    "@babel/helper-string-parser": "npm:^7.22.5"
-    "@babel/helper-validator-identifier": "npm:^7.22.20"
-    to-fast-properties: "npm:^2.0.0"
-  checksum: 70e4db41acb6793d0eb8d81a2fa88f19ee661219b84bd5f703dbdb54eb3a4d3c0dfc55e69034c945b479df9f43fd4b1376480aaccfc19797ce5af1c5d2576b36
-  languageName: node
-  linkType: hard
-
-"@babel/types@npm:^7.22.10, @babel/types@npm:^7.23.3":
+"@babel/types@npm:^7.0.0, @babel/types@npm:^7.0.0-beta.49, @babel/types@npm:^7.12.11, @babel/types@npm:^7.12.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.10, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.19, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.3, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3":
   version: 7.23.3
   resolution: "@babel/types@npm:7.23.3"
   dependencies:
@@ -2438,7 +2359,7 @@ __metadata:
     "@formatjs/intl-pluralrules": "npm:^5.2.2"
     "@gamestdio/websocket": "npm:^0.3.2"
     "@github/webauthn-json": "npm:^2.1.1"
-    "@material-symbols/svg-600": "npm:^0.13.1"
+    "@material-symbols/svg-600": "npm:^0.14.0"
     "@rails/ujs": "npm:^7.1.1"
     "@reduxjs/toolkit": "npm:^1.9.5"
     "@svgr/webpack": "npm:^5.5.0"
@@ -2621,10 +2542,10 @@ __metadata:
   languageName: unknown
   linkType: soft
 
-"@material-symbols/svg-600@npm:^0.13.1":
-  version: 0.13.2
-  resolution: "@material-symbols/svg-600@npm:0.13.2"
-  checksum: d467928fe07e640cef8767aaa144a5feda9f060596bf324bcbd0d4c19877073c8bb1b0dba126699b6830906d593bb63ea33ce3c58d102ce67efac674e5e5bfed
+"@material-symbols/svg-600@npm:^0.14.0":
+  version: 0.14.0
+  resolution: "@material-symbols/svg-600@npm:0.14.0"
+  checksum: e6547a9a0b2072f4109f2e4e0863367ea2507efce740c427a8544100db02ffff52f33608aac1a355f4977e2c0b2ce6cdd6bfee9177bb13cee0b28418f948b5a5
   languageName: node
   linkType: hard
 
@@ -11728,14 +11649,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0":
-  version: 7.0.3
-  resolution: "minipass@npm:7.0.3"
-  checksum: c85426bce6310368218aad1f20b8f242180b6c2058209c78840959d6fff8a4738076a3224c3a6b651080f95684d559be1bdb084939bc40011c653ec4552cf06e
-  languageName: node
-  linkType: hard
-
-"minipass@npm:^7.0.2, minipass@npm:^7.0.3":
+"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3":
   version: 7.0.4
   resolution: "minipass@npm:7.0.4"
   checksum: 6c7370a6dfd257bf18222da581ba89a5eaedca10e158781232a8b5542a90547540b4b9b7e7f490e4cda43acfbd12e086f0453728ecf8c19e0ef6921bc5958ac5

From ac69f90098eba87d54f0bbfc0d76349d93c0792c Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Fri, 10 Nov 2023 07:46:00 -0500
Subject: [PATCH 2/5] Add `Api::V1::Instances::BaseController` base controller
 class (#27797)

---
 app/controllers/api/v1/instances/activity_controller.rb   | 6 +-----
 app/controllers/api/v1/instances/base_controller.rb       | 8 ++++++++
 .../api/v1/instances/domain_blocks_controller.rb          | 4 +---
 .../api/v1/instances/extended_descriptions_controller.rb  | 5 +----
 app/controllers/api/v1/instances/languages_controller.rb  | 5 +----
 app/controllers/api/v1/instances/peers_controller.rb      | 5 +----
 .../api/v1/instances/privacy_policies_controller.rb       | 6 +-----
 app/controllers/api/v1/instances/rules_controller.rb      | 5 +----
 .../api/v1/instances/translation_languages_controller.rb  | 6 +-----
 9 files changed, 16 insertions(+), 34 deletions(-)
 create mode 100644 app/controllers/api/v1/instances/base_controller.rb

diff --git a/app/controllers/api/v1/instances/activity_controller.rb b/app/controllers/api/v1/instances/activity_controller.rb
index 9da77f8dab..4c17bd79c2 100644
--- a/app/controllers/api/v1/instances/activity_controller.rb
+++ b/app/controllers/api/v1/instances/activity_controller.rb
@@ -1,12 +1,8 @@
 # frozen_string_literal: true
 
-class Api::V1::Instances::ActivityController < Api::BaseController
+class Api::V1::Instances::ActivityController < Api::V1::Instances::BaseController
   before_action :require_enabled_api!
 
-  skip_before_action :require_authenticated_user!, unless: :limited_federation_mode?
-
-  vary_by ''
-
   def show
     cache_even_if_authenticated!
     render_with_cache json: :activity, expires_in: 1.day
diff --git a/app/controllers/api/v1/instances/base_controller.rb b/app/controllers/api/v1/instances/base_controller.rb
new file mode 100644
index 0000000000..ed0bebf0ff
--- /dev/null
+++ b/app/controllers/api/v1/instances/base_controller.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+class Api::V1::Instances::BaseController < Api::BaseController
+  skip_before_action :require_authenticated_user!,
+                     unless: :limited_federation_mode?
+
+  vary_by ''
+end
diff --git a/app/controllers/api/v1/instances/domain_blocks_controller.rb b/app/controllers/api/v1/instances/domain_blocks_controller.rb
index c91234e088..566764dbf0 100644
--- a/app/controllers/api/v1/instances/domain_blocks_controller.rb
+++ b/app/controllers/api/v1/instances/domain_blocks_controller.rb
@@ -1,8 +1,6 @@
 # frozen_string_literal: true
 
-class Api::V1::Instances::DomainBlocksController < Api::BaseController
-  skip_before_action :require_authenticated_user!, unless: :limited_federation_mode?
-
+class Api::V1::Instances::DomainBlocksController < Api::V1::Instances::BaseController
   before_action :require_enabled_api!
   before_action :set_domain_blocks
 
diff --git a/app/controllers/api/v1/instances/extended_descriptions_controller.rb b/app/controllers/api/v1/instances/extended_descriptions_controller.rb
index 376fec9066..73d2248117 100644
--- a/app/controllers/api/v1/instances/extended_descriptions_controller.rb
+++ b/app/controllers/api/v1/instances/extended_descriptions_controller.rb
@@ -1,13 +1,10 @@
 # frozen_string_literal: true
 
-class Api::V1::Instances::ExtendedDescriptionsController < Api::BaseController
-  skip_before_action :require_authenticated_user!, unless: :limited_federation_mode?
+class Api::V1::Instances::ExtendedDescriptionsController < Api::V1::Instances::BaseController
   skip_around_action :set_locale
 
   before_action :set_extended_description
 
-  vary_by ''
-
   # Override `current_user` to avoid reading session cookies unless in whitelist mode
   def current_user
     super if limited_federation_mode?
diff --git a/app/controllers/api/v1/instances/languages_controller.rb b/app/controllers/api/v1/instances/languages_controller.rb
index 17509e748c..ea184d90da 100644
--- a/app/controllers/api/v1/instances/languages_controller.rb
+++ b/app/controllers/api/v1/instances/languages_controller.rb
@@ -1,13 +1,10 @@
 # frozen_string_literal: true
 
-class Api::V1::Instances::LanguagesController < Api::BaseController
-  skip_before_action :require_authenticated_user!, unless: :limited_federation_mode?
+class Api::V1::Instances::LanguagesController < Api::V1::Instances::BaseController
   skip_around_action :set_locale
 
   before_action :set_languages
 
-  vary_by ''
-
   def show
     cache_even_if_authenticated!
     render json: @languages, each_serializer: REST::LanguageSerializer
diff --git a/app/controllers/api/v1/instances/peers_controller.rb b/app/controllers/api/v1/instances/peers_controller.rb
index 08a982f227..83116472bb 100644
--- a/app/controllers/api/v1/instances/peers_controller.rb
+++ b/app/controllers/api/v1/instances/peers_controller.rb
@@ -1,13 +1,10 @@
 # frozen_string_literal: true
 
-class Api::V1::Instances::PeersController < Api::BaseController
+class Api::V1::Instances::PeersController < Api::V1::Instances::BaseController
   before_action :require_enabled_api!
 
-  skip_before_action :require_authenticated_user!, unless: :limited_federation_mode?
   skip_around_action :set_locale
 
-  vary_by ''
-
   # Override `current_user` to avoid reading session cookies unless in whitelist mode
   def current_user
     super if limited_federation_mode?
diff --git a/app/controllers/api/v1/instances/privacy_policies_controller.rb b/app/controllers/api/v1/instances/privacy_policies_controller.rb
index f5b1b4ec5f..9f87317d53 100644
--- a/app/controllers/api/v1/instances/privacy_policies_controller.rb
+++ b/app/controllers/api/v1/instances/privacy_policies_controller.rb
@@ -1,12 +1,8 @@
 # frozen_string_literal: true
 
-class Api::V1::Instances::PrivacyPoliciesController < Api::BaseController
-  skip_before_action :require_authenticated_user!, unless: :limited_federation_mode?
-
+class Api::V1::Instances::PrivacyPoliciesController < Api::V1::Instances::BaseController
   before_action :set_privacy_policy
 
-  vary_by ''
-
   def show
     cache_even_if_authenticated!
     render json: @privacy_policy, serializer: REST::PrivacyPolicySerializer
diff --git a/app/controllers/api/v1/instances/rules_controller.rb b/app/controllers/api/v1/instances/rules_controller.rb
index 2f71984b05..d240d72464 100644
--- a/app/controllers/api/v1/instances/rules_controller.rb
+++ b/app/controllers/api/v1/instances/rules_controller.rb
@@ -1,13 +1,10 @@
 # frozen_string_literal: true
 
-class Api::V1::Instances::RulesController < Api::BaseController
-  skip_before_action :require_authenticated_user!, unless: :limited_federation_mode?
+class Api::V1::Instances::RulesController < Api::V1::Instances::BaseController
   skip_around_action :set_locale
 
   before_action :set_rules
 
-  vary_by ''
-
   # Override `current_user` to avoid reading session cookies unless in whitelist mode
   def current_user
     super if limited_federation_mode?
diff --git a/app/controllers/api/v1/instances/translation_languages_controller.rb b/app/controllers/api/v1/instances/translation_languages_controller.rb
index 78423e40e4..b8f7a16383 100644
--- a/app/controllers/api/v1/instances/translation_languages_controller.rb
+++ b/app/controllers/api/v1/instances/translation_languages_controller.rb
@@ -1,12 +1,8 @@
 # frozen_string_literal: true
 
-class Api::V1::Instances::TranslationLanguagesController < Api::BaseController
-  skip_before_action :require_authenticated_user!, unless: :limited_federation_mode?
-
+class Api::V1::Instances::TranslationLanguagesController < Api::V1::Instances::BaseController
   before_action :set_languages
 
-  vary_by ''
-
   def show
     cache_even_if_authenticated!
     render json: @languages

From 43e2f763b2f43b5bbcb3b80890ebc89b73545b3b Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Fri, 10 Nov 2023 07:47:38 -0500
Subject: [PATCH 3/5] Extract crutches_active_mentions from FeedManager
 (#27785)

---
 app/lib/feed_manager.rb | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb
index 2ed1457841..4e645a11f6 100644
--- a/app/lib/feed_manager.rb
+++ b/app/lib/feed_manager.rb
@@ -551,7 +551,7 @@ class FeedManager
   def build_crutches(receiver_id, statuses)
     crutches = {}
 
-    crutches[:active_mentions] = Mention.active.where(status_id: statuses.flat_map { |s| [s.id, s.reblog_of_id] }.compact).pluck(:status_id, :account_id).each_with_object({}) { |(id, account_id), mapping| (mapping[id] ||= []).push(account_id) }
+    crutches[:active_mentions] = crutches_active_mentions(statuses)
 
     check_for_blocks = statuses.flat_map do |s|
       arr = crutches[:active_mentions][s.id] || []
@@ -578,4 +578,12 @@ class FeedManager
 
     crutches
   end
+
+  def crutches_active_mentions(statuses)
+    Mention
+      .active
+      .where(status_id: statuses.flat_map { |status| [status.id, status.reblog_of_id] }.compact)
+      .pluck(:status_id, :account_id)
+      .each_with_object({}) { |(id, account_id), mapping| (mapping[id] ||= []).push(account_id) }
+  end
 end

From ac62b995efdf6fc71f3a1adf60da99ed7ddde26b Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
 <41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 10 Nov 2023 14:07:04 +0100
Subject: [PATCH 4/5] New Crowdin Translations (automated) (#27804)

Co-authored-by: GitHub Actions <noreply@github.com>
---
 app/javascript/mastodon/locales/cy.json    |   1 +
 app/javascript/mastodon/locales/da.json    |   1 +
 app/javascript/mastodon/locales/de.json    |   1 +
 app/javascript/mastodon/locales/es-AR.json |   1 +
 app/javascript/mastodon/locales/es-MX.json |   1 +
 app/javascript/mastodon/locales/es.json    |   1 +
 app/javascript/mastodon/locales/eu.json    |   1 +
 app/javascript/mastodon/locales/fr-QC.json |   1 +
 app/javascript/mastodon/locales/fr.json    |   1 +
 app/javascript/mastodon/locales/gl.json    |   1 +
 app/javascript/mastodon/locales/he.json    |   1 +
 app/javascript/mastodon/locales/hu.json    |   1 +
 app/javascript/mastodon/locales/is.json    |   1 +
 app/javascript/mastodon/locales/it.json    |   1 +
 app/javascript/mastodon/locales/ja.json    |   1 +
 app/javascript/mastodon/locales/lt.json    | 102 ++++++++++++++++++---
 app/javascript/mastodon/locales/lv.json    |   1 +
 app/javascript/mastodon/locales/nl.json    |   1 +
 app/javascript/mastodon/locales/nn.json    |   1 +
 app/javascript/mastodon/locales/pl.json    |   1 +
 app/javascript/mastodon/locales/sq.json    |   1 +
 app/javascript/mastodon/locales/sv.json    |   1 +
 app/javascript/mastodon/locales/th.json    |   1 +
 app/javascript/mastodon/locales/tr.json    |   1 +
 app/javascript/mastodon/locales/uk.json    |   1 +
 app/javascript/mastodon/locales/zh-CN.json |   1 +
 app/javascript/mastodon/locales/zh-HK.json |   1 +
 app/javascript/mastodon/locales/zh-TW.json |   1 +
 config/locales/doorkeeper.lt.yml           |  68 ++++++++++++++
 config/locales/fi.yml                      |   4 +-
 config/locales/ja.yml                      |  10 +-
 config/locales/lt.yml                      |  23 +++--
 config/locales/lv.yml                      |  15 ++-
 config/locales/simple_form.ja.yml          |   4 +-
 34 files changed, 222 insertions(+), 31 deletions(-)

diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json
index 28c7ae1783..183ab6955b 100644
--- a/app/javascript/mastodon/locales/cy.json
+++ b/app/javascript/mastodon/locales/cy.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "Canlyniadau chwilio",
   "emoji_button.symbols": "Symbolau",
   "emoji_button.travel": "Teithio a Llefydd",
+  "empty_column.account_hides_collections": "Mae'r defnyddiwr wedi dewis i beidio rhannu'r wybodaeth yma",
   "empty_column.account_suspended": "Cyfrif wedi'i atal",
   "empty_column.account_timeline": "Dim postiadau yma!",
   "empty_column.account_unavailable": "Nid yw'r proffil ar gael",
diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json
index 0a8a4a1475..bb8b72bca4 100644
--- a/app/javascript/mastodon/locales/da.json
+++ b/app/javascript/mastodon/locales/da.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "Søgeresultater",
   "emoji_button.symbols": "Symboler",
   "emoji_button.travel": "Rejser og steder",
+  "empty_column.account_hides_collections": "Brugeren har valgt ikke at gøre denne information tilgængelig",
   "empty_column.account_suspended": "Konto suspenderet",
   "empty_column.account_timeline": "Ingen indlæg hér!",
   "empty_column.account_unavailable": "Profil utilgængelig",
diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json
index 0b93905816..e4f7fe6cec 100644
--- a/app/javascript/mastodon/locales/de.json
+++ b/app/javascript/mastodon/locales/de.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "Suchergebnisse",
   "emoji_button.symbols": "Symbole",
   "emoji_button.travel": "Reisen & Orte",
+  "empty_column.account_hides_collections": "Das Konto hat sich dazu entschieden, diese Information nicht zu veröffentlichen",
   "empty_column.account_suspended": "Konto gesperrt",
   "empty_column.account_timeline": "Keine Beiträge vorhanden!",
   "empty_column.account_unavailable": "Profil nicht verfügbar",
diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json
index 7aeb66b546..71d6e3119b 100644
--- a/app/javascript/mastodon/locales/es-AR.json
+++ b/app/javascript/mastodon/locales/es-AR.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "Resultados de búsqueda",
   "emoji_button.symbols": "Símbolos",
   "emoji_button.travel": "Viajes y lugares",
+  "empty_column.account_hides_collections": "Este usuario eligió no publicar esta información",
   "empty_column.account_suspended": "Cuenta suspendida",
   "empty_column.account_timeline": "¡No hay mensajes acá!",
   "empty_column.account_unavailable": "Perfil no disponible",
diff --git a/app/javascript/mastodon/locales/es-MX.json b/app/javascript/mastodon/locales/es-MX.json
index f29a6fd0e5..aadc901f99 100644
--- a/app/javascript/mastodon/locales/es-MX.json
+++ b/app/javascript/mastodon/locales/es-MX.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "Resultados de búsqueda",
   "emoji_button.symbols": "Símbolos",
   "emoji_button.travel": "Viajes y lugares",
+  "empty_column.account_hides_collections": "Este usuario ha elegido no hacer disponible esta información",
   "empty_column.account_suspended": "Cuenta suspendida",
   "empty_column.account_timeline": "¡No hay toots aquí!",
   "empty_column.account_unavailable": "Perfil no disponible",
diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json
index 5684ec4873..f3735d9685 100644
--- a/app/javascript/mastodon/locales/es.json
+++ b/app/javascript/mastodon/locales/es.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "Resultados de búsqueda",
   "emoji_button.symbols": "Símbolos",
   "emoji_button.travel": "Viajes y lugares",
+  "empty_column.account_hides_collections": "Este usuario ha decidido no mostrar esta información",
   "empty_column.account_suspended": "Cuenta suspendida",
   "empty_column.account_timeline": "¡No hay publicaciones aquí!",
   "empty_column.account_unavailable": "Perfil no disponible",
diff --git a/app/javascript/mastodon/locales/eu.json b/app/javascript/mastodon/locales/eu.json
index 5b4fef59c0..7f109ea082 100644
--- a/app/javascript/mastodon/locales/eu.json
+++ b/app/javascript/mastodon/locales/eu.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "Bilaketaren emaitzak",
   "emoji_button.symbols": "Sinboloak",
   "emoji_button.travel": "Bidaiak eta tokiak",
+  "empty_column.account_hides_collections": "Erabiltzaile honek informazio hau erabilgarri ez egotea aukeratu du.",
   "empty_column.account_suspended": "Kanporatutako kontua",
   "empty_column.account_timeline": "Ez dago bidalketarik hemen!",
   "empty_column.account_unavailable": "Profila ez dago eskuragarri",
diff --git a/app/javascript/mastodon/locales/fr-QC.json b/app/javascript/mastodon/locales/fr-QC.json
index 16a18048b4..a6dd91becf 100644
--- a/app/javascript/mastodon/locales/fr-QC.json
+++ b/app/javascript/mastodon/locales/fr-QC.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "Résultats",
   "emoji_button.symbols": "Symboles",
   "emoji_button.travel": "Voyage et lieux",
+  "empty_column.account_hides_collections": "Cet utilisateur·ice préfère ne pas rendre publiques ces informations",
   "empty_column.account_suspended": "Compte suspendu",
   "empty_column.account_timeline": "Aucune publication ici!",
   "empty_column.account_unavailable": "Profil non disponible",
diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json
index 9471918543..0d2ba2bb9b 100644
--- a/app/javascript/mastodon/locales/fr.json
+++ b/app/javascript/mastodon/locales/fr.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "Résultats de la recherche",
   "emoji_button.symbols": "Symboles",
   "emoji_button.travel": "Voyage et lieux",
+  "empty_column.account_hides_collections": "Cet utilisateur·ice préfère ne pas rendre publiques ces informations",
   "empty_column.account_suspended": "Compte suspendu",
   "empty_column.account_timeline": "Aucun message ici !",
   "empty_column.account_unavailable": "Profil non disponible",
diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json
index 14ff22b287..e79e549264 100644
--- a/app/javascript/mastodon/locales/gl.json
+++ b/app/javascript/mastodon/locales/gl.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "Resultados da procura",
   "emoji_button.symbols": "Símbolos",
   "emoji_button.travel": "Viaxes e Lugares",
+  "empty_column.account_hides_collections": "A usuaria decideu non facer pública esta información",
   "empty_column.account_suspended": "Conta suspendida",
   "empty_column.account_timeline": "Non hai publicacións aquí!",
   "empty_column.account_unavailable": "Perfil non dispoñible",
diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json
index 13d3239655..485e8313ad 100644
--- a/app/javascript/mastodon/locales/he.json
+++ b/app/javascript/mastodon/locales/he.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "תוצאות חיפוש",
   "emoji_button.symbols": "סמלים",
   "emoji_button.travel": "טיולים ואתרים",
+  "empty_column.account_hides_collections": "המשתמש.ת בחר.ה להסתיר מידע זה",
   "empty_column.account_suspended": "חשבון מושהה",
   "empty_column.account_timeline": "אין עדיין אף הודעה!",
   "empty_column.account_unavailable": "פרופיל לא זמין",
diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json
index 482dc48be2..ca20271619 100644
--- a/app/javascript/mastodon/locales/hu.json
+++ b/app/javascript/mastodon/locales/hu.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "Keresési találatok",
   "emoji_button.symbols": "Szimbólumok",
   "emoji_button.travel": "Utazás és Helyek",
+  "empty_column.account_hides_collections": "Ez a felhasználó úgy döntött, hogy nem teszi elérhetővé ezt az információt.",
   "empty_column.account_suspended": "Fiók felfüggesztve",
   "empty_column.account_timeline": "Itt nincs bejegyzés!",
   "empty_column.account_unavailable": "A profil nem érhető el",
diff --git a/app/javascript/mastodon/locales/is.json b/app/javascript/mastodon/locales/is.json
index f2e6f1f449..0b6a8012ad 100644
--- a/app/javascript/mastodon/locales/is.json
+++ b/app/javascript/mastodon/locales/is.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "Leitarniðurstöður",
   "emoji_button.symbols": "Tákn",
   "emoji_button.travel": "Ferðalög og staðir",
+  "empty_column.account_hides_collections": "Notandinn hefur valið að gera ekki tiltækar þessar upplýsingar",
   "empty_column.account_suspended": "Notandaaðgangur í frysti",
   "empty_column.account_timeline": "Engar færslur hér!",
   "empty_column.account_unavailable": "Notandasnið ekki tiltækt",
diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json
index 473a123edf..4a2f41ce64 100644
--- a/app/javascript/mastodon/locales/it.json
+++ b/app/javascript/mastodon/locales/it.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "Risultati della ricerca",
   "emoji_button.symbols": "Simboli",
   "emoji_button.travel": "Viaggi & Luoghi",
+  "empty_column.account_hides_collections": "Questo utente ha scelto di non rendere disponibili queste informazioni",
   "empty_column.account_suspended": "Profilo sospeso",
   "empty_column.account_timeline": "Nessun post qui!",
   "empty_column.account_unavailable": "Profilo non disponibile",
diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json
index a01354463f..72a57c8e3f 100644
--- a/app/javascript/mastodon/locales/ja.json
+++ b/app/javascript/mastodon/locales/ja.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "検索結果",
   "emoji_button.symbols": "記号",
   "emoji_button.travel": "旅行と場所",
+  "empty_column.account_hides_collections": "このユーザーはこの情報を開示しないことにしています。",
   "empty_column.account_suspended": "アカウントは停止されています",
   "empty_column.account_timeline": "投稿がありません!",
   "empty_column.account_unavailable": "プロフィールは利用できません",
diff --git a/app/javascript/mastodon/locales/lt.json b/app/javascript/mastodon/locales/lt.json
index 62aaa84758..a1ab531316 100644
--- a/app/javascript/mastodon/locales/lt.json
+++ b/app/javascript/mastodon/locales/lt.json
@@ -1,25 +1,37 @@
 {
-  "about.blocks": "Moderatorių prižiūrimi serveriai",
-  "about.contact": "Kontaktai:",
-  "about.disclaimer": "Mastodon, tai nemokama, atviro kodo programa, kuriuos prekybinis ženklas priklauso Mastodon GmbH.",
+  "about.blocks": "Prižiūrimi serveriai",
+  "about.contact": "Kontaktuoti:",
+  "about.disclaimer": "Mastodon – nemokama atvirojo šaltinio programa ir Mastodon gGmbH prekės ženklas.",
   "about.domain_blocks.no_reason_available": "Priežastis nežinoma",
-  "about.domain_blocks.suspended.title": "Uždraustas",
-  "about.not_available": "Šiame serveryje informacijos nėra.",
+  "about.domain_blocks.preamble": "Mastodon paprastai leidžia peržiūrėti turinį ir bendrauti su naudotojais iš bet kurio kito fediverse esančio serverio. Šios yra išimtys, kurios buvo padarytos šiame konkrečiame serveryje.",
+  "about.domain_blocks.silenced.explanation": "Paprastai nematysi profilių ir turinio iš šio serverio, nebent jį aiškiai ieškosi arba pasirinksi jį sekdamas (-a).",
+  "about.domain_blocks.silenced.title": "Ribota",
+  "about.domain_blocks.suspended.explanation": "Jokie duomenys iš šio serverio nebus apdorojami, saugomi ar keičiami, todėl bet kokia sąveika ar bendravimas su šio serverio naudotojais bus neįmanomas.",
+  "about.domain_blocks.suspended.title": "Uždrausta",
+  "about.not_available": "Ši informacija nebuvo pateikta šiame serveryje.",
+  "about.powered_by": "Decentralizuota socialinė žiniasklaida, kurią valdo {mastodon}",
   "about.rules": "Serverio taisyklės",
   "account.account_note_header": "Pastaba",
-  "account.add_or_remove_from_list": "Pridėti arba ištrinti iš sąrašo",
-  "account.badges.bot": "Robotas",
+  "account.add_or_remove_from_list": "Pridėti arba ištrinti iš sąrašų",
+  "account.badges.bot": "Automatizuotas",
   "account.badges.group": "Grupė",
   "account.block": "Užblokuoti @{name}",
-  "account.block_domain": "Hide everything from {domain}",
+  "account.block_domain": "Blokuoti domeną {domain}",
+  "account.block_short": "Blokuoti",
   "account.blocked": "Užblokuota",
-  "account.cancel_follow_request": "Withdraw follow request",
-  "account.domain_blocked": "Domain hidden",
+  "account.browse_more_on_origin_server": "Naršyti daugiau originaliame profilyje",
+  "account.cancel_follow_request": "Atšaukti sekimą",
+  "account.direct": "Privačiai paminėti @{name}",
+  "account.disable_notifications": "Nustoti man pranešti, kai @{name} paskelbia",
+  "account.domain_blocked": "Užblokuotas domenas",
+  "account.edit_profile": "Redaguoti profilį",
   "account.follow": "Sekti",
   "account.follows_you": "Seka jus",
   "account.go_to_profile": "Eiti į profilį",
+  "account.in_memoriam": "Atminimui.",
   "account.joined_short": "Prisijungė",
-  "account.media": "Media",
+  "account.locked_info": "Šios paskyros privatumo būsena nustatyta kaip užrakinta. Savininkas (-ė) rankiniu būdu peržiūri, kas gali sekti.",
+  "account.media": "Medija",
   "account.mute": "Užtildyti @{name}",
   "account.muted": "Užtildytas",
   "account.posts": "Toots",
@@ -33,6 +45,10 @@
   "account.unmute_short": "Atitildyti",
   "account_note.placeholder": "Click to add a note",
   "alert.unexpected.title": "Oi!",
+  "announcement.announcement": "Skelbimas",
+  "audio.hide": "Slėpti garsą",
+  "autosuggest_hashtag.per_week": "{count} per savaitę",
+  "bundle_column_error.error.title": "O, ne!",
   "column.domain_blocks": "Hidden domains",
   "column.lists": "Sąrašai",
   "column.mutes": "Užtildyti vartotojai",
@@ -43,24 +59,50 @@
   "column_header.show_settings": "Rodyti nustatymus",
   "column_header.unpin": "Atsegti",
   "column_subheading.settings": "Nustatymai",
-  "community.column_settings.media_only": "Media only",
+  "community.column_settings.media_only": "Tik medija",
+  "compose.language.change": "Keisti kalbą",
+  "compose.language.search": "Ieškoti kalbų...",
+  "compose.published.body": "Įrašas paskelbtas.",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
   "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.placeholder": "What is on your mind?",
   "compose_form.publish_form": "Publish",
+  "compose_form.sensitive.hide": "{count, plural, one {Žymėti mediją kaip jautrią} few {Žymėti medijas kaip jautrias} many {Žymėti medijos kaip jautrios} other {Žymėti medijų kaip jautrių}}",
+  "compose_form.sensitive.marked": "{count, plural, one {Medija pažymėta kaip jautri} few {Medijos pažymėtos kaip jautrios} many {Medijos pažymėta kaip jautrios} other {Medijų pažymėtos kaip jautrios}}",
+  "compose_form.sensitive.unmarked": "{count, plural, one {Medija nepažymėta kaip jautri} few {Medijos nepažymėtos kaip jautrios} many {Medijos nepažymėta kaip jautri} other {Medijų nepažymėta kaip jautrios}}",
   "compose_form.spoiler.marked": "Text is hidden behind warning",
   "compose_form.spoiler.unmarked": "Text is not hidden",
+  "confirmations.delete.confirm": "Ištrinti",
   "confirmations.delete.message": "Are you sure you want to delete this status?",
+  "confirmations.discard_edit_media.confirm": "Atmesti",
+  "confirmations.discard_edit_media.message": "Turi neišsaugotų medijos aprašymo ar peržiūros pakeitimų, vis tiek juos atmesti?",
   "confirmations.domain_block.confirm": "Hide entire domain",
+  "confirmations.reply.confirm": "Atsakyti",
+  "confirmations.reply.message": "Atsakydamas (-a) dabar perrašysi šiuo metu rašomą žinutę. Ar tikrai nori tęsti?",
+  "confirmations.unfollow.confirm": "Nebesekti",
   "dismissable_banner.explore_links": "These news stories are being talked about by people on this and other servers of the decentralized network right now.",
   "dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.",
   "embed.instructions": "Embed this status on your website by copying the code below.",
+  "emoji_button.search": "Paieška...",
+  "empty_column.account_hides_collections": "Šis naudotojas (-a) pasirinko nepadaryti šią informaciją prieinamą",
   "empty_column.account_timeline": "No toots here!",
   "empty_column.bookmarked_statuses": "You don't have any bookmarked toots yet. When you bookmark one, it will show up here.",
   "empty_column.domain_blocks": "There are no hidden domains yet.",
+  "empty_column.hashtag": "Nėra nieko šiame saitažodyje kol kas.",
   "empty_column.home": "Your home timeline is empty! Follow more people to fill it up. {suggestions}",
   "empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
+  "firehose.local": "Šis serveris",
+  "follow_requests.unlocked_explanation": "Nors tavo paskyra neužrakinta, {domain} personalas mano, kad galbūt norėsi rankiniu būdu patikrinti šių paskyrų sekimo užklausas.",
+  "followed_tags": "Sekamos saitažodžiai",
+  "footer.about": "Apie",
+  "footer.invite": "Kviesti žmones",
   "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "interaction_modal.no_account_yet": "Nesi Mastodon?",
+  "interaction_modal.on_another_server": "Kitame serveryje",
+  "interaction_modal.on_this_server": "Šiame serveryje",
+  "interaction_modal.sign_in": "Nesi prisijungęs (-usi) prie šio serverio. Kur yra laikoma tavo paskyra?",
+  "interaction_modal.sign_in_hint": "Patarimas: tai svetainė, kurioje užsiregistravai. Jei neprisimeni, ieškok sveikinimo el. laiško savo pašto dėžutėje. Taip pat gali įvesti visą savo naudotojo vardą (pvz., @Mastodon@mastodon.social).",
+  "interaction_modal.title.favourite": "Mėgstamiausias {name} įrašas",
   "keyboard_shortcuts.back": "to navigate back",
   "keyboard_shortcuts.blocked": "to open blocked users list",
   "keyboard_shortcuts.boost": "to boost",
@@ -72,13 +114,14 @@
   "keyboard_shortcuts.federated": "to open federated timeline",
   "keyboard_shortcuts.heading": "Keyboard Shortcuts",
   "keyboard_shortcuts.home": "to open home timeline",
+  "keyboard_shortcuts.hotkey": "Spartusis klavišas",
   "keyboard_shortcuts.legend": "to display this legend",
   "keyboard_shortcuts.local": "to open local timeline",
   "keyboard_shortcuts.mention": "to mention author",
   "keyboard_shortcuts.muted": "to open muted users list",
   "keyboard_shortcuts.my_profile": "to open your profile",
   "keyboard_shortcuts.notifications": "to open notifications column",
-  "keyboard_shortcuts.open_media": "to open media",
+  "keyboard_shortcuts.open_media": "Atidaryti mediją",
   "keyboard_shortcuts.pinned": "to open pinned toots list",
   "keyboard_shortcuts.profile": "to open author's profile",
   "keyboard_shortcuts.reply": "to reply",
@@ -87,21 +130,39 @@
   "keyboard_shortcuts.spoilers": "to show/hide CW field",
   "keyboard_shortcuts.start": "to open \"get started\" column",
   "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
-  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
+  "keyboard_shortcuts.toggle_sensitivity": "Rodyti / slėpti mediją",
   "keyboard_shortcuts.toot": "to start a brand new toot",
   "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
   "keyboard_shortcuts.up": "to move up in the list",
+  "lightbox.close": "Uždaryti",
+  "media_gallery.toggle_visible": "{number, plural, one {Slėpti vaizdą} few {Slėpti vaizdus} many {Slėpti vaizdo} other {Slėpti vaizdų}}",
   "navigation_bar.compose": "Compose new toot",
   "navigation_bar.domain_blocks": "Hidden domains",
+  "navigation_bar.follows_and_followers": "Sekimai ir sekėjai",
+  "navigation_bar.lists": "Sąrašai",
+  "navigation_bar.logout": "Atsijungti",
+  "navigation_bar.mutes": "Užtildyti naudotojai",
+  "navigation_bar.opened_in_classic_interface": "Įrašai, paskyros ir kiti konkretūs puslapiai pagal numatytuosius nustatymus atidaromi klasikinėje žiniatinklio sąsajoje.",
+  "navigation_bar.personal": "Asmeninis",
   "navigation_bar.pins": "Pinned toots",
+  "navigation_bar.preferences": "Nuostatos",
   "not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.",
+  "notification.own_poll": "Tavo apklausa baigėsi",
+  "notification.poll": "Apklausa, kurioje balsavai, pasibaigė",
   "notification.reblog": "{name} boosted your status",
+  "notification.status": "{name} ką tik paskelbė",
+  "notification.update": "{name} redagavo įrašą",
+  "notifications.clear": "Išvalyti pranešimus",
+  "notifications.clear_confirmation": "Ar tikrai nori visam laikui išvalyti visus pranešimus?",
+  "notifications.column_settings.admin.report": "Nauji ataskaitos:",
   "notifications.column_settings.status": "New toots:",
+  "notifications.filter.mentions": "Paminėjimai",
   "onboarding.actions.go_to_explore": "See what's trending",
   "onboarding.actions.go_to_home": "Go to your home feed",
   "onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!",
   "onboarding.follows.title": "Popular on Mastodon",
-  "onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:",
+  "onboarding.share.message": "Aš {username} #Mastodon! Ateik sekti manęs adresu {url}",
+  "onboarding.start.lead": "Dabar esi Mastodon dalis – unikalios decentralizuotos socialinės žiniasklaidos platformos, kurioje tu, o ne algoritmas, pats nustatai savo patirtį. Pradėkime tavo kelionę šioje naujoje socialinėje erdvėje:",
   "onboarding.start.skip": "Want to skip right ahead?",
   "onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.",
   "onboarding.steps.follow_people.title": "Follow {count, plural, one {one person} other {# people}}",
@@ -110,11 +171,17 @@
   "onboarding.steps.setup_profile.title": "Customize your profile",
   "onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!",
   "onboarding.steps.share_profile.title": "Share your profile",
+  "poll.vote": "Balsuoti",
+  "poll.voted": "Tu balsavai už šį atsakymą",
+  "poll.votes": "{votes, plural, one {# balsas} few {# balsai} many {# balso} other {# balsų}}",
   "privacy.change": "Adjust status privacy",
   "privacy.direct.long": "Post to mentioned users only",
   "privacy.direct.short": "Direct",
   "privacy.private.long": "Post to followers only",
   "privacy.private.short": "Followers-only",
+  "privacy.unlisted.long": "Matomas visiems, bet atsisakyta atradimo funkcijų",
+  "privacy.unlisted.short": "Neįtrauktas į sąrašą",
+  "privacy_policy.last_updated": "Paskutinį kartą atnaujinta {date}",
   "report.placeholder": "Type or paste additional comments",
   "report.submit": "Submit report",
   "report.target": "Report {target}",
@@ -124,14 +191,19 @@
   "status.admin_status": "Open this status in the moderation interface",
   "status.copy": "Copy link to status",
   "status.edited_x_times": "Edited {count, plural, one {# time} other {# times}}",
+  "status.media.open": "Spausk, kad atidaryti",
+  "status.media.show": "Spausk, kad pamatyti",
+  "status.media_hidden": "Paslėpta medija",
   "status.open": "Expand this status",
   "status.pinned": "Pinned toot",
   "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
   "status.title.with_attachments": "{user} posted {attachmentCount, plural, one {an attachment} other {# attachments}}",
+  "status.uncached_media_warning": "Peržiūra nepasiekiama",
   "timeline_hint.resources.statuses": "Older toots",
   "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {# days}}",
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
+  "upload_modal.edit_media": "Redaguoti mediją",
   "upload_progress.label": "Uploading…"
 }
diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json
index 7f71d9318b..5d681b8291 100644
--- a/app/javascript/mastodon/locales/lv.json
+++ b/app/javascript/mastodon/locales/lv.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "Meklēšanas rezultāti",
   "emoji_button.symbols": "Simboli",
   "emoji_button.travel": "Ceļošana un vietas",
+  "empty_column.account_hides_collections": "Šis lietotājs ir izvēlējies nedarīt šo informāciju pieejamu",
   "empty_column.account_suspended": "Konta darbība ir apturēta",
   "empty_column.account_timeline": "Šeit ziņojumu nav!",
   "empty_column.account_unavailable": "Profils nav pieejams",
diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json
index 87a2af4f20..131d2e4aa0 100644
--- a/app/javascript/mastodon/locales/nl.json
+++ b/app/javascript/mastodon/locales/nl.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "Zoekresultaten",
   "emoji_button.symbols": "Symbolen",
   "emoji_button.travel": "Reizen en locaties",
+  "empty_column.account_hides_collections": "Deze gebruiker heeft ervoor gekozen deze informatie niet beschikbaar te maken",
   "empty_column.account_suspended": "Account opgeschort",
   "empty_column.account_timeline": "Hier zijn geen berichten!",
   "empty_column.account_unavailable": "Profiel is niet beschikbaar",
diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json
index 8ff390aabb..aa30aef7d2 100644
--- a/app/javascript/mastodon/locales/nn.json
+++ b/app/javascript/mastodon/locales/nn.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "Søkeresultat",
   "emoji_button.symbols": "Symbol",
   "emoji_button.travel": "Reise & stader",
+  "empty_column.account_hides_collections": "Denne brukaren har valt å ikkje gjere denne informasjonen tilgjengeleg",
   "empty_column.account_suspended": "Kontoen er suspendert",
   "empty_column.account_timeline": "Ingen tut her!",
   "empty_column.account_unavailable": "Profil ikkje tilgjengeleg",
diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json
index 84ea64bb98..643f78a884 100644
--- a/app/javascript/mastodon/locales/pl.json
+++ b/app/javascript/mastodon/locales/pl.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "Wyniki wyszukiwania",
   "emoji_button.symbols": "Symbole",
   "emoji_button.travel": "Podróże i miejsca",
+  "empty_column.account_hides_collections": "Użytkownik postanowił nie udostępniać tych informacji",
   "empty_column.account_suspended": "Konto zawieszone",
   "empty_column.account_timeline": "Brak wpisów tutaj!",
   "empty_column.account_unavailable": "Profil niedostępny",
diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json
index 2e908fdc5b..8d54ef41b1 100644
--- a/app/javascript/mastodon/locales/sq.json
+++ b/app/javascript/mastodon/locales/sq.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "Përfundime kërkimi",
   "emoji_button.symbols": "Simbole",
   "emoji_button.travel": "Udhëtime & Vende",
+  "empty_column.account_hides_collections": "Ky përdorues ka zgjedhur të mos e japë këtë informacion",
   "empty_column.account_suspended": "Llogaria u pezullua",
   "empty_column.account_timeline": "S’ka mesazhe këtu!",
   "empty_column.account_unavailable": "Profil jashtë funksionimi",
diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json
index e0b6fc4722..edf981e112 100644
--- a/app/javascript/mastodon/locales/sv.json
+++ b/app/javascript/mastodon/locales/sv.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "Sökresultat",
   "emoji_button.symbols": "Symboler",
   "emoji_button.travel": "Resor & platser",
+  "empty_column.account_hides_collections": "Användaren har valt att inte göra denna information tillgänglig",
   "empty_column.account_suspended": "Kontot är avstängt",
   "empty_column.account_timeline": "Inga inlägg här!",
   "empty_column.account_unavailable": "Profilen ej tillgänglig",
diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json
index ff6e5a52d5..80f862cbe0 100644
--- a/app/javascript/mastodon/locales/th.json
+++ b/app/javascript/mastodon/locales/th.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "ผลลัพธ์การค้นหา",
   "emoji_button.symbols": "สัญลักษณ์",
   "emoji_button.travel": "การเดินทางและสถานที่",
+  "empty_column.account_hides_collections": "ผู้ใช้นี้ได้เลือกที่จะไม่ทำให้ข้อมูลนี้พร้อมใช้งาน",
   "empty_column.account_suspended": "ระงับบัญชีอยู่",
   "empty_column.account_timeline": "ไม่มีโพสต์ที่นี่!",
   "empty_column.account_unavailable": "โปรไฟล์ไม่พร้อมใช้งาน",
diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json
index de92b9b56f..9ad2594930 100644
--- a/app/javascript/mastodon/locales/tr.json
+++ b/app/javascript/mastodon/locales/tr.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "Arama sonuçları",
   "emoji_button.symbols": "Semboller",
   "emoji_button.travel": "Seyahat ve Yerler",
+  "empty_column.account_hides_collections": "Bu kullanıcı bu bilgiyi sağlamayı tercih etmemiştir",
   "empty_column.account_suspended": "Hesap askıya alındı",
   "empty_column.account_timeline": "Burada hiç gönderi yok!",
   "empty_column.account_unavailable": "Profil kullanılamıyor",
diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json
index aa17e12545..09fa58fbf9 100644
--- a/app/javascript/mastodon/locales/uk.json
+++ b/app/javascript/mastodon/locales/uk.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "Результати пошуку",
   "emoji_button.symbols": "Символи",
   "emoji_button.travel": "Подорожі та місця",
+  "empty_column.account_hides_collections": "Цей користувач вирішив не робити цю інформацію доступною",
   "empty_column.account_suspended": "Обліковий запис заблоковано",
   "empty_column.account_timeline": "Тут немає дописів!",
   "empty_column.account_unavailable": "Профіль недоступний",
diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json
index c311b5ae33..f830aa2985 100644
--- a/app/javascript/mastodon/locales/zh-CN.json
+++ b/app/javascript/mastodon/locales/zh-CN.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "搜索结果",
   "emoji_button.symbols": "符号",
   "emoji_button.travel": "旅行和地点",
+  "empty_column.account_hides_collections": "该用户选择不提供此信息",
   "empty_column.account_suspended": "账户已被停用",
   "empty_column.account_timeline": "这里没有嘟文!",
   "empty_column.account_unavailable": "个人资料不可用",
diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json
index 47880f7112..7121a7d03e 100644
--- a/app/javascript/mastodon/locales/zh-HK.json
+++ b/app/javascript/mastodon/locales/zh-HK.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "搜尋結果",
   "emoji_button.symbols": "符號",
   "emoji_button.travel": "旅遊景物",
+  "empty_column.account_hides_collections": "這位使用者選擇不公開此資訊",
   "empty_column.account_suspended": "帳號已停權",
   "empty_column.account_timeline": "這裡還沒有嘟文!",
   "empty_column.account_unavailable": "無法取得個人資料",
diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json
index 5d3d74ea68..db4fe4eab2 100644
--- a/app/javascript/mastodon/locales/zh-TW.json
+++ b/app/javascript/mastodon/locales/zh-TW.json
@@ -222,6 +222,7 @@
   "emoji_button.search_results": "搜尋結果",
   "emoji_button.symbols": "符號",
   "emoji_button.travel": "旅遊與地點",
+  "empty_column.account_hides_collections": "這位使用者選擇不提供此資訊",
   "empty_column.account_suspended": "帳號已被停權",
   "empty_column.account_timeline": "這裡還沒有嘟文!",
   "empty_column.account_unavailable": "無法取得個人檔案",
diff --git a/config/locales/doorkeeper.lt.yml b/config/locales/doorkeeper.lt.yml
index 6c5cb837ac..36f31e39ea 100644
--- a/config/locales/doorkeeper.lt.yml
+++ b/config/locales/doorkeeper.lt.yml
@@ -1 +1,69 @@
+---
 lt:
+  doorkeeper:
+    authorizations:
+      error:
+        title: Įvyko klaida.
+      new:
+        prompt_html: "%{client_name} norėtų gauti leidimą prieigos prie tavo paskyros. Tai trečiosios šalies programėlė. <strong>Jei ja nepasitiki, neturėtum jai leisti.</strong>"
+    authorized_applications:
+      index:
+        title: Tavo leidžiamos programėlės
+    grouped_scopes:
+      title:
+        blocks: Blokavimai
+        follow: Sekimai, nutildymai ir blokavimai
+        statuses: Įrašai
+    layouts:
+      admin:
+        nav:
+          applications: Programėlės
+          oauth2_provider: OAuth2 teikėjas
+      application:
+        title: Reikalingas OAuth įgaliojimas
+    scopes:
+      admin:read: skaityti visus serveryje esančius duomenis
+      admin:read:accounts: skaityti neskelbtiną visų paskyrų informaciją
+      admin:read:canonical_email_blocks: skaityti neskelbtiną visų kanoninių el. laiško blokavimų informaciją
+      admin:read:domain_allows: skaityti neskelbtiną visų domeno leidimus informaciją
+      admin:read:domain_blocks: skaityti neskelbtiną visų domeno blokavimų informaciją
+      admin:read:email_domain_blocks: skaityti neskelbtiną visų el. laiško domeno blokavimų informaciją
+      admin:read:ip_blocks: skaityti neskelbtiną visų IP blokavimų informaciją
+      admin:read:reports: skaityti neskelbtiną visų ataskaitų ir praneštų paskyrų informaciją
+      admin:write: modifikuoti visus serveryje esančius duomenis
+      admin:write:accounts: atlikti paskyrų prižiūrėjimo veiksmus
+      admin:write:canonical_email_blocks: atlikti kanoninių el. laiško blokavimų prižiūrėjimo veiksmus
+      admin:write:domain_allows: atlikti prižiūrėjimo veiksmus su domeno leidimais
+      admin:write:domain_blocks: atlikti prižiūrėjimo veiksmus su domenų blokavimais
+      admin:write:email_domain_blocks: atlikti prižiūrėjimo veiksmus su el. laiško domenų blokavimais
+      admin:write:ip_blocks: atlikti prižiūrėjimo veiksmus su IP blokavimais
+      crypto: naudoti galo iki galo šifravimą
+      follow: modifikuoti paskyros santykius
+      push: gauti tavo stumiamuosius pranešimus
+      read: skaityti tavo visus paskyros duomenis
+      read:accounts: matyti paskyrų informaciją
+      read:blocks: matyti tavo blokavimus
+      read:bookmarks: matyti tavo žymes
+      read:favourites: matyti tavo mėgstamiausius
+      read:filters: matyti tavo filtrus
+      read:follows: matyti tavo sekimus
+      read:lists: matyti tavo sąrašus
+      read:mutes: matyti tavo nutildymus
+      read:notifications: matyti tavo pranešimus
+      read:reports: matyti tavo ataskaitas
+      read:search: ieškoti tavo vardu
+      read:statuses: matyti visus įrašus
+      write: modifikuoti visus tavo paskyros duomenis
+      write:accounts: modifikuoti tavo profilį
+      write:blocks: blokuoti paskyras ir domenus
+      write:bookmarks: įrašyti įrašus
+      write:conversations: nutildyti ir ištrinti pokalbius
+      write:favourites: mėgti įrašai
+      write:filters: sukurti filtrus
+      write:follows: sekti žmones
+      write:lists: sukurti sąrašus
+      write:media: įkelti medijos failus
+      write:mutes: nutildyti žmones ir pokalbius
+      write:notifications: išvalyti tavo pranešimus
+      write:reports: pranešti kitus asmenus
+      write:statuses: skelbti įrašus
diff --git a/config/locales/fi.yml b/config/locales/fi.yml
index d6f327c327..4fe0179dfe 100644
--- a/config/locales/fi.yml
+++ b/config/locales/fi.yml
@@ -1041,13 +1041,13 @@ fi:
       hint_html: Vielä yksi juttu! Meidän on vahvistettava, että olet ihminen (tämän avulla pidämme roskapostin poissa!). Ratkaise alla oleva CAPTCHA-vahvistus ja paina "Jatka".
       title: Turvatarkastus
     confirmations:
-      awaiting_review: Sähköpostiosoitteesi on vahvistettu! Seuraavaksi palvelimen %{domain} ylläpito tarkistaa rekisteröitymisesi ja saat lopuksi ilmoituksen sähköpostitse, jos tilisi hyväksytään!
+      awaiting_review: Sähköpostiosoitteesi on vahvistettu! Seuraavaksi palvelimen %{domain} ylläpito tarkistaa rekisteröitymisesi, ja saat lopuksi ilmoituksen sähköpostitse, jos tilisi hyväksytään!
       awaiting_review_title: Rekisteröitymisesi on tarkistettavana
       clicking_this_link: tästä linkistä
       login_link: kirjautumalla sisään
       proceed_to_login_html: Voit nyt jatkaa %{login_link}.
       redirect_to_app_html: Sinun olisi pitänyt ohjautua sovellukseen <strong>%{app_name}</strong>. Jos näin ei tapahtunut, yritä avata se %{clicking_this_link} tai palaa sovellukseen manuaalisesti.
-      registration_complete: Rekisteröitymisesi palvelimelle %{domain} on suoritettu!
+      registration_complete: Rekisteröitymisesi palvelimelle %{domain} on nyt valmis!
       welcome_title: Tervetuloa, %{name}!
       wrong_email_hint: Jos sähköpostiosoite ei ole oikein, voit muuttaa sen tilin asetuksista.
     delete_account: Poista tili
diff --git a/config/locales/ja.yml b/config/locales/ja.yml
index 0c805b9e56..ca438f53d2 100644
--- a/config/locales/ja.yml
+++ b/config/locales/ja.yml
@@ -1025,12 +1025,12 @@ ja:
     confirmations:
       awaiting_review: メールアドレスは確認済みです。%{domain} のモデレーターによりアカウント登録の審査が完了すると、メールでお知らせします。
       awaiting_review_title: 登録の審査待ちです
-      clicking_this_link: こちらのリンク
-      login_link: こちらのリンク
-      proceed_to_login_html: "%{login_link}から早速ログインしてみましょう。"
-      redirect_to_app_html: "<strong>%{app_name}</strong>に戻ります。自動で移動しない場合は%{clicking_this_link}を押すか、手動でアプリを切り替えてください。"
+      clicking_this_link: このリンクを押す
+      login_link: ログイン
+      proceed_to_login_html: それでは%{login_link}しましょう。
+      redirect_to_app_html: 自動的に<strong>%{app_name}</strong>に戻らなかった場合、%{clicking_this_link}か、手動でアプリを切り替えてください。
       registration_complete: "%{domain} へのアカウント登録が完了しました。"
-      welcome_title: Mastodonへようこそ、%{name}さん
+      welcome_title: ようこそ、%{name}さん!
       wrong_email_hint: メールアドレスが正しくない場合は、アカウント設定で変更できます。
     delete_account: アカウントの削除
     delete_account_html: アカウントを削除したい場合、<a href="%{path}">こちら</a>から手続きが行えます。削除する前に、確認画面があります。
diff --git a/config/locales/lt.yml b/config/locales/lt.yml
index 7ad63c5e39..2f4d813c9e 100644
--- a/config/locales/lt.yml
+++ b/config/locales/lt.yml
@@ -58,6 +58,7 @@ lt:
       follows: Seka
       header: Antraštė
       inbox_url: Gautųjų URL
+      invite_request_text: Priežastys prisijungiant
       invited_by: Pakvietė
       ip: IP
       joined: Prisijungė
@@ -183,10 +184,10 @@ lt:
       deactivate_all: Deaktyvuoti visus
       filter:
         all: Visi
-        available: Prieinamas
+        available: Pasiekiamas
         expired: Pasibaigęs
         title: Filtras
-      title: Pakvietimai
+      title: Kvietimai
     relays:
       add_new: Pridėti naują pamainą
       delete: Ištrinti
@@ -236,6 +237,8 @@ lt:
       everyone: Numatytieji leidimai
       everyone_full_description_html: Tai – <strong>bazinis vaidmuo</strong>, turintis įtakos <strong>visiems naudotojams</strong>, net ir tiems, kurie neturi priskirto vaidmens. Visi kiti vaidmenys iš jo paveldi teises.
     settings:
+      captcha_enabled:
+        desc_html: Tai priklauso nuo hCaptcha išorinių skriptų, kurie gali kelti susirūpinimą dėl saugumo ir privatumo. Be to, <strong>dėl to registracijos procesas kai kuriems žmonėms (ypač neįgaliesiems) gali būti gerokai sunkiau prieinami</strong>. Dėl šių priežasčių apsvarstyk alternatyvias priemones, pavyzdžiui, patvirtinimu arba kvietimu grindžiamą registraciją.
       domain_blocks:
         all: Visiems
     statuses:
@@ -285,6 +288,9 @@ lt:
     or_log_in_with: Arba prisijungti su
     register: Užsiregistruoti
     reset_password: Atstatyti slaptažodį
+    rules:
+      invited_by: 'Gali prisijungti prie %{domain} pagal kvietimą, kurį gavai iš:'
+      preamble_invited: Prieš tęsiant, atsižvelk į pagrindines taisykles, kurias nustatė %{domain} prižiūrėtojai.
     security: Apsauga
     set_new_password: Nustatyti naują slaptažodį
   datetime:
@@ -367,7 +373,7 @@ lt:
     upload: Įkelti
   invites:
     delete: Deaktyvuoti
-    expired: Pasibaigęs
+    expired: Pasibaigė
     expires_in:
       '1800': 30 minučių
       '21600': 6 valandų
@@ -378,10 +384,15 @@ lt:
     expires_in_prompt: Niekada
     generate: Generuoti
     invited_by: 'Jus pakvietė:'
-    max_uses_prompt: Be limito
-    prompt: Generuoti ir dalintis įrašais su kitais, kad sukurti prieigą prie serverio
+    max_uses:
+      few: "%{count} panaudojimai"
+      many: "%{count} panaudojimo"
+      one: 1 panaudojimas
+      other: "%{count} panaudojimų"
+    max_uses_prompt: Nėra limito
+    prompt: Generuok ir bendrink nuorodas su kitais, kad suteiktum prieigą prie šio serverio
     table:
-      expires_at: Pasibaigia
+      expires_at: Baigsis
       uses: Naudojimai
     title: Pakviesti žmones
   media_attachments:
diff --git a/config/locales/lv.yml b/config/locales/lv.yml
index 28a1a33dcb..4bcf23de4d 100644
--- a/config/locales/lv.yml
+++ b/config/locales/lv.yml
@@ -343,7 +343,7 @@ lv:
       title: Pielāgotās emocijzīmes
       uncategorized: Nekategorizētās
       unlist: Izslēgt
-      unlisted: Nerindota
+      unlisted: Neminētie
       update_failed_msg: Nevarēja atjaunināt šo emocijzīmi
       updated_msg: Emocijzīme veiksmīgi atjaunināta!
       upload: Augšupielādēt
@@ -545,6 +545,7 @@ lv:
       total_reported: Ziņojumi par viņiem
       total_storage: Multividesu pielikumi
       totals_time_period_hint_html: Tālāk redzamajās summās ir iekļauti dati par visu laiku.
+      unknown_instance: Pašlaik šajā serverī nav ierakstu par šo domēnu.
     invites:
       deactivate_all: Deaktivēt visu
       filter:
@@ -1058,6 +1059,14 @@ lv:
       hint_html: Vēl tikai viena lieta! Mums ir jāapstiprina, ka tu esi cilvēks (tas ir tāpēc, lai mēs varētu nepieļaut surogātpasta izsūtīšanu!). Atrisini tālāk norādīto CAPTCHA un noklikšķini uz "Turpināt".
       title: Drošības pārbaude
     confirmations:
+      awaiting_review: Tava e-pasta adrese ir apstiprināta! %{domain} darbinieki tagad pārskata tavu reģistrāciju. Tu saņemsi e-pastu, ja viņi apstiprinās tavu kontu!
+      awaiting_review_title: Tava reģistrācija tiek izskatīta
+      clicking_this_link: klikšķinot šo saiti
+      login_link: pieteikties
+      proceed_to_login_html: Tagad vari doties uz %{login_link}.
+      redirect_to_app_html: Tev vajadzētu būt novirzītam uz lietotni <strong>%{app_name}</strong>. Ja tas nenotika, mēģini %{clicking_this_link} vai manuāli atgriezieties lietotnē.
+      registration_complete: Tava reģistrācija domēnā %{domain} tagad ir pabeigta!
+      welcome_title: Laipni lūdzam, %{name}!
       wrong_email_hint: Ja šī e-pasta adrese nav pareiza, varat to mainīt konta iestatījumos.
     delete_account: Dzēst kontu
     delete_account_html: Ja vēlies dzēst savu kontu, tu vari <a href="%{path}">turpināt šeit</a>. Tev tiks lūgts apstiprinājums.
@@ -1119,6 +1128,7 @@ lv:
       functional: Tavs konts ir pilnībā darboties spējīgs.
       pending: Tavu pieteikumu gaida mūsu darbinieku izskatīšana. Tas var aizņemt kādu laiku. Ja tavs pieteikums tiks apstiprināts, tu saņemsi e-pastu.
       redirecting_to: Tavs konts ir neaktīvs, jo pašlaik tas tiek novirzīts uz %{acct}.
+      self_destruct: Tā kā %{domain} tiek slēgts, tu iegūsi tikai ierobežotu piekļuvi savam kontam.
       view_strikes: Skati iepriekšējos brīdinājumus par savu kontu
     too_fast: Veidlapa ir iesniegta pārāk ātri, mēģini vēlreiz.
     use_security_key: Lietot drošības atslēgu
@@ -1596,6 +1606,9 @@ lv:
     over_daily_limit: Tu esi pārsniedzis šodien ieplānoto %{limit} ziņu ierobežojumu
     over_total_limit: Tu esi pārsniedzis ieplānoto %{limit} ziņu ierobežojumu
     too_soon: Ieplānotajam datumam ir jābūt nākotnē
+  self_destruct:
+    lead_html: Diemžēl domēns <strong>%{domain}</strong> tiek neatgriezeniski slēgts. Ja tev tur bija konts, tu nevarēsi turpināt to lietot, taču joprojām vari pieprasīt savu datu kopiju.
+    title: Šis serveris tiek slēgts
   sessions:
     activity: Pēdējā aktivitāte
     browser: Pārlūks
diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml
index 41ae838b2e..08e866b55e 100644
--- a/config/locales/simple_form.ja.yml
+++ b/config/locales/simple_form.ja.yml
@@ -247,7 +247,7 @@ ja:
         mascot: カスタムマスコット(レガシー)
         media_cache_retention_period: メディアキャッシュの保持期間
         peers_api_enabled: 発見したサーバーのリストをAPIで公開する
-        profile_directory: ディレクトリを有効にする
+        profile_directory: プロフィール一覧を有効にする
         registrations_mode: 新規登録が可能な人
         require_invite_text: 申請事由の入力を必須にする
         show_domain_blocks: ドメインブロックを表示
@@ -258,7 +258,7 @@ ja:
         site_short_description: サーバーの説明
         site_terms: プライバシーポリシー
         site_title: サーバーの名前
-        status_page_url: ステータスページのURL
+        status_page_url: サーバーの状態ページのURL
         theme: デフォルトテーマ
         thumbnail: サーバーのサムネイル
         timeline_preview: 公開タイムラインへの未認証のアクセスを許可する

From 9dc3ce878b51ab80b19365b2a74101cb3e5a8903 Mon Sep 17 00:00:00 2001
From: Matt Jankowski <matt@jankowski.online>
Date: Fri, 10 Nov 2023 10:13:42 -0500
Subject: [PATCH 5/5] Speed-up in `Settings::` controllers specs (#27808)

---
 .../settings/aliases_controller_spec.rb       |  5 +-
 .../settings/applications_controller_spec.rb  | 66 ++++++------------
 .../settings/deletes_controller_spec.rb       | 21 +-----
 .../settings/exports_controller_spec.rb       |  5 +-
 .../settings/imports_controller_spec.rb       | 69 ++++---------------
 .../login_activities_controller_spec.rb       |  5 +-
 .../migration/redirects_controller_spec.rb    |  5 +-
 .../settings/migrations_controller_spec.rb    | 21 +++---
 .../preferences/appearance_controller_spec.rb |  5 +-
 .../notifications_controller_spec.rb          |  5 +-
 .../preferences/other_controller_spec.rb      |  5 +-
 .../settings/profiles_controller_spec.rb      |  5 +-
 .../webauthn_credentials_controller_spec.rb   | 59 +++-------------
 ..._authentication_methods_controller_spec.rb |  5 +-
 14 files changed, 65 insertions(+), 216 deletions(-)

diff --git a/spec/controllers/settings/aliases_controller_spec.rb b/spec/controllers/settings/aliases_controller_spec.rb
index 9636c1ac55..18e568be0b 100644
--- a/spec/controllers/settings/aliases_controller_spec.rb
+++ b/spec/controllers/settings/aliases_controller_spec.rb
@@ -17,11 +17,8 @@ describe Settings::AliasesController do
       get :index
     end
 
-    it 'returns http success' do
+    it 'returns http success with private cache control headers', :aggregate_failures do
       expect(response).to have_http_status(200)
-    end
-
-    it 'returns private cache control headers' do
       expect(response.headers['Cache-Control']).to include('private, no-store')
     end
   end
diff --git a/spec/controllers/settings/applications_controller_spec.rb b/spec/controllers/settings/applications_controller_spec.rb
index 169304b3ed..ccbb634911 100644
--- a/spec/controllers/settings/applications_controller_spec.rb
+++ b/spec/controllers/settings/applications_controller_spec.rb
@@ -18,11 +18,8 @@ describe Settings::ApplicationsController do
       get :index
     end
 
-    it 'returns http success' do
+    it 'returns http success with private cache control headers', :aggregate_failures do
       expect(response).to have_http_status(200)
-    end
-
-    it 'returns private cache control headers' do
       expect(response.headers['Cache-Control']).to include('private, no-store')
     end
   end
@@ -51,7 +48,7 @@ describe Settings::ApplicationsController do
 
   describe 'POST #create' do
     context 'when success (passed scopes as a String)' do
-      def call_create
+      subject do
         post :create, params: {
           doorkeeper_application: {
             name: 'My New App',
@@ -60,20 +57,16 @@ describe Settings::ApplicationsController do
             scopes: 'read write follow',
           },
         }
-        response
       end
 
-      it 'creates an entry in the database' do
-        expect { call_create }.to change(Doorkeeper::Application, :count)
-      end
-
-      it 'redirects back to applications page' do
-        expect(call_create).to redirect_to(settings_applications_path)
+      it 'creates an entry in the database', :aggregate_failures do
+        expect { subject }.to change(Doorkeeper::Application, :count)
+        expect(response).to redirect_to(settings_applications_path)
       end
     end
 
     context 'when success (passed scopes as an Array)' do
-      def call_create
+      subject do
         post :create, params: {
           doorkeeper_application: {
             name: 'My New App',
@@ -82,15 +75,11 @@ describe Settings::ApplicationsController do
             scopes: %w(read write follow),
           },
         }
-        response
       end
 
-      it 'creates an entry in the database' do
-        expect { call_create }.to change(Doorkeeper::Application, :count)
-      end
-
-      it 'redirects back to applications page' do
-        expect(call_create).to redirect_to(settings_applications_path)
+      it 'creates an entry in the database', :aggregate_failures do
+        expect { subject }.to change(Doorkeeper::Application, :count)
+        expect(response).to redirect_to(settings_applications_path)
       end
     end
 
@@ -106,11 +95,8 @@ describe Settings::ApplicationsController do
         }
       end
 
-      it 'returns http success' do
+      it 'returns http success and renders form', :aggregate_failures do
         expect(response).to have_http_status(200)
-      end
-
-      it 'renders form again' do
         expect(response).to render_template(:new)
       end
     end
@@ -118,13 +104,7 @@ describe Settings::ApplicationsController do
 
   describe 'PATCH #update' do
     context 'when success' do
-      let(:opts) do
-        {
-          website: 'https://foo.bar/',
-        }
-      end
-
-      def call_update
+      subject do
         patch :update, params: {
           id: app.id,
           doorkeeper_application: opts,
@@ -132,13 +112,17 @@ describe Settings::ApplicationsController do
         response
       end
 
-      it 'updates existing application' do
-        call_update
-        expect(app.reload.website).to eql(opts[:website])
+      let(:opts) do
+        {
+          website: 'https://foo.bar/',
+        }
       end
 
-      it 'redirects back to applications page' do
-        expect(call_update).to redirect_to(settings_application_path(app))
+      it 'updates existing application' do
+        subject
+
+        expect(app.reload.website).to eql(opts[:website])
+        expect(response).to redirect_to(settings_application_path(app))
       end
     end
 
@@ -155,11 +139,8 @@ describe Settings::ApplicationsController do
         }
       end
 
-      it 'returns http success' do
+      it 'returns http success and renders form', :aggregate_failures do
         expect(response).to have_http_status(200)
-      end
-
-      it 'renders form again' do
         expect(response).to render_template(:show)
       end
     end
@@ -170,11 +151,8 @@ describe Settings::ApplicationsController do
       post :destroy, params: { id: app.id }
     end
 
-    it 'redirects back to applications page' do
+    it 'redirects back to applications page and removes the app' do
       expect(response).to redirect_to(settings_applications_path)
-    end
-
-    it 'removes the app' do
       expect(Doorkeeper::Application.find_by(id: app.id)).to be_nil
     end
   end
diff --git a/spec/controllers/settings/deletes_controller_spec.rb b/spec/controllers/settings/deletes_controller_spec.rb
index 7ee18f9fb1..2c1532ecd8 100644
--- a/spec/controllers/settings/deletes_controller_spec.rb
+++ b/spec/controllers/settings/deletes_controller_spec.rb
@@ -14,22 +14,16 @@ describe Settings::DeletesController do
         get :show
       end
 
-      it 'renders confirmation page' do
+      it 'renders confirmation page with private cache control headers', :aggregate_failures do
         expect(response).to have_http_status(200)
-      end
-
-      it 'returns private cache control headers' do
         expect(response.headers['Cache-Control']).to include('private, no-store')
       end
 
       context 'when suspended' do
         let(:user) { Fabricate(:user, account_attributes: { suspended_at: Time.now.utc }) }
 
-        it 'returns http forbidden' do
+        it 'returns http forbidden with private cache control headers', :aggregate_failures do
           expect(response).to have_http_status(403)
-        end
-
-        it 'returns private cache control headers' do
           expect(response.headers['Cache-Control']).to include('private, no-store')
         end
       end
@@ -56,19 +50,10 @@ describe Settings::DeletesController do
           delete :destroy, params: { form_delete_confirmation: { password: 'petsmoldoggos' } }
         end
 
-        it 'redirects to sign in page' do
+        it 'removes user record and redirects', :aggregate_failures do
           expect(response).to redirect_to '/auth/sign_in'
-        end
-
-        it 'removes user record' do
           expect(User.find_by(id: user.id)).to be_nil
-        end
-
-        it 'marks account as suspended' do
           expect(user.account.reload).to be_suspended
-        end
-
-        it 'does not create an email block' do
           expect(CanonicalEmailBlock.block?(user.email)).to be false
         end
 
diff --git a/spec/controllers/settings/exports_controller_spec.rb b/spec/controllers/settings/exports_controller_spec.rb
index 6a42021318..c8c11c3be3 100644
--- a/spec/controllers/settings/exports_controller_spec.rb
+++ b/spec/controllers/settings/exports_controller_spec.rb
@@ -14,11 +14,8 @@ describe Settings::ExportsController do
         get :show
       end
 
-      it 'returns http success' do
+      it 'returns http success with private cache control headers', :aggregate_failures do
         expect(response).to have_http_status(200)
-      end
-
-      it 'returns private cache control headers' do
         expect(response.headers['Cache-Control']).to include('private, no-store')
       end
     end
diff --git a/spec/controllers/settings/imports_controller_spec.rb b/spec/controllers/settings/imports_controller_spec.rb
index 900d0eb90d..1e7b758931 100644
--- a/spec/controllers/settings/imports_controller_spec.rb
+++ b/spec/controllers/settings/imports_controller_spec.rb
@@ -19,15 +19,9 @@ RSpec.describe Settings::ImportsController do
       get :index
     end
 
-    it 'assigns the expected imports' do
-      expect(assigns(:recent_imports)).to eq [import]
-    end
-
-    it 'returns http success' do
+    it 'assigns the expected imports', :aggregate_failures do
       expect(response).to have_http_status(200)
-    end
-
-    it 'returns private cache control headers' do
+      expect(assigns(:recent_imports)).to eq [import]
       expect(response.headers['Cache-Control']).to include('private, no-store')
     end
   end
@@ -72,17 +66,10 @@ RSpec.describe Settings::ImportsController do
     context 'with someone else\'s import' do
       let(:bulk_import) { Fabricate(:bulk_import, state: :unconfirmed) }
 
-      it 'does not change the import\'s state' do
+      it 'does not change the import\'s state and returns missing', :aggregate_failures do
         expect { subject }.to_not(change { bulk_import.reload.state })
-      end
 
-      it 'does not fire the import worker' do
-        subject
         expect(BulkImportWorker).to_not have_received(:perform_async)
-      end
-
-      it 'returns http not found' do
-        subject
         expect(response).to have_http_status(404)
       end
     end
@@ -90,17 +77,10 @@ RSpec.describe Settings::ImportsController do
     context 'with an already-confirmed import' do
       let(:bulk_import) { Fabricate(:bulk_import, account: user.account, state: :in_progress) }
 
-      it 'does not change the import\'s state' do
+      it 'does not change the import\'s state and returns missing', :aggregate_failures do
         expect { subject }.to_not(change { bulk_import.reload.state })
-      end
 
-      it 'does not fire the import worker' do
-        subject
         expect(BulkImportWorker).to_not have_received(:perform_async)
-      end
-
-      it 'returns http not found' do
-        subject
         expect(response).to have_http_status(404)
       end
     end
@@ -108,17 +88,10 @@ RSpec.describe Settings::ImportsController do
     context 'with an unconfirmed import' do
       let(:bulk_import) { Fabricate(:bulk_import, account: user.account, state: :unconfirmed) }
 
-      it 'changes the import\'s state to scheduled' do
+      it 'changes the import\'s state to scheduled and redirects', :aggregate_failures do
         expect { subject }.to change { bulk_import.reload.state.to_sym }.from(:unconfirmed).to(:scheduled)
-      end
 
-      it 'fires the import worker on the expected import' do
-        subject
         expect(BulkImportWorker).to have_received(:perform_async).with(bulk_import.id)
-      end
-
-      it 'redirects to imports path' do
-        subject
         expect(response).to redirect_to(settings_imports_path)
       end
     end
@@ -130,12 +103,9 @@ RSpec.describe Settings::ImportsController do
     context 'with someone else\'s import' do
       let(:bulk_import) { Fabricate(:bulk_import, state: :unconfirmed) }
 
-      it 'does not delete the import' do
+      it 'does not delete the import and returns missing', :aggregate_failures do
         expect { subject }.to_not(change { BulkImport.exists?(bulk_import.id) })
-      end
 
-      it 'returns http not found' do
-        subject
         expect(response).to have_http_status(404)
       end
     end
@@ -143,12 +113,9 @@ RSpec.describe Settings::ImportsController do
     context 'with an already-confirmed import' do
       let(:bulk_import) { Fabricate(:bulk_import, account: user.account, state: :in_progress) }
 
-      it 'does not delete the import' do
+      it 'does not delete the import and returns missing', :aggregate_failures do
         expect { subject }.to_not(change { BulkImport.exists?(bulk_import.id) })
-      end
 
-      it 'returns http not found' do
-        subject
         expect(response).to have_http_status(404)
       end
     end
@@ -156,12 +123,9 @@ RSpec.describe Settings::ImportsController do
     context 'with an unconfirmed import' do
       let(:bulk_import) { Fabricate(:bulk_import, account: user.account, state: :unconfirmed) }
 
-      it 'deletes the import' do
+      it 'deletes the import and redirects', :aggregate_failures do
         expect { subject }.to change { BulkImport.exists?(bulk_import.id) }.from(true).to(false)
-      end
 
-      it 'redirects to imports path' do
-        subject
         expect(response).to redirect_to(settings_imports_path)
       end
     end
@@ -177,13 +141,10 @@ RSpec.describe Settings::ImportsController do
         bulk_import.update(total_items: bulk_import.rows.count, processed_items: bulk_import.rows.count, imported_items: 0)
       end
 
-      it 'returns http success' do
+      it 'returns expected contents', :aggregate_failures do
         subject
-        expect(response).to have_http_status(200)
-      end
 
-      it 'returns expected contents' do
-        subject
+        expect(response).to have_http_status(200)
         expect(response.body).to eq expected_contents
       end
     end
@@ -283,12 +244,9 @@ RSpec.describe Settings::ImportsController do
       let(:import_file) { file }
       let(:import_mode) { mode }
 
-      it 'creates an unconfirmed bulk_import with expected type' do
+      it 'creates an unconfirmed bulk_import with expected type and redirects', :aggregate_failures do
         expect { subject }.to change { user.account.bulk_imports.pluck(:state, :type) }.from([]).to([['unconfirmed', import_type]])
-      end
 
-      it 'redirects to confirmation page for the import' do
-        subject
         expect(response).to redirect_to(settings_import_path(user.account.bulk_imports.first))
       end
     end
@@ -298,12 +256,9 @@ RSpec.describe Settings::ImportsController do
       let(:import_file) { file }
       let(:import_mode) { mode }
 
-      it 'does not creates an unconfirmed bulk_import' do
+      it 'does not creates an unconfirmed bulk_import', :aggregate_failures do
         expect { subject }.to_not(change { user.account.bulk_imports.count })
-      end
 
-      it 'sets error to the import' do
-        subject
         expect(assigns(:import).errors).to_not be_empty
       end
     end
diff --git a/spec/controllers/settings/login_activities_controller_spec.rb b/spec/controllers/settings/login_activities_controller_spec.rb
index 80c8f484cc..4f266e03dd 100644
--- a/spec/controllers/settings/login_activities_controller_spec.rb
+++ b/spec/controllers/settings/login_activities_controller_spec.rb
@@ -16,11 +16,8 @@ describe Settings::LoginActivitiesController do
       get :index
     end
 
-    it 'returns http success' do
+    it 'returns http success with private cache control headers', :aggregate_failures do
       expect(response).to have_http_status(200)
-    end
-
-    it 'returns private cache control headers' do
       expect(response.headers['Cache-Control']).to include('private, no-store')
     end
   end
diff --git a/spec/controllers/settings/migration/redirects_controller_spec.rb b/spec/controllers/settings/migration/redirects_controller_spec.rb
index aa6df64cff..b909a02668 100644
--- a/spec/controllers/settings/migration/redirects_controller_spec.rb
+++ b/spec/controllers/settings/migration/redirects_controller_spec.rb
@@ -16,11 +16,8 @@ describe Settings::Migration::RedirectsController do
       get :new
     end
 
-    it 'returns http success' do
+    it 'returns http success with private cache control headers', :aggregate_failures do
       expect(response).to have_http_status(200)
-    end
-
-    it 'returns private cache control headers' do
       expect(response.headers['Cache-Control']).to include('private, no-store')
     end
   end
diff --git a/spec/controllers/settings/migrations_controller_spec.rb b/spec/controllers/settings/migrations_controller_spec.rb
index 9b12bc40f1..f3340574d0 100644
--- a/spec/controllers/settings/migrations_controller_spec.rb
+++ b/spec/controllers/settings/migrations_controller_spec.rb
@@ -71,24 +71,22 @@ describe Settings::MigrationsController do
       context 'when acct is the current account' do
         let(:acct) { user.account }
 
-        it 'renders show' do
-          expect(subject).to render_template :show
-        end
+        it 'does not update the moved account', :aggregate_failures do
+          subject
 
-        it 'does not update the moved account' do
           expect(user.account.reload.moved_to_account_id).to be_nil
+          expect(response).to render_template :show
         end
       end
 
       context 'when target account does not reference the account being moved from' do
         let(:acct) { Fabricate(:account, also_known_as: []) }
 
-        it 'renders show' do
-          expect(subject).to render_template :show
-        end
+        it 'does not update the moved account', :aggregate_failures do
+          subject
 
-        it 'does not update the moved account' do
           expect(user.account.reload.moved_to_account_id).to be_nil
+          expect(response).to render_template :show
         end
       end
 
@@ -100,12 +98,11 @@ describe Settings::MigrationsController do
           user.account.migrations.create!(acct: moved_to.acct)
         end
 
-        it 'renders show' do
-          expect(subject).to render_template :show
-        end
+        it 'does not update the moved account', :aggregate_failures do
+          subject
 
-        it 'does not update the moved account' do
           expect(user.account.reload.moved_to_account_id).to be_nil
+          expect(response).to render_template :show
         end
       end
     end
diff --git a/spec/controllers/settings/preferences/appearance_controller_spec.rb b/spec/controllers/settings/preferences/appearance_controller_spec.rb
index 9a98a41886..ee0ded1b91 100644
--- a/spec/controllers/settings/preferences/appearance_controller_spec.rb
+++ b/spec/controllers/settings/preferences/appearance_controller_spec.rb
@@ -16,11 +16,8 @@ describe Settings::Preferences::AppearanceController do
       get :show
     end
 
-    it 'returns http success' do
+    it 'returns http success with private cache control headers', :aggregate_failures do
       expect(response).to have_http_status(200)
-    end
-
-    it 'returns private cache control headers' do
       expect(response.headers['Cache-Control']).to include('private, no-store')
     end
   end
diff --git a/spec/controllers/settings/preferences/notifications_controller_spec.rb b/spec/controllers/settings/preferences/notifications_controller_spec.rb
index 6a04df9edb..b61d7461ce 100644
--- a/spec/controllers/settings/preferences/notifications_controller_spec.rb
+++ b/spec/controllers/settings/preferences/notifications_controller_spec.rb
@@ -16,11 +16,8 @@ describe Settings::Preferences::NotificationsController do
       get :show
     end
 
-    it 'returns http success' do
+    it 'returns http success with private cache control headers', :aggregate_failures do
       expect(response).to have_http_status(200)
-    end
-
-    it 'returns private cache control headers' do
       expect(response.headers['Cache-Control']).to include('private, no-store')
     end
   end
diff --git a/spec/controllers/settings/preferences/other_controller_spec.rb b/spec/controllers/settings/preferences/other_controller_spec.rb
index 750510b04b..61a94a4142 100644
--- a/spec/controllers/settings/preferences/other_controller_spec.rb
+++ b/spec/controllers/settings/preferences/other_controller_spec.rb
@@ -16,11 +16,8 @@ describe Settings::Preferences::OtherController do
       get :show
     end
 
-    it 'returns http success' do
+    it 'returns http success with private cache control headers', :aggregate_failures do
       expect(response).to have_http_status(200)
-    end
-
-    it 'returns private cache control headers' do
       expect(response.headers['Cache-Control']).to include('private, no-store')
     end
   end
diff --git a/spec/controllers/settings/profiles_controller_spec.rb b/spec/controllers/settings/profiles_controller_spec.rb
index 806fad19a8..e3197f0a6d 100644
--- a/spec/controllers/settings/profiles_controller_spec.rb
+++ b/spec/controllers/settings/profiles_controller_spec.rb
@@ -17,11 +17,8 @@ RSpec.describe Settings::ProfilesController do
       get :show
     end
 
-    it 'returns http success' do
+    it 'returns http success with private cache control headers', :aggregate_failures do
       expect(response).to have_http_status(200)
-    end
-
-    it 'returns private cache control headers' do
       expect(response.headers['Cache-Control']).to include('private, no-store')
     end
   end
diff --git a/spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb b/spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb
index 2ffad13c61..719ed2f886 100644
--- a/spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb
+++ b/spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb
@@ -121,24 +121,12 @@ describe Settings::TwoFactorAuthentication::WebauthnCredentialsController do
             add_webauthn_credential(user)
           end
 
-          it 'returns http success' do
-            get :options
+          it 'includes existing credentials in list of excluded credentials', :aggregate_failures do
+            expect { get :options }.to_not change(user, :webauthn_id)
 
             expect(response).to have_http_status(200)
-          end
-
-          it 'stores the challenge on the session' do
-            get :options
 
             expect(controller.session[:webauthn_challenge]).to be_present
-          end
-
-          it 'does not change webauthn_id' do
-            expect { get :options }.to_not change(user, :webauthn_id)
-          end
-
-          it 'includes existing credentials in list of excluded credentials' do
-            get :options
 
             excluded_credentials_ids = response.parsed_body['excludeCredentials'].pluck('id')
             expect(excluded_credentials_ids).to match_array(user.webauthn_credentials.pluck(:external_id))
@@ -146,21 +134,11 @@ describe Settings::TwoFactorAuthentication::WebauthnCredentialsController do
         end
 
         context 'when user does not have webauthn enabled' do
-          it 'returns http success' do
+          it 'stores the challenge on the session and sets user webauthn_id', :aggregate_failures do
             get :options
 
             expect(response).to have_http_status(200)
-          end
-
-          it 'stores the challenge on the session' do
-            get :options
-
             expect(controller.session[:webauthn_challenge]).to be_present
-          end
-
-          it 'sets user webauthn_id' do
-            get :options
-
             expect(user.reload.webauthn_id).to be_present
           end
         end
@@ -217,28 +195,15 @@ describe Settings::TwoFactorAuthentication::WebauthnCredentialsController do
           end
 
           context 'when creation succeeds' do
-            it 'returns http success' do
-              controller.session[:webauthn_challenge] = challenge
-
-              post :create, params: { credential: new_webauthn_credential, nickname: nickname }
-
-              expect(response).to have_http_status(200)
-            end
-
-            it 'adds a new credential to user credentials' do
+            it 'adds a new credential to user credentials and does not change webauthn_id', :aggregate_failures do
               controller.session[:webauthn_challenge] = challenge
 
               expect do
                 post :create, params: { credential: new_webauthn_credential, nickname: nickname }
               end.to change { user.webauthn_credentials.count }.by(1)
-            end
+                                                               .and not_change(user, :webauthn_id)
 
-            it 'does not change webauthn_id' do
-              controller.session[:webauthn_challenge] = challenge
-
-              expect do
-                post :create, params: { credential: new_webauthn_credential, nickname: nickname }
-              end.to_not change(user, :webauthn_id)
+              expect(response).to have_http_status(200)
             end
           end
 
@@ -328,17 +293,13 @@ describe Settings::TwoFactorAuthentication::WebauthnCredentialsController do
           end
 
           context 'when deletion succeeds' do
-            it 'redirects to 2FA methods list and shows flash success' do
-              delete :destroy, params: { id: user.webauthn_credentials.take.id }
-
-              expect(response).to redirect_to settings_two_factor_authentication_methods_path
-              expect(flash[:success]).to be_present
-            end
-
-            it 'deletes the credential' do
+            it 'redirects to 2FA methods list and shows flash success and deletes the credential', :aggregate_failures do
               expect do
                 delete :destroy, params: { id: user.webauthn_credentials.take.id }
               end.to change { user.webauthn_credentials.count }.by(-1)
+
+              expect(response).to redirect_to settings_two_factor_authentication_methods_path
+              expect(flash[:success]).to be_present
             end
           end
         end
diff --git a/spec/controllers/settings/two_factor_authentication_methods_controller_spec.rb b/spec/controllers/settings/two_factor_authentication_methods_controller_spec.rb
index 3e61912ad4..de0d28463b 100644
--- a/spec/controllers/settings/two_factor_authentication_methods_controller_spec.rb
+++ b/spec/controllers/settings/two_factor_authentication_methods_controller_spec.rb
@@ -29,11 +29,8 @@ describe Settings::TwoFactorAuthenticationMethodsController do
           get :index
         end
 
-        it 'returns http success' do
+        it 'returns http success with private cache control headers', :aggregate_failures do
           expect(response).to have_http_status(200)
-        end
-
-        it 'returns private cache control headers' do
           expect(response.headers['Cache-Control']).to include('private, no-store')
         end
       end