about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Yip <yipdw@member.fsf.org>2018-03-02 21:46:44 -0600
committerDavid Yip <yipdw@member.fsf.org>2018-03-02 21:46:44 -0600
commit1b8fcd4df52c8d715f89180faea8205310f197ae (patch)
tree705b8b59bafdd26cb96983e2da0104e8b7308ea7
parentee00da01d2e4cc455b92f1f4a7c9142c73048433 (diff)
parentecf06d7e821a4b8f4585f1b6f0e39c595ed047ce (diff)
Merge remote-tracking branch 'origin/master' into merge-upstream
  Conflicts:
 	README.md
 	app/controllers/follower_accounts_controller.rb
 	app/controllers/following_accounts_controller.rb
 	app/serializers/rest/instance_serializer.rb
 	app/views/stream_entries/_simple_status.html.haml
 	config/locales/simple_form.ja.yml
-rw-r--r--.env.production.sample15
-rw-r--r--Gemfile8
-rw-r--r--Gemfile.lock16
-rw-r--r--app/controllers/accounts_controller.rb36
-rw-r--r--app/controllers/api/base_controller.rb4
-rw-r--r--app/controllers/api/v1/accounts/search_controller.rb4
-rw-r--r--app/controllers/api/v1/accounts/statuses_controller.rb6
-rw-r--r--app/controllers/api/v1/accounts_controller.rb6
-rw-r--r--app/controllers/api/v1/reports_controller.rb12
-rw-r--r--app/controllers/api/v1/search_controller.rb6
-rw-r--r--app/controllers/api/v1/timelines/public_controller.rb14
-rw-r--r--app/controllers/api/v1/timelines/tag_controller.rb14
-rw-r--r--app/controllers/application_controller.rb6
-rw-r--r--app/controllers/auth/sessions_controller.rb2
-rw-r--r--app/controllers/follower_accounts_controller.rb2
-rw-r--r--app/controllers/following_accounts_controller.rb2
-rw-r--r--app/javascript/mastodon/actions/reports.js9
-rw-r--r--app/javascript/mastodon/actions/timelines.js4
-rw-r--r--app/javascript/mastodon/components/media_gallery.js5
-rw-r--r--app/javascript/mastodon/components/status.js1
-rw-r--r--app/javascript/mastodon/features/account/components/action_bar.js4
-rw-r--r--app/javascript/mastodon/features/account_gallery/components/media_item.js16
-rw-r--r--app/javascript/mastodon/features/account_gallery/index.js5
-rw-r--r--app/javascript/mastodon/features/account_timeline/components/header.js8
-rw-r--r--app/javascript/mastodon/features/account_timeline/index.js23
-rw-r--r--app/javascript/mastodon/features/compose/components/search.js5
-rw-r--r--app/javascript/mastodon/features/status/components/detailed_status.js1
-rw-r--r--app/javascript/mastodon/features/ui/components/bundle.js11
-rw-r--r--app/javascript/mastodon/features/ui/components/columns_area.js17
-rw-r--r--app/javascript/mastodon/features/ui/components/report_modal.js47
-rw-r--r--app/javascript/mastodon/features/ui/components/tabs_bar.js3
-rw-r--r--app/javascript/mastodon/features/ui/index.js1
-rw-r--r--app/javascript/mastodon/features/ui/util/react_router_helpers.js11
-rw-r--r--app/javascript/mastodon/features/video/index.js25
-rw-r--r--app/javascript/mastodon/initial_state.js1
-rw-r--r--app/javascript/mastodon/locales/ar.json12
-rw-r--r--app/javascript/mastodon/locales/bg.json8
-rw-r--r--app/javascript/mastodon/locales/ca.json76
-rw-r--r--app/javascript/mastodon/locales/de.json8
-rw-r--r--app/javascript/mastodon/locales/defaultMessages.json44
-rw-r--r--app/javascript/mastodon/locales/en.json8
-rw-r--r--app/javascript/mastodon/locales/eo.json286
-rw-r--r--app/javascript/mastodon/locales/es.json8
-rw-r--r--app/javascript/mastodon/locales/fa.json8
-rw-r--r--app/javascript/mastodon/locales/fi.json384
-rw-r--r--app/javascript/mastodon/locales/fr.json12
-rw-r--r--app/javascript/mastodon/locales/gl.json10
-rw-r--r--app/javascript/mastodon/locales/he.json8
-rw-r--r--app/javascript/mastodon/locales/hr.json8
-rw-r--r--app/javascript/mastodon/locales/hu.json10
-rw-r--r--app/javascript/mastodon/locales/hy.json8
-rw-r--r--app/javascript/mastodon/locales/id.json8
-rw-r--r--app/javascript/mastodon/locales/io.json8
-rw-r--r--app/javascript/mastodon/locales/it.json8
-rw-r--r--app/javascript/mastodon/locales/ja.json14
-rw-r--r--app/javascript/mastodon/locales/ko.json8
-rw-r--r--app/javascript/mastodon/locales/nl.json10
-rw-r--r--app/javascript/mastodon/locales/no.json8
-rw-r--r--app/javascript/mastodon/locales/oc.json8
-rw-r--r--app/javascript/mastodon/locales/pl.json13
-rw-r--r--app/javascript/mastodon/locales/pt-BR.json10
-rw-r--r--app/javascript/mastodon/locales/pt.json8
-rw-r--r--app/javascript/mastodon/locales/ru.json8
-rw-r--r--app/javascript/mastodon/locales/sk.json42
-rw-r--r--app/javascript/mastodon/locales/sr-Latn.json8
-rw-r--r--app/javascript/mastodon/locales/sr.json8
-rw-r--r--app/javascript/mastodon/locales/sv.json8
-rw-r--r--app/javascript/mastodon/locales/th.json8
-rw-r--r--app/javascript/mastodon/locales/tr.json8
-rw-r--r--app/javascript/mastodon/locales/uk.json8
-rw-r--r--app/javascript/mastodon/locales/zh-CN.json8
-rw-r--r--app/javascript/mastodon/locales/zh-HK.json8
-rw-r--r--app/javascript/mastodon/locales/zh-TW.json8
-rw-r--r--app/javascript/mastodon/reducers/reports.js4
-rw-r--r--app/javascript/styles/mastodon/about.scss363
-rw-r--r--app/javascript/styles/mastodon/accounts.scss83
-rw-r--r--app/javascript/styles/mastodon/components.scss215
-rw-r--r--app/javascript/styles/mastodon/forms.scss5
-rw-r--r--app/lib/activitypub/activity.rb2
-rw-r--r--app/lib/activitypub/activity/flag.rb25
-rw-r--r--app/lib/activitypub/activity/reject.rb2
-rw-r--r--app/lib/exceptions.rb1
-rw-r--r--app/lib/request.rb19
-rw-r--r--app/lib/sidekiq_error_handler.rb11
-rw-r--r--app/models/concerns/paginable.rb9
-rw-r--r--app/models/import.rb2
-rw-r--r--app/models/report.rb4
-rw-r--r--app/models/user.rb26
-rw-r--r--app/serializers/activitypub/flag_serializer.rb27
-rw-r--r--app/serializers/initial_state_serializer.rb1
-rw-r--r--app/serializers/rest/instance_serializer.rb11
-rw-r--r--app/services/report_service.rb54
-rw-r--r--app/views/about/show.html.haml148
-rw-r--r--app/views/accounts/_follow_button.html.haml23
-rw-r--r--app/views/accounts/_grid_card.html.haml7
-rw-r--r--app/views/accounts/_header.html.haml19
-rw-r--r--app/views/accounts/show.html.haml7
-rw-r--r--app/views/auth/passwords/edit.html.haml4
-rw-r--r--app/views/auth/registrations/edit.html.haml4
-rw-r--r--app/views/auth/sessions/new.html.haml2
-rw-r--r--app/views/settings/preferences/show.html.haml2
-rw-r--r--app/views/stream_entries/_detailed_status.html.haml2
-rw-r--r--app/views/stream_entries/_simple_status.html.haml1
-rw-r--r--app/views/tags/_features.html.haml25
-rw-r--r--app/views/tags/show.html.haml61
-rw-r--r--config/application.rb1
-rw-r--r--config/environments/development.rb6
-rw-r--r--config/environments/production.rb2
-rw-r--r--config/initializers/devise.rb36
-rw-r--r--config/initializers/sidekiq.rb4
-rw-r--r--config/locales/activerecord.ar.yml4
-rw-r--r--config/locales/ar.yml113
-rw-r--r--config/locales/ca.yml170
-rw-r--r--config/locales/devise.ar.yml17
-rw-r--r--config/locales/devise.ca.yml14
-rw-r--r--config/locales/devise.de.yml6
-rw-r--r--config/locales/devise.eo.yml100
-rw-r--r--config/locales/devise.hr.yml3
-rw-r--r--config/locales/devise.hu.yml23
-rw-r--r--config/locales/devise.pt.yml2
-rw-r--r--config/locales/devise.sk.yml20
-rw-r--r--config/locales/devise.sv.yml23
-rw-r--r--config/locales/doorkeeper.ar.yml18
-rw-r--r--config/locales/doorkeeper.eo.yml52
-rw-r--r--config/locales/doorkeeper.hu.yml7
-rw-r--r--config/locales/en.yml4
-rw-r--r--config/locales/eo.yml753
-rw-r--r--config/locales/fr.yml5
-rw-r--r--config/locales/gl.yml10
-rw-r--r--config/locales/hu.yml91
-rw-r--r--config/locales/ja.yml23
-rw-r--r--config/locales/nl.yml14
-rw-r--r--config/locales/oc.yml7
-rw-r--r--config/locales/pl.yml5
-rw-r--r--config/locales/pt-BR.yml2
-rw-r--r--config/locales/pt.yml1
-rw-r--r--config/locales/simple_form.ar.yml20
-rw-r--r--config/locales/simple_form.ca.yml76
-rw-r--r--config/locales/simple_form.de.yml1
-rw-r--r--config/locales/simple_form.eo.yml69
-rw-r--r--config/locales/simple_form.fr.yml2
-rw-r--r--config/locales/simple_form.gl.yml2
-rw-r--r--config/locales/simple_form.hu.yml20
-rw-r--r--config/locales/simple_form.ja.yml2
-rw-r--r--config/locales/simple_form.nl.yml2
-rw-r--r--config/locales/simple_form.pt.yml75
-rw-r--r--config/locales/simple_form.sk.yml8
-rw-r--r--config/locales/simple_form.sv.yml1
-rw-r--r--config/locales/sk.yml125
-rw-r--r--config/locales/sv.yml8
-rw-r--r--db/schema.rb1
-rw-r--r--lib/devise/ldap_authenticatable.rb49
-rw-r--r--lib/mastodon/version.rb4
-rw-r--r--lib/tasks/mastodon.rake18
-rw-r--r--package.json2
-rw-r--r--spec/lib/activitypub/activity/flag_spec.rb37
-rw-r--r--spec/lib/request_spec.rb31
-rw-r--r--spec/services/report_service_spec.rb25
158 files changed, 3355 insertions, 1401 deletions
diff --git a/.env.production.sample b/.env.production.sample
index d46768d09..d920f18e9 100644
--- a/.env.production.sample
+++ b/.env.production.sample
@@ -33,7 +33,6 @@ LOCAL_DOMAIN=example.com
 
 # Application secrets
 # Generate each with the `RAILS_ENV=production bundle exec rake secret` task (`docker-compose run --rm web rake secret` if you use docker compose)
-PAPERCLIP_SECRET=
 SECRET_KEY_BASE=
 OTP_SECRET=
 
@@ -143,6 +142,16 @@ STREAMING_CLUSTER_NUM=1
 # Maximum allowed character count
 # MAX_TOOT_CHARS=500
 
+# LDAP authentication (optional)
+# LDAP_ENABLED=true
+# LDAP_HOST=localhost
+# LDAP_PORT=389
+# LDAP_METHOD=simple_tls
+# LDAP_BASE=
+# LDAP_BIND_DN=
+# LDAP_PASSWORD=
+# LDAP_UID=cn
+
 # PAM authentication (optional)
 # PAM authentication uses for the email generation the "email" pam variable
 # and optional as fallback PAM_DEFAULT_SUFFIX
@@ -153,7 +162,7 @@ STREAMING_CLUSTER_NUM=1
 # PAM_DEFAULT_SUFFIX=pam
 # Name of the pam service (pam "auth" section is evaluated)
 # PAM_DEFAULT_SERVICE=rpam
-# Name of the pam service used for checking if an user can register (pam "account" section is evaluated)
+# Name of the pam service used for checking if an user can register (pam "account" section is evaluated) (nil (disabled) by default)
 # PAM_CONTROLLED_SERVICE=rpam
 
 # Global OAuth settings (optional) :
@@ -186,7 +195,7 @@ STREAMING_CLUSTER_NUM=1
 # Optional SAML authentication (cf. omniauth-saml)
 # SAML_ENABLED=true
 # SAML_ACS_URL=
-# SAML_ISSUER=http://localhost:3000/auth/auth/saml/metadata
+# SAML_ISSUER=http://localhost:3000/auth/auth/saml/callback
 # SAML_IDP_SSO_TARGET_URL=https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO
 # SAML_IDP_CERT=
 # SAML_IDP_CERT_FINGERPRINT=
diff --git a/Gemfile b/Gemfile
index b6962861f..bf53d4c77 100644
--- a/Gemfile
+++ b/Gemfile
@@ -7,7 +7,6 @@ gem 'pkg-config', '~> 1.2'
 
 gem 'puma', '~> 3.10'
 gem 'rails', '~> 5.1.4'
-gem 'uglifier', '~> 3.2'
 
 gem 'hamlit-rails', '~> 0.2'
 gem 'pg', '~> 0.20'
@@ -35,8 +34,9 @@ gem 'devise', '~> 4.4'
 gem 'devise-two-factor', '~> 3.0'
 
 gem 'devise_pam_authenticatable2', '~> 8.0', install_if: -> { ENV['PAM_ENABLED'] == 'true' }
+gem 'net-ldap', '~> 0.10', install_if: -> { ENV['LDAP_ENABLED'] == 'true' }
 gem 'omniauth-cas', '~> 1.1', install_if: -> { ENV['CAS_ENABLED'] == 'true' }
-gem 'omniauth-saml', '~> 1.8', install_if: -> { ENV['SAML_ENABLED'] == 'true' }
+gem 'omniauth-saml', '~> 1.10', install_if: -> { ENV['SAML_ENABLED'] == 'true' }
 gem 'omniauth', '~> 1.2'
 
 gem 'doorkeeper', '~> 4.2'
@@ -98,6 +98,10 @@ group :development, :test do
   gem 'rspec-rails', '~> 3.7'
 end
 
+group :production, :test do
+  gem 'private_address_check', '~> 0.4.1'
+end
+
 group :test do
   gem 'capybara', '~> 2.15'
   gem 'climate_control', '~> 0.2'
diff --git a/Gemfile.lock b/Gemfile.lock
index 1905cf3e1..f0ad8ab55 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -178,7 +178,6 @@ GEM
     et-orbi (1.0.8)
       tzinfo
     excon (0.59.0)
-    execjs (2.7.0)
     fabrication (2.18.0)
     faker (1.8.4)
       i18n (~> 0.5)
@@ -319,6 +318,7 @@ GEM
     multi_json (1.12.2)
     multipart-post (2.0.0)
     necromancer (0.4.0)
+    net-ldap (0.16.1)
     net-scp (1.2.1)
       net-ssh (>= 2.6.5)
     net-ssh (4.2.0)
@@ -340,9 +340,9 @@ GEM
       addressable (~> 2.3)
       nokogiri (~> 1.5)
       omniauth (~> 1.2)
-    omniauth-saml (1.9.0)
+    omniauth-saml (1.10.0)
       omniauth (~> 1.3, >= 1.3.2)
-      ruby-saml (~> 1.4, >= 1.4.3)
+      ruby-saml (~> 1.7)
     orm_adapter (0.5.0)
     ostatus2 (2.0.3)
       addressable (~> 2.5)
@@ -379,6 +379,7 @@ GEM
     premailer-rails (1.10.1)
       actionmailer (>= 3, < 6)
       premailer (~> 1.7, >= 1.7.9)
+    private_address_check (0.4.1)
     pry (0.11.3)
       coderay (~> 1.1.0)
       method_source (~> 0.9.0)
@@ -498,7 +499,7 @@ GEM
       unicode-display_width (~> 1.0, >= 1.0.1)
     ruby-oembed (0.12.0)
     ruby-progressbar (1.9.0)
-    ruby-saml (1.6.1)
+    ruby-saml (1.7.2)
       nokogiri (>= 1.5.10)
     rufus-scheduler (3.4.2)
       et-orbi (~> 1.0)
@@ -586,8 +587,6 @@ GEM
       thread_safe (~> 0.1)
     tzinfo-data (1.2017.3)
       tzinfo (>= 1.0.0)
-    uglifier (3.2.0)
-      execjs (>= 0.3.0, < 3)
     unf (0.1.4)
       unf_ext
     unf_ext (0.0.7.4)
@@ -672,12 +671,13 @@ DEPENDENCIES
   memory_profiler
   microformats (~> 4.0)
   mime-types (~> 3.1)
+  net-ldap (~> 0.10)
   nokogiri (~> 1.8)
   nsa (~> 0.2)
   oj (~> 3.3)
   omniauth (~> 1.2)
   omniauth-cas (~> 1.1)
-  omniauth-saml (~> 1.8)
+  omniauth-saml (~> 1.10)
   ostatus2 (~> 2.0)
   ox (~> 2.8)
   paperclip (~> 5.1)
@@ -688,6 +688,7 @@ DEPENDENCIES
   pkg-config (~> 1.2)
   posix-spawn
   premailer-rails
+  private_address_check (~> 0.4.1)
   pry-rails (~> 0.3)
   puma (~> 3.10)
   pundit (~> 1.1)
@@ -724,7 +725,6 @@ DEPENDENCIES
   tty-prompt
   twitter-text (~> 1.14)
   tzinfo-data (~> 1.2017)
-  uglifier (~> 3.2)
   webmock (~> 3.0)
   webpacker (~> 3.0)
   webpush
diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb
index c9725ed00..1efaf619b 100644
--- a/app/controllers/accounts_controller.rb
+++ b/app/controllers/accounts_controller.rb
@@ -1,6 +1,8 @@
 # frozen_string_literal: true
 
 class AccountsController < ApplicationController
+  PAGE_SIZE = 20
+
   include AccountControllerConcern
 
   before_action :set_cache_headers
@@ -17,13 +19,16 @@ class AccountsController < ApplicationController
         end
 
         @pinned_statuses = cache_collection(@account.pinned_statuses, Status) if show_pinned_statuses?
-        @statuses        = filtered_statuses.paginate_by_max_id(20, params[:max_id], params[:since_id])
+        @statuses        = filtered_status_page(params)
         @statuses        = cache_collection(@statuses, Status)
-        @next_url        = next_url unless @statuses.empty?
+        unless @statuses.empty?
+          @older_url        = older_url if @statuses.last.id > filtered_statuses.last.id
+          @newer_url        = newer_url if @statuses.first.id < filtered_statuses.first.id
+        end
       end
 
       format.atom do
-        @entries = @account.stream_entries.where(hidden: false).with_includes.paginate_by_max_id(20, params[:max_id], params[:since_id])
+        @entries = @account.stream_entries.where(hidden: false).with_includes.paginate_by_max_id(PAGE_SIZE, params[:max_id], params[:since_id])
         render xml: OStatus::AtomSerializer.render(OStatus::AtomSerializer.new.feed(@account, @entries.reject { |entry| entry.status.nil? }))
       end
 
@@ -70,13 +75,22 @@ class AccountsController < ApplicationController
     @account = Account.find_local!(params[:username])
   end
 
-  def next_url
+  def older_url
+    ::Rails.logger.info("older: max_id #{@statuses.last.id}, url #{pagination_url(max_id: @statuses.last.id)}")
+    pagination_url(max_id: @statuses.last.id)
+  end
+
+  def newer_url
+    pagination_url(min_id: @statuses.first.id)
+  end
+
+  def pagination_url(max_id: nil, min_id: nil)
     if media_requested?
-      short_account_media_url(@account, max_id: @statuses.last.id)
+      short_account_media_url(@account, max_id: max_id, min_id: min_id)
     elsif replies_requested?
-      short_account_with_replies_url(@account, max_id: @statuses.last.id)
+      short_account_with_replies_url(@account, max_id: max_id, min_id: min_id)
     else
-      short_account_url(@account, max_id: @statuses.last.id)
+      short_account_url(@account, max_id: max_id, min_id: min_id)
     end
   end
 
@@ -87,4 +101,12 @@ class AccountsController < ApplicationController
   def replies_requested?
     request.path.ends_with?('/with_replies')
   end
+
+  def filtered_status_page(params)
+    if params[:min_id].present?
+      filtered_statuses.paginate_by_min_id(PAGE_SIZE, params[:min_id]).reverse
+    else
+      filtered_statuses.paginate_by_max_id(PAGE_SIZE, params[:max_id], params[:since_id]).to_a
+    end
+  end
 end
diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb
index 52e68ab35..7b5168b31 100644
--- a/app/controllers/api/base_controller.rb
+++ b/app/controllers/api/base_controller.rb
@@ -51,6 +51,10 @@ class Api::BaseController < ApplicationController
     [params[:limit].to_i.abs, default_limit * 2].min
   end
 
+  def truthy_param?(key)
+    ActiveModel::Type::Boolean.new.cast(params[key])
+  end
+
   def current_resource_owner
     @current_user ||= User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token
   end
diff --git a/app/controllers/api/v1/accounts/search_controller.rb b/app/controllers/api/v1/accounts/search_controller.rb
index 11e647c3c..7649da433 100644
--- a/app/controllers/api/v1/accounts/search_controller.rb
+++ b/app/controllers/api/v1/accounts/search_controller.rb
@@ -22,8 +22,4 @@ class Api::V1::Accounts::SearchController < Api::BaseController
       following: truthy_param?(:following)
     )
   end
-
-  def truthy_param?(key)
-    params[key] == 'true'
-  end
 end
diff --git a/app/controllers/api/v1/accounts/statuses_controller.rb b/app/controllers/api/v1/accounts/statuses_controller.rb
index 095f6937b..7261ccd24 100644
--- a/app/controllers/api/v1/accounts/statuses_controller.rb
+++ b/app/controllers/api/v1/accounts/statuses_controller.rb
@@ -28,9 +28,9 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
 
   def account_statuses
     default_statuses.tap do |statuses|
-      statuses.merge!(only_media_scope) if params[:only_media]
-      statuses.merge!(pinned_scope) if params[:pinned]
-      statuses.merge!(no_replies_scope) if params[:exclude_replies]
+      statuses.merge!(only_media_scope) if truthy_param?(:only_media)
+      statuses.merge!(pinned_scope) if truthy_param?(:pinned)
+      statuses.merge!(no_replies_scope) if truthy_param?(:exclude_replies)
     end
   end
 
diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb
index 4e73e9e8b..d64325944 100644
--- a/app/controllers/api/v1/accounts_controller.rb
+++ b/app/controllers/api/v1/accounts_controller.rb
@@ -13,9 +13,9 @@ class Api::V1::AccountsController < Api::BaseController
   end
 
   def follow
-    FollowService.new.call(current_user.account, @account.acct, reblogs: params[:reblogs])
+    FollowService.new.call(current_user.account, @account.acct, reblogs: truthy_param?(:reblogs))
 
-    options = @account.locked? ? {} : { following_map: { @account.id => { reblogs: params[:reblogs] } }, requested_map: { @account.id => false } }
+    options = @account.locked? ? {} : { following_map: { @account.id => { reblogs: truthy_param?(:reblogs) } }, requested_map: { @account.id => false } }
 
     render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships(options)
   end
@@ -26,7 +26,7 @@ class Api::V1::AccountsController < Api::BaseController
   end
 
   def mute
-    MuteService.new.call(current_user.account, @account, notifications: params[:notifications])
+    MuteService.new.call(current_user.account, @account, notifications: truthy_param?(:notifications))
     render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships
   end
 
diff --git a/app/controllers/api/v1/reports_controller.rb b/app/controllers/api/v1/reports_controller.rb
index 22828217d..f5095e073 100644
--- a/app/controllers/api/v1/reports_controller.rb
+++ b/app/controllers/api/v1/reports_controller.rb
@@ -13,14 +13,14 @@ class Api::V1::ReportsController < Api::BaseController
   end
 
   def create
-    @report = current_account.reports.create!(
-      target_account: reported_account,
+    @report = ReportService.new.call(
+      current_account,
+      reported_account,
       status_ids: reported_status_ids,
-      comment: report_params[:comment]
+      comment: report_params[:comment],
+      forward: report_params[:forward]
     )
 
-    User.staff.includes(:account).each { |u| AdminMailer.new_report(u.account, @report).deliver_later }
-
     render json: @report, serializer: REST::ReportSerializer
   end
 
@@ -39,6 +39,6 @@ class Api::V1::ReportsController < Api::BaseController
   end
 
   def report_params
-    params.permit(:account_id, :comment, status_ids: [])
+    params.permit(:account_id, :comment, :forward, status_ids: [])
   end
 end
diff --git a/app/controllers/api/v1/search_controller.rb b/app/controllers/api/v1/search_controller.rb
index d1b4e0402..99b635ad9 100644
--- a/app/controllers/api/v1/search_controller.rb
+++ b/app/controllers/api/v1/search_controller.rb
@@ -33,12 +33,8 @@ class Api::V1::SearchController < Api::BaseController
     SearchService.new.call(
       params[:q],
       RESULTS_LIMIT,
-      resolving_search?,
+      truthy_param?(:resolve),
       current_account
     )
   end
-
-  def resolving_search?
-    params[:resolve] == 'true'
-  end
 end
diff --git a/app/controllers/api/v1/timelines/public_controller.rb b/app/controllers/api/v1/timelines/public_controller.rb
index 49887778e..d7d70b94d 100644
--- a/app/controllers/api/v1/timelines/public_controller.rb
+++ b/app/controllers/api/v1/timelines/public_controller.rb
@@ -21,15 +21,23 @@ class Api::V1::Timelines::PublicController < Api::BaseController
   end
 
   def public_statuses
-    public_timeline_statuses.paginate_by_max_id(
+    statuses = public_timeline_statuses.paginate_by_max_id(
       limit_param(DEFAULT_STATUSES_LIMIT),
       params[:max_id],
       params[:since_id]
     )
+
+    if truthy_param?(:only_media)
+      # `SELECT DISTINCT id, updated_at` is too slow, so pluck ids at first, and then select id, updated_at with ids.
+      status_ids = statuses.joins(:media_attachments).distinct(:id).pluck(:id)
+      statuses.where(id: status_ids)
+    else
+      statuses
+    end
   end
 
   def public_timeline_statuses
-    Status.as_public_timeline(current_account, params[:local])
+    Status.as_public_timeline(current_account, truthy_param?(:local))
   end
 
   def insert_pagination_headers
@@ -37,7 +45,7 @@ class Api::V1::Timelines::PublicController < Api::BaseController
   end
 
   def pagination_params(core_params)
-    params.permit(:local, :limit).merge(core_params)
+    params.permit(:local, :limit, :only_media).merge(core_params)
   end
 
   def next_path
diff --git a/app/controllers/api/v1/timelines/tag_controller.rb b/app/controllers/api/v1/timelines/tag_controller.rb
index 08db04a39..eb32611ad 100644
--- a/app/controllers/api/v1/timelines/tag_controller.rb
+++ b/app/controllers/api/v1/timelines/tag_controller.rb
@@ -29,16 +29,24 @@ class Api::V1::Timelines::TagController < Api::BaseController
     if @tag.nil?
       []
     else
-      tag_timeline_statuses.paginate_by_max_id(
+      statuses = tag_timeline_statuses.paginate_by_max_id(
         limit_param(DEFAULT_STATUSES_LIMIT),
         params[:max_id],
         params[:since_id]
       )
+
+      if truthy_param?(:only_media)
+        # `SELECT DISTINCT id, updated_at` is too slow, so pluck ids at first, and then select id, updated_at with ids.
+        status_ids = statuses.joins(:media_attachments).distinct(:id).pluck(:id)
+        statuses.where(id: status_ids)
+      else
+        statuses
+      end
     end
   end
 
   def tag_timeline_statuses
-    Status.as_tag_timeline(@tag, current_account, params[:local])
+    Status.as_tag_timeline(@tag, current_account, truthy_param?(:local))
   end
 
   def insert_pagination_headers
@@ -46,7 +54,7 @@ class Api::V1::Timelines::TagController < Api::BaseController
   end
 
   def pagination_params(core_params)
-    params.permit(:local, :limit).merge(core_params)
+    params.permit(:local, :limit, :only_media).merge(core_params)
   end
 
   def next_path
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index a296d96db..fc745eaec 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -15,7 +15,7 @@ class ApplicationController < ActionController::Base
   helper_method :current_flavour
   helper_method :current_skin
   helper_method :single_user_mode?
-  helper_method :use_pam?
+  helper_method :use_seamless_external_login?
 
   rescue_from ActionController::RoutingError, with: :not_found
   rescue_from ActiveRecord::RecordNotFound, with: :not_found
@@ -146,8 +146,8 @@ class ApplicationController < ActionController::Base
     @single_user_mode ||= Rails.configuration.x.single_user_mode && Account.exists?
   end
 
-  def use_pam?
-    Devise.pam_authentication
+  def use_seamless_external_login?
+    Devise.pam_authentication || Devise.ldap_authentication
   end
 
   def current_account
diff --git a/app/controllers/auth/sessions_controller.rb b/app/controllers/auth/sessions_controller.rb
index 475cd540a..c9e507343 100644
--- a/app/controllers/auth/sessions_controller.rb
+++ b/app/controllers/auth/sessions_controller.rb
@@ -38,7 +38,7 @@ class Auth::SessionsController < Devise::SessionsController
     if session[:otp_user_id]
       User.find(session[:otp_user_id])
     elsif user_params[:email]
-      if use_pam? && Devise.check_at_sign && user_params[:email].index('@').nil?
+      if use_seamless_external_login? && Devise.check_at_sign && user_params[:email].index('@').nil?
         User.joins(:account).find_by(accounts: { username: user_params[:email] })
       else
         User.find_for_authentication(email: user_params[:email])
diff --git a/app/controllers/follower_accounts_controller.rb b/app/controllers/follower_accounts_controller.rb
index 080cbde11..c74d3f86d 100644
--- a/app/controllers/follower_accounts_controller.rb
+++ b/app/controllers/follower_accounts_controller.rb
@@ -9,6 +9,8 @@ class FollowerAccountsController < ApplicationController
     respond_to do |format|
       format.html do
         use_pack 'public'
+
+        @relationships = AccountRelationshipsPresenter.new(@follows.map(&:account_id), current_user.account_id) if user_signed_in?
       end
 
       format.json do
diff --git a/app/controllers/following_accounts_controller.rb b/app/controllers/following_accounts_controller.rb
index 74e83ad81..4c1e3f327 100644
--- a/app/controllers/following_accounts_controller.rb
+++ b/app/controllers/following_accounts_controller.rb
@@ -9,6 +9,8 @@ class FollowingAccountsController < ApplicationController
     respond_to do |format|
       format.html do
         use_pack 'public'
+
+        @relationships = AccountRelationshipsPresenter.new(@follows.map(&:target_account_id), current_user.account_id) if user_signed_in?
       end
 
       format.json do
diff --git a/app/javascript/mastodon/actions/reports.js b/app/javascript/mastodon/actions/reports.js
index b19a07285..afa0c3412 100644
--- a/app/javascript/mastodon/actions/reports.js
+++ b/app/javascript/mastodon/actions/reports.js
@@ -10,6 +10,7 @@ export const REPORT_SUBMIT_FAIL    = 'REPORT_SUBMIT_FAIL';
 
 export const REPORT_STATUS_TOGGLE  = 'REPORT_STATUS_TOGGLE';
 export const REPORT_COMMENT_CHANGE = 'REPORT_COMMENT_CHANGE';
+export const REPORT_FORWARD_CHANGE = 'REPORT_FORWARD_CHANGE';
 
 export function initReport(account, status) {
   return dispatch => {
@@ -45,6 +46,7 @@ export function submitReport() {
       account_id: getState().getIn(['reports', 'new', 'account_id']),
       status_ids: getState().getIn(['reports', 'new', 'status_ids']),
       comment: getState().getIn(['reports', 'new', 'comment']),
+      forward: getState().getIn(['reports', 'new', 'forward']),
     }).then(response => {
       dispatch(closeModal());
       dispatch(submitReportSuccess(response.data));
@@ -78,3 +80,10 @@ export function changeReportComment(comment) {
     comment,
   };
 };
+
+export function changeReportForward(forward) {
+  return {
+    type: REPORT_FORWARD_CHANGE,
+    forward,
+  };
+};
diff --git a/app/javascript/mastodon/actions/timelines.js b/app/javascript/mastodon/actions/timelines.js
index df6a36379..858a12b15 100644
--- a/app/javascript/mastodon/actions/timelines.js
+++ b/app/javascript/mastodon/actions/timelines.js
@@ -120,7 +120,7 @@ export function refreshTimeline(timelineId, path, params = {}) {
 export const refreshHomeTimeline         = () => refreshTimeline('home', '/api/v1/timelines/home');
 export const refreshPublicTimeline       = () => refreshTimeline('public', '/api/v1/timelines/public');
 export const refreshCommunityTimeline    = () => refreshTimeline('community', '/api/v1/timelines/public', { local: true });
-export const refreshAccountTimeline      = accountId => refreshTimeline(`account:${accountId}`, `/api/v1/accounts/${accountId}/statuses`);
+export const refreshAccountTimeline      = (accountId, withReplies) => refreshTimeline(`account:${accountId}${withReplies ? ':with_replies' : ''}`, `/api/v1/accounts/${accountId}/statuses`, { exclude_replies: !withReplies });
 export const refreshAccountMediaTimeline = accountId => refreshTimeline(`account:${accountId}:media`, `/api/v1/accounts/${accountId}/statuses`, { only_media: true });
 export const refreshHashtagTimeline      = hashtag => refreshTimeline(`hashtag:${hashtag}`, `/api/v1/timelines/tag/${hashtag}`);
 export const refreshListTimeline         = id => refreshTimeline(`list:${id}`, `/api/v1/timelines/list/${id}`);
@@ -161,7 +161,7 @@ export function expandTimeline(timelineId, path, params = {}) {
 export const expandHomeTimeline         = () => expandTimeline('home', '/api/v1/timelines/home');
 export const expandPublicTimeline       = () => expandTimeline('public', '/api/v1/timelines/public');
 export const expandCommunityTimeline    = () => expandTimeline('community', '/api/v1/timelines/public', { local: true });
-export const expandAccountTimeline      = accountId => expandTimeline(`account:${accountId}`, `/api/v1/accounts/${accountId}/statuses`);
+export const expandAccountTimeline      = (accountId, withReplies) => expandTimeline(`account:${accountId}${withReplies ? ':with_replies' : ''}`, `/api/v1/accounts/${accountId}/statuses`, { exclude_replies: !withReplies });
 export const expandAccountMediaTimeline = accountId => expandTimeline(`account:${accountId}:media`, `/api/v1/accounts/${accountId}/statuses`, { only_media: true });
 export const expandHashtagTimeline      = hashtag => expandTimeline(`hashtag:${hashtag}`, `/api/v1/timelines/tag/${hashtag}`);
 export const expandListTimeline         = id => expandTimeline(`list:${id}`, `/api/v1/timelines/list/${id}`);
diff --git a/app/javascript/mastodon/components/media_gallery.js b/app/javascript/mastodon/components/media_gallery.js
index 9e1bb77c2..3568a8440 100644
--- a/app/javascript/mastodon/components/media_gallery.js
+++ b/app/javascript/mastodon/components/media_gallery.js
@@ -283,8 +283,9 @@ export default class MediaGallery extends React.PureComponent {
       if (width) {
         style.height = width / this.props.media.getIn([0, 'meta', 'small', 'aspect']);
       }
+    } else if (width) {
+      style.height = width / (16/9);
     } else {
-      // crop the image
       style.height = height;
     }
 
@@ -309,7 +310,7 @@ export default class MediaGallery extends React.PureComponent {
       if (this.isStandaloneEligible()) {
         children = <Item standalone onClick={this.handleClick} attachment={media.get(0)} />;
       } else {
-        children = media.take(4).map((attachment, i) => <Item key={attachment.get('id')} onClick={this.handleClick} attachment={attachment} index={i} size={size} containerWidth={width} containerHeight={height} />);
+        children = media.take(4).map((attachment, i) => <Item key={attachment.get('id')} onClick={this.handleClick} attachment={attachment} index={i} size={size} containerWidth={width} containerHeight={style.height} />);
       }
     }
 
diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js
index c030510a0..c52cd5f09 100644
--- a/app/javascript/mastodon/components/status.js
+++ b/app/javascript/mastodon/components/status.js
@@ -184,6 +184,7 @@ export default class Status extends ImmutablePureComponent {
                 src={video.get('url')}
                 width={239}
                 height={110}
+                inline
                 sensitive={status.get('sensitive')}
                 onOpenVideo={this.handleOpenVideo}
               />
diff --git a/app/javascript/mastodon/features/account/components/action_bar.js b/app/javascript/mastodon/features/account/components/action_bar.js
index b4f812c9a..b538fa5fc 100644
--- a/app/javascript/mastodon/features/account/components/action_bar.js
+++ b/app/javascript/mastodon/features/account/components/action_bar.js
@@ -53,11 +53,11 @@ export default class ActionBar extends React.PureComponent {
     let extraInfo = '';
 
     menu.push({ text: intl.formatMessage(messages.mention, { name: account.get('username') }), action: this.props.onMention });
+
     if ('share' in navigator) {
       menu.push({ text: intl.formatMessage(messages.share, { name: account.get('username') }), action: this.handleShare });
     }
-    menu.push(null);
-    menu.push({ text: intl.formatMessage(messages.media), to: `/accounts/${account.get('id')}/media` });
+
     menu.push(null);
 
     if (account.get('id') === me) {
diff --git a/app/javascript/mastodon/features/account_gallery/components/media_item.js b/app/javascript/mastodon/features/account_gallery/components/media_item.js
index dda3d4e37..59c805c38 100644
--- a/app/javascript/mastodon/features/account_gallery/components/media_item.js
+++ b/app/javascript/mastodon/features/account_gallery/components/media_item.js
@@ -12,24 +12,26 @@ export default class MediaItem extends ImmutablePureComponent {
   render () {
     const { media } = this.props;
     const status = media.get('status');
+    const focusX = media.getIn(['meta', 'focus', 'x']);
+    const focusY = media.getIn(['meta', 'focus', 'y']);
+    const x = ((focusX /  2) + .5) * 100;
+    const y = ((focusY / -2) + .5) * 100;
+    const style = {};
 
-    let content, style;
+    let content;
 
     if (media.get('type') === 'gifv') {
       content = <span className='media-gallery__gifv__label'>GIF</span>;
     }
 
     if (!status.get('sensitive')) {
-      style = { backgroundImage: `url(${media.get('preview_url')})` };
+      style.backgroundImage    = `url(${media.get('preview_url')})`;
+      style.backgroundPosition = `${x}% ${y}%`;
     }
 
     return (
       <div className='account-gallery__item'>
-        <Permalink
-          to={`/statuses/${status.get('id')}`}
-          href={status.get('url')}
-          style={style}
-        >
+        <Permalink to={`/statuses/${status.get('id')}`} href={status.get('url')} style={style}>
           {content}
         </Permalink>
       </div>
diff --git a/app/javascript/mastodon/features/account_gallery/index.js b/app/javascript/mastodon/features/account_gallery/index.js
index ece219a3d..4b408256a 100644
--- a/app/javascript/mastodon/features/account_gallery/index.js
+++ b/app/javascript/mastodon/features/account_gallery/index.js
@@ -11,7 +11,6 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
 import { getAccountGallery } from '../../selectors';
 import MediaItem from './components/media_item';
 import HeaderContainer from '../account_timeline/containers/header_container';
-import { FormattedMessage } from 'react-intl';
 import { ScrollContainer } from 'react-router-scroll-4';
 import LoadMore from '../../components/load_more';
 
@@ -89,10 +88,6 @@ export default class AccountGallery extends ImmutablePureComponent {
           <div className='scrollable' onScroll={this.handleScroll}>
             <HeaderContainer accountId={this.props.params.accountId} />
 
-            <div className='account-section-headline'>
-              <FormattedMessage id='account.media' defaultMessage='Media' />
-            </div>
-
             <div className='account-gallery__container'>
               {medias.map(media => (
                 <MediaItem
diff --git a/app/javascript/mastodon/features/account_timeline/components/header.js b/app/javascript/mastodon/features/account_timeline/components/header.js
index 0ddb6b6c1..5cd4af1d3 100644
--- a/app/javascript/mastodon/features/account_timeline/components/header.js
+++ b/app/javascript/mastodon/features/account_timeline/components/header.js
@@ -6,6 +6,8 @@ import ActionBar from '../../account/components/action_bar';
 import MissingIndicator from '../../../components/missing_indicator';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import MovedNote from './moved_note';
+import { FormattedMessage } from 'react-intl';
+import { NavLink } from 'react-router-dom';
 
 export default class Header extends ImmutablePureComponent {
 
@@ -91,6 +93,12 @@ export default class Header extends ImmutablePureComponent {
           onBlockDomain={this.handleBlockDomain}
           onUnblockDomain={this.handleUnblockDomain}
         />
+
+        <div className='account__section-headline'>
+          <NavLink exact to={`/accounts/${account.get('id')}`}><FormattedMessage id='account.posts' defaultMessage='Toots' /></NavLink>
+          <NavLink exact to={`/accounts/${account.get('id')}/with_replies`}><FormattedMessage id='account.posts_with_replies' defaultMessage='Toots with replies' /></NavLink>
+          <NavLink exact to={`/accounts/${account.get('id')}/media`}><FormattedMessage id='account.media' defaultMessage='Media' /></NavLink>
+        </div>
       </div>
     );
   }
diff --git a/app/javascript/mastodon/features/account_timeline/index.js b/app/javascript/mastodon/features/account_timeline/index.js
index f8c85c296..aed009ef0 100644
--- a/app/javascript/mastodon/features/account_timeline/index.js
+++ b/app/javascript/mastodon/features/account_timeline/index.js
@@ -12,11 +12,15 @@ import ColumnBackButton from '../../components/column_back_button';
 import { List as ImmutableList } from 'immutable';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 
-const mapStateToProps = (state, props) => ({
-  statusIds: state.getIn(['timelines', `account:${props.params.accountId}`, 'items'], ImmutableList()),
-  isLoading: state.getIn(['timelines', `account:${props.params.accountId}`, 'isLoading']),
-  hasMore: !!state.getIn(['timelines', `account:${props.params.accountId}`, 'next']),
-});
+const mapStateToProps = (state, { params: { accountId }, withReplies = false }) => {
+  const path = withReplies ? `${accountId}:with_replies` : accountId;
+
+  return {
+    statusIds: state.getIn(['timelines', `account:${path}`, 'items'], ImmutableList()),
+    isLoading: state.getIn(['timelines', `account:${path}`, 'isLoading']),
+    hasMore: !!state.getIn(['timelines', `account:${path}`, 'next']),
+  };
+};
 
 @connect(mapStateToProps)
 export default class AccountTimeline extends ImmutablePureComponent {
@@ -27,23 +31,24 @@ export default class AccountTimeline extends ImmutablePureComponent {
     statusIds: ImmutablePropTypes.list,
     isLoading: PropTypes.bool,
     hasMore: PropTypes.bool,
+    withReplies: PropTypes.bool,
   };
 
   componentWillMount () {
     this.props.dispatch(fetchAccount(this.props.params.accountId));
-    this.props.dispatch(refreshAccountTimeline(this.props.params.accountId));
+    this.props.dispatch(refreshAccountTimeline(this.props.params.accountId, this.props.withReplies));
   }
 
   componentWillReceiveProps (nextProps) {
-    if (nextProps.params.accountId !== this.props.params.accountId && nextProps.params.accountId) {
+    if ((nextProps.params.accountId !== this.props.params.accountId && nextProps.params.accountId) || nextProps.withReplies !== this.props.withReplies) {
       this.props.dispatch(fetchAccount(nextProps.params.accountId));
-      this.props.dispatch(refreshAccountTimeline(nextProps.params.accountId));
+      this.props.dispatch(refreshAccountTimeline(nextProps.params.accountId, nextProps.params.withReplies));
     }
   }
 
   handleScrollToBottom = () => {
     if (!this.props.isLoading && this.props.hasMore) {
-      this.props.dispatch(expandAccountTimeline(this.props.params.accountId));
+      this.props.dispatch(expandAccountTimeline(this.props.params.accountId, this.props.withReplies));
     }
   }
 
diff --git a/app/javascript/mastodon/features/compose/components/search.js b/app/javascript/mastodon/features/compose/components/search.js
index 398fc44ce..71c0a203f 100644
--- a/app/javascript/mastodon/features/compose/components/search.js
+++ b/app/javascript/mastodon/features/compose/components/search.js
@@ -4,6 +4,7 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import Overlay from 'react-overlays/lib/Overlay';
 import Motion from '../../ui/util/optional_motion';
 import spring from 'react-motion/lib/spring';
+import { searchEnabled } from '../../../initial_state';
 
 const messages = defineMessages({
   placeholder: { id: 'search.placeholder', defaultMessage: 'Search' },
@@ -17,7 +18,7 @@ class SearchPopout extends React.PureComponent {
 
   render () {
     const { style } = this.props;
-
+    const extraInformation = searchEnabled ? <FormattedMessage id='search_popout.tips.full_text' defaultMessage='Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.' /> : <FormattedMessage id='search_popout.tips.text' defaultMessage='Simple text returns matching display names, usernames and hashtags' />;
     return (
       <div style={{ ...style, position: 'absolute', width: 285 }}>
         <Motion defaultStyle={{ opacity: 0, scaleX: 0.85, scaleY: 0.75 }} style={{ opacity: spring(1, { damping: 35, stiffness: 400 }), scaleX: spring(1, { damping: 35, stiffness: 400 }), scaleY: spring(1, { damping: 35, stiffness: 400 }) }}>
@@ -32,7 +33,7 @@ class SearchPopout extends React.PureComponent {
                 <li><em>URL</em> <FormattedMessage id='search_popout.tips.status' defaultMessage='status' /></li>
               </ul>
 
-              <FormattedMessage id='search_popout.tips.text' defaultMessage='Simple text returns matching display names, usernames and hashtags' />
+              {extraInformation}
             </div>
           )}
         </Motion>
diff --git a/app/javascript/mastodon/features/status/components/detailed_status.js b/app/javascript/mastodon/features/status/components/detailed_status.js
index abdb9a3f6..d4f21fc32 100644
--- a/app/javascript/mastodon/features/status/components/detailed_status.js
+++ b/app/javascript/mastodon/features/status/components/detailed_status.js
@@ -57,6 +57,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
             src={video.get('url')}
             width={300}
             height={150}
+            inline
             onOpenVideo={this.handleOpenVideo}
             sensitive={status.get('sensitive')}
           />
diff --git a/app/javascript/mastodon/features/ui/components/bundle.js b/app/javascript/mastodon/features/ui/components/bundle.js
index fc88e0c70..06a6c9cdd 100644
--- a/app/javascript/mastodon/features/ui/components/bundle.js
+++ b/app/javascript/mastodon/features/ui/components/bundle.js
@@ -26,7 +26,7 @@ class Bundle extends React.Component {
     onFetchFail: noop,
   }
 
-  static cache = {}
+  static cache = new Map
 
   state = {
     mod: undefined,
@@ -51,13 +51,12 @@ class Bundle extends React.Component {
 
   load = (props) => {
     const { fetchComponent, onFetch, onFetchSuccess, onFetchFail, renderDelay } = props || this.props;
+    const cachedMod = Bundle.cache.get(fetchComponent);
 
     onFetch();
 
-    if (Bundle.cache[fetchComponent.name]) {
-      const mod = Bundle.cache[fetchComponent.name];
-
-      this.setState({ mod: mod.default });
+    if (cachedMod) {
+      this.setState({ mod: cachedMod.default });
       onFetchSuccess();
       return Promise.resolve();
     }
@@ -71,7 +70,7 @@ class Bundle extends React.Component {
 
     return fetchComponent()
       .then((mod) => {
-        Bundle.cache[fetchComponent.name] = mod;
+        Bundle.cache.set(fetchComponent, mod);
         this.setState({ mod: mod.default });
         onFetchSuccess();
       })
diff --git a/app/javascript/mastodon/features/ui/components/columns_area.js b/app/javascript/mastodon/features/ui/components/columns_area.js
index a01e5a390..e82c46402 100644
--- a/app/javascript/mastodon/features/ui/components/columns_area.js
+++ b/app/javascript/mastodon/features/ui/components/columns_area.js
@@ -6,6 +6,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
 
 import ReactSwipeableViews from 'react-swipeable-views';
 import { links, getIndex, getLink } from './tabs_bar';
+import { Link } from 'react-router-dom';
 
 import BundleContainer from '../containers/bundle_container';
 import ColumnLoading from './column_loading';
@@ -152,11 +153,19 @@ export default class ColumnsArea extends ImmutablePureComponent {
     this.pendingIndex = null;
 
     if (singleColumn) {
-      return columnIndex !== -1 ? (
-        <ReactSwipeableViews index={columnIndex} onChangeIndex={this.handleSwipe} onTransitionEnd={this.handleAnimationEnd} animateTransitions={shouldAnimate} springConfig={{ duration: '400ms', delay: '0s', easeFunction: 'ease' }} style={{ height: '100%' }}>
+      const floatingActionButton = this.context.router.history.location.pathname === '/statuses/new' ? null : <Link key='floating-action-button' to='/statuses/new' className='floating-action-button'><i className='fa fa-pencil' /></Link>;
+
+      return columnIndex !== -1 ? [
+        <ReactSwipeableViews key='content' index={columnIndex} onChangeIndex={this.handleSwipe} onTransitionEnd={this.handleAnimationEnd} animateTransitions={shouldAnimate} springConfig={{ duration: '400ms', delay: '0s', easeFunction: 'ease' }} style={{ height: '100%' }}>
           {links.map(this.renderView)}
-        </ReactSwipeableViews>
-      ) : <div className='columns-area'>{children}</div>;
+        </ReactSwipeableViews>,
+
+        floatingActionButton,
+      ] : [
+        <div className='columns-area'>{children}</div>,
+
+        floatingActionButton,
+      ];
     }
 
     return (
diff --git a/app/javascript/mastodon/features/ui/components/report_modal.js b/app/javascript/mastodon/features/ui/components/report_modal.js
index b5dfa422e..3ae97646f 100644
--- a/app/javascript/mastodon/features/ui/components/report_modal.js
+++ b/app/javascript/mastodon/features/ui/components/report_modal.js
@@ -1,6 +1,6 @@
 import React from 'react';
 import { connect } from 'react-redux';
-import { changeReportComment, submitReport } from '../../../actions/reports';
+import { changeReportComment, changeReportForward, submitReport } from '../../../actions/reports';
 import { refreshAccountTimeline } from '../../../actions/timelines';
 import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
@@ -10,8 +10,11 @@ import StatusCheckBox from '../../report/containers/status_check_box_container';
 import { OrderedSet } from 'immutable';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import Button from '../../../components/button';
+import Toggle from 'react-toggle';
+import IconButton from '../../../components/icon_button';
 
 const messages = defineMessages({
+  close: { id: 'lightbox.close', defaultMessage: 'Close' },
   placeholder: { id: 'report.placeholder', defaultMessage: 'Additional comments' },
   submit: { id: 'report.submit', defaultMessage: 'Submit' },
 });
@@ -26,6 +29,7 @@ const makeMapStateToProps = () => {
       isSubmitting: state.getIn(['reports', 'new', 'isSubmitting']),
       account: getAccount(state, accountId),
       comment: state.getIn(['reports', 'new', 'comment']),
+      forward: state.getIn(['reports', 'new', 'forward']),
       statusIds: OrderedSet(state.getIn(['timelines', `account:${accountId}`, 'items'])).union(state.getIn(['reports', 'new', 'status_ids'])),
     };
   };
@@ -42,14 +46,19 @@ export default class ReportModal extends ImmutablePureComponent {
     account: ImmutablePropTypes.map,
     statusIds: ImmutablePropTypes.orderedSet.isRequired,
     comment: PropTypes.string.isRequired,
+    forward: PropTypes.bool,
     dispatch: PropTypes.func.isRequired,
     intl: PropTypes.object.isRequired,
   };
 
-  handleCommentChange = (e) => {
+  handleCommentChange = e => {
     this.props.dispatch(changeReportComment(e.target.value));
   }
 
+  handleForwardChange = e => {
+    this.props.dispatch(changeReportForward(e.target.checked));
+  }
+
   handleSubmit = () => {
     this.props.dispatch(submitReport());
   }
@@ -65,26 +74,25 @@ export default class ReportModal extends ImmutablePureComponent {
   }
 
   render () {
-    const { account, comment, intl, statusIds, isSubmitting } = this.props;
+    const { account, comment, intl, statusIds, isSubmitting, forward, onClose } = this.props;
 
     if (!account) {
       return null;
     }
 
+    const domain = account.get('acct').split('@')[1];
+
     return (
       <div className='modal-root__modal report-modal'>
         <div className='report-modal__target'>
+          <IconButton className='media-modal__close' title={intl.formatMessage(messages.close)} icon='times' onClick={onClose} size={16} />
           <FormattedMessage id='report.target' defaultMessage='Report {target}' values={{ target: <strong>{account.get('acct')}</strong> }} />
         </div>
 
         <div className='report-modal__container'>
-          <div className='report-modal__statuses'>
-            <div>
-              {statusIds.map(statusId => <StatusCheckBox id={statusId} key={statusId} disabled={isSubmitting} />)}
-            </div>
-          </div>
-
           <div className='report-modal__comment'>
+            <p><FormattedMessage id='report.hint' defaultMessage='The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:' /></p>
+
             <textarea
               className='setting-text light'
               placeholder={intl.formatMessage(messages.placeholder)}
@@ -92,11 +100,26 @@ export default class ReportModal extends ImmutablePureComponent {
               onChange={this.handleCommentChange}
               disabled={isSubmitting}
             />
+
+            {domain && (
+              <div>
+                <p><FormattedMessage id='report.forward_hint' defaultMessage='The account is from another server. Send an anonymized copy of the report there as well?' /></p>
+
+                <div className='setting-toggle'>
+                  <Toggle id='report-forward' checked={forward} disabled={isSubmitting} onChange={this.handleForwardChange} />
+                  <label htmlFor='report-forward' className='setting-toggle__label'><FormattedMessage id='report.forward' defaultMessage='Forward to {target}' values={{ target: domain }} /></label>
+                </div>
+              </div>
+            )}
+
+            <Button disabled={isSubmitting} text={intl.formatMessage(messages.submit)} onClick={this.handleSubmit} />
           </div>
-        </div>
 
-        <div className='report-modal__action-bar'>
-          <Button disabled={isSubmitting} text={intl.formatMessage(messages.submit)} onClick={this.handleSubmit} />
+          <div className='report-modal__statuses'>
+            <div>
+              {statusIds.map(statusId => <StatusCheckBox id={statusId} key={statusId} disabled={isSubmitting} />)}
+            </div>
+          </div>
         </div>
       </div>
     );
diff --git a/app/javascript/mastodon/features/ui/components/tabs_bar.js b/app/javascript/mastodon/features/ui/components/tabs_bar.js
index 7694e5ab3..77fe5f5e2 100644
--- a/app/javascript/mastodon/features/ui/components/tabs_bar.js
+++ b/app/javascript/mastodon/features/ui/components/tabs_bar.js
@@ -6,14 +6,13 @@ import { debounce } from 'lodash';
 import { isUserTouching } from '../../../is_mobile';
 
 export const links = [
-  <NavLink className='tabs-bar__link primary' to='/statuses/new' data-preview-title-id='tabs_bar.compose' data-preview-icon='pencil' ><i className='fa fa-fw fa-pencil' /><FormattedMessage id='tabs_bar.compose' defaultMessage='Compose' /></NavLink>,
   <NavLink className='tabs-bar__link primary' to='/timelines/home' data-preview-title-id='column.home' data-preview-icon='home' ><i className='fa fa-fw fa-home' /><FormattedMessage id='tabs_bar.home' defaultMessage='Home' /></NavLink>,
   <NavLink className='tabs-bar__link primary' to='/notifications' data-preview-title-id='column.notifications' data-preview-icon='bell' ><i className='fa fa-fw fa-bell' /><FormattedMessage id='tabs_bar.notifications' defaultMessage='Notifications' /></NavLink>,
 
   <NavLink className='tabs-bar__link secondary' to='/timelines/public/local' data-preview-title-id='column.community' data-preview-icon='users' ><i className='fa fa-fw fa-users' /><FormattedMessage id='tabs_bar.local_timeline' defaultMessage='Local' /></NavLink>,
   <NavLink className='tabs-bar__link secondary' exact to='/timelines/public' data-preview-title-id='column.public' data-preview-icon='globe' ><i className='fa fa-fw fa-globe' /><FormattedMessage id='tabs_bar.federated_timeline' defaultMessage='Federated' /></NavLink>,
 
-  <NavLink className='tabs-bar__link primary' style={{ flexGrow: '0', flexBasis: '30px' }} to='/getting-started' data-preview-title-id='getting_started.heading' data-preview-icon='asterisk' ><i className='fa fa-fw fa-asterisk' /></NavLink>,
+  <NavLink className='tabs-bar__link primary' style={{ flexGrow: '0', flexBasis: '30px' }} to='/getting-started' data-preview-title-id='getting_started.heading' data-preview-icon='bars' ><i className='fa fa-fw fa-bars' /></NavLink>,
 ];
 
 export function getIndex (path) {
diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js
index 5b0d7246a..ef909136f 100644
--- a/app/javascript/mastodon/features/ui/index.js
+++ b/app/javascript/mastodon/features/ui/index.js
@@ -398,6 +398,7 @@ export default class UI extends React.Component {
               <WrappedRoute path='/statuses/:statusId/favourites' component={Favourites} content={children} />
 
               <WrappedRoute path='/accounts/:accountId' exact component={AccountTimeline} content={children} />
+              <WrappedRoute path='/accounts/:accountId/with_replies' component={AccountTimeline} content={children} componentParams={{ withReplies: true }} />
               <WrappedRoute path='/accounts/:accountId/followers' component={Followers} content={children} />
               <WrappedRoute path='/accounts/:accountId/following' component={Following} content={children} />
               <WrappedRoute path='/accounts/:accountId/media' component={AccountGallery} content={children} />
diff --git a/app/javascript/mastodon/features/ui/util/react_router_helpers.js b/app/javascript/mastodon/features/ui/util/react_router_helpers.js
index 43007ddc3..32dfe320b 100644
--- a/app/javascript/mastodon/features/ui/util/react_router_helpers.js
+++ b/app/javascript/mastodon/features/ui/util/react_router_helpers.js
@@ -35,14 +35,19 @@ export class WrappedRoute extends React.Component {
     component: PropTypes.func.isRequired,
     content: PropTypes.node,
     multiColumn: PropTypes.bool,
-  }
+    componentParams: PropTypes.object,
+  };
+
+  static defaultProps = {
+    componentParams: {},
+  };
 
   renderComponent = ({ match }) => {
-    const { component, content, multiColumn } = this.props;
+    const { component, content, multiColumn, componentParams } = this.props;
 
     return (
       <BundleContainer fetchComponent={component} loading={this.renderLoading} error={this.renderError}>
-        {Component => <Component params={match.params} multiColumn={multiColumn}>{content}</Component>}
+        {Component => <Component params={match.params} multiColumn={multiColumn} {...componentParams}>{content}</Component>}
       </BundleContainer>
     );
   }
diff --git a/app/javascript/mastodon/features/video/index.js b/app/javascript/mastodon/features/video/index.js
index c81a5cb5f..98ebcb6f9 100644
--- a/app/javascript/mastodon/features/video/index.js
+++ b/app/javascript/mastodon/features/video/index.js
@@ -97,6 +97,7 @@ export default class Video extends React.PureComponent {
     onOpenVideo: PropTypes.func,
     onCloseVideo: PropTypes.func,
     detailed: PropTypes.bool,
+    inline: PropTypes.bool,
     intl: PropTypes.object.isRequired,
   };
 
@@ -105,6 +106,7 @@ export default class Video extends React.PureComponent {
     duration: 0,
     paused: true,
     dragging: false,
+    containerWidth: false,
     fullscreen: false,
     hovered: false,
     muted: false,
@@ -113,6 +115,12 @@ export default class Video extends React.PureComponent {
 
   setPlayerRef = c => {
     this.player = c;
+
+    if (c) {
+      this.setState({
+        containerWidth: c.offsetWidth,
+      });
+    }
   }
 
   setVideoRef = c => {
@@ -246,12 +254,23 @@ export default class Video extends React.PureComponent {
   }
 
   render () {
-    const { preview, src, width, height, startTime, onOpenVideo, onCloseVideo, intl, alt, detailed } = this.props;
-    const { currentTime, duration, buffer, dragging, paused, fullscreen, hovered, muted, revealed } = this.state;
+    const { preview, src, inline, startTime, onOpenVideo, onCloseVideo, intl, alt, detailed } = this.props;
+    const { containerWidth, currentTime, duration, buffer, dragging, paused, fullscreen, hovered, muted, revealed } = this.state;
     const progress = (currentTime / duration) * 100;
+    const playerStyle = {};
+
+    let { width, height } = this.props;
+
+    if (inline && containerWidth) {
+      width  = containerWidth;
+      height = containerWidth / (16/9);
+
+      playerStyle.width  = width;
+      playerStyle.height = height;
+    }
 
     return (
-      <div className={classNames('video-player', { inactive: !revealed, detailed, inline: width && height && !fullscreen, fullscreen })} style={{ width, height }} ref={this.setPlayerRef} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>
+      <div className={classNames('video-player', { inactive: !revealed, detailed, inline: inline && !fullscreen, fullscreen })} style={playerStyle} ref={this.setPlayerRef} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>
         <video
           ref={this.setVideoRef}
           src={src}
diff --git a/app/javascript/mastodon/initial_state.js b/app/javascript/mastodon/initial_state.js
index 6f1356324..df310e7e1 100644
--- a/app/javascript/mastodon/initial_state.js
+++ b/app/javascript/mastodon/initial_state.js
@@ -10,5 +10,6 @@ export const unfollowModal = getMeta('unfollow_modal');
 export const boostModal = getMeta('boost_modal');
 export const deleteModal = getMeta('delete_modal');
 export const me = getMeta('me');
+export const searchEnabled = getMeta('search_enabled');
 
 export default initialState;
diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json
index 310c7aa55..b326bc3b1 100644
--- a/app/javascript/mastodon/locales/ar.json
+++ b/app/javascript/mastodon/locales/ar.json
@@ -13,7 +13,8 @@
   "account.moved_to": "{name} إنتقل إلى :",
   "account.mute": "أكتم @{name}",
   "account.mute_notifications": "كتم إخطارات @{name}",
-  "account.posts": "المشاركات",
+  "account.posts": "التبويقات",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "أبلغ عن @{name}",
   "account.requested": "في انتظار الموافقة",
   "account.share": "مشاركة @{name}'s profile",
@@ -50,7 +51,7 @@
   "column_header.unpin": "فك التدبيس",
   "column_subheading.navigation": "التصفح",
   "column_subheading.settings": "الإعدادات",
-  "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
+  "compose_form.hashtag_warning": "هذا التبويق لن يُدرَج تحت أي وسم كان بما أنه غير مُدرَج. لا يُسمح بالبحث إلّا عن التبويقات العمومية عن طريق الوسوم.",
   "compose_form.lock_disclaimer": "حسابك ليس {locked}. يمكن لأي شخص متابعتك و عرض المنشورات.",
   "compose_form.lock_disclaimer.lock": "مقفل",
   "compose_form.placeholder": "فيمَ تفكّر؟",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "إلغاء",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "تعليقات إضافية",
   "report.submit": "إرسال",
   "report.target": "إبلاغ",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "حالة",
   "search_popout.tips.text": "جملة قصيرة تُمكّنُك من عرض أسماء و حسابات و كلمات رمزية",
   "search_popout.tips.user": "مستخدِم",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {result} و {results}}",
   "standalone.public_title": "نظرة على ...",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "إسحب ثم أفلت للرفع",
   "upload_button.label": "إضافة وسائط",
   "upload_form.description": "وصف للمعاقين بصريا",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "إلغاء",
   "upload_progress.label": "يرفع...",
   "video.close": "إغلاق الفيديو",
diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json
index 8188ae2c0..90e394a19 100644
--- a/app/javascript/mastodon/locales/bg.json
+++ b/app/javascript/mastodon/locales/bg.json
@@ -14,6 +14,7 @@
   "account.mute": "Mute @{name}",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.posts": "Публикации",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Report @{name}",
   "account.requested": "В очакване на одобрение",
   "account.share": "Share @{name}'s profile",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Отказ",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Additional comments",
   "report.submit": "Submit",
   "report.target": "Reporting",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
   "search_popout.tips.user": "user",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
   "standalone.public_title": "A look inside...",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "Drag & drop to upload",
   "upload_button.label": "Добави медия",
   "upload_form.description": "Describe for the visually impaired",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Отмяна",
   "upload_progress.label": "Uploading...",
   "video.close": "Close video",
diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json
index ecaae0847..95b75cfc9 100644
--- a/app/javascript/mastodon/locales/ca.json
+++ b/app/javascript/mastodon/locales/ca.json
@@ -1,29 +1,30 @@
 {
-  "account.block": "Bloquejar @{name}",
-  "account.block_domain": "Amagar tot de {domain}",
+  "account.block": "Bloca @{name}",
+  "account.block_domain": "Amaga-ho tot de {domain}",
   "account.disclaimer_full": "La informació següent pot reflectir incompleta el perfil de l'usuari.",
-  "account.edit_profile": "Editar perfil",
-  "account.follow": "Seguir",
+  "account.edit_profile": "Edita el perfil",
+  "account.follow": "Segueix",
   "account.followers": "Seguidors",
   "account.follows": "Seguint",
-  "account.follows_you": "et segueix",
+  "account.follows_you": "Et segueix",
   "account.hide_reblogs": "Amaga els impulsos de @{name}",
   "account.media": "Media",
   "account.mention": "Esmentar @{name}",
   "account.moved_to": "{name} s'ha mogut a:",
-  "account.mute": "Silenciar @{name}",
+  "account.mute": "Silencia @{name}",
   "account.mute_notifications": "Notificacions desactivades de @{name}",
-  "account.posts": "Publicacions",
+  "account.posts": "Toots",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Informe @{name}",
   "account.requested": "Esperant aprovació. Clic per a cancel·lar la petició de seguiment",
-  "account.share": "Compartir el perfil de @{name}",
+  "account.share": "Comparteix el perfil de @{name}",
   "account.show_reblogs": "Mostra els impulsos de @{name}",
-  "account.unblock": "Desbloquejar @{name}",
+  "account.unblock": "Desbloca @{name}",
   "account.unblock_domain": "Mostra {domain}",
-  "account.unfollow": "Deixar de seguir",
+  "account.unfollow": "Deixa de seguir",
   "account.unmute": "Treure silenci de @{name}",
   "account.unmute_notifications": "Activar notificacions de @{name}",
-  "account.view_full_profile": "Veure el perfil complet",
+  "account.view_full_profile": "Mostra el perfil complet",
   "boost_modal.combo": "Pots premer {combo} per saltar-te això el proper cop",
   "bundle_column_error.body": "S'ha produït un error en carregar aquest component.",
   "bundle_column_error.retry": "Torna-ho a provar",
@@ -31,7 +32,7 @@
   "bundle_modal_error.close": "Tanca",
   "bundle_modal_error.message": "S'ha produït un error en carregar aquest component.",
   "bundle_modal_error.retry": "Torna-ho a provar",
-  "column.blocks": "Usuaris bloquejats",
+  "column.blocks": "Usuaris blocats",
   "column.community": "Línia de temps local",
   "column.favourites": "Favorits",
   "column.follow_requests": "Peticions per seguir-te",
@@ -45,46 +46,46 @@
   "column_header.hide_settings": "Amaga la configuració",
   "column_header.moveLeft_settings": "Mou la columna cap a l'esquerra",
   "column_header.moveRight_settings": "Mou la columna cap a la dreta",
-  "column_header.pin": "Fixar",
+  "column_header.pin": "Fixa",
   "column_header.show_settings": "Mostra la configuració",
-  "column_header.unpin": "Deslligar",
+  "column_header.unpin": "No fixis",
   "column_subheading.navigation": "Navegació",
   "column_subheading.settings": "Configuració",
   "compose_form.hashtag_warning": "Aquest toot no es mostrarà en cap etiqueta ja que no està llistat. Només els toots públics poden ser cercats per etiqueta.",
   "compose_form.lock_disclaimer": "El teu compte no està bloquejat {locked}. Tothom pot seguir-te i veure els teus missatges a seguidors.",
-  "compose_form.lock_disclaimer.lock": "bloquejat",
+  "compose_form.lock_disclaimer.lock": "blocat",
   "compose_form.placeholder": "En què estàs pensant?",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Marcar multimèdia com a sensible",
-  "compose_form.spoiler": "Amagar text darrera l'advertència",
-  "compose_form.spoiler_placeholder": "Escriu l'advertència aquí",
-  "confirmation_modal.cancel": "Cancel·lar",
-  "confirmations.block.confirm": "Bloquejar",
-  "confirmations.block.message": "Estàs segur que vols bloquejar {name}?",
-  "confirmations.delete.confirm": "Esborrar",
-  "confirmations.delete.message": "Estàs segur que vols esborrar aquest estat?",
-  "confirmations.delete_list.confirm": "Delete",
-  "confirmations.delete_list.message": "Estàs segur que vols esborrar permanenment aquesta llista?",
-  "confirmations.domain_block.confirm": "Amagar tot el domini",
-  "confirmations.domain_block.message": "Estàs realment, realment segur que vols bloquejar totalment {domain}? En la majoria dels casos bloquejar o silenciar és suficient i preferible.",
-  "confirmations.mute.confirm": "Silenciar",
+  "compose_form.sensitive": "Marca el contingut multimèdia com a sensible",
+  "compose_form.spoiler": "Amaga el text darrera darrere un avís",
+  "compose_form.spoiler_placeholder": "Escriu l'avís aquí",
+  "confirmation_modal.cancel": "Cancel·la",
+  "confirmations.block.confirm": "Bloca",
+  "confirmations.block.message": "Estàs segur que vols blocar {name}?",
+  "confirmations.delete.confirm": "Suprimeix",
+  "confirmations.delete.message": "Estàs segur que vols suprimir aquest estat?",
+  "confirmations.delete_list.confirm": "Suprimeix",
+  "confirmations.delete_list.message": "Estàs segur que vols suprimir permanentment aquesta llista?",
+  "confirmations.domain_block.confirm": "Amaga tot el domini",
+  "confirmations.domain_block.message": "Estàs realment, realment segur que vols blocar totalment {domain}? En la majoria dels casos blocar o silenciar uns pocs objectius és suficient i preferible.",
+  "confirmations.mute.confirm": "Silencia",
   "confirmations.mute.message": "Estàs segur que vols silenciar {name}?",
-  "confirmations.unfollow.confirm": "Deixar de seguir",
+  "confirmations.unfollow.confirm": "Deixa de seguir",
   "confirmations.unfollow.message": "Estàs segur que vols deixar de seguir {name}?",
   "embed.instructions": "Incrusta aquest estat al lloc web copiant el codi a continuació.",
   "embed.preview": "Aquí tenim quin aspecte tindrá:",
   "emoji_button.activity": "Activitat",
   "emoji_button.custom": "Personalitzat",
-  "emoji_button.flags": "Marques",
-  "emoji_button.food": "Menjar i Beure",
-  "emoji_button.label": "Inserir emoji",
+  "emoji_button.flags": "Banderes",
+  "emoji_button.food": "Menjar i beure",
+  "emoji_button.label": "Insereix un emoji",
   "emoji_button.nature": "Natura",
   "emoji_button.not_found": "Emojos no!! (╯°□°)╯︵ ┻━┻",
   "emoji_button.objects": "Objectes",
   "emoji_button.people": "Gent",
-  "emoji_button.recent": "Freqüentment utilitzat",
-  "emoji_button.search": "Cercar...",
+  "emoji_button.recent": "Usats freqüentment",
+  "emoji_button.search": "Cerca...",
   "emoji_button.search_results": "Resultats de la cerca",
   "emoji_button.symbols": "Símbols",
   "emoji_button.travel": "Viatges i Llocs",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "fa {number} minuts",
   "relative_time.seconds": "fa {number} segons",
   "reply_indicator.cancel": "Cancel·lar",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Comentaris addicionals",
   "report.submit": "Enviar",
   "report.target": "Informes",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "El text simple retorna coincidències amb els noms de visualització, els noms d'usuari i els hashtags",
   "search_popout.tips.user": "usuari",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, un {result} altres {results}}",
   "standalone.public_title": "Una mirada a l'interior ...",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "Arrossega i deixa anar per carregar",
   "upload_button.label": "Afegir multimèdia",
   "upload_form.description": "Descriure els problemes visuals",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Desfer",
   "upload_progress.label": "Pujant...",
   "video.close": "Tancar el vídeo",
diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json
index aadcfac97..7f29f83ce 100644
--- a/app/javascript/mastodon/locales/de.json
+++ b/app/javascript/mastodon/locales/de.json
@@ -14,6 +14,7 @@
   "account.mute": "@{name} stummschalten",
   "account.mute_notifications": "Benachrichtigungen von @{name} verbergen",
   "account.posts": "Beiträge",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "@{name} melden",
   "account.requested": "Warte auf Erlaubnis. Klicke zum Abbrechen",
   "account.share": "Profil von @{name} teilen",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Abbrechen",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Zusätzliche Kommentare",
   "report.submit": "Absenden",
   "report.target": "{target} melden",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
   "search_popout.tips.user": "user",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {Ergebnis} other {Ergebnisse}}",
   "standalone.public_title": "Ein kleiner Einblick …",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "Zum Hochladen hereinziehen",
   "upload_button.label": "Mediendatei hinzufügen",
   "upload_form.description": "Für Menschen mit Sehbehinderung beschreiben",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Entfernen",
   "upload_progress.label": "Wird hochgeladen …",
   "video.close": "Video schließen",
diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json
index c0841d6f5..52a82ff27 100644
--- a/app/javascript/mastodon/locales/defaultMessages.json
+++ b/app/javascript/mastodon/locales/defaultMessages.json
@@ -318,11 +318,19 @@
   {
     "descriptors": [
       {
+        "defaultMessage": "Toots",
+        "id": "account.posts"
+      },
+      {
+        "defaultMessage": "Toots with replies",
+        "id": "account.posts_with_replies"
+      },
+      {
         "defaultMessage": "Media",
         "id": "account.media"
       }
     ],
-    "path": "app/javascript/mastodon/features/account_gallery/index.json"
+    "path": "app/javascript/mastodon/features/account_timeline/components/header.json"
   },
   {
     "descriptors": [
@@ -651,6 +659,18 @@
   {
     "descriptors": [
       {
+        "defaultMessage": "People",
+        "id": "search_results.accounts"
+      },
+      {
+        "defaultMessage": "Toots",
+        "id": "search_results.statuses"
+      },
+      {
+        "defaultMessage": "Hashtags",
+        "id": "search_results.hashtags"
+      },
+      {
         "defaultMessage": "{count, number} {count, plural, one {result} other {results}}",
         "id": "search_results.total"
       }
@@ -707,12 +727,16 @@
   {
     "descriptors": [
       {
+        "defaultMessage": "Describe for the visually impaired",
+        "id": "upload_form.description"
+      },
+      {
         "defaultMessage": "Undo",
         "id": "upload_form.undo"
       },
       {
-        "defaultMessage": "Describe for the visually impaired",
-        "id": "upload_form.description"
+        "defaultMessage": "Crop",
+        "id": "upload_form.focus"
       }
     ],
     "path": "app/javascript/mastodon/features/compose/components/upload.json"
@@ -1576,6 +1600,18 @@
       {
         "defaultMessage": "Report {target}",
         "id": "report.target"
+      },
+      {
+        "defaultMessage": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
+        "id": "report.hint"
+      },
+      {
+        "defaultMessage": "The account is from another server. Send an anonymized copy of the report there as well?",
+        "id": "report.forward_hint"
+      },
+      {
+        "defaultMessage": "Forward to {target}",
+        "id": "report.forward"
       }
     ],
     "path": "app/javascript/mastodon/features/ui/components/report_modal.json"
@@ -1672,4 +1708,4 @@
     ],
     "path": "app/javascript/mastodon/features/video/index.json"
   }
-]
+]
\ No newline at end of file
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index e72c45bf2..d2d8f3995 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -14,6 +14,7 @@
   "account.mute": "Mute @{name}",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.posts": "Toots",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Report @{name}",
   "account.requested": "Awaiting approval. Click to cancel follow request",
   "account.share": "Share @{name}'s profile",
@@ -214,6 +215,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Cancel",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Additional comments",
   "report.submit": "Submit",
   "report.target": "Reporting {target}",
@@ -223,6 +227,9 @@
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
   "search_popout.tips.user": "user",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
   "standalone.public_title": "A look inside...",
   "status.block": "Block @{name}",
@@ -259,6 +266,7 @@
   "upload_area.title": "Drag & drop to upload",
   "upload_button.label": "Add media",
   "upload_form.description": "Describe for the visually impaired",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Undo",
   "upload_progress.label": "Uploading...",
   "video.close": "Close video",
diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json
index cf0b4f2ec..b6153145f 100644
--- a/app/javascript/mastodon/locales/eo.json
+++ b/app/javascript/mastodon/locales/eo.json
@@ -1,236 +1,243 @@
 {
   "account.block": "Bloki @{name}",
-  "account.block_domain": "Kaŝi ĉion el {domain}",
-  "account.disclaimer_full": "La ĉi-subaj informoj povas ne plene reflekti la profilon de la uzanto.",
-  "account.edit_profile": "Redakti la profilon",
+  "account.block_domain": "Kaŝi ĉion de {domain}",
+  "account.disclaimer_full": "Subaj informoj povas reflekti la profilon de la uzanto nekomplete.",
+  "account.edit_profile": "Redakti profilon",
   "account.follow": "Sekvi",
   "account.followers": "Sekvantoj",
   "account.follows": "Sekvatoj",
   "account.follows_you": "Sekvas vin",
-  "account.hide_reblogs": "Maski diskonigitaĵojn de @{name}",
-  "account.media": "Sonbildaĵoj",
+  "account.hide_reblogs": "Kaŝi diskonigojn de @{name}",
+  "account.media": "Aŭdovidaĵoj",
   "account.mention": "Mencii @{name}",
-  "account.moved_to": "{name} movis al:",
+  "account.moved_to": "{name} moviĝis al:",
   "account.mute": "Silentigi @{name}",
   "account.mute_notifications": "Silentigi sciigojn el @{name}",
-  "account.posts": "Mesaĝoj",
+  "account.posts": "Hupoj",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Signali @{name}",
-  "account.requested": "Atendas aprobon",
+  "account.requested": "Atendo de aprobo. Alklaku por nuligi peton de sekvado",
   "account.share": "Diskonigi la profilon de @{name}",
-  "account.show_reblogs": "Montri diskonigaĵojn de @{name}",
+  "account.show_reblogs": "Montri diskonigojn de @{name}",
   "account.unblock": "Malbloki @{name}",
   "account.unblock_domain": "Malkaŝi {domain}",
-  "account.unfollow": "Ne plus sekvi",
+  "account.unfollow": "Ne plu sekvi",
   "account.unmute": "Malsilentigi @{name}",
   "account.unmute_notifications": "Malsilentigi sciigojn de @{name}",
   "account.view_full_profile": "Vidi plenan profilon",
-  "boost_modal.combo": "La proksiman fojon, premu {combo} por pasigi",
-  "bundle_column_error.body": "Io malfunkciis ŝargante tiun ĉi komponanton.",
+  "boost_modal.combo": "Vi povas premi {combo} por preterpasi sekvafoje",
+  "bundle_column_error.body": "Io misfunkciis en la ŝargado de ĉi tiu elemento.",
   "bundle_column_error.retry": "Bonvolu reprovi",
   "bundle_column_error.title": "Reta eraro",
   "bundle_modal_error.close": "Fermi",
-  "bundle_modal_error.message": "Io malfunkciis ŝargante tiun ĉi komponanton.",
+  "bundle_modal_error.message": "Io misfunkciis en la ŝargado de ĉi tiu elemento.",
   "bundle_modal_error.retry": "Bonvolu reprovi",
   "column.blocks": "Blokitaj uzantoj",
   "column.community": "Loka tempolinio",
-  "column.favourites": "Favoritoj",
-  "column.follow_requests": "Abonpetoj",
+  "column.favourites": "Stelumoj",
+  "column.follow_requests": "Petoj de sekvado",
   "column.home": "Hejmo",
   "column.lists": "Listoj",
   "column.mutes": "Silentigitaj uzantoj",
   "column.notifications": "Sciigoj",
-  "column.pins": "Alpinglitaj pepoj",
+  "column.pins": "Alpinglitaj mesaĝoj",
   "column.public": "Fratara tempolinio",
   "column_back_button.label": "Reveni",
   "column_header.hide_settings": "Kaŝi agordojn",
   "column_header.moveLeft_settings": "Movi kolumnon maldekstren",
   "column_header.moveRight_settings": "Movi kolumnon dekstren",
   "column_header.pin": "Alpingli",
-  "column_header.show_settings": "Malkaŝi agordojn",
+  "column_header.show_settings": "Montri agordojn",
   "column_header.unpin": "Depingli",
   "column_subheading.navigation": "Navigado",
   "column_subheading.settings": "Agordoj",
-  "compose_form.hashtag_warning": "Ĉi tiu pepo ne estos listigita en iu ajn kradvorta listo pro ĝia videbleco estas “eksterlista”. Nur publikaj pepoj povas esti kradvorte trovitaj.",
-  "compose_form.lock_disclaimer": "Via konta ne estas ŝlosita. Iu ajn povas sekvi vin por vidi viajn privatajn pepojn.",
+  "compose_form.hashtag_warning": "Ĉi tiu mesaĝo ne estos listigita per ajna kradvorto. Nur publikaj mesaĝoj estas serĉeblaj per kradvortoj.",
+  "compose_form.lock_disclaimer": "Via konta ne estas {locked}. Iu ajn povas sekvi vin por vidi viajn mesaĝojn nur por sekvantoj.",
   "compose_form.lock_disclaimer.lock": "ŝlosita",
   "compose_form.placeholder": "Pri kio vi pensas?",
   "compose_form.publish": "Hup",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Marki ke la enhavo estas tikla",
-  "compose_form.spoiler": "Kaŝi la tekston malantaŭ averto",
-  "compose_form.spoiler_placeholder": "Skribu tie vian averton",
-  "confirmation_modal.cancel": "Malfari",
+  "compose_form.sensitive": "Marki aŭdovidaĵon tikla",
+  "compose_form.spoiler": "Kaŝi tekston malantaŭ averto",
+  "compose_form.spoiler_placeholder": "Skribu vian averton ĉi tie",
+  "confirmation_modal.cancel": "Nuligi",
   "confirmations.block.confirm": "Bloki",
-  "confirmations.block.message": "Ĉu vi konfirmas la blokadon de {name}?",
-  "confirmations.delete.confirm": "Malaperigi",
-  "confirmations.delete.message": "Ĉu vi konfirmas la malaperigon de tiun pepon?",
-  "confirmations.delete_list.confirm": "Delete",
-  "confirmations.delete_list.message": "Ĉu vi certas forviŝi ĉi tiun liston por ĉiam?",
-  "confirmations.domain_block.confirm": "Kaŝi la tutan reton",
-  "confirmations.domain_block.message": "Ĉu vi vere, vere certas, ke vi volas bloki {domain} tute? Plej ofte, kelkaj celitaj blokadoj aŭ silentigoj estas sufiĉaj kaj preferindaj.",
+  "confirmations.block.message": "Ĉu vi certas, ke vi volas bloki {name}?",
+  "confirmations.delete.confirm": "Forigi",
+  "confirmations.delete.message": "Ĉu vi certas, ke vi volas forigi ĉi tiun mesaĝon?",
+  "confirmations.delete_list.confirm": "Forigi",
+  "confirmations.delete_list.message": "Ĉu vi certas, ke vi volas porĉiame forigi ĉi tiun liston?",
+  "confirmations.domain_block.confirm": "Kaŝi la tutan domajnon",
+  "confirmations.domain_block.message": "Ĉu vi vere, vere certas, ke vi volas tute bloki {domain}? Plej ofte, trafa blokado kaj silentigado sufiĉas kaj preferindas.",
   "confirmations.mute.confirm": "Silentigi",
-  "confirmations.mute.message": "Ĉu vi konfirmas la silentigon de {name}?",
+  "confirmations.mute.message": "Ĉu vi certas, ke vi volas silentigi {name}?",
   "confirmations.unfollow.confirm": "Ne plu sekvi",
-  "confirmations.unfollow.message": "Ĉu vi volas ĉesi sekvi {name}?",
-  "embed.instructions": "Enmetu tiun statkonigon ĉe vian retejon kopiante la ĉi-suban kodon.",
+  "confirmations.unfollow.message": "Ĉu vi certas, ke vi volas ĉesi sekvi {name}?",
+  "embed.instructions": "Enkorpigu ĉi tiun mesaĝon en vian retejon per kopio de la suba kodo.",
   "embed.preview": "Ĝi aperos tiel:",
-  "emoji_button.activity": "Aktivecoj",
-  "emoji_button.custom": "Personaj",
+  "emoji_button.activity": "Agadoj",
+  "emoji_button.custom": "Propraj",
   "emoji_button.flags": "Flagoj",
   "emoji_button.food": "Manĝi kaj trinki",
-  "emoji_button.label": "Enmeti mieneton",
+  "emoji_button.label": "Enmeti emoĝion",
   "emoji_button.nature": "Naturo",
-  "emoji_button.not_found": "Neniuj mienetoj!! (╯°□°)╯︵ ┻━┻",
-  "emoji_button.objects": "Objektoj",
+  "emoji_button.not_found": "Neniu emoĝio!! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.objects": "Aĵoj",
   "emoji_button.people": "Homoj",
   "emoji_button.recent": "Ofte uzataj",
   "emoji_button.search": "Serĉo…",
-  "emoji_button.search_results": "Rezultatoj de serĉo",
+  "emoji_button.search_results": "Serĉaj rezultoj",
   "emoji_button.symbols": "Simboloj",
-  "emoji_button.travel": "Vojaĝoj & lokoj",
+  "emoji_button.travel": "Vojaĝoj kaj lokoj",
   "empty_column.community": "La loka tempolinio estas malplena. Skribu ion por plenigi ĝin!",
-  "empty_column.hashtag": "Ĝise, neniu enhavo estas asociita kun tiu kradvorto.",
+  "empty_column.hashtag": "Ankoraŭ estas nenio per ĉi tiu kradvorto.",
   "empty_column.home": "Via hejma tempolinio estas malplena! Vizitu {public} aŭ uzu la serĉilon por renkonti aliajn uzantojn.",
   "empty_column.home.public_timeline": "la publika tempolinio",
-  "empty_column.list": "Estas ankoraŭ nenio en ĉi tiu listo. Tuj kiam anoj de ĉi tiu listo publikigos, ties pepoj aperos ĉi tie.",
-  "empty_column.notifications": "Vi dume ne havas sciigojn. Interagi kun aliajn uzantojn por komenci la konversacion.",
-  "empty_column.public": "Estas nenio ĉi tie! Publike skribu ion, aŭ mane sekvu uzantojn de aliaj instancoj por plenigi la publikan tempolinion",
-  "follow_request.authorize": "Akcepti",
+  "empty_column.list": "Ankoraŭ estas nenio en ĉi tiu listo. Kiam membroj de ĉi tiu listo afiŝos novajn mesaĝojn, ili aperos ĉi tie.",
+  "empty_column.notifications": "Vi ankoraŭ ne havas sciigojn. Interagu kun aliaj por komenci konversacion.",
+  "empty_column.public": "Estas nenio ĉi tie! Publike skribu ion, aŭ mane sekvu uzantojn de aliaj nodoj por plenigi la publikan tempolinion",
+  "follow_request.authorize": "Rajtigi",
   "follow_request.reject": "Rifuzi",
   "getting_started.appsshort": "Aplikaĵoj",
   "getting_started.faq": "Oftaj demandoj",
   "getting_started.heading": "Por komenci",
-  "getting_started.open_source_notice": "Mastodono estas malfermkoda programo. Vi povas kontribui aŭ raporti problemojn en GitHub je {github}.",
+  "getting_started.open_source_notice": "Mastodon estas malfermitkoda programo. Vi povas kontribui aŭ raporti problemojn en GitHub je {github}.",
   "getting_started.userguide": "Gvidilo de uzo",
   "home.column_settings.advanced": "Precizaj agordoj",
   "home.column_settings.basic": "Bazaj agordoj",
-  "home.column_settings.filter_regex": "Forfiltri per regulesprimo",
+  "home.column_settings.filter_regex": "Filtri per regulesprimoj",
   "home.column_settings.show_reblogs": "Montri diskonigojn",
   "home.column_settings.show_replies": "Montri respondojn",
-  "home.settings": "Agordoj de la kolumno",
-  "keyboard_shortcuts.back": "reeniri",
-  "keyboard_shortcuts.boost": "diskonigi",
-  "keyboard_shortcuts.column": "fokusigi statuson en unu el la columnoj",
-  "keyboard_shortcuts.compose": "por fokusigi la redaktujon",
-  "keyboard_shortcuts.description": "Description",
-  "keyboard_shortcuts.down": "subenmovi en la listo",
-  "keyboard_shortcuts.enter": "to open status",
-  "keyboard_shortcuts.favourite": "ŝatitaren",
-  "keyboard_shortcuts.heading": "Keyboard Shortcuts",
+  "home.settings": "Kolumnaj agordoj",
+  "keyboard_shortcuts.back": "por reveni",
+  "keyboard_shortcuts.boost": "por diskonigi",
+  "keyboard_shortcuts.column": "por fokusigi mesaĝon en unu el la kolumnoj",
+  "keyboard_shortcuts.compose": "por fokusigi la tekstujon",
+  "keyboard_shortcuts.description": "Priskribo",
+  "keyboard_shortcuts.down": "por iri suben en la listo",
+  "keyboard_shortcuts.enter": "por malfermi mesaĝon",
+  "keyboard_shortcuts.favourite": "por stelumi",
+  "keyboard_shortcuts.heading": "Klavaraj mallongigoj",
   "keyboard_shortcuts.hotkey": "Rapidklavo",
-  "keyboard_shortcuts.legend": "por montri ĉi tiun legendon",
-  "keyboard_shortcuts.mention": "por sciigi ties aŭtoron",
+  "keyboard_shortcuts.legend": "por montri ĉi tiun noton",
+  "keyboard_shortcuts.mention": "por mencii la aŭtoron",
   "keyboard_shortcuts.reply": "por respondi",
-  "keyboard_shortcuts.search": "por fokusigi la serĉadon",
-  "keyboard_shortcuts.toot": "por ekredakti tute novan pepon",
-  "keyboard_shortcuts.unfocus": "por malfokusigi la redaktujon aŭ la serĉilon",
-  "keyboard_shortcuts.up": "por suprenmovi en la listo",
+  "keyboard_shortcuts.search": "por fokusigi la serĉilon",
+  "keyboard_shortcuts.toot": "por komenci tute novan mesaĝon",
+  "keyboard_shortcuts.unfocus": "por malfokusigi la tekstujon aŭ la serĉilon",
+  "keyboard_shortcuts.up": "por iri supren en la listo",
   "lightbox.close": "Fermi",
-  "lightbox.next": "Malantaŭa",
+  "lightbox.next": "Sekva",
   "lightbox.previous": "Antaŭa",
   "lists.account.add": "Aldoni al la listo",
-  "lists.account.remove": "Forviŝi de la listo",
-  "lists.delete": "Delete list",
+  "lists.account.remove": "Forigi de la listo",
+  "lists.delete": "Forigi la liston",
   "lists.edit": "Redakti la liston",
   "lists.new.create": "Aldoni liston",
-  "lists.new.title_placeholder": "Titulo de la nova listo",
-  "lists.search": "Serĉi el la homoj kiujn vi sekvas",
+  "lists.new.title_placeholder": "Titolo de la nova listo",
+  "lists.search": "Serĉi inter la homoj, kiujn vi sekvas",
   "lists.subheading": "Viaj listoj",
-  "loading_indicator.label": "Ŝarganta…",
-  "media_gallery.toggle_visible": "Baskuli videblecon",
+  "loading_indicator.label": "Ŝargado…",
+  "media_gallery.toggle_visible": "Baskuligi videblecon",
   "missing_indicator.label": "Ne trovita",
-  "missing_indicator.sublabel": "Ĉi tiu rimedo ne troviĝis",
-  "mute_modal.hide_notifications": "Ĉu kaŝi sciigojn el tiu ĉi uzanto?",
+  "missing_indicator.sublabel": "Ĉi tiu rimedo ne estis trovita",
+  "mute_modal.hide_notifications": "Ĉu kaŝi sciigojn el ĉi tiu uzanto?",
   "navigation_bar.blocks": "Blokitaj uzantoj",
   "navigation_bar.community_timeline": "Loka tempolinio",
-  "navigation_bar.edit_profile": "Redakti la profilon",
-  "navigation_bar.favourites": "Favoritaj",
-  "navigation_bar.follow_requests": "Abonpetoj",
-  "navigation_bar.info": "Plia informo",
-  "navigation_bar.keyboard_shortcuts": "Klavmallongigo",
+  "navigation_bar.edit_profile": "Redakti profilon",
+  "navigation_bar.favourites": "Stelumoj",
+  "navigation_bar.follow_requests": "Petoj de sekvado",
+  "navigation_bar.info": "Pri ĉiu tiu nodo",
+  "navigation_bar.keyboard_shortcuts": "Klavaraj mallongigoj",
   "navigation_bar.lists": "Listoj",
   "navigation_bar.logout": "Elsaluti",
   "navigation_bar.mutes": "Silentigitaj uzantoj",
-  "navigation_bar.pins": "Alpinglitaj pepoj",
+  "navigation_bar.pins": "Alpinglitaj mesaĝoj",
   "navigation_bar.preferences": "Preferoj",
   "navigation_bar.public_timeline": "Fratara tempolinio",
-  "notification.favourite": "{name} favoris vian mesaĝon",
-  "notification.follow": "{name} sekvis vin",
+  "notification.favourite": "{name} stelumis vian mesaĝon",
+  "notification.follow": "{name} eksekvis vin",
   "notification.mention": "{name} menciis vin",
   "notification.reblog": "{name} diskonigis vian mesaĝon",
-  "notifications.clear": "Forviŝi la sciigojn",
-  "notifications.clear_confirmation": "Ĉu vi certe volas malaperigi ĉiujn viajn sciigojn?",
-  "notifications.column_settings.alert": "Retumilaj atentigoj",
-  "notifications.column_settings.favourite": "Favoritoj:",
+  "notifications.clear": "Forviŝi sciigojn",
+  "notifications.clear_confirmation": "Ĉu vi certas, ke vi volas porĉiame forviŝi ĉiujn viajn sciigojn?",
+  "notifications.column_settings.alert": "Retumilaj sciigoj",
+  "notifications.column_settings.favourite": "Stelumoj:",
   "notifications.column_settings.follow": "Novaj sekvantoj:",
   "notifications.column_settings.mention": "Mencioj:",
   "notifications.column_settings.push": "Puŝsciigoj",
-  "notifications.column_settings.push_meta": "Tiu ĉi aparato",
+  "notifications.column_settings.push_meta": "Ĉi tiu aparato",
   "notifications.column_settings.reblog": "Diskonigoj:",
-  "notifications.column_settings.show": "Montri en kolono",
+  "notifications.column_settings.show": "Montri en kolumno",
   "notifications.column_settings.sound": "Eligi sonon",
   "onboarding.done": "Farita",
-  "onboarding.next": "Malantaŭa",
-  "onboarding.page_five.public_timelines": "La loka tempolinio enhavas mesaĝojn de ĉiuj ĉe {domain}. La federacia tempolinio enhavas ĉiujn mesaĝojn de uzantoj, kiujn iu ĉe {domain} sekvas. Ambaŭ tre utilas por trovi novajn kunparolantojn.",
-  "onboarding.page_four.home": "La hejma tempolinio enhavas la mesaĝojn de ĉiuj uzantoj, kiuj vi sekvas.",
-  "onboarding.page_four.notifications": "La sciiga kolumno informas vin kiam iu interagas kun vi.",
-  "onboarding.page_one.federation": "Mastodono estas reto de nedependaj serviloj, unuiĝintaj por krei pligrandan socian retejon. Ni nomas tiujn servilojn instancoj.",
-  "onboarding.page_one.full_handle": "Via tuta uzantnomo",
-  "onboarding.page_one.handle_hint": "Jen kion vi dirintus al viaj amikoj por serĉi.",
-  "onboarding.page_one.welcome": "Bonvenon al Mastodono!",
-  "onboarding.page_six.admin": "Via instancestro estas {admin}.",
-  "onboarding.page_six.almost_done": "Estas preskaŭ finita…",
-  "onboarding.page_six.appetoot": "Bonan a‘pepi’ton!",
-  "onboarding.page_six.apps_available": "{apps} estas elŝuteblaj por iOS, Androido kaj alioj.",
-  "onboarding.page_six.github": "Mastodono estas libera, senpaga kaj malfermkoda programaro. Vi povas signali cimojn, proponi funkciojn aŭ kontribui al gîa kreskado ĉe {github}.",
-  "onboarding.page_six.guidelines": "komunreguloj",
-  "onboarding.page_six.read_guidelines": "Ni petas vin: ne forgesu legi la {guidelines}n de {domain}!",
-  "onboarding.page_six.various_app": "telefon-aplikaĵoj",
-  "onboarding.page_three.profile": "Redaktu vian profilon por ŝanĝi vian avataron, priskribon kaj vian nomon. Vi tie trovos ankoraŭ aliajn agordojn.",
-  "onboarding.page_three.search": "Uzu la serĉokampo por trovi uzantojn kaj esplori kradvortojn tiel ke {illustration} kaj {introductions}. Por trovi iun, kiu ne estas ĉe ĉi tiu instanco, uzu ĝian kompletan uznomon.",
-  "onboarding.page_two.compose": "Skribu pepojn en la verkkolumno. Vi povas aldoni bildojn, ŝanĝi la agordojn de privateco kaj aldoni tiklavertojn (« content warning ») dank' al la piktogramoj malsupre.",
-  "onboarding.skip": "Pasigi",
-  "privacy.change": "Alĝustigi la privateco de la mesaĝo",
-  "privacy.direct.long": "Vidigi nur al la menciitaj personoj",
+  "onboarding.next": "Sekva",
+  "onboarding.page_five.public_timelines": "La loka tempolinio montras publikajn mesaĝojn de ĉiuj en {domain}. La fratara tempolinio montras publikajn mesaĝojn de ĉiuj, kiuj estas sekvataj de homoj en {domain}. Tio estas la publikaj tempolinioj, kio estas bona maniero por malkovri novajn homojn.",
+  "onboarding.page_four.home": "La hejma tempolinio montras mesaĝojn de ĉiuj uzantoj, kiujn vi sekvas.",
+  "onboarding.page_four.notifications": "La sciiga kolumno montras kiam iu interagas kun vi.",
+  "onboarding.page_one.federation": "Mastodon estas reto de sendependaj serviloj, unuiĝintaj por krei pligrandan socian reton. Ni nomas tiujn servilojn nodoj.",
+  "onboarding.page_one.full_handle": "Via kompleta uzantnomo",
+  "onboarding.page_one.handle_hint": "Jen kion vi petus al viaj amikoj serĉi.",
+  "onboarding.page_one.welcome": "Bonvenon en Mastodon!",
+  "onboarding.page_six.admin": "Via noda administranto estas {admin}.",
+  "onboarding.page_six.almost_done": "Preskaŭ finita…",
+  "onboarding.page_six.appetoot": "Saĝan mesaĝadon!",
+  "onboarding.page_six.apps_available": "{apps} estas disponeblaj por iOS, Android kaj aliaj platformoj.",
+  "onboarding.page_six.github": "Mastodon estas libera, senpaga kaj malfermitkoda programo. Vi povas raporti cimojn, proponi funkciojn aŭ kontribui al la kodo en {github}.",
+  "onboarding.page_six.guidelines": "komunumaj gvidlinioj",
+  "onboarding.page_six.read_guidelines": "Bonvolu atenti pri la {guidelines} de {domain}!",
+  "onboarding.page_six.various_app": "telefonaj aplikaĵoj",
+  "onboarding.page_three.profile": "Redaktu vian profilon por ŝanĝi vian profilbildon, priskribon kaj nomon. Vi ankaŭ trovos tie aliajn agordojn.",
+  "onboarding.page_three.search": "Uzu la serĉilon por trovi uzantojn kaj esplori kradvortojn, tiel {illustration} kaj {introductions}. Por trovi iun, kiu ne estas en ĉi tiu nodo, uzu ties kompletan uzantnomon.",
+  "onboarding.page_two.compose": "Skribu mesaĝojn en la skriba kolumno. Vi povas alŝuti bildojn, ŝanĝi privatecajn agordojn, kaj aldoni avertojn pri la enhavo per la subaj bildetoj.",
+  "onboarding.skip": "Preterpasi",
+  "privacy.change": "Agordi mesaĝan privatecon",
+  "privacy.direct.long": "Afiŝi nur al menciitaj uzantoj",
   "privacy.direct.short": "Rekta",
-  "privacy.private.long": "Vidigi nur al viaj sekvantoj",
-  "privacy.private.short": "Nursekvanta",
-  "privacy.public.long": "Vidigi en publikaj tempolinioj",
+  "privacy.private.long": "Afiŝi nur al sekvantoj",
+  "privacy.private.short": "Nur por sekvantoj",
+  "privacy.public.long": "Afiŝi en publikaj tempolinioj",
   "privacy.public.short": "Publika",
-  "privacy.unlisted.long": "Ne vidigi en publikaj tempolinioj",
+  "privacy.unlisted.long": "Ne afiŝi en publikaj tempolinioj",
   "privacy.unlisted.short": "Nelistigita",
-  "regeneration_indicator.label": "Elŝultanta…",
-  "regeneration_indicator.sublabel": "Via ĉefpaĝo estas preparanta!",
+  "regeneration_indicator.label": "Ŝargado…",
+  "regeneration_indicator.sublabel": "Via hejma fluo pretiĝas!",
   "relative_time.days": "{number}t",
   "relative_time.hours": "{number}h",
   "relative_time.just_now": "nun",
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
-  "reply_indicator.cancel": "Malfari",
+  "reply_indicator.cancel": "Nuligi",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Pliaj komentoj",
   "report.submit": "Sendi",
-  "report.target": "Signalaĵo",
+  "report.target": "Signali {target}",
   "search.placeholder": "Serĉi",
   "search_popout.search_format": "Detala serĉo",
   "search_popout.tips.hashtag": "kradvorto",
-  "search_popout.tips.status": "statkonigo",
-  "search_popout.tips.text": "Simpla teksto eligas la kongruajn afiŝnomojn, uznomojn kaj kradvortojn",
+  "search_popout.tips.status": "mesaĝoj",
+  "search_popout.tips.text": "Simpla teksto montras la kongruajn afiŝitajn nomojn, uzantnomojn kaj kradvortojn",
   "search_popout.tips.user": "uzanto",
-  "search_results.total": "{count, number} {count, plural, one {rezultato} other {rezultatoj}}",
-  "standalone.public_title": "Rigardeti…",
-  "status.block": "Block @{name}",
-  "status.cannot_reblog": "Tiun publikaĵon oni ne povas diskonigi",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
+  "search_results.total": "{count, number} {count, plural, one {rezulto} other {rezultoj}}",
+  "standalone.public_title": "Enrigardo…",
+  "status.block": "Bloki @{name}",
+  "status.cannot_reblog": "Ĉi tiu mesaĝo ne diskonigeblas",
   "status.delete": "Forigi",
-  "status.embed": "Enmeti",
-  "status.favourite": "Favori",
-  "status.load_more": "Ŝargi plie",
-  "status.media_hidden": "Sonbildaĵo kaŝita",
+  "status.embed": "Enkorpigi",
+  "status.favourite": "Stelumi",
+  "status.load_more": "Ŝargi pli",
+  "status.media_hidden": "Aŭdovidaĵo kaŝita",
   "status.mention": "Mencii @{name}",
   "status.more": "Pli",
   "status.mute": "Silentigi @{name}",
   "status.mute_conversation": "Silentigi konversacion",
-  "status.open": "Disfaldi statkonigon",
-  "status.pin": "Pingli al la profilo",
+  "status.open": "Grandigi ĉi tiun mesaĝon",
+  "status.pin": "Alpingli en la profilo",
   "status.reblog": "Diskonigi",
   "status.reblogged_by": "{name} diskonigis",
   "status.reply": "Respondi",
@@ -239,28 +246,29 @@
   "status.sensitive_toggle": "Alklaki por vidi",
   "status.sensitive_warning": "Tikla enhavo",
   "status.share": "Diskonigi",
-  "status.show_less": "Refaldi",
-  "status.show_more": "Disfaldi",
+  "status.show_less": "Malgrandigi",
+  "status.show_more": "Grandigi",
   "status.unmute_conversation": "Malsilentigi konversacion",
   "status.unpin": "Depingli de profilo",
   "tabs_bar.compose": "Ekskribi",
-  "tabs_bar.federated_timeline": "Federacia tempolinio",
+  "tabs_bar.federated_timeline": "Fratara tempolinio",
   "tabs_bar.home": "Hejmo",
   "tabs_bar.local_timeline": "Loka tempolinio",
   "tabs_bar.notifications": "Sciigoj",
   "ui.beforeunload": "Via malneto perdiĝos se vi eliras de Mastodon.",
-  "upload_area.title": "Algliti por alŝuti",
-  "upload_button.label": "Aldoni sonbildaĵon",
-  "upload_form.description": "Priskribi por la misvidantaj",
+  "upload_area.title": "Altreni kaj lasi por alŝuti",
+  "upload_button.label": "Aldoni aŭdovidaĵon",
+  "upload_form.description": "Priskribi por misvidantaj homoj",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Malfari",
-  "upload_progress.label": "Alŝutanta…",
+  "upload_progress.label": "Alŝutado…",
   "video.close": "Fermi videon",
-  "video.exit_fullscreen": "Eliri el plenekrano",
-  "video.expand": "Vastigi videon",
-  "video.fullscreen": "Igi plenekrane",
+  "video.exit_fullscreen": "Eksigi plenekrana",
+  "video.expand": "Grandigi videon",
+  "video.fullscreen": "Igi plenekrana",
   "video.hide": "Kaŝi videon",
   "video.mute": "Silentigi",
   "video.pause": "Paŭzi",
-  "video.play": "Legi",
+  "video.play": "Ekigi",
   "video.unmute": "Malsilentigi"
 }
diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json
index 4bb15396c..5f16ec974 100644
--- a/app/javascript/mastodon/locales/es.json
+++ b/app/javascript/mastodon/locales/es.json
@@ -14,6 +14,7 @@
   "account.mute": "Silenciar a @{name}",
   "account.mute_notifications": "Silenciar notificaciones de @{name}",
   "account.posts": "Publicaciones",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Reportar a @{name}",
   "account.requested": "Esperando aprobación",
   "account.share": "Compartir el perfil de @{name}",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Cancelar",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Comentarios adicionales",
   "report.submit": "Publicar",
   "report.target": "Reportando",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "El texto simple devuelve correspondencias de nombre, usuario y hashtag",
   "search_popout.tips.user": "usuario",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {resultado} other {resultados}}",
   "standalone.public_title": "Un pequeño vistazo...",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "Arrastra y suelta para subir",
   "upload_button.label": "Subir multimedia",
   "upload_form.description": "Describir para los usuarios con dificultad visual",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Deshacer",
   "upload_progress.label": "Subiendo…",
   "video.close": "Cerrar video",
diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json
index 6846da66d..4fd467a66 100644
--- a/app/javascript/mastodon/locales/fa.json
+++ b/app/javascript/mastodon/locales/fa.json
@@ -14,6 +14,7 @@
   "account.mute": "بی‌صدا کردن @{name}",
   "account.mute_notifications": "بی‌صداکردن اعلان‌ها از طرف @{name}",
   "account.posts": "نوشته‌ها",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "گزارش @{name}",
   "account.requested": "در انتظار پذیرش",
   "account.share": "هم‌رسانی نمایهٔ @{name}",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "لغو",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "توضیح اضافه",
   "report.submit": "بفرست",
   "report.target": "گزارش‌دادن",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "نوشته",
   "search_popout.tips.text": "جستجوی متنی ساده برای نام‌ها، نام‌های کاربری، و هشتگ‌ها",
   "search_popout.tips.user": "کاربر",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {نتیجه} other {نتیجه}}",
   "standalone.public_title": "نگاهی به کاربران این سرور...",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "برای بارگذاری به این‌جا بکشید",
   "upload_button.label": "افزودن تصویر",
   "upload_form.description": "نوشتهٔ توضیحی برای کم‌بینایان و نابینایان",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "واگردانی",
   "upload_progress.label": "بارگذاری...",
   "video.close": "بستن ویدیو",
diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json
index eb81e7eb4..d27ba1834 100644
--- a/app/javascript/mastodon/locales/fi.json
+++ b/app/javascript/mastodon/locales/fi.json
@@ -1,266 +1,274 @@
 {
   "account.block": "Estä @{name}",
-  "account.block_domain": "Hide everything from {domain}",
-  "account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
+  "account.block_domain": "Piilota kaikki sisältö verkkotunnuksesta {domain}",
+  "account.disclaimer_full": "Alla olevat käyttäjän profiilitiedot saattavat olla epätäydellisiä.",
   "account.edit_profile": "Muokkaa",
   "account.follow": "Seuraa",
   "account.followers": "Seuraajia",
   "account.follows": "Seuraa",
   "account.follows_you": "Seuraa sinua",
-  "account.hide_reblogs": "Hide boosts from @{name}",
+  "account.hide_reblogs": "Piilota buustaukset käyttäjältä @{name}",
   "account.media": "Media",
   "account.mention": "Mainitse @{name}",
-  "account.moved_to": "{name} has moved to:",
-  "account.mute": "Mute @{name}",
-  "account.mute_notifications": "Mute notifications from @{name}",
-  "account.posts": "Postit",
+  "account.moved_to": "{name} on muuttanut instanssiin:",
+  "account.mute": "Mykistä @{name}",
+  "account.mute_notifications": "Mykistä ilmoitukset käyttäjältä @{name}",
+  "account.posts": "Töötit",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Report @{name}",
-  "account.requested": "Odottaa hyväksyntää",
-  "account.share": "Share @{name}'s profile",
-  "account.show_reblogs": "Show boosts from @{name}",
+  "account.requested": "Odottaa hyväksyntää. Klikkaa peruuttaaksesi seurauspyynnön",
+  "account.share": "Jaa käyttäjän @{name} profiili",
+  "account.show_reblogs": "Näytä boostaukset käyttäjältä @{name}",
   "account.unblock": "Salli @{name}",
-  "account.unblock_domain": "Unhide {domain}",
-  "account.unfollow": "Lopeta seuraaminen",
-  "account.unmute": "Unmute @{name}",
-  "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account.view_full_profile": "View full profile",
-  "boost_modal.combo": "You can press {combo} to skip this next time",
-  "bundle_column_error.body": "Something went wrong while loading this component.",
-  "bundle_column_error.retry": "Try again",
+  "account.unblock_domain": "Näytä {domain}",
+  "account.unfollow": "Lakkaa seuraamasta",
+  "account.unmute": "Poista mykistys käyttäjältä @{name}",
+  "account.unmute_notifications": "Poista mykistys käyttäjän @{name} ilmoituksilta",
+  "account.view_full_profile": "Näytä koko profiili",
+  "boost_modal.combo": "Voit painaa näppäimiä {combo} ohittaaksesi tämän ensi kerralla",
+  "bundle_column_error.body": "Jokin meni vikaan tätä komponenttia ladatessa.",
+  "bundle_column_error.retry": "Yritä uudestaan",
   "bundle_column_error.title": "Network error",
-  "bundle_modal_error.close": "Close",
-  "bundle_modal_error.message": "Something went wrong while loading this component.",
-  "bundle_modal_error.retry": "Try again",
-  "column.blocks": "Blocked users",
+  "bundle_modal_error.close": "Sulje",
+  "bundle_modal_error.message": "Jokin meni vikaan tätä komponenttia ladatessa.",
+  "bundle_modal_error.retry": "Yritä uudestaan",
+  "column.blocks": "Estetyt käyttäjät",
   "column.community": "Paikallinen aikajana",
-  "column.favourites": "Favourites",
-  "column.follow_requests": "Follow requests",
+  "column.favourites": "Suosikit",
+  "column.follow_requests": "Seurauspyynnöt",
   "column.home": "Koti",
-  "column.lists": "Lists",
-  "column.mutes": "Muted users",
+  "column.lists": "Listat",
+  "column.mutes": "Mykistetyt käyttäjät",
   "column.notifications": "Ilmoitukset",
   "column.pins": "Pinned toot",
   "column.public": "Yleinen aikajana",
   "column_back_button.label": "Takaisin",
-  "column_header.hide_settings": "Hide settings",
-  "column_header.moveLeft_settings": "Move column to the left",
-  "column_header.moveRight_settings": "Move column to the right",
-  "column_header.pin": "Pin",
-  "column_header.show_settings": "Show settings",
-  "column_header.unpin": "Unpin",
-  "column_subheading.navigation": "Navigation",
-  "column_subheading.settings": "Settings",
-  "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
-  "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
-  "compose_form.lock_disclaimer.lock": "locked",
+  "column_header.hide_settings": "Piilota asetukset",
+  "column_header.moveLeft_settings": "Siirrä saraketta vasemmalle",
+  "column_header.moveRight_settings": "Siirrä saraketta oikealle",
+  "column_header.pin": "Kiinnitä",
+  "column_header.show_settings": "Näytä asetukset",
+  "column_header.unpin": "Poista kiinnitys",
+  "column_subheading.navigation": "Navigaatio",
+  "column_subheading.settings": "Asetukset",
+  "compose_form.hashtag_warning": "Tämä töötti ei tule näkymään hashtag-hauissa, koska se ei näy julkisilla aikajanoilla. Vain julkisia tööttejä voi hakea hashtageilla.",
+  "compose_form.lock_disclaimer": "Tilisi ei ole {locked}. Kuka tahansa voi seurata tiliäsi ja nähdä vain seuraajille -postauksesi.",
+  "compose_form.lock_disclaimer.lock": "lukittu",
   "compose_form.placeholder": "Mitä sinulla on mielessä?",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
   "compose_form.sensitive": "Merkitse media herkäksi",
   "compose_form.spoiler": "Piiloita teksti varoituksen taakse",
   "compose_form.spoiler_placeholder": "Content warning",
-  "confirmation_modal.cancel": "Cancel",
-  "confirmations.block.confirm": "Block",
-  "confirmations.block.message": "Are you sure you want to block {name}?",
+  "confirmation_modal.cancel": "Peruuta",
+  "confirmations.block.confirm": "Estä",
+  "confirmations.block.message": "Oletko varma, että haluat estää käyttäjän {name}?",
   "confirmations.delete.confirm": "Delete",
-  "confirmations.delete.message": "Are you sure you want to delete this status?",
+  "confirmations.delete.message": "Oletko varma, että haluat poistaa tämän statuspäivityksen?",
   "confirmations.delete_list.confirm": "Delete",
-  "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
-  "confirmations.domain_block.confirm": "Hide entire domain",
-  "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
-  "confirmations.mute.confirm": "Mute",
-  "confirmations.mute.message": "Are you sure you want to mute {name}?",
-  "confirmations.unfollow.confirm": "Unfollow",
-  "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
-  "embed.instructions": "Embed this status on your website by copying the code below.",
-  "embed.preview": "Here is what it will look like:",
-  "emoji_button.activity": "Activity",
-  "emoji_button.custom": "Custom",
-  "emoji_button.flags": "Flags",
-  "emoji_button.food": "Food & Drink",
-  "emoji_button.label": "Insert emoji",
-  "emoji_button.nature": "Nature",
-  "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻",
-  "emoji_button.objects": "Objects",
-  "emoji_button.people": "People",
-  "emoji_button.recent": "Frequently used",
-  "emoji_button.search": "Search...",
-  "emoji_button.search_results": "Search results",
-  "emoji_button.symbols": "Symbols",
-  "emoji_button.travel": "Travel & Places",
-  "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
-  "empty_column.hashtag": "There is nothing in this hashtag yet.",
-  "empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.",
-  "empty_column.home.public_timeline": "the public timeline",
-  "empty_column.list": "There is nothing in this list yet.",
-  "empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
-  "empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up",
-  "follow_request.authorize": "Authorize",
-  "follow_request.reject": "Reject",
-  "getting_started.appsshort": "Apps",
+  "confirmations.delete_list.message": "Oletko varma, että haluat poistaa tämän listan pysyvästi?",
+  "confirmations.domain_block.confirm": "Piilota koko verkko-osoite",
+  "confirmations.domain_block.message": "Oletko aivan oikeasti varma että haluat estää koko verkko-osoitteen {domain}? Useimmissa tapauksissa muutamat kohdistetut estot ja mykistykset ovat riittäviä ja suositeltavampia.",
+  "confirmations.mute.confirm": "Mykistä",
+  "confirmations.mute.message": "Oletko varma että haluat mykistää käyttäjän {name}?",
+  "confirmations.unfollow.confirm": "Lakkaa seuraamasta",
+  "confirmations.unfollow.message": "Oletko varma, että haluat lakata seuraamasta käyttäjää {name}?",
+  "embed.instructions": "Upota tämä statuspäivitys sivullesi kopioimalla alla oleva koodi.",
+  "embed.preview": "Tältä se tulee näyttämään:",
+  "emoji_button.activity": "Aktiviteetit",
+  "emoji_button.custom": "Mukautetut",
+  "emoji_button.flags": "Liput",
+  "emoji_button.food": "Ruoka ja juoma",
+  "emoji_button.label": "Lisää emoji",
+  "emoji_button.nature": "Luonto",
+  "emoji_button.not_found": "Ei emojeja!! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.objects": "Objektit",
+  "emoji_button.people": "Ihmiset",
+  "emoji_button.recent": "Usein käytetyt",
+  "emoji_button.search": "Etsi...",
+  "emoji_button.search_results": "Hakutulokset",
+  "emoji_button.symbols": "Symbolit",
+  "emoji_button.travel": "Matkailu",
+  "empty_column.community": "Paikallinen aikajana on tyhjä. Kirjoita jotain julkista saadaksesi pyörät pyörimään!",
+  "empty_column.hashtag": "Tässä hashtagissa ei ole vielä mitään.",
+  "empty_column.home": "Kotiaikajanasi on tyhjä! Käy vierailemassa {public}ssa tai käytä hakutoimintoa aloittaaksesi ja tavataksesi muita käyttäjiä.",
+  "empty_column.home.public_timeline": "yleinen aikajana",
+  "empty_column.list": "Tämä lista on vielä tyhjä. Kun listan jäsenet julkaisevat statuspäivityksiä, ne näkyvät tässä.",
+  "empty_column.notifications": "Sinulle ei ole vielä ilmoituksia. Juttele muille aloittaaksesi keskustelun.",
+  "empty_column.public": "Täällä ei ole mitään! Kirjoita jotain julkisesti, tai käy manuaalisesti seuraamassa käyttäjiä muista instansseista saadaksesi sisältöä",
+  "follow_request.authorize": "Valtuuta",
+  "follow_request.reject": "Hylkää",
+  "getting_started.appsshort": "Sovellukset",
   "getting_started.faq": "FAQ",
   "getting_started.heading": "Aloitus",
-  "getting_started.open_source_notice": "Mastodon Mastodon on avoimen lähdekoodin ohjelma. Voit avustaa tai raportoida ongelmia GitHub palvelussa {github}.",
-  "getting_started.userguide": "User Guide",
-  "home.column_settings.advanced": "Advanced",
-  "home.column_settings.basic": "Basic",
-  "home.column_settings.filter_regex": "Filter out by regular expressions",
-  "home.column_settings.show_reblogs": "Show boosts",
-  "home.column_settings.show_replies": "Show replies",
-  "home.settings": "Column settings",
-  "keyboard_shortcuts.back": "to navigate back",
-  "keyboard_shortcuts.boost": "to boost",
-  "keyboard_shortcuts.column": "to focus a status in one of the columns",
-  "keyboard_shortcuts.compose": "to focus the compose textarea",
+  "getting_started.open_source_notice": "Mastodon on avoimen lähdekoodin ohjelma. Voit avustaa tai raportoida ongelmia GitHub palvelussa {github}.",
+  "getting_started.userguide": "Käyttöopas",
+  "home.column_settings.advanced": "Tarkemmat asetukset",
+  "home.column_settings.basic": "Perusasetukset",
+  "home.column_settings.filter_regex": "Suodata säännöllisten lauseiden avulla",
+  "home.column_settings.show_reblogs": "Näytä buustaukset",
+  "home.column_settings.show_replies": "Näytä vastaukset",
+  "home.settings": "Sarakeasetukset",
+  "keyboard_shortcuts.back": "liikkuaksesi taaksepäin",
+  "keyboard_shortcuts.boost": "buustataksesi",
+  "keyboard_shortcuts.column": "keskittääksesi statuspäivitykseen yhdessä sarakkeista",
+  "keyboard_shortcuts.compose": "aktivoidaksesi tekstinkirjoitusalueen",
   "keyboard_shortcuts.description": "Description",
-  "keyboard_shortcuts.down": "to move down in the list",
+  "keyboard_shortcuts.down": "liikkuaksesi listassa alaspäin",
   "keyboard_shortcuts.enter": "to open status",
-  "keyboard_shortcuts.favourite": "to favourite",
-  "keyboard_shortcuts.heading": "Keyboard Shortcuts",
-  "keyboard_shortcuts.hotkey": "Hotkey",
-  "keyboard_shortcuts.legend": "to display this legend",
-  "keyboard_shortcuts.mention": "to mention author",
-  "keyboard_shortcuts.reply": "to reply",
-  "keyboard_shortcuts.search": "to focus search",
-  "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",
+  "keyboard_shortcuts.favourite": "tykätäksesi",
+  "keyboard_shortcuts.heading": "Näppäinoikotiet",
+  "keyboard_shortcuts.hotkey": "Pikanäppäin",
+  "keyboard_shortcuts.legend": "näyttääksesi tämän selitteen",
+  "keyboard_shortcuts.mention": "mainitaksesi julkaisijan",
+  "keyboard_shortcuts.reply": "vastataksesi",
+  "keyboard_shortcuts.search": "aktivoidaksesi hakukentän",
+  "keyboard_shortcuts.toot": "aloittaaksesi uuden töötin kirjoittamisen",
+  "keyboard_shortcuts.unfocus": "poistaaksesi aktivoinnin tekstikentästä/hakukentästä",
+  "keyboard_shortcuts.up": "liikkuaksesi listassa ylöspäin",
   "lightbox.close": "Sulje",
-  "lightbox.next": "Next",
-  "lightbox.previous": "Previous",
-  "lists.account.add": "Add to list",
-  "lists.account.remove": "Remove from list",
+  "lightbox.next": "Seuraava",
+  "lightbox.previous": "Edellinen",
+  "lists.account.add": "Lisää listaan",
+  "lists.account.remove": "Poista listalta",
   "lists.delete": "Delete list",
-  "lists.edit": "Edit list",
-  "lists.new.create": "Add list",
-  "lists.new.title_placeholder": "New list title",
-  "lists.search": "Search among people you follow",
-  "lists.subheading": "Your lists",
+  "lists.edit": "Muokkaa listaa",
+  "lists.new.create": "Lisää lista",
+  "lists.new.title_placeholder": "Uuden listan otsikko",
+  "lists.search": "Etsi seuraamiesi henkilöiden joukosta",
+  "lists.subheading": "Omat listat",
   "loading_indicator.label": "Ladataan...",
-  "media_gallery.toggle_visible": "Toggle visibility",
-  "missing_indicator.label": "Not found",
-  "missing_indicator.sublabel": "This resource could not be found",
-  "mute_modal.hide_notifications": "Hide notifications from this user?",
-  "navigation_bar.blocks": "Blocked users",
+  "media_gallery.toggle_visible": "Säädä näkyvyyttä",
+  "missing_indicator.label": "Ei löydetty",
+  "missing_indicator.sublabel": "Tätä resurssia ei löytynyt",
+  "mute_modal.hide_notifications": "Piilota ilmoitukset tältä käyttäjältä?",
+  "navigation_bar.blocks": "Estetyt käyttäjät",
   "navigation_bar.community_timeline": "Paikallinen aikajana",
   "navigation_bar.edit_profile": "Muokkaa profiilia",
-  "navigation_bar.favourites": "Favourites",
-  "navigation_bar.follow_requests": "Follow requests",
-  "navigation_bar.info": "Extended information",
-  "navigation_bar.keyboard_shortcuts": "Keyboard shortcuts",
-  "navigation_bar.lists": "Lists",
+  "navigation_bar.favourites": "Suosikit",
+  "navigation_bar.follow_requests": "Seurauspyynnöt",
+  "navigation_bar.info": "Tietoa tästä instanssista",
+  "navigation_bar.keyboard_shortcuts": "Näppäinoikotiet",
+  "navigation_bar.lists": "Listat",
   "navigation_bar.logout": "Kirjaudu ulos",
-  "navigation_bar.mutes": "Muted users",
-  "navigation_bar.pins": "Pinned toots",
+  "navigation_bar.mutes": "Mykistetyt käyttäjät",
+  "navigation_bar.pins": "Kiinnitetyt töötit",
   "navigation_bar.preferences": "Ominaisuudet",
   "navigation_bar.public_timeline": "Yleinen aikajana",
   "notification.favourite": "{name} tykkäsi statuksestasi",
   "notification.follow": "{name} seurasi sinua",
   "notification.mention": "{name} mainitsi sinut",
   "notification.reblog": "{name} buustasi statustasi",
-  "notifications.clear": "Clear notifications",
-  "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
+  "notifications.clear": "Tyhjennä ilmoitukset",
+  "notifications.clear_confirmation": "Oletko varma, että haluat lopullisesti tyhjentää kaikki ilmoituksesi?",
   "notifications.column_settings.alert": "Työpöytä ilmoitukset",
   "notifications.column_settings.favourite": "Tykkäyksiä:",
   "notifications.column_settings.follow": "Uusia seuraajia:",
   "notifications.column_settings.mention": "Mainintoja:",
-  "notifications.column_settings.push": "Push notifications",
-  "notifications.column_settings.push_meta": "This device",
+  "notifications.column_settings.push": "Push-ilmoitukset",
+  "notifications.column_settings.push_meta": "Tämä laite",
   "notifications.column_settings.reblog": "Buusteja:",
   "notifications.column_settings.show": "Näytä sarakkeessa",
-  "notifications.column_settings.sound": "Play sound",
-  "onboarding.done": "Done",
-  "onboarding.next": "Next",
-  "onboarding.page_five.public_timelines": "The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.",
-  "onboarding.page_four.home": "The home timeline shows posts from people you follow.",
-  "onboarding.page_four.notifications": "The notifications column shows when someone interacts with you.",
-  "onboarding.page_one.federation": "Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
-  "onboarding.page_one.full_handle": "Your full handle",
+  "notifications.column_settings.sound": "Soita ääni",
+  "onboarding.done": "Valmis",
+  "onboarding.next": "Seuraava",
+  "onboarding.page_five.public_timelines": "Paikallinen aikajana näyttää kaikki julkiset julkaisut kaikilta, jotka ovat verkko-osoitteessa {domain}. Yleinen aikajana näyttää julkiset julkaisut kaikilta niiltä, joita käyttäjät verkko-osoitteessa {domain} seuraavat. Nämä ovat julkiset aikajanat, ja ne ovat hyviä tapoja löytää uusia ihmisiä.",
+  "onboarding.page_four.home": "Kotiaikajana näyttää julkaisut ihmisiltä joita seuraat.",
+  "onboarding.page_four.notifications": "Ilmoitukset-sarake näyttää sinulle, kun joku on viestii kanssasi.",
+  "onboarding.page_one.federation": "Mastodon on yhteisöpalvelu, joka toimii monen itsenäisen palvelimen muodostamassa verkossa. Me kutsumme näitä palvelimia instansseiksi.",
+  "onboarding.page_one.full_handle": "Koko käyttäjänimesi",
   "onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.",
-  "onboarding.page_one.welcome": "Welcome to Mastodon!",
-  "onboarding.page_six.admin": "Your instance's admin is {admin}.",
-  "onboarding.page_six.almost_done": "Almost done...",
-  "onboarding.page_six.appetoot": "Bon Appetoot!",
-  "onboarding.page_six.apps_available": "There are {apps} available for iOS, Android and other platforms.",
+  "onboarding.page_one.welcome": "Tervetuloa Mastodoniin!",
+  "onboarding.page_six.admin": "Instanssisi ylläpitäjä on {admin}.",
+  "onboarding.page_six.almost_done": "Melkein valmista...",
+  "onboarding.page_six.appetoot": "Bon Appetööt!",
+  "onboarding.page_six.apps_available": "{apps} on saatavilla iOS:lle, Androidille ja muille alustoille.",
   "onboarding.page_six.github": "Mastodon is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
-  "onboarding.page_six.guidelines": "community guidelines",
-  "onboarding.page_six.read_guidelines": "Please read {domain}'s {guidelines}!",
-  "onboarding.page_six.various_app": "mobile apps",
-  "onboarding.page_three.profile": "Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.",
-  "onboarding.page_three.search": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.",
-  "onboarding.page_two.compose": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.",
-  "onboarding.skip": "Skip",
-  "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.public.long": "Post to public timelines",
-  "privacy.public.short": "Public",
-  "privacy.unlisted.long": "Do not show in public timelines",
-  "privacy.unlisted.short": "Unlisted",
-  "regeneration_indicator.label": "Loading…",
-  "regeneration_indicator.sublabel": "Your home feed is being prepared!",
+  "onboarding.page_six.guidelines": "yhteisön säännöt",
+  "onboarding.page_six.read_guidelines": "Ole hyvä ja lue {domain}:n {guidelines}!",
+  "onboarding.page_six.various_app": "mobiilisovellukset",
+  "onboarding.page_three.profile": "Muokkaa profiiliasi muuttaaksesi kuvakettasi, esittelyäsi ja nimimerkkiäsi. Löydät sieltä myös muita henkilökohtaisia asetuksia.",
+  "onboarding.page_three.search": "Käytä hakukenttää löytääksesi ihmisiä ja etsiäksesi hashtageja, kuten {illustration} tai {introductions}. Hakeaksesi henkilöä joka on toisessa instanssissa, käytä hänen käyttäjänimeään kokonaisuudessaan.",
+  "onboarding.page_two.compose": "Kirjoita postauksia kirjoita-sarakkeessa. Voit ladata kuvia, vaihtaa yksityisyysasetuksia ja lisätä sisältövaroituksia alla olevista painikkeista.",
+  "onboarding.skip": "Ohita",
+  "privacy.change": "Säädä töötin yksityisyysasetuksia",
+  "privacy.direct.long": "Julkaise vain mainituille käyttäjille",
+  "privacy.direct.short": "Yksityisviesti",
+  "privacy.private.long": "Julkaise vain seuraajille",
+  "privacy.private.short": "Vain seuraajat",
+  "privacy.public.long": "Julkaise julkisille aikajanoille",
+  "privacy.public.short": "Julkinen",
+  "privacy.unlisted.long": "Älä julkaise yleisillä aikajanoilla",
+  "privacy.unlisted.short": "Julkinen, mutta älä näytä julkisella aikajanalla",
+  "regeneration_indicator.label": "Ladataan…",
+  "regeneration_indicator.sublabel": "Kotinäkymääsi valmistellaan!",
   "relative_time.days": "{number}d",
   "relative_time.hours": "{number}h",
-  "relative_time.just_now": "now",
+  "relative_time.just_now": "nyt",
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Peruuta",
-  "report.placeholder": "Additional comments",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
+  "report.placeholder": "Lisäkommentit",
   "report.submit": "Submit",
   "report.target": "Reporting",
   "search.placeholder": "Hae",
-  "search_popout.search_format": "Advanced search format",
-  "search_popout.tips.hashtag": "hashtag",
+  "search_popout.search_format": "Tarkennettu haku",
+  "search_popout.tips.hashtag": "hashtagi",
   "search_popout.tips.status": "status",
-  "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
-  "search_popout.tips.user": "user",
+  "search_popout.tips.text": "Pelkkä tekstihaku palauttaa hakua vastaavat nimimerkit, käyttäjänimet ja hastagit",
+  "search_popout.tips.user": "käyttäjä",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
-  "standalone.public_title": "A look inside...",
+  "standalone.public_title": "Kurkistus sisälle...",
   "status.block": "Block @{name}",
-  "status.cannot_reblog": "This post cannot be boosted",
+  "status.cannot_reblog": "Tätä postausta ei voi buustata",
   "status.delete": "Poista",
-  "status.embed": "Embed",
+  "status.embed": "Upota",
   "status.favourite": "Tykkää",
-  "status.load_more": "Load more",
-  "status.media_hidden": "Media hidden",
+  "status.load_more": "Lataa lisää",
+  "status.media_hidden": "Media piilotettu",
   "status.mention": "Mainitse @{name}",
-  "status.more": "More",
-  "status.mute": "Mute @{name}",
-  "status.mute_conversation": "Mute conversation",
-  "status.open": "Expand this status",
-  "status.pin": "Pin on profile",
+  "status.more": "Lisää",
+  "status.mute": "Mykistä @{name}",
+  "status.mute_conversation": "Mykistä keskustelu",
+  "status.open": "Laajenna statuspäivitys",
+  "status.pin": "Kiinnitä profiiliin",
   "status.reblog": "Buustaa",
   "status.reblogged_by": "{name} buustasi",
   "status.reply": "Vastaa",
-  "status.replyAll": "Reply to thread",
+  "status.replyAll": "Vastaa ketjuun",
   "status.report": "Report @{name}",
   "status.sensitive_toggle": "Klikkaa nähdäksesi",
   "status.sensitive_warning": "Arkaluontoista sisältöä",
-  "status.share": "Share",
-  "status.show_less": "Show less",
-  "status.show_more": "Show more",
-  "status.unmute_conversation": "Unmute conversation",
-  "status.unpin": "Unpin from profile",
+  "status.share": "Jaa",
+  "status.show_less": "Näytä vähemmän",
+  "status.show_more": "Näytä lisää",
+  "status.unmute_conversation": "Poista mykistys keskustelulta",
+  "status.unpin": "Irrota profiilista",
   "tabs_bar.compose": "Luo",
   "tabs_bar.federated_timeline": "Federated",
   "tabs_bar.home": "Koti",
-  "tabs_bar.local_timeline": "Local",
+  "tabs_bar.local_timeline": "Paikallinen",
   "tabs_bar.notifications": "Ilmoitukset",
-  "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
-  "upload_area.title": "Drag & drop to upload",
+  "ui.beforeunload": "Luonnoksesi menetetään, jos poistut Mastodonista.",
+  "upload_area.title": "Raahaa ja pudota tähän ladataksesi",
   "upload_button.label": "Lisää mediaa",
-  "upload_form.description": "Describe for the visually impaired",
+  "upload_form.description": "Anna kuvaus näkörajoitteisia varten",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Peru",
-  "upload_progress.label": "Uploading...",
-  "video.close": "Close video",
-  "video.exit_fullscreen": "Exit full screen",
-  "video.expand": "Expand video",
+  "upload_progress.label": "Ladataan...",
+  "video.close": "Sulje video",
+  "video.exit_fullscreen": "Poistu koko näytön tilasta",
+  "video.expand": "Laajenna video",
   "video.fullscreen": "Full screen",
-  "video.hide": "Hide video",
-  "video.mute": "Mute sound",
-  "video.pause": "Pause",
-  "video.play": "Play",
-  "video.unmute": "Unmute sound"
+  "video.hide": "Piilota video",
+  "video.mute": "Mykistä ääni",
+  "video.pause": "Keskeytä",
+  "video.play": "Toista",
+  "video.unmute": "Poista mykistys ääneltä"
 }
diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json
index 17075f6de..b10187dfd 100644
--- a/app/javascript/mastodon/locales/fr.json
+++ b/app/javascript/mastodon/locales/fr.json
@@ -14,6 +14,7 @@
   "account.mute": "Masquer @{name}",
   "account.mute_notifications": "Ignorer les notifications de @{name}",
   "account.posts": "Statuts",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Signaler",
   "account.requested": "Invitation envoyée",
   "account.share": "Partager le profil de @{name}",
@@ -163,7 +164,7 @@
   "notifications.column_settings.alert": "Notifications locales",
   "notifications.column_settings.favourite": "Favoris :",
   "notifications.column_settings.follow": "Nouveaux⋅elles abonné⋅e·s :",
-  "notifications.column_settings.mention": "Mentions :",
+  "notifications.column_settings.mention": "Mentions :",
   "notifications.column_settings.push": "Notifications push",
   "notifications.column_settings.push_meta": "Cet appareil",
   "notifications.column_settings.reblog": "Partages :",
@@ -200,13 +201,16 @@
   "privacy.unlisted.long": "Ne pas afficher dans les fils publics",
   "privacy.unlisted.short": "Non-listé",
   "regeneration_indicator.label": "Chargement…",
-  "regeneration_indicator.sublabel": "Votre page principale est en cours de préparation!",
+  "regeneration_indicator.sublabel": "Le flux de votre page principale est en cours de préparation !",
   "relative_time.days": "{number} j",
   "relative_time.hours": "{number} h",
   "relative_time.just_now": "à l’instant",
   "relative_time.minutes": "{number} min",
   "relative_time.seconds": "{number} s",
   "reply_indicator.cancel": "Annuler",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Commentaires additionnels",
   "report.submit": "Envoyer",
   "report.target": "Signalement",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "statuts",
   "search_popout.tips.text": "Un texte simple renvoie les noms affichés, les noms d’utilisateur⋅ice et les hashtags correspondants",
   "search_popout.tips.user": "utilisateur⋅ice",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {résultat} other {résultats}}",
   "standalone.public_title": "Jeter un coup d’œil…",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "Glissez et déposez pour envoyer",
   "upload_button.label": "Joindre un média",
   "upload_form.description": "Décrire pour les malvoyants",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Annuler",
   "upload_progress.label": "Envoi en cours…",
   "video.close": "Fermer la vidéo",
diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json
index 9e8352ba4..0b91f57ae 100644
--- a/app/javascript/mastodon/locales/gl.json
+++ b/app/javascript/mastodon/locales/gl.json
@@ -13,7 +13,8 @@
   "account.moved_to": "{name} marchou a:",
   "account.mute": "Acalar @{name}",
   "account.mute_notifications": "Acalar as notificacións de @{name}",
-  "account.posts": "Publicacións",
+  "account.posts": "Toots",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Informar sobre @{name}",
   "account.requested": "Agardando aceptación. Pulse para cancelar a solicitude de seguimento",
   "account.share": "Compartir o perfil de @{name}",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Cancelar",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Comentarios adicionais",
   "report.submit": "Enviar",
   "report.target": "Informar {target}",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "estado",
   "search_popout.tips.text": "Texto simple devolve coincidencias con nomes públicos, nomes de usuaria e etiquetas",
   "search_popout.tips.user": "usuaria",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count,plural,one {result} outros {results}}",
   "standalone.public_title": "Ollada dentro...",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "Arrastre e solte para subir",
   "upload_button.label": "Engadir medios",
   "upload_form.description": "Describa para deficientes visuais",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Desfacer",
   "upload_progress.label": "Subindo...",
   "video.close": "Pechar video",
diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json
index d6665295f..e430fabf8 100644
--- a/app/javascript/mastodon/locales/he.json
+++ b/app/javascript/mastodon/locales/he.json
@@ -14,6 +14,7 @@
   "account.mute": "להשתיק את @{name}",
   "account.mute_notifications": "להסתיר התראות מאת @{name}",
   "account.posts": "הודעות",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "לדווח על @{name}",
   "account.requested": "בהמתנה לאישור",
   "account.share": "לשתף את אודות @{name}",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "ביטול",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "הערות נוספות",
   "report.submit": "שליחה",
   "report.target": "דיווח",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "טקסט פשוט מחזיר כינויים, שמות משתמש והאשתגים",
   "search_popout.tips.user": "משתמש(ת)",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {תוצאה} other {תוצאות}}",
   "standalone.public_title": "הצצה פנימה...",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "ניתן להעלות על ידי Drag & drop",
   "upload_button.label": "הוספת מדיה",
   "upload_form.description": "תיאור לכבדי ראיה",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "ביטול",
   "upload_progress.label": "עולה...",
   "video.close": "סגירת וידאו",
diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json
index c49ae160f..543a739bc 100644
--- a/app/javascript/mastodon/locales/hr.json
+++ b/app/javascript/mastodon/locales/hr.json
@@ -14,6 +14,7 @@
   "account.mute": "Utišaj @{name}",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.posts": "Postovi",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Prijavi @{name}",
   "account.requested": "Čeka pristanak",
   "account.share": "Share @{name}'s profile",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Otkaži",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Dodatni komentari",
   "report.submit": "Pošalji",
   "report.target": "Prijavljivanje",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
   "search_popout.tips.user": "user",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
   "standalone.public_title": "A look inside...",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "Povuci i spusti kako bi uploadao",
   "upload_button.label": "Dodaj media",
   "upload_form.description": "Describe for the visually impaired",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Poništi",
   "upload_progress.label": "Uploadam...",
   "video.close": "Close video",
diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json
index 316687129..38b3698b6 100644
--- a/app/javascript/mastodon/locales/hu.json
+++ b/app/javascript/mastodon/locales/hu.json
@@ -7,13 +7,14 @@
   "account.followers": "Követők",
   "account.follows": "Követve",
   "account.follows_you": "Követnek téged",
-  "account.hide_reblogs": "@{name} kedvenceinek elrejtése",
+  "account.hide_reblogs": "Rejtsd el a tülkölést @{name}-tól/től",
   "account.media": "Média",
   "account.mention": "@{name} említése",
   "account.moved_to": "{name} átköltözött:",
   "account.mute": "@{name} némítása",
   "account.mute_notifications": "@{name} értesítések némítása",
   "account.posts": "Státuszok",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "@{name} jelentése",
   "account.requested": "Engedélyre vár. Kattintson a követési kérés visszavonására",
   "account.share": "@{name} profiljának megosztása",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Mégsem",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "További kommentek",
   "report.submit": "Submit",
   "report.target": "Reporting",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
   "search_popout.tips.user": "felhasználó",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
   "standalone.public_title": "Betekintés...",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "Húzza ide a feltöltéshez",
   "upload_button.label": "Média hozzáadása",
   "upload_form.description": "Describe for the visually impaired",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Mégsem",
   "upload_progress.label": "Uploading...",
   "video.close": "Close video",
diff --git a/app/javascript/mastodon/locales/hy.json b/app/javascript/mastodon/locales/hy.json
index f46db5b00..15d8f22e6 100644
--- a/app/javascript/mastodon/locales/hy.json
+++ b/app/javascript/mastodon/locales/hy.json
@@ -14,6 +14,7 @@
   "account.mute": "Լռեցնել @{name}֊ին",
   "account.mute_notifications": "Անջատել ծանուցումները @{name}֊ից",
   "account.posts": "Գրառումներ",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Բողոքել @{name}֊ից",
   "account.requested": "Հաստատման կարիք ունի։ Սեղմիր՝ հետեւելու հայցը չեղարկելու համար։",
   "account.share": "Կիսվել @{name}֊ի էջով",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}ր",
   "relative_time.seconds": "{number}վ",
   "reply_indicator.cancel": "Չեղարկել",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Լրացուցիչ մեկնաբանություններ",
   "report.submit": "Ուղարկել",
   "report.target": "Բողոքել {target}֊ի մասին",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "թութ",
   "search_popout.tips.text": "Հասարակ տեքստը կվերադարձնի համընկնող անուններ, օգտանուններ ու պիտակներ",
   "search_popout.tips.user": "օգտատեր",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
   "standalone.public_title": "Այս պահին…",
   "status.block": "Արգելափակել @{name}֊ին",
@@ -252,6 +259,7 @@
   "upload_area.title": "Քաշիր ու նետիր՝ վերբեռնելու համար",
   "upload_button.label": "Ավելացնել մեդիա",
   "upload_form.description": "Նկարագրություն ավելացրու տեսողական խնդիրներ ունեցողների համար",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Հետարկել",
   "upload_progress.label": "Վերբեռնվում է…",
   "video.close": "Փակել  տեսագրությունը",
diff --git a/app/javascript/mastodon/locales/id.json b/app/javascript/mastodon/locales/id.json
index 6edf855d3..ac4aaa1aa 100644
--- a/app/javascript/mastodon/locales/id.json
+++ b/app/javascript/mastodon/locales/id.json
@@ -14,6 +14,7 @@
   "account.mute": "Bisukan @{name}",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.posts": "Postingan",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Laporkan @{name}",
   "account.requested": "Menunggu persetujuan",
   "account.share": "Share @{name}'s profile",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Batal",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Komentar tambahan",
   "report.submit": "Kirim",
   "report.target": "Melaporkan",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
   "search_popout.tips.user": "user",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count} {count, plural, one {hasil} other {hasil}}",
   "standalone.public_title": "A look inside...",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "Seret & lepaskan untuk mengunggah",
   "upload_button.label": "Tambahkan media",
   "upload_form.description": "Describe for the visually impaired",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Undo",
   "upload_progress.label": "Mengunggah...",
   "video.close": "Close video",
diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json
index 7aa7cb144..d431fac49 100644
--- a/app/javascript/mastodon/locales/io.json
+++ b/app/javascript/mastodon/locales/io.json
@@ -14,6 +14,7 @@
   "account.mute": "Celar @{name}",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.posts": "Mesaji",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Denuncar @{name}",
   "account.requested": "Vartante aprobo",
   "account.share": "Share @{name}'s profile",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Nihiligar",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Plusa komenti",
   "report.submit": "Sendar",
   "report.target": "Denuncante",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
   "search_popout.tips.user": "user",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {rezulto} other {rezulti}}",
   "standalone.public_title": "A look inside...",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "Tranar faligar por kargar",
   "upload_button.label": "Adjuntar kontenajo",
   "upload_form.description": "Describe for the visually impaired",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Desfacar",
   "upload_progress.label": "Kargante...",
   "video.close": "Close video",
diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json
index 61467df16..eec1a7feb 100644
--- a/app/javascript/mastodon/locales/it.json
+++ b/app/javascript/mastodon/locales/it.json
@@ -14,6 +14,7 @@
   "account.mute": "Silenzia @{name}",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.posts": "Posts",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Segnala @{name}",
   "account.requested": "In attesa di approvazione",
   "account.share": "Share @{name}'s profile",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Annulla",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Commenti aggiuntivi",
   "report.submit": "Invia",
   "report.target": "Invio la segnalazione",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
   "search_popout.tips.user": "user",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count} {count, plural, one {risultato} other {risultati}}",
   "standalone.public_title": "A look inside...",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "Trascina per caricare",
   "upload_button.label": "Aggiungi file multimediale",
   "upload_form.description": "Describe for the visually impaired",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Annulla",
   "upload_progress.label": "Sto caricando...",
   "video.close": "Close video",
diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json
index 4449af52f..f1ad2911d 100644
--- a/app/javascript/mastodon/locales/ja.json
+++ b/app/javascript/mastodon/locales/ja.json
@@ -14,11 +14,12 @@
   "account.mute": "@{name}さんをミュート",
   "account.mute_notifications": "@{name}さんからの通知を受け取らない",
   "account.posts": "投稿",
+  "account.posts_with_replies": "トゥートと返信",
   "account.report": "@{name}さんを通報",
   "account.requested": "フォロー承認待ちです。クリックしてキャンセル",
   "account.share": "@{name}さんのプロフィールを共有する",
   "account.show_reblogs": "@{name}さんからのブーストを表示",
-  "account.unblock": "@{name}さんのブロック解除",
+  "account.unblock": "@{name}さんのブロックを解除",
   "account.unblock_domain": "{domain}を表示",
   "account.unfollow": "フォロー解除",
   "account.unmute": "@{name}さんのミュートを解除",
@@ -71,7 +72,7 @@
   "confirmations.delete_list.confirm": "削除",
   "confirmations.delete_list.message": "本当にこのリストを完全に削除しますか?",
   "confirmations.domain_block.confirm": "ドメイン全体を非表示",
-  "confirmations.domain_block.message": "本当に{domain}全体を非表示にしますか? 多くの場合は個別にブロックやミュートするだけで充分であり、また好ましいです。",
+  "confirmations.domain_block.message": "本当に{domain}全体を非表示にしますか? 多くの場合は個別にブロックやミュートするだけで充分であり、また好ましいです。",
   "confirmations.mute.confirm": "ミュート",
   "confirmations.mute.message": "本当に{name}さんをミュートしますか?",
   "confirmations.unfollow.confirm": "フォロー解除",
@@ -207,13 +208,16 @@
   "privacy.unlisted.long": "公開TLで表示しない",
   "privacy.unlisted.short": "未収載",
   "regeneration_indicator.label": "読み込み中…",
-  "regeneration_indicator.sublabel": "ホームタイムラインは準備中です!",
+  "regeneration_indicator.sublabel": "ホームタイムラインは準備中です!",
   "relative_time.days": "{number}日前",
   "relative_time.hours": "{number}時間前",
   "relative_time.just_now": "今",
   "relative_time.minutes": "{number}分前",
   "relative_time.seconds": "{number}秒前",
   "reply_indicator.cancel": "キャンセル",
+  "report.forward": "{target} に転送する",
+  "report.forward_hint": "このアカウントは別のインスタンスに所属しています。通報内容を匿名で転送しますか?",
+  "report.hint": "通報内容はあなたのインスタンスのモデレーターへ送信されます。通報理由を入力してください。:",
   "report.placeholder": "追加コメント",
   "report.submit": "通報する",
   "report.target": "{target}さんを通報する",
@@ -223,6 +227,9 @@
   "search_popout.tips.status": "トゥート",
   "search_popout.tips.text": "表示名やユーザー名、ハッシュタグに一致する単純なテキスト",
   "search_popout.tips.user": "ユーザー",
+  "search_results.accounts": "人々",
+  "search_results.hashtags": "ハッシュタグ",
+  "search_results.statuses": "トゥート",
   "search_results.total": "{count, number}件の結果",
   "standalone.public_title": "今こんな話をしています...",
   "status.block": "@{name}さんをブロック",
@@ -259,6 +266,7 @@
   "upload_area.title": "ドラッグ&ドロップでアップロード",
   "upload_button.label": "メディアを追加",
   "upload_form.description": "視覚障害者のための説明",
+  "upload_form.focus": "焦点",
   "upload_form.undo": "やり直す",
   "upload_progress.label": "アップロード中...",
   "video.close": "動画を閉じる",
diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json
index 02b4b18e2..8e7c82682 100644
--- a/app/javascript/mastodon/locales/ko.json
+++ b/app/javascript/mastodon/locales/ko.json
@@ -14,6 +14,7 @@
   "account.mute": "@{name} 뮤트",
   "account.mute_notifications": "@{name}의 알림을 뮤트",
   "account.posts": "게시물",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "@{name} 신고",
   "account.requested": "승인 대기 중. 클릭해서 취소하기",
   "account.share": "@{name}의 프로파일 공유",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}분 전",
   "relative_time.seconds": "{number}초 전",
   "reply_indicator.cancel": "취소",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "코멘트",
   "report.submit": "신고하기",
   "report.target": "문제가 된 사용자",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "툿",
   "search_popout.tips.text": "단순한 텍스트 검색은 관계된 프로필 이름, 유저 이름 그리고 해시태그를 표시합니다",
   "search_popout.tips.user": "유저",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number}건의 결과",
   "standalone.public_title": "지금 이런 이야기를 하고 있습니다…",
   "status.block": "@{name} 차단",
@@ -252,6 +259,7 @@
   "upload_area.title": "드래그 & 드롭으로 업로드",
   "upload_button.label": "미디어 추가",
   "upload_form.description": "시각장애인을 위한 설명",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "재시도",
   "upload_progress.label": "업로드 중...",
   "video.close": "동영상 닫기",
diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json
index 11a012de5..315f92120 100644
--- a/app/javascript/mastodon/locales/nl.json
+++ b/app/javascript/mastodon/locales/nl.json
@@ -14,6 +14,7 @@
   "account.mute": "Negeer @{name}",
   "account.mute_notifications": "Negeer meldingen van @{name}",
   "account.posts": "Toots",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Rapporteer @{name}",
   "account.requested": "Wacht op goedkeuring. Klik om het volgverzoek te annuleren",
   "account.share": "Profiel van @{name} delen",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Annuleren",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Extra opmerkingen",
   "report.submit": "Verzenden",
   "report.target": "Rapporteer {target}",
@@ -216,9 +220,12 @@
   "search_popout.tips.status": "toot",
   "search_popout.tips.text": "Gebruik gewone tekst om te zoeken op weergavenamen, gebruikersnamen en hashtags",
   "search_popout.tips.user": "gebruiker",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {resultaat} other {resultaten}}",
   "standalone.public_title": "Een kijkje binnenin...",
-  "status.block": "Block @{name}",
+  "status.block": "Blokkeer @{name}",
   "status.cannot_reblog": "Deze toot kan niet geboost worden",
   "status.delete": "Verwijderen",
   "status.embed": "Embed",
@@ -252,6 +259,7 @@
   "upload_area.title": "Hierin slepen om te uploaden",
   "upload_button.label": "Media toevoegen",
   "upload_form.description": "Omschrijf dit voor mensen met een visuele beperking",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Ongedaan maken",
   "upload_progress.label": "Uploaden...",
   "video.close": "Video sluiten",
diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json
index 21fd50183..b319ea1a5 100644
--- a/app/javascript/mastodon/locales/no.json
+++ b/app/javascript/mastodon/locales/no.json
@@ -14,6 +14,7 @@
   "account.mute": "Demp @{name}",
   "account.mute_notifications": "Ignorer varsler fra @{name}",
   "account.posts": "Innlegg",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Rapportér @{name}",
   "account.requested": "Venter på godkjennelse",
   "account.share": "Del @{name}s profil",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Avbryt",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Tilleggskommentarer",
   "report.submit": "Send inn",
   "report.target": "Rapporterer",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "Enkel tekst returnerer matchende visningsnavn, brukernavn og emneknagger",
   "search_popout.tips.user": "bruker",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {resultat} other {resultater}}",
   "standalone.public_title": "En titt inni...",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "Dra og slipp for å laste opp",
   "upload_button.label": "Legg til media",
   "upload_form.description": "Beskriv for synshemmede",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Angre",
   "upload_progress.label": "Laster opp...",
   "video.close": "Lukk video",
diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json
index 3cf99028a..2402e1759 100644
--- a/app/javascript/mastodon/locales/oc.json
+++ b/app/javascript/mastodon/locales/oc.json
@@ -14,6 +14,7 @@
   "account.mute": "Rescondre @{name}",
   "account.mute_notifications": "Rescondre las notificacions de @{name}",
   "account.posts": "Estatuts",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Senhalar @{name}",
   "account.requested": "Invitacion mandada. Clicatz per anullar",
   "account.share": "Partejar lo perfil a @{name}",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "fa {number}min",
   "relative_time.seconds": "fa {number}s",
   "reply_indicator.cancel": "Anullar",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Comentaris addicionals",
   "report.submit": "Mandar",
   "report.target": "Senhalar {target}",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "estatut",
   "search_popout.tips.text": "Lo tèxt brut tòrna escais, noms d’utilizaire e etiquetas correspondents",
   "search_popout.tips.user": "utilizaire",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {resultat} other {resultats}}",
   "standalone.public_title": "Una ulhada dedins…",
   "status.block": "Blocar @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "Lisatz e depausatz per mandar",
   "upload_button.label": "Ajustar un mèdia",
   "upload_form.description": "Descripcion pels mal vesents",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Anullar",
   "upload_progress.label": "Mandadís…",
   "video.close": "Tampar la vidèo",
diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json
index bcc28b65a..4eccc3655 100644
--- a/app/javascript/mastodon/locales/pl.json
+++ b/app/javascript/mastodon/locales/pl.json
@@ -14,6 +14,7 @@
   "account.mute": "Wycisz @{name}",
   "account.mute_notifications": "Wycisz powiadomienia o @{name}",
   "account.posts": "Wpisy",
+  "account.posts_with_replies": "Wpisy z odpowiedziami",
   "account.report": "Zgłoś @{name}",
   "account.requested": "Oczekująca prośba, kliknij aby anulować",
   "account.share": "Udostępnij profil @{name}",
@@ -99,7 +100,7 @@
   "empty_column.home.public_timeline": "publiczna oś czasu",
   "empty_column.list": "Nie ma nic na tej liście. Kiedy członkowie listy dodadzą nowe wpisy, pojawia się one tutaj.",
   "empty_column.notifications": "Nie masz żadnych powiadomień. Rozpocznij interakcje z innymi użytkownikami.",
-  "empty_column.public": "Tu nic nie ma! Napisz coś publicznie, lub dodaj ludzi z innych instancji, aby to wyświetlić.",
+  "empty_column.public": "Tu nic nie ma! Napisz coś publicznie, lub dodaj ludzi z innych instancji, aby to wyświetlić",
   "follow_request.authorize": "Autoryzuj",
   "follow_request.reject": "Odrzuć",
   "getting_started.appsshort": "Aplikacje",
@@ -134,11 +135,11 @@
   "lightbox.next": "Następne",
   "lightbox.previous": "Poprzednie",
   "lists.account.add": "Dodaj do listy",
-  "lists.account.remove": "Usuń z listy",
+  "lists.account.remove": "Usunąć z listy",
   "lists.delete": "Usuń listę",
   "lists.edit": "Edytuj listę",
   "lists.new.create": "Utwórz listę",
-  "lists.new.title_placeholder": "Wprowadź tytuł listy…",
+  "lists.new.title_placeholder": "Wprowadź tytuł listy",
   "lists.search": "Szukaj wśród osób które śledzisz",
   "lists.subheading": "Twoje listy",
   "loading_indicator.label": "Ładowanie…",
@@ -206,7 +207,7 @@
   "privacy.public.short": "Publiczny",
   "privacy.unlisted.long": "Niewidoczny na publicznych osiach czasu",
   "privacy.unlisted.short": "Niewidoczny",
-  "regeneration_indicator.label": "Ładowanie…",
+  "regeneration_indicator.label": "Ładuję…",
   "regeneration_indicator.sublabel": "Twoja oś czasu jest przygotowywana!",
   "relative_time.days": "{number} dni",
   "relative_time.hours": "{number} godz.",
@@ -214,6 +215,9 @@
   "relative_time.minutes": "{number} min.",
   "relative_time.seconds": "{number} s.",
   "reply_indicator.cancel": "Anuluj",
+  "report.forward": "Przekaż na {target}",
+  "report.forward_hint": "To konto znajduje się na innej instancji. Czy chcesz wysłać anonimową kopię zgłoszenia rnież na nią?",
+  "report.hint": "Zgłoszenie zostanie wysłane moderatorom Twojej instancji. Poniżej możesz też umieścić wyjaśnieni dlaczego zgłaszasz to konto:",
   "report.placeholder": "Dodatkowe komentarze",
   "report.submit": "Wyślij",
   "report.target": "Zgłaszanie {target}",
@@ -262,6 +266,7 @@
   "upload_area.title": "Przeciągnij i upuść aby wysłać",
   "upload_button.label": "Dodaj zawartość multimedialną",
   "upload_form.description": "Wprowadź opis dla niewidomych i niedowidzących",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Cofnij",
   "upload_progress.label": "Wysyłanie",
   "video.close": "Zamknij film",
diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json
index 3d63da850..c07661e92 100644
--- a/app/javascript/mastodon/locales/pt-BR.json
+++ b/app/javascript/mastodon/locales/pt-BR.json
@@ -14,6 +14,7 @@
   "account.mute": "Silenciar @{name}",
   "account.mute_notifications": "Silenciar notificações de @{name}",
   "account.posts": "Posts",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Denunciar @{name}",
   "account.requested": "Aguardando aprovação. Clique para cancelar a solicitação",
   "account.share": "Compartilhar perfil de @{name}",
@@ -90,7 +91,7 @@
   "emoji_button.travel": "Viagens & Lugares",
   "empty_column.community": "A timeline local está vazia. Escreva algo publicamente para começar!",
   "empty_column.hashtag": "Ainda não há qualquer conteúdo com essa hashtag.",
-  "empty_column.home": "Você ainda não segue usuário algo. Visite a timeline {public} ou use o buscador para procurar e conhecer outros usuários.",
+  "empty_column.home": "Você ainda não segue usuário algum. Visite a timeline {public} ou use o buscador para procurar e conhecer outros usuários.",
   "empty_column.home.public_timeline": "global",
   "empty_column.list": "Ainda não há nada nesta lista. Quando membros dessa lista fizerem novas postagens, elas aparecerão aqui.",
   "empty_column.notifications": "Você ainda não possui notificações. Interaja com outros usuários para começar a conversar.",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Cancelar",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Comentários adicionais",
   "report.submit": "Enviar",
   "report.target": "Denunciar",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "Texto simples retorna nomes de exibição, usuários e hashtags correspondentes",
   "search_popout.tips.user": "usuário",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {resultado} other {resultados}}",
   "standalone.public_title": "Dê uma espiada...",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "Arraste e solte para enviar",
   "upload_button.label": "Adicionar mídia",
   "upload_form.description": "Descreva a imagem para deficientes visuais",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Desfazer",
   "upload_progress.label": "Salvando...",
   "video.close": "Fechar vídeo",
diff --git a/app/javascript/mastodon/locales/pt.json b/app/javascript/mastodon/locales/pt.json
index 2fd13db15..61233a1b9 100644
--- a/app/javascript/mastodon/locales/pt.json
+++ b/app/javascript/mastodon/locales/pt.json
@@ -14,6 +14,7 @@
   "account.mute": "Silenciar @{name}",
   "account.mute_notifications": "Silenciar notificações de @{name}",
   "account.posts": "Posts",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Denunciar @{name}",
   "account.requested": "A aguardar aprovação",
   "account.share": "Partilhar o perfil @{name}",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Cancelar",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Comentários adicionais",
   "report.submit": "Enviar",
   "report.target": "Denunciar",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "O texto simples retorna a correspondência de nomes, utilizadores e hashtags",
   "search_popout.tips.user": "utilizador",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {resultado} other {resultados}}",
   "standalone.public_title": "Espreitar lá dentro...",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "Arraste e solte para enviar",
   "upload_button.label": "Adicionar media",
   "upload_form.description": "Descrição da imagem para pessoas com dificuldades visuais",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Anular",
   "upload_progress.label": "A gravar...",
   "video.close": "Fechar vídeo",
diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json
index 58ffa8d55..76d3fec13 100644
--- a/app/javascript/mastodon/locales/ru.json
+++ b/app/javascript/mastodon/locales/ru.json
@@ -14,6 +14,7 @@
   "account.mute": "Заглушить",
   "account.mute_notifications": "Скрыть уведомления от @{name}",
   "account.posts": "Посты",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Пожаловаться",
   "account.requested": "Ожидает подтверждения",
   "account.share": "Поделиться профилем @{name}",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}м",
   "relative_time.seconds": "{number}с",
   "reply_indicator.cancel": "Отмена",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Комментарий",
   "report.submit": "Отправить",
   "report.target": "Жалуемся на",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "статус",
   "search_popout.tips.text": "Простой ввод текста покажет совпадающие имена пользователей, отображаемые имена и хэштеги",
   "search_popout.tips.user": "пользователь",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {результат} few {результата} many {результатов} other {результатов}}",
   "standalone.public_title": "Прямо сейчас",
   "status.block": "Заблокировать @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "Перетащите сюда, чтобы загрузить",
   "upload_button.label": "Добавить медиаконтент",
   "upload_form.description": "Описать для людей с нарушениями зрения",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Отменить",
   "upload_progress.label": "Загрузка...",
   "video.close": "Закрыть видео",
diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json
index 1a0629708..de273770a 100644
--- a/app/javascript/mastodon/locales/sk.json
+++ b/app/javascript/mastodon/locales/sk.json
@@ -4,7 +4,7 @@
   "account.disclaimer_full": "Inofrmácie nižšie nemusia byť úplným odrazom uživateľovho účtu.",
   "account.edit_profile": "Upraviť profil",
   "account.follow": "Následovať",
-  "account.followers": "Následovaťelia",
+  "account.followers": "Sledujúci",
   "account.follows": "Sledujete",
   "account.follows_you": "Následuje vás",
   "account.hide_reblogs": "Skryť povýšenia od @{name}",
@@ -13,7 +13,8 @@
   "account.moved_to": "{name} sa presunul/a na:",
   "account.mute": "Ignorovať @{name}",
   "account.mute_notifications": "Stĺmiť notifikácie od @{name}",
-  "account.posts": "Správy",
+  "account.posts": "Hlášky",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Nahlásiť @{name}",
   "account.requested": "Čaká na schválenie. Kliknite pre zrušenie žiadosti",
   "account.share": "Zdieľať @{name} profil",
@@ -72,7 +73,7 @@
   "confirmations.mute.message": "Naozaj chcete ignorovať {name}?",
   "confirmations.unfollow.confirm": "Nesledovať",
   "confirmations.unfollow.message": "Naozaj chcete prestať sledovať {name}?",
-  "embed.instructions": "Skopírujte kód uvedený nižšie pre pridanie tohto statusu na vašu web stránku.",
+  "embed.instructions": "Umiestnite kód uvedený nižšie pre pridanie tohto statusu na vašu web stránku.",
   "embed.preview": "Tu je ako to bude vyzerať:",
   "emoji_button.activity": "Aktivita",
   "emoji_button.custom": "Vlastné",
@@ -100,7 +101,7 @@
   "getting_started.appsshort": "Aplikácie",
   "getting_started.faq": "FAQ",
   "getting_started.heading": "Začíname",
-  "getting_started.open_source_notice": "Mastodon má otvorený kód. Nahlásiť chyby, alebo prispievať vlastným kódom môžeš na GitHube v {github}.",
+  "getting_started.open_source_notice": "Mastodon má otvorený kód. Nahlásiť chyby, alebo prispievať vlastným kódom môžete na GitHube v {github}.",
   "getting_started.userguide": "Používateľská príručka",
   "home.column_settings.advanced": "Rozšírené",
   "home.column_settings.basic": "Základné",
@@ -122,11 +123,11 @@
   "keyboard_shortcuts.mention": "spomenúť autora",
   "keyboard_shortcuts.reply": "odpovedať",
   "keyboard_shortcuts.search": "zamerať sa na vyhľadávanie",
-  "keyboard_shortcuts.toot": "začať úplne nový toot",
-  "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
+  "keyboard_shortcuts.toot": "začať úplne novú hlášku",
+  "keyboard_shortcuts.unfocus": "nesústrediť sa na písaciu plochu, alebo hľadanie",
   "keyboard_shortcuts.up": "posunúť sa vyššie v zozname",
   "lightbox.close": "Zatvoriť",
-  "lightbox.next": "Ďalší",
+  "lightbox.next": "Ďalšie",
   "lightbox.previous": "Predchádzajúci",
   "lists.account.add": "Pridať do zoznamu",
   "lists.account.remove": "Odobrať zo zoznamu",
@@ -159,10 +160,10 @@
   "notification.mention": "{name} vás spomenul",
   "notification.reblog": "{name} re-tootol tvoj status",
   "notifications.clear": "Vyčistiť zoznam notifikácii",
-  "notifications.clear_confirmation": "Naozaj chcete nenávratne vymazať všetky vaše notifikácie?",
+  "notifications.clear_confirmation": "Naozaj chcete nenávratne prečistiť všetky vaše notifikácie?",
   "notifications.column_settings.alert": "Notifikácie na ploche",
   "notifications.column_settings.favourite": "Obľúbené:",
-  "notifications.column_settings.follow": "Nový nasledujúci:",
+  "notifications.column_settings.follow": "Noví následujúci:",
   "notifications.column_settings.mention": "Zmienenia:",
   "notifications.column_settings.push": "Push notifikácie",
   "notifications.column_settings.push_meta": "Toto zariadenie",
@@ -175,7 +176,7 @@
   "onboarding.page_four.home": "Domovská časová os zobrazí správy od ľudí ktorých sledujete.",
   "onboarding.page_four.notifications": "Stĺpec s notifikáciami zobrazí keď budete s niekým komunikovať.",
   "onboarding.page_one.federation": "Mastodon je sieť nezávislých serverov, spojením ktorých vzniká jedna veľká federovaná sociálna sieť.",
-  "onboarding.page_one.full_handle": "Your full handle",
+  "onboarding.page_one.full_handle": "Vaša celá prezývka aj s adresou",
   "onboarding.page_one.handle_hint": "Toto je čo by ste povedali vaším priateľom že majú hľadať.",
   "onboarding.page_one.welcome": "Vitajte na Mastodone!",
   "onboarding.page_six.admin": "Správca tohto servera je {admin}.",
@@ -193,7 +194,7 @@
   "privacy.change": "Zmeňiť viditeľnosť statusu",
   "privacy.direct.long": "Poslať priamo iba spomenutým používateľom",
   "privacy.direct.short": "Súkromne",
-  "privacy.private.long": "Poslať iba sledujúcim",
+  "privacy.private.long": "Poslať iba následovateľom",
   "privacy.private.short": "Iba pre sledujúcich",
   "privacy.public.long": "Poslať všetkým verejne",
   "privacy.public.short": "Verejné",
@@ -207,23 +208,29 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Zrušiť",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Ďalšie komentáre",
   "report.submit": "Poslať",
   "report.target": "Nahlásenie {target}",
   "search.placeholder": "Hľadať",
-  "search_popout.search_format": "Pokročilý tvar vyhľadávania",
-  "search_popout.tips.hashtag": "hashtag",
+  "search_popout.search_format": "Pokročilý formát vyhľadávania",
+  "search_popout.tips.hashtag": "haštag",
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "Jednoduchý text vráti zhodujúce sa mená, prezývky a hashtagy",
   "search_popout.tips.user": "používateľ",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {result} ostatné {results}}",
   "standalone.public_title": "Pohľad dovnútra...",
   "status.block": "Blokovať @{name}",
   "status.cannot_reblog": "Tento príspevok nemôže byť re-tootnutý",
   "status.delete": "Zmazať",
-  "status.embed": "Embed",
+  "status.embed": "Vložiť",
   "status.favourite": "Páči sa mi",
-  "status.load_more": "Zobraziť viac",
+  "status.load_more": "Zobraz viac",
   "status.media_hidden": "Skryté médiá",
   "status.mention": "Napísať @{name}",
   "status.more": "Viac",
@@ -239,8 +246,8 @@
   "status.sensitive_toggle": "Kliknite pre zobrazenie",
   "status.sensitive_warning": "Chúlostivý obsah",
   "status.share": "Zdieľať",
-  "status.show_less": "Zobraziť menej",
-  "status.show_more": "Zobraziť viac",
+  "status.show_less": "Zobraz menej",
+  "status.show_more": "Zobraz viac",
   "status.unmute_conversation": "Prestať ignorovať konverzáciu",
   "status.unpin": "Odopnúť z profilu",
   "tabs_bar.compose": "Napísať",
@@ -252,6 +259,7 @@
   "upload_area.title": "Ťahaj a pusti pre nahratie",
   "upload_button.label": "Pridať médiá",
   "upload_form.description": "Opis pre slabo vidiacich",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Navrátiť",
   "upload_progress.label": "Nahráva sa...",
   "video.close": "Zavrieť video",
diff --git a/app/javascript/mastodon/locales/sr-Latn.json b/app/javascript/mastodon/locales/sr-Latn.json
index cd48967cb..bf67a52d6 100644
--- a/app/javascript/mastodon/locales/sr-Latn.json
+++ b/app/javascript/mastodon/locales/sr-Latn.json
@@ -14,6 +14,7 @@
   "account.mute": "Ućutkaj korisnika @{name}",
   "account.mute_notifications": "Isključi obaveštenja od korisnika @{name}",
   "account.posts": "Statusa",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Prijavi @{name}",
   "account.requested": "Čekam odobrenje. Kliknite da poništite zahtev za praćenje",
   "account.share": "Podeli profil korisnika @{name}",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Poništi",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Dodatni komentari",
   "report.submit": "Pošalji",
   "report.target": "Prijavljujem {target}",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "Traženjem običnog teksta ćete dobiti sva pronađena imena, sva korisnička imena i sve nađene heštegove",
   "search_popout.tips.user": "korisnik",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {rezultat} few {rezultata} other {rezultata}}",
   "standalone.public_title": "Pogled iznutra...",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "Prevucite ovde da otpremite",
   "upload_button.label": "Dodaj multimediju",
   "upload_form.description": "Opiši za slabovide osobe",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Opozovi",
   "upload_progress.label": "Otpremam...",
   "video.close": "Zatvori video",
diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json
index 595a70ea6..d8d1ebae7 100644
--- a/app/javascript/mastodon/locales/sr.json
+++ b/app/javascript/mastodon/locales/sr.json
@@ -14,6 +14,7 @@
   "account.mute": "Ућуткај корисника @{name}",
   "account.mute_notifications": "Искључи обавештења од корисника @{name}",
   "account.posts": "Статуса",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Пријави @{name}",
   "account.requested": "Чекам одобрење. Кликните да поништите захтев за праћење",
   "account.share": "Подели профил корисника @{name}",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Поништи",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Додатни коментари",
   "report.submit": "Пошаљи",
   "report.target": "Пријављујем {target}",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "статус",
   "search_popout.tips.text": "Тражењем обичног текста ћете добити сва пронађена имена, сва корисничка имена и све нађене хештегове",
   "search_popout.tips.user": "корисник",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {резултат} few {резултата} other {резултата}}",
   "standalone.public_title": "Поглед изнутра...",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "Превуците овде да отпремите",
   "upload_button.label": "Додај мултимедију",
   "upload_form.description": "Опиши за слабовиде особе",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Опозови",
   "upload_progress.label": "Отпремам...",
   "video.close": "Затвори видео",
diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json
index 3f25648c2..0bf66c547 100644
--- a/app/javascript/mastodon/locales/sv.json
+++ b/app/javascript/mastodon/locales/sv.json
@@ -14,6 +14,7 @@
   "account.mute": "Tysta @{name}",
   "account.mute_notifications": "Stäng av notifieringar från @{name}",
   "account.posts": "Inlägg",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Rapportera @{name}",
   "account.requested": "Inväntar godkännande. Klicka för att avbryta följförfrågan",
   "account.share": "Dela @{name}'s profil",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Ångra",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Ytterligare kommentarer",
   "report.submit": "Skicka",
   "report.target": "Rapporterar {target}",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "Enkel text returnerar matchande visningsnamn, användarnamn och hashtags",
   "search_popout.tips.user": "användare",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, ett {result} andra {results}}",
   "standalone.public_title": "En titt inuti...",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "Dra & släpp för att ladda upp",
   "upload_button.label": "Lägg till media",
   "upload_form.description": "Beskriv för synskadade",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Ångra",
   "upload_progress.label": "Laddar upp...",
   "video.close": "Stäng video",
diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json
index 740fb80e7..d6ccc9412 100644
--- a/app/javascript/mastodon/locales/th.json
+++ b/app/javascript/mastodon/locales/th.json
@@ -14,6 +14,7 @@
   "account.mute": "Mute @{name}",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.posts": "Posts",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Report @{name}",
   "account.requested": "Awaiting approval",
   "account.share": "Share @{name}'s profile",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Cancel",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Additional comments",
   "report.submit": "Submit",
   "report.target": "Reporting",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
   "search_popout.tips.user": "user",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
   "standalone.public_title": "A look inside...",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "Drag & drop to upload",
   "upload_button.label": "Add media",
   "upload_form.description": "Describe for the visually impaired",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Undo",
   "upload_progress.label": "Uploading...",
   "video.close": "Close video",
diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json
index 8805e52f4..702c8454d 100644
--- a/app/javascript/mastodon/locales/tr.json
+++ b/app/javascript/mastodon/locales/tr.json
@@ -14,6 +14,7 @@
   "account.mute": "Sustur @{name}",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.posts": "Gönderiler",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Rapor et @{name}",
   "account.requested": "Onay bekleniyor",
   "account.share": "Share @{name}'s profile",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "İptal",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Ek yorumlar",
   "report.submit": "Gönder",
   "report.target": "Raporlama",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
   "search_popout.tips.user": "user",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {sonuç} other {sonuçlar}}",
   "standalone.public_title": "A look inside...",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "Upload için sürükle bırak yapınız",
   "upload_button.label": "Görsel ekle",
   "upload_form.description": "Describe for the visually impaired",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Geri al",
   "upload_progress.label": "Yükleniyor...",
   "video.close": "Close video",
diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json
index 2cdaba0ac..b5bd88cbb 100644
--- a/app/javascript/mastodon/locales/uk.json
+++ b/app/javascript/mastodon/locales/uk.json
@@ -14,6 +14,7 @@
   "account.mute": "Заглушити",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.posts": "Пости",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "Поскаржитися",
   "account.requested": "Очікує підтвердження",
   "account.share": "Share @{name}'s profile",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Відмінити",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "Додаткові коментарі",
   "report.submit": "Відправити",
   "report.target": "Скаржимося на",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
   "search_popout.tips.user": "user",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {результат} few {результати} many {результатів} other {результатів}}",
   "standalone.public_title": "A look inside...",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "Перетягніть сюди, щоб завантажити",
   "upload_button.label": "Додати медіаконтент",
   "upload_form.description": "Describe for the visually impaired",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "Відмінити",
   "upload_progress.label": "Завантаження...",
   "video.close": "Close video",
diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json
index a02211b8a..7cc5903cd 100644
--- a/app/javascript/mastodon/locales/zh-CN.json
+++ b/app/javascript/mastodon/locales/zh-CN.json
@@ -14,6 +14,7 @@
   "account.mute": "隐藏 @{name}",
   "account.mute_notifications": "隐藏来自 @{name} 的通知",
   "account.posts": "嘟文",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "举报 @{name}",
   "account.requested": "正在等待对方同意。点击以取消发送关注请求",
   "account.share": "分享 @{name} 的个人资料",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}分",
   "relative_time.seconds": "{number}秒",
   "reply_indicator.cancel": "取消",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "附言",
   "report.submit": "提交",
   "report.target": "举报 {target}",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "嘟文",
   "search_popout.tips.text": "使用普通字符进行搜索将会返回昵称、用户名和话题标签",
   "search_popout.tips.user": "用户",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "共 {count, number} 个结果",
   "standalone.public_title": "大家都在干啥?",
   "status.block": "屏蔽 @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "将文件拖放到此处开始上传",
   "upload_button.label": "上传媒体文件",
   "upload_form.description": "为视觉障碍人士添加文字说明",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "取消上传",
   "upload_progress.label": "上传中…",
   "video.close": "关闭视频",
diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json
index 0a3ae423d..d21ecc463 100644
--- a/app/javascript/mastodon/locales/zh-HK.json
+++ b/app/javascript/mastodon/locales/zh-HK.json
@@ -14,6 +14,7 @@
   "account.mute": "將 @{name} 靜音",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.posts": "文章",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "舉報 @{name}",
   "account.requested": "等候審批",
   "account.share": "分享 @{name} 的個人資料",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "取消",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "額外訊息",
   "report.submit": "提交",
   "report.target": "舉報",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
   "search_popout.tips.user": "user",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} 項結果",
   "standalone.public_title": "站點一瞥…",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "將檔案拖放至此上載",
   "upload_button.label": "上載媒體檔案",
   "upload_form.description": "Describe for the visually impaired",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "還原",
   "upload_progress.label": "上載中……",
   "video.close": "關閉影片",
diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json
index 1201fe3c7..f1ae29283 100644
--- a/app/javascript/mastodon/locales/zh-TW.json
+++ b/app/javascript/mastodon/locales/zh-TW.json
@@ -14,6 +14,7 @@
   "account.mute": "消音 @{name}",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.posts": "貼文",
+  "account.posts_with_replies": "Toots with replies",
   "account.report": "檢舉 @{name}",
   "account.requested": "正在等待許可",
   "account.share": "分享 @{name} 的用者資訊",
@@ -207,6 +208,9 @@
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "取消",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
   "report.placeholder": "更多訊息",
   "report.submit": "送出",
   "report.target": "通報中",
@@ -216,6 +220,9 @@
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
   "search_popout.tips.user": "user",
+  "search_results.accounts": "People",
+  "search_results.hashtags": "Hashtags",
+  "search_results.statuses": "Toots",
   "search_results.total": "{count, number} 項結果",
   "standalone.public_title": "站點一瞥…",
   "status.block": "Block @{name}",
@@ -252,6 +259,7 @@
   "upload_area.title": "拖放來上傳",
   "upload_button.label": "增加媒體",
   "upload_form.description": "Describe for the visually impaired",
+  "upload_form.focus": "Crop",
   "upload_form.undo": "復原",
   "upload_progress.label": "上傳中...",
   "video.close": "關閉影片",
diff --git a/app/javascript/mastodon/reducers/reports.js b/app/javascript/mastodon/reducers/reports.js
index a08bbec38..21ae6f93f 100644
--- a/app/javascript/mastodon/reducers/reports.js
+++ b/app/javascript/mastodon/reducers/reports.js
@@ -6,6 +6,7 @@ import {
   REPORT_CANCEL,
   REPORT_STATUS_TOGGLE,
   REPORT_COMMENT_CHANGE,
+  REPORT_FORWARD_CHANGE,
 } from '../actions/reports';
 import { Map as ImmutableMap, Set as ImmutableSet } from 'immutable';
 
@@ -15,6 +16,7 @@ const initialState = ImmutableMap({
     account_id: null,
     status_ids: ImmutableSet(),
     comment: '',
+    forward: false,
   }),
 });
 
@@ -42,6 +44,8 @@ export default function reports(state = initialState, action) {
     });
   case REPORT_COMMENT_CHANGE:
     return state.setIn(['new', 'comment'], action.comment);
+  case REPORT_FORWARD_CHANGE:
+    return state.setIn(['new', 'forward'], action.forward);
   case REPORT_SUBMIT_REQUEST:
     return state.setIn(['new', 'isSubmitting'], true);
   case REPORT_SUBMIT_FAIL:
diff --git a/app/javascript/styles/mastodon/about.scss b/app/javascript/styles/mastodon/about.scss
index a95b75984..9ce83aa9b 100644
--- a/app/javascript/styles/mastodon/about.scss
+++ b/app/javascript/styles/mastodon/about.scss
@@ -15,117 +15,169 @@ $small-breakpoint: 960px;
   }
 }
 
-.show-xs,
-.show-sm {
-  display: none;
-}
+.landing-page {
+  .grid {
+    display: grid;
+    grid-gap: 10px;
+    grid-template-columns: 1fr 2fr;
+    grid-auto-columns: 25%;
+    grid-auto-rows: max-content;
+
+    .column-0 {
+      display: none;
+    }
 
-.show-m {
-  display: block;
-}
+    .column-1 {
+      grid-column: 1;
+      grid-row: 1;
+    }
 
-@media screen and (max-width: $small-breakpoint) {
-  .hide-sm {
-    display: none !important;
-  }
+    .column-2 {
+      grid-column: 2;
+      grid-row: 1;
+    }
 
-  .show-sm {
-    display: block !important;
-  }
-}
+    .column-3 {
+      grid-column: 3;
+      grid-row: 1 / 3;
+    }
 
-@media screen and (max-width: $column-breakpoint) {
-  .hide-xs {
-    display: none !important;
+    .column-4 {
+      grid-column: 1 / 3;
+      grid-row: 2;
+    }
   }
 
-  .show-xs {
-    display: block !important;
-  }
-}
+  @media screen and (max-width: $small-breakpoint) {
+    .grid {
+      grid-template-columns: 40% 60%;
 
-.row {
-  display: flex;
-  flex-wrap: wrap;
-  margin: 0 -5px;
+      .column-0 {
+        display: none;
+      }
 
-  @for $i from 1 through 15 {
-    .column-#{$i} {
-      box-sizing: border-box;
-      min-height: 1px;
-      flex: 0 0 percentage($i / 15);
-      max-width: percentage($i / 15);
-      padding: 0 5px;
+      .column-1 {
+        grid-column: 1;
+        grid-row: 1;
 
-      @media screen and (max-width: $small-breakpoint) {
-        &-sm {
-          box-sizing: border-box;
-          min-height: 1px;
-          flex: 0 0 percentage($i / 15);
-          max-width: percentage($i / 15);
-          padding: 0 5px;
-
-          @media screen and (max-width: $column-breakpoint) {
-            max-width: 100%;
-            flex: 0 0 100%;
-            margin-bottom: 10px;
-
-            &:last-child {
-              margin-bottom: 0;
-            }
-          }
+        &.non-preview .landing-page__forms {
+          height: 100%;
         }
       }
 
-      @media screen and (max-width: $column-breakpoint) {
-        max-width: 100%;
-        flex: 0 0 100%;
-        margin-bottom: 10px;
+      .column-2 {
+        grid-column: 2;
+        grid-row: 1 / 3;
 
-        &:last-child {
-          margin-bottom: 0;
+        &.non-preview {
+          grid-column: 2;
+          grid-row: 1;
+        }
+      }
+
+      .column-3 {
+        grid-column: 1;
+        grid-row: 2 / 4;
+      }
+
+      .column-4 {
+        grid-column: 2;
+        grid-row: 3;
+
+        &.non-preview {
+          grid-column: 1 / 3;
+          grid-row: 2;
         }
       }
     }
   }
-}
 
-.column-flex {
-  display: flex;
-  flex-direction: column;
-}
+  @media screen and (max-width: $column-breakpoint) {
+    .grid {
+      grid-template-columns: auto;
 
-.separator-or {
-  position: relative;
-  margin: 40px 0;
-  text-align: center;
+      .column-0 {
+        display: block;
+        grid-column: 1;
+        grid-row: 1;
+      }
 
-  &::before {
-    content: "";
-    display: block;
-    width: 100%;
-    height: 0;
-    border-bottom: 1px solid rgba($ui-base-lighter-color, .6);
-    position: absolute;
-    top: 50%;
-    left: 0;
+      .column-1 {
+        grid-column: 1;
+        grid-row: 3;
+
+        .brand {
+          display: none;
+        }
+      }
+
+      .column-2 {
+        grid-column: 1;
+        grid-row: 2;
+
+        .landing-page__logo,
+        .landing-page__call-to-action {
+          display: none;
+        }
+
+        &.non-preview {
+          grid-column: 1;
+          grid-row: 2;
+        }
+      }
+
+      .column-3 {
+        grid-column: 1;
+        grid-row: 5;
+      }
+
+      .column-4 {
+        grid-column: 1;
+        grid-row: 4;
+
+        &.non-preview {
+          grid-column: 1;
+          grid-row: 4;
+        }
+      }
+    }
   }
 
-  span {
-    display: inline-block;
-    background: $ui-base-color;
-    font-size: 12px;
-    font-weight: 500;
-    color: $ui-primary-color;
-    text-transform: uppercase;
+  .column-flex {
+    display: flex;
+    flex-direction: column;
+  }
+
+  .separator-or {
     position: relative;
-    z-index: 1;
-    padding: 0 8px;
-    cursor: default;
+    margin: 40px 0;
+    text-align: center;
+
+    &::before {
+      content: "";
+      display: block;
+      width: 100%;
+      height: 0;
+      border-bottom: 1px solid rgba($ui-base-lighter-color, .6);
+      position: absolute;
+      top: 50%;
+      left: 0;
+    }
+
+    span {
+      display: inline-block;
+      background: $ui-base-color;
+      font-size: 12px;
+      font-weight: 500;
+      color: $ui-primary-color;
+      text-transform: uppercase;
+      position: relative;
+      z-index: 1;
+      padding: 0 8px;
+      cursor: default;
+    }
   }
-}
 
-.landing-page {
   p,
   li {
     font-family: 'mastodon-font-sans-serif', sans-serif;
@@ -539,6 +591,7 @@ $small-breakpoint: 960px;
 
       img {
         position: static;
+        padding: 10px 0;
       }
 
       @media screen and (max-width: $small-breakpoint) {
@@ -558,18 +611,33 @@ $small-breakpoint: 960px;
   }
 
   &__call-to-action {
-    margin-bottom: 10px;
     background: darken($ui-base-color, 4%);
     border-radius: 4px;
     padding: 25px 40px;
     overflow: hidden;
 
     .row {
+      display: flex;
+      flex-direction: row-reverse;
+      flex-wrap: wrap;
+      justify-content: space-between;
       align-items: center;
     }
 
-    .information-board__section {
-      padding: 0;
+    .row__information-board {
+      display: flex;
+      justify-content: flex-end;
+      align-items: flex-end;
+
+      .information-board__section {
+        flex: 1 0 auto;
+        padding: 0 10px;
+      }
+    }
+
+    .row__mascot {
+      flex: 1;
+      margin: 10px -50px 0 0;
     }
   }
 
@@ -619,6 +687,8 @@ $small-breakpoint: 960px;
 
   &__short-description {
     .row {
+      display: flex;
+      flex-wrap: wrap;
       align-items: center;
       margin-bottom: 40px;
     }
@@ -668,7 +738,6 @@ $small-breakpoint: 960px;
     height: 100%;
 
     @media screen and (max-width: $small-breakpoint) {
-      margin-bottom: 10px;
       height: auto;
     }
 
@@ -717,6 +786,7 @@ $small-breakpoint: 960px;
     width: 100%;
     flex: 1 1 auto;
     overflow: hidden;
+    height: 100%;
 
     .column-header {
       color: inherit;
@@ -942,93 +1012,54 @@ $small-breakpoint: 960px;
   }
 
   &.tag-page {
-    .features {
-      padding: 30px 0;
-
-      .container-alt {
-        max-width: 820px;
-
-        #mastodon-timeline {
-          margin-right: 0;
-          border-top-right-radius: 0;
-        }
-
-        .about-mastodon {
-          .about-hashtag {
-            background: darken($ui-base-color, 4%);
-            padding: 0 20px 20px 30px;
-            border-radius: 0 5px 5px 0;
-
-            .brand {
-              padding-top: 20px;
-              margin-bottom: 20px;
-
-              img {
-                height: 48px;
-                width: auto;
-              }
-            }
-
-            p {
-              strong {
-                color: $ui-secondary-color;
-                font-weight: 700;
-              }
-            }
+    .grid {
+      @media screen and (min-width: $small-breakpoint) {
+        grid-template-columns: 33% 67%;
+      }
 
-            .cta {
-              margin: 0;
+      .column-2 {
+        grid-column: 2;
+        grid-row: 1;
+      }
+    }
 
-              .button {
-                margin-right: 4px;
-              }
-            }
-          }
+    .brand {
+      text-align: unset;
+      padding: 0;
 
-          .features-list {
-            margin-left: 30px;
-            margin-right: 10px;
-          }
-        }
+      img {
+        height: 48px;
+        width: auto;
       }
     }
 
-    @media screen and (max-width: 675px) {
-      .features {
-        padding: 10px 0;
+    .cta {
+      margin: 0;
 
-        .container-alt {
-          display: flex;
-          flex-direction: column;
-
-          #mastodon-timeline {
-            order: 2;
-            flex: 0 0 auto;
-            height: 60vh;
-            margin-bottom: 20px;
-            border-top-right-radius: 4px;
-          }
+      .button {
+        margin-right: 4px;
+      }
+    }
 
-          .about-mastodon {
-            order: 1;
-            flex: 0 0 auto;
-            max-width: 100%;
+    @media screen and (max-width: $column-breakpoint) {
+      .grid {
+        .column-1 {
+          grid-column: 1;
+          grid-row: 2;
+        }
 
-            .about-hashtag {
-              background: unset;
-              padding: 0;
-              border-radius: 0;
+        .column-2 {
+          grid-column: 1;
+          grid-row: 1;
+        }
+      }
 
-              .cta {
-                margin: 20px 0;
-              }
-            }
+      .brand {
+        margin: 0;
+      }
 
-            .features-list {
-              display: none;
-            }
-          }
-        }
+      .landing-page__features {
+        display: none;
       }
     }
   }
diff --git a/app/javascript/styles/mastodon/accounts.scss b/app/javascript/styles/mastodon/accounts.scss
index 9015d04cb..873963c90 100644
--- a/app/javascript/styles/mastodon/accounts.scss
+++ b/app/javascript/styles/mastodon/accounts.scss
@@ -97,32 +97,6 @@
     }
   }
 
-  .controls {
-    position: absolute;
-    top: 15px;
-    left: 15px;
-    z-index: 2;
-
-    .icon-button {
-      color: rgba($white, 0.8);
-      text-decoration: none;
-      font-size: 13px;
-      line-height: 13px;
-      font-weight: 500;
-
-      .fa {
-        font-weight: 400;
-        margin-right: 5px;
-      }
-
-      &:hover,
-      &:active,
-      &:focus {
-        color: $white;
-      }
-    }
-  }
-
   .roles {
     margin-bottom: 30px;
     padding: 0 15px;
@@ -226,6 +200,40 @@
   }
 }
 
+.card,
+.account-grid-card {
+  .controls {
+    position: absolute;
+    top: 15px;
+    left: 15px;
+    z-index: 2;
+
+    .icon-button {
+      color: rgba($white, 0.8);
+      text-decoration: none;
+      font-size: 13px;
+      line-height: 13px;
+      font-weight: 500;
+
+      .fa {
+        font-weight: 400;
+        margin-right: 5px;
+      }
+
+      &:hover,
+      &:active,
+      &:focus {
+        color: $white;
+      }
+    }
+  }
+}
+
+.account-grid-card .controls {
+  left: auto;
+  right: 15px;
+}
+
 .pagination {
   padding: 30px 0;
   text-align: center;
@@ -233,8 +241,8 @@
 
   a,
   .current,
-  .next,
-  .prev,
+  .newer,
+  .older,
   .page,
   .gap {
     font-size: 14px;
@@ -257,13 +265,13 @@
     cursor: default;
   }
 
-  .prev,
-  .next {
+  .older,
+  .newer {
     text-transform: uppercase;
     color: $ui-secondary-color;
   }
 
-  .prev {
+  .older {
     float: left;
     padding-left: 0;
 
@@ -273,7 +281,7 @@
     }
   }
 
-  .next {
+  .newer {
     float: right;
     padding-right: 0;
 
@@ -295,8 +303,8 @@
       display: none;
     }
 
-    .next,
-    .prev {
+    .newer,
+    .older {
       display: inline-block;
     }
   }
@@ -411,13 +419,14 @@
       font-weight: 400;
     }
 
-    .note {
+    .account__header__content {
       padding: 10px 15px;
       padding-top: 15px;
-      box-sizing: border-box;
       color: lighten($ui-base-color, 26%);
       word-wrap: break-word;
-      min-height: 80px;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      height: 5.5em;
     }
   }
 }
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index 0b5a721a7..d8364ef81 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -1878,7 +1878,7 @@
   font-size: 14px;
   font-weight: 500;
   border-bottom: 2px solid lighten($ui-base-color, 8%);
-  transition: all 200ms linear;
+  transition: all 50ms linear;
 
   .fa {
     font-weight: 400;
@@ -1895,7 +1895,6 @@
   &:active {
     @media screen and (min-width: 631px) {
       background: lighten($ui-base-color, 14%);
-      transition: all 100ms linear;
     }
   }
 
@@ -3891,8 +3890,7 @@ a.status-card {
 
 .boost-modal__action-bar,
 .confirmation-modal__action-bar,
-.mute-modal__action-bar,
-.report-modal__action-bar {
+.mute-modal__action-bar {
   display: flex;
   justify-content: space-between;
   background: $ui-secondary-color;
@@ -3936,21 +3934,94 @@ a.status-card {
   vertical-align: middle;
 }
 
+.report-modal {
+  width: 90vw;
+  max-width: 700px;
+}
+
+.report-modal__container {
+  display: flex;
+  border-top: 1px solid $ui-secondary-color;
+
+  @media screen and (max-width: 480px) {
+    flex-wrap: wrap;
+    overflow-y: auto;
+  }
+}
+
 .report-modal__statuses,
 .report-modal__comment {
-  padding: 10px;
+  box-sizing: border-box;
+  width: 50%;
+
+  @media screen and (max-width: 480px) {
+    width: 100%;
+  }
 }
 
 .report-modal__statuses {
+  flex: 1 1 auto;
   min-height: 20vh;
   max-height: 40vh;
   overflow-y: auto;
   overflow-x: hidden;
+
+  @media screen and (max-width: 480px) {
+    max-height: 10vh;
+  }
 }
 
 .report-modal__comment {
+  padding: 20px;
+  border-right: 1px solid $ui-secondary-color;
+  max-width: 320px;
+
+  p {
+    font-size: 14px;
+    line-height: 20px;
+    margin-bottom: 20px;
+  }
+
   .setting-text {
-    margin-top: 10px;
+    display: block;
+    box-sizing: border-box;
+    width: 100%;
+    margin: 0;
+    color: $ui-base-color;
+    background: $white;
+    padding: 10px;
+    font-family: inherit;
+    font-size: 14px;
+    resize: vertical;
+    border: 0;
+    outline: 0;
+    border-radius: 4px;
+    border: 1px solid $ui-secondary-color;
+    margin-bottom: 20px;
+
+    &:focus {
+      border: 1px solid darken($ui-secondary-color, 8%);
+    }
+  }
+
+  .setting-toggle {
+    margin-top: 20px;
+    margin-bottom: 24px;
+
+    &__label {
+      color: $ui-base-color;
+      font-size: 14px;
+    }
+  }
+
+  @media screen and (max-width: 480px) {
+    padding: 10px;
+    max-width: 100%;
+    order: 2;
+
+    .setting-toggle {
+      margin-bottom: 4px;
+    }
   }
 }
 
@@ -4043,6 +4114,15 @@ a.status-card {
   }
 }
 
+.report-modal__target {
+  padding: 20px;
+
+  .media-modal__close {
+    top: 19px;
+    right: 15px;
+  }
+}
+
 .loading-bar {
   background-color: $ui-highlight-color;
   height: 3px;
@@ -4154,6 +4234,7 @@ a.status-card {
   &.standalone {
     .media-gallery__item-gifv-thumbnail {
       transform: none;
+      top: 0;
     }
   }
 }
@@ -4283,7 +4364,7 @@ a.status-card {
 
   &.inline {
     video {
-      object-fit: cover;
+      object-fit: contain;
       position: relative;
       top: 50%;
       transform: translateY(-50%);
@@ -4503,64 +4584,96 @@ a.status-card {
 /* End Video Player */
 
 .account-gallery__container {
-  margin: -2px;
-  padding: 4px;
   display: flex;
+  justify-content: center;
   flex-wrap: wrap;
+  padding: 2px;
 }
 
 .account-gallery__item {
-  flex: 1 1 auto;
-  width: calc(100% / 3 - 4px);
-  height: 95px;
-  margin: 2px;
+  flex-grow: 1;
+  width: 50%;
+  overflow: hidden;
+  position: relative;
+
+  &::before {
+    content: "";
+    display: block;
+    padding-top: 100%;
+  }
 
   a {
     display: block;
-    width: 100%;
-    height: 100%;
+    width: calc(100% - 4px);
+    height: calc(100% - 4px);
+    margin: 2px;
+    top: 0;
+    left: 0;
     background-color: $base-overlay-background;
     background-size: cover;
     background-position: center;
-    position: relative;
+    position: absolute;
     color: inherit;
     text-decoration: none;
+    border-radius: 4px;
 
     &:hover,
     &:active,
     &:focus {
       outline: 0;
+
+      &::before {
+        content: "";
+        display: block;
+        width: 100%;
+        height: 100%;
+        background: rgba($base-overlay-background, 0.3);
+        border-radius: 4px;
+      }
     }
   }
 }
 
-.account-section-headline {
-  color: $ui-base-lighter-color;
-  background: lighten($ui-base-color, 2%);
-  border-bottom: 1px solid lighten($ui-base-color, 4%);
-  padding: 15px 10px;
-  font-size: 14px;
-  font-weight: 500;
-  position: relative;
+.account__section-headline {
+  background: darken($ui-base-color, 4%);
+  border-bottom: 1px solid lighten($ui-base-color, 8%);
   cursor: default;
+  display: flex;
 
-  &::before,
-  &::after {
+  a {
     display: block;
-    content: "";
-    position: absolute;
-    bottom: 0;
-    left: 18px;
-    width: 0;
-    height: 0;
-    border-style: solid;
-    border-width: 0 10px 10px;
-    border-color: transparent transparent lighten($ui-base-color, 4%);
-  }
+    flex: 1 1 auto;
+    color: $ui-primary-color;
+    padding: 15px 0;
+    font-size: 14px;
+    font-weight: 500;
+    text-align: center;
+    text-decoration: none;
+    position: relative;
 
-  &::after {
-    bottom: -1px;
-    border-color: transparent transparent $ui-base-color;
+    &.active {
+      color: $ui-secondary-color;
+
+      &::before,
+      &::after {
+        display: block;
+        content: "";
+        position: absolute;
+        bottom: 0;
+        left: 50%;
+        width: 0;
+        height: 0;
+        transform: translateX(-50%);
+        border-style: solid;
+        border-width: 0 10px 10px;
+        border-color: transparent transparent lighten($ui-base-color, 8%);
+      }
+
+      &::after {
+        bottom: -1px;
+        border-color: transparent transparent $ui-base-color;
+      }
+    }
   }
 }
 
@@ -4910,3 +5023,27 @@ noscript {
     left: 0;
   }
 }
+
+.floating-action-button {
+  position: fixed;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  width: 3.9375rem;
+  height: 3.9375rem;
+  bottom: 1.3125rem;
+  right: 1.3125rem;
+  background: darken($ui-highlight-color, 3%);
+  color: $white;
+  border-radius: 50%;
+  font-size: 21px;
+  line-height: 21px;
+  text-decoration: none;
+  box-shadow: 2px 3px 9px rgba($base-shadow-color, 0.4);
+
+  &:hover,
+  &:focus,
+  &:active {
+    background: lighten($ui-highlight-color, 7%);
+  }
+}
diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss
index dec7d2284..2e38cda4e 100644
--- a/app/javascript/styles/mastodon/forms.scss
+++ b/app/javascript/styles/mastodon/forms.scss
@@ -278,6 +278,11 @@ code {
   .actions {
     margin-top: 30px;
     display: flex;
+
+    &.actions--top {
+      margin-top: 0;
+      margin-bottom: 30px;
+    }
   }
 
   button,
diff --git a/app/lib/activitypub/activity.rb b/app/lib/activitypub/activity.rb
index 4617905c6..6f4a3b491 100644
--- a/app/lib/activitypub/activity.rb
+++ b/app/lib/activitypub/activity.rb
@@ -44,6 +44,8 @@ class ActivityPub::Activity
         ActivityPub::Activity::Accept
       when 'Reject'
         ActivityPub::Activity::Reject
+      when 'Flag'
+        ActivityPub::Activity::Flag
       end
     end
   end
diff --git a/app/lib/activitypub/activity/flag.rb b/app/lib/activitypub/activity/flag.rb
new file mode 100644
index 000000000..36d3c5730
--- /dev/null
+++ b/app/lib/activitypub/activity/flag.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+class ActivityPub::Activity::Flag < ActivityPub::Activity
+  def perform
+    target_accounts            = object_uris.map { |uri| account_from_uri(uri) }.compact.select(&:local?)
+    target_statuses_by_account = object_uris.map { |uri| status_from_uri(uri) }.compact.select(&:local?).group_by(&:account_id)
+
+    target_accounts.each do |target_account|
+      next if Report.where(account: @account, target_account: target_account).exists?
+
+      target_statuses = target_statuses_by_account[target_account.id]
+
+      ReportService.new.call(
+        @account,
+        target_account,
+        status_ids: target_statuses.nil? ? [] : target_statuses.map(&:id),
+        comment: @json['content'] || ''
+      )
+    end
+  end
+
+  def object_uris
+    @object_uris ||= Array(@object.is_a?(Array) ? @object.map { |item| value_or_id(item) } : value_or_id(@object))
+  end
+end
diff --git a/app/lib/activitypub/activity/reject.rb b/app/lib/activitypub/activity/reject.rb
index d815feeb6..28d472883 100644
--- a/app/lib/activitypub/activity/reject.rb
+++ b/app/lib/activitypub/activity/reject.rb
@@ -17,6 +17,8 @@ class ActivityPub::Activity::Reject < ActivityPub::Activity
 
     follow_request = FollowRequest.find_by(account: target_account, target_account: @account)
     follow_request&.reject!
+
+    UnfollowService.new.call(target_account, @account) if target_account.following?(@account)
   end
 
   def target_uri
diff --git a/app/lib/exceptions.rb b/app/lib/exceptions.rb
index b2489711d..95e3365c2 100644
--- a/app/lib/exceptions.rb
+++ b/app/lib/exceptions.rb
@@ -4,6 +4,7 @@ module Mastodon
   class Error < StandardError; end
   class NotPermittedError < Error; end
   class ValidationError < Error; end
+  class HostValidationError < ValidationError; end
   class RaceConditionError < Error; end
 
   class UnexpectedResponseError < Error
diff --git a/app/lib/request.rb b/app/lib/request.rb
index 7671f4ffc..5776b3d78 100644
--- a/app/lib/request.rb
+++ b/app/lib/request.rb
@@ -1,5 +1,8 @@
 # frozen_string_literal: true
 
+require 'ipaddr'
+require 'socket'
+
 class Request
   REQUEST_TARGET = '(request-target)'
 
@@ -8,7 +11,7 @@ class Request
   def initialize(verb, url, **options)
     @verb    = verb
     @url     = Addressable::URI.parse(url).normalize
-    @options = options
+    @options = options.merge(socket_class: Socket)
     @headers = {}
 
     set_common_headers!
@@ -87,4 +90,18 @@ class Request
   def http_client
     HTTP.timeout(:per_operation, timeout).follow(max_hops: 2)
   end
+
+  class Socket < TCPSocket
+    class << self
+      def open(host, *args)
+        address = IPSocket.getaddress(host)
+        raise Mastodon::HostValidationError if PrivateAddressCheck.private_address? IPAddr.new(address)
+        super address, *args
+      end
+
+      alias new open
+    end
+  end
+
+  private_constant :Socket
 end
diff --git a/app/lib/sidekiq_error_handler.rb b/app/lib/sidekiq_error_handler.rb
new file mode 100644
index 000000000..23785cf05
--- /dev/null
+++ b/app/lib/sidekiq_error_handler.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class SidekiqErrorHandler
+  def call(*)
+    yield
+  rescue Mastodon::HostValidationError => e
+    Rails.logger.error "#{e.class}: #{e.message}"
+    Rails.logger.error e.backtrace.join("\n")
+    # Do not retry
+  end
+end
diff --git a/app/models/concerns/paginable.rb b/app/models/concerns/paginable.rb
index 6061bf9bd..66695677e 100644
--- a/app/models/concerns/paginable.rb
+++ b/app/models/concerns/paginable.rb
@@ -10,5 +10,14 @@ module Paginable
       query = query.where(arel_table[:id].gt(since_id)) if since_id.present?
       query
     }
+
+    # Differs from :paginate_by_max_id in that it gives the results immediately following min_id,
+    # whereas since_id gives the items with largest id, but with since_id as a cutoff.
+    # Results will be in ascending order by id.
+    scope :paginate_by_min_id, ->(limit, min_id = nil) {
+      query = reorder(arel_table[:id]).limit(limit)
+      query = query.where(arel_table[:id].gt(min_id)) if min_id.present?
+      query
+    }
   end
 end
diff --git a/app/models/import.rb b/app/models/import.rb
index ba88435bf..fdb4c6b80 100644
--- a/app/models/import.rb
+++ b/app/models/import.rb
@@ -26,7 +26,7 @@ class Import < ApplicationRecord
 
   validates :type, presence: true
 
-  has_attached_file :data, url: '/system/:hash.:extension', hash_secret: ENV['PAPERCLIP_SECRET']
+  has_attached_file :data
   validates_attachment_content_type :data, content_type: FILE_TYPES
   validates_attachment_presence :data
 end
diff --git a/app/models/report.rb b/app/models/report.rb
index f55fb6d3e..dd123fc15 100644
--- a/app/models/report.rb
+++ b/app/models/report.rb
@@ -24,6 +24,10 @@ class Report < ApplicationRecord
 
   validates :comment, length: { maximum: 1000 }
 
+  def object_type
+    :flag
+  end
+
   def statuses
     Status.where(id: status_ids).includes(:account, :media_attachments, :mentions)
   end
diff --git a/app/models/user.rb b/app/models/user.rb
index 197799294..b3e5f9352 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -44,7 +44,7 @@ class User < ApplicationRecord
   ACTIVE_DURATION = 14.days
 
   devise :two_factor_authenticatable,
-         otp_secret_encryption_key: ENV['OTP_SECRET']
+         otp_secret_encryption_key: ENV.fetch('OTP_SECRET')
 
   devise :two_factor_backupable,
          otp_number_of_backup_codes: 10
@@ -52,7 +52,6 @@ class User < ApplicationRecord
   devise :registerable, :recoverable, :rememberable, :trackable, :validatable,
          :confirmable
 
-  devise :pam_authenticatable if Devise.pam_authentication
   devise :omniauthable
 
   belongs_to :account, inverse_of: :user
@@ -117,6 +116,12 @@ class User < ApplicationRecord
     acc.destroy! unless save
   end
 
+  def ldap_setup(_attributes)
+    self.confirmed_at = Time.now.utc
+    self.admin = false
+    save!
+  end
+
   def confirmed?
     confirmed_at.present?
   end
@@ -247,17 +252,17 @@ class User < ApplicationRecord
   end
 
   def password_required?
-    return false if Devise.pam_authentication
+    return false if Devise.pam_authentication || Devise.ldap_authentication
     super
   end
 
   def send_reset_password_instructions
-    return false if encrypted_password.blank? && Devise.pam_authentication
+    return false if encrypted_password.blank? && (Devise.pam_authentication || Devise.ldap_authentication)
     super
   end
 
   def reset_password!(new_password, new_password_confirmation)
-    return false if encrypted_password.blank? && Devise.pam_authentication
+    return false if encrypted_password.blank? && (Devise.pam_authentication || Devise.ldap_authentication)
     super
   end
 
@@ -280,6 +285,17 @@ class User < ApplicationRecord
     end
   end
 
+  def self.ldap_get_user(attributes = {})
+    resource = joins(:account).find_by(accounts: { username: attributes[Devise.ldap_uid.to_sym].first })
+
+    if resource.blank?
+      resource = new(email: attributes[:mail].first, account_attributes: { username: attributes[Devise.ldap_uid.to_sym].first })
+      resource.ldap_setup(attributes)
+    end
+
+    resource
+  end
+
   def self.authenticate_with_pam(attributes = {})
     return nil unless Devise.pam_authentication
     super
diff --git a/app/serializers/activitypub/flag_serializer.rb b/app/serializers/activitypub/flag_serializer.rb
new file mode 100644
index 000000000..53e8f726d
--- /dev/null
+++ b/app/serializers/activitypub/flag_serializer.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class ActivityPub::FlagSerializer < ActiveModel::Serializer
+  attributes :id, :type, :actor, :content
+  attribute :virtual_object, key: :object
+
+  def id
+    # This is nil for now
+    ActivityPub::TagManager.instance.uri_for(object)
+  end
+
+  def type
+    'Flag'
+  end
+
+  def actor
+    ActivityPub::TagManager.instance.uri_for(instance_options[:account] || object.account)
+  end
+
+  def virtual_object
+    [ActivityPub::TagManager.instance.uri_for(object.target_account)] + object.statuses.map { |s| ActivityPub::TagManager.instance.uri_for(s) }
+  end
+
+  def content
+    object.comment
+  end
+end
diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb
index 5434f1c56..1d17e2b0a 100644
--- a/app/serializers/initial_state_serializer.rb
+++ b/app/serializers/initial_state_serializer.rb
@@ -22,6 +22,7 @@ class InitialStateSerializer < ActiveModel::Serializer
       locale: I18n.locale,
       domain: Rails.configuration.x.local_domain,
       admin: object.admin&.id&.to_s,
+      search_enabled: Chewy.enabled?,
     }
 
     if object.current_account
diff --git a/app/serializers/rest/instance_serializer.rb b/app/serializers/rest/instance_serializer.rb
index 65907dad2..0168b18ea 100644
--- a/app/serializers/rest/instance_serializer.rb
+++ b/app/serializers/rest/instance_serializer.rb
@@ -4,7 +4,12 @@ class REST::InstanceSerializer < ActiveModel::Serializer
   include RoutingHelper
 
   attributes :uri, :title, :description, :email,
-             :version, :urls, :stats, :thumbnail, :max_toot_chars
+             :version, :urls, :stats, :thumbnail, :max_toot_chars,
+             :languages
+
+  has_one :contact_account, serializer: REST::AccountSerializer
+
+  delegate :contact_account, to: :instance_presenter
 
   def uri
     Rails.configuration.x.local_domain
@@ -46,6 +51,10 @@ class REST::InstanceSerializer < ActiveModel::Serializer
     { streaming_api: Rails.configuration.x.streaming_api_base_url }
   end
 
+  def languages
+    [ENV.fetch('DEFAULT_LOCALE', I18n.default_locale)]
+  end
+
   private
 
   def instance_presenter
diff --git a/app/services/report_service.rb b/app/services/report_service.rb
new file mode 100644
index 000000000..c06488a6d
--- /dev/null
+++ b/app/services/report_service.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+class ReportService < BaseService
+  def call(source_account, target_account, options = {})
+    @source_account = source_account
+    @target_account = target_account
+    @status_ids     = options.delete(:status_ids) || []
+    @comment        = options.delete(:comment) || ''
+    @options        = options
+
+    create_report!
+    notify_staff!
+    forward_to_origin! if !@target_account.local? && ActiveModel::Type::Boolean.new.cast(@options[:forward])
+
+    @report
+  end
+
+  private
+
+  def create_report!
+    @report = @source_account.reports.create!(
+      target_account: @target_account,
+      status_ids: @status_ids,
+      comment: @comment
+    )
+  end
+
+  def notify_staff!
+    User.staff.includes(:account).each do |u|
+      AdminMailer.new_report(u.account, @report).deliver_later
+    end
+  end
+
+  def forward_to_origin!
+    ActivityPub::DeliveryWorker.perform_async(
+      payload,
+      some_local_account.id,
+      @target_account.inbox_url
+    )
+  end
+
+  def payload
+    Oj.dump(ActiveModelSerializers::SerializableResource.new(
+      @report,
+      serializer: ActivityPub::FlagSerializer,
+      adapter: ActivityPub::Adapter,
+      account: some_local_account
+    ).as_json)
+  end
+
+  def some_local_account
+    @some_local_account ||= Account.local.where(suspended: false).first
+  end
+end
diff --git a/app/views/about/show.html.haml b/app/views/about/show.html.haml
index bc357e522..37bfde887 100644
--- a/app/views/about/show.html.haml
+++ b/app/views/about/show.html.haml
@@ -7,51 +7,100 @@
 
 .landing-page.alternative
   .container
-    .row
-      .column-4.hide-sm.show-xs.show-m
-        .landing-page__forms
-          .brand
-            = link_to root_url do
-              = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
-
-          .hide-xs
+    .grid
+      .column-0
+        .brand
+          = link_to root_url do
+            = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
+
+      - if Setting.timeline_preview
+        .column-1
+          .landing-page__forms
+            .brand
+              = link_to root_url do
+                = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
+
             = render 'forms'
 
-      .column-7.column-9-sm
-        .landing-page__hero
-          = image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url || asset_pack_path('preview.jpg'), alt: @instance_presenter.site_title
+      - else
+        .column-1.non-preview
+          .landing-page__forms
+            .brand
+              = link_to root_url do
+                = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
 
-        .landing-page__information
-          .landing-page__short-description
+            = render 'forms'
+
+      - if Setting.timeline_preview
+        .column-2
+          .landing-page__hero
+            = image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url || asset_pack_path('preview.jpg'), alt: @instance_presenter.site_title
+
+          .landing-page__information
+            .landing-page__short-description
+              .row
+                .landing-page__logo
+                  = image_tag asset_pack_path('logo_transparent.svg'), alt: 'Mastodon'
+
+                %h1
+                  = @instance_presenter.site_title
+                  %small!= t 'about.hosted_on', domain: content_tag(:span, site_hostname)
+
+              %p= @instance_presenter.site_description.html_safe.presence || t('about.generic_description', domain: site_hostname)
+
+          .landing-page__call-to-action
             .row
-              .landing-page__logo.hide-xs
-                = image_tag asset_pack_path('logo_transparent.svg'), alt: 'Mastodon'
+              .row__information-board
+                .information-board__section
+                  %span= t 'about.user_count_before'
+                  %strong= number_with_delimiter @instance_presenter.user_count
+                  %span= t 'about.user_count_after'
+                .information-board__section
+                  %span= t 'about.status_count_before'
+                  %strong= number_with_delimiter @instance_presenter.status_count
+                  %span= t 'about.status_count_after'
+              .row__mascot
+                .landing-page__mascot
+                  = image_tag asset_pack_path('elephant_ui_plane.svg')
 
-              %h1
-                = @instance_presenter.site_title
-                %small!= t 'about.hosted_on', domain: content_tag(:span, site_hostname)
+      - else
+        .column-2.non-preview
+          .landing-page__hero
+            = image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url || asset_pack_path('preview.jpg'), alt: @instance_presenter.site_title
 
-            %p= @instance_presenter.site_description.html_safe.presence || t('about.generic_description', domain: site_hostname)
+          .landing-page__information
+            .landing-page__short-description
+              .row
+                .landing-page__logo
+                  = image_tag asset_pack_path('logo_transparent.svg'), alt: 'Mastodon'
 
-        .show-xs
-          .landing-page__forms
-            = render 'forms'
-        .landing-page__call-to-action.hide-xs
-          .row
-            .column-5
-              .landing-page__mascot
-                = image_tag asset_pack_path('elephant_ui_plane.svg')
-            .column-5
-              .information-board__section
-                %span= t 'about.user_count_before'
-                %strong= number_with_delimiter @instance_presenter.user_count
-                %span= t 'about.user_count_after'
-            .column-5
-              .information-board__section
-                %span= t 'about.status_count_before'
-                %strong= number_with_delimiter @instance_presenter.status_count
-                %span= t 'about.status_count_after'
-        .landing-page__information
+                %h1
+                  = @instance_presenter.site_title
+                  %small!= t 'about.hosted_on', domain: content_tag(:span, site_hostname)
+
+              %p= @instance_presenter.site_description.html_safe.presence || t('about.generic_description', domain: site_hostname)
+
+          .landing-page__call-to-action
+            .row
+              .row__information-board
+                .information-board__section
+                  %span= t 'about.user_count_before'
+                  %strong= number_with_delimiter @instance_presenter.user_count
+                  %span= t 'about.user_count_after'
+                .information-board__section
+                  %span= t 'about.status_count_before'
+                  %strong= number_with_delimiter @instance_presenter.status_count
+                  %span= t 'about.status_count_after'
+              .row__mascot
+                .landing-page__mascot
+                  = image_tag asset_pack_path('elephant_ui_plane.svg')
+
+      - if Setting.timeline_preview
+        .column-3
+          #mastodon-timeline{ data: { props: Oj.dump(default_props) } }
+
+      - if Setting.timeline_preview
+        .column-4.landing-page__information
           .landing-page__features
             %h3= t 'about.what_is_mastodon'
             %p= t 'about.about_mastodon_html'
@@ -66,13 +115,18 @@
               = link_to t('about.source_code'), @instance_presenter.source_url
               = " (#{@instance_presenter.version_number})"
 
-      .column-4.column-6-sm.column-flex
-        .show-sm.hide-xs
-          .landing-page__forms
-            .brand
-              = link_to root_url do
-                = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
+      - else
+        .column-4.non-preview.landing-page__information
+          .landing-page__features
+            %h3= t 'about.what_is_mastodon'
+            %p= t 'about.about_mastodon_html'
 
-            = render 'forms'
-        - if Setting.timeline_preview
-          #mastodon-timeline{ data: { props: Oj.dump(default_props) } }
+            = render 'features'
+
+            .landing-page__features__action
+              = link_to t('about.learn_more'), 'https://joinmastodon.org/', class: 'button button-alternative'
+
+          .landing-page__footer
+            %p
+              = link_to t('about.source_code'), @instance_presenter.source_url
+              = " (#{@instance_presenter.version_number})"
diff --git a/app/views/accounts/_follow_button.html.haml b/app/views/accounts/_follow_button.html.haml
new file mode 100644
index 000000000..e476e0aff
--- /dev/null
+++ b/app/views/accounts/_follow_button.html.haml
@@ -0,0 +1,23 @@
+- relationships ||= nil
+
+- unless account.memorial? || account.moved?
+  - if user_signed_in?
+    - requested = relationships ? relationships.requested[account.id].present? : current_account.requested?(account)
+    - following = relationships ? relationships.following[account.id].present? : current_account.following?(account)
+
+  - if user_signed_in? && current_account.id != account.id && !requested
+    .controls
+      - if following
+        = link_to account_unfollow_path(account), data: { method: :post }, class: 'icon-button' do
+          = fa_icon 'user-times'
+          = t('accounts.unfollow')
+      - else
+        = link_to account_follow_path(account), data: { method: :post }, class: 'icon-button' do
+          = fa_icon 'user-plus'
+          = t('accounts.follow')
+  - elsif !user_signed_in?
+    .controls
+      .remote-follow
+        = link_to account_remote_follow_path(account), class: 'icon-button' do
+          = fa_icon 'user-plus'
+          = t('accounts.remote_follow')
diff --git a/app/views/accounts/_grid_card.html.haml b/app/views/accounts/_grid_card.html.haml
index 305eb2c44..95acbd581 100644
--- a/app/views/accounts/_grid_card.html.haml
+++ b/app/views/accounts/_grid_card.html.haml
@@ -1,9 +1,12 @@
 .account-grid-card
   .account-grid-card__header{ style: "background-image: url(#{account.header.url(:original)})" }
+    = render 'accounts/follow_button', account: account, relationships: @relationships
   .account-grid-card__avatar
     .avatar= image_tag account.avatar.url(:original)
   .name
     = link_to TagManager.instance.url_for(account) do
       %span.display_name.emojify= display_name(account)
-      %span.username @#{account.acct}
-  %p.note.emojify= truncate(strip_tags(account.note), length: 150)
+      %span.username
+        @#{account.local? ? account.local_username_and_domain : account.acct}
+        = fa_icon('lock') if account.locked?
+  .account__header__content.p-note.emojify= Formatter.instance.simplified_format(account)
diff --git a/app/views/accounts/_header.html.haml b/app/views/accounts/_header.html.haml
index b0062752c..74251b923 100644
--- a/app/views/accounts/_header.html.haml
+++ b/app/views/accounts/_header.html.haml
@@ -1,24 +1,7 @@
 - processed_bio = FrontmatterHandler.instance.process_bio Formatter.instance.simplified_format account
 .card.h-card.p-author{ style: "background-image: url(#{account.header.url(:original)})" }
   .card__illustration
-    - unless account.memorial? || account.moved?
-      - if user_signed_in? && current_account.id != account.id && !current_account.requested?(account)
-        .controls
-          - if current_account.following?(account)
-            = link_to account_unfollow_path(account), data: { method: :post }, class: 'icon-button' do
-              = fa_icon 'user-times'
-              = t('accounts.unfollow')
-          - else
-            = link_to account_follow_path(account), data: { method: :post }, class: 'icon-button' do
-              = fa_icon 'user-plus'
-              = t('accounts.follow')
-      - elsif !user_signed_in?
-        .controls
-          .remote-follow
-            = link_to account_remote_follow_path(account), class: 'icon-button' do
-              = fa_icon 'user-plus'
-              = t('accounts.remote_follow')
-
+    = render 'accounts/follow_button', account: account
     .avatar= image_tag account.avatar.url(:original), class: 'u-photo'
 
   .card__bio
diff --git a/app/views/accounts/show.html.haml b/app/views/accounts/show.html.haml
index accad5f78..21c585dab 100644
--- a/app/views/accounts/show.html.haml
+++ b/app/views/accounts/show.html.haml
@@ -39,6 +39,9 @@
 
       = render partial: 'stream_entries/status', collection: @statuses, as: :status
 
-  - if @statuses.size == 20
+  - if @newer_url || @older_url
     .pagination
-      = link_to safe_join([t('pagination.next'), fa_icon('chevron-right')], ' '), @next_url, class: 'next', rel: 'next'
+      - if @older_url
+        = link_to safe_join([fa_icon('chevron-left'), t('pagination.older')], ' '), @older_url, class: 'older', rel: 'older'
+      - if @newer_url
+        = link_to safe_join([t('pagination.newer'), fa_icon('chevron-right')], ' '), @newer_url, class: 'newer', rel: 'newer'
diff --git a/app/views/auth/passwords/edit.html.haml b/app/views/auth/passwords/edit.html.haml
index 703c821c0..12880c227 100644
--- a/app/views/auth/passwords/edit.html.haml
+++ b/app/views/auth/passwords/edit.html.haml
@@ -4,7 +4,7 @@
 = simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f|
   = render 'shared/error_messages', object: resource
 
-  - if !use_pam? || resource.encrypted_password.present?
+  - if !use_seamless_external_login?? || resource.encrypted_password.present?
     = f.input :reset_password_token, as: :hidden
 
     = f.input :password, autofocus: true, placeholder: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.new_password'), :autocomplete => 'off' }
@@ -13,6 +13,6 @@
     .actions
       = f.button :button, t('auth.set_new_password'), type: :submit
   - else
-    = t('simple_form.labels.defaults.pam_account')
+    %p.hint= t('users.seamless_external_login')
 
 .form-footer= render 'auth/shared/links'
diff --git a/app/views/auth/registrations/edit.html.haml b/app/views/auth/registrations/edit.html.haml
index ca18caa56..fac702b38 100644
--- a/app/views/auth/registrations/edit.html.haml
+++ b/app/views/auth/registrations/edit.html.haml
@@ -4,7 +4,7 @@
 = simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, class: 'auth_edit' }) do |f|
   = render 'shared/error_messages', object: resource
 
-  - if !use_pam? || resource.encrypted_password.present?
+  - if !use_seamless_external_login? || resource.encrypted_password.present?
     = f.input :email, placeholder: t('simple_form.labels.defaults.email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }
     = f.input :password, placeholder: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.new_password'), :autocomplete => 'off' }
     = f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_new_password'), :autocomplete => 'off' }
@@ -13,7 +13,7 @@
     .actions
       = f.button :button, t('generic.save_changes'), type: :submit
   - else
-    = t('simple_form.labels.defaults.pam_account')
+    %p.hint= t('users.seamless_external_login')
 
 %hr/
 
diff --git a/app/views/auth/sessions/new.html.haml b/app/views/auth/sessions/new.html.haml
index 1c3a0b6b4..0c9f9d5fe 100644
--- a/app/views/auth/sessions/new.html.haml
+++ b/app/views/auth/sessions/new.html.haml
@@ -5,7 +5,7 @@
   = render partial: 'shared/og'
 
 = simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
-  - if use_pam?
+  - if use_seamless_external_login?
     = f.input :email, autofocus: true, placeholder: t('simple_form.labels.defaults.username_or_email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.username_or_email') }
   - else
     = f.input :email, autofocus: true, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }
diff --git a/app/views/settings/preferences/show.html.haml b/app/views/settings/preferences/show.html.haml
index 75dfa027e..102e4d200 100644
--- a/app/views/settings/preferences/show.html.haml
+++ b/app/views/settings/preferences/show.html.haml
@@ -4,7 +4,7 @@
 = simple_form_for current_user, url: settings_preferences_path, html: { method: :put } do |f|
   = render 'shared/error_messages', object: current_user
 
-  .actions
+  .actions.actions--top
     = f.button :button, t('generic.save_changes'), type: :submit
 
   %h4= t 'preferences.languages'
diff --git a/app/views/stream_entries/_detailed_status.html.haml b/app/views/stream_entries/_detailed_status.html.haml
index 470bff218..e1122d5a2 100644
--- a/app/views/stream_entries/_detailed_status.html.haml
+++ b/app/views/stream_entries/_detailed_status.html.haml
@@ -22,7 +22,7 @@
   - if !status.media_attachments.empty?
     - if status.media_attachments.first.video?
       - video = status.media_attachments.first
-      %div{ data: { component: 'Video', props: Oj.dump(src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 670, height: 380, detailed: true) }}
+      %div{ data: { component: 'Video', props: Oj.dump(src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 670, height: 380, detailed: true, inline: true) }}
     - else
       %div{ data: { component: 'MediaGallery', props: Oj.dump(height: 380, sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, standalone: true, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, 'reduceMotion': current_account&.user&.setting_reduce_motion, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }) }}
   - elsif status.preview_cards.first
diff --git a/app/views/stream_entries/_simple_status.html.haml b/app/views/stream_entries/_simple_status.html.haml
index 03d416fd6..2ad1f5120 100644
--- a/app/views/stream_entries/_simple_status.html.haml
+++ b/app/views/stream_entries/_simple_status.html.haml
@@ -20,7 +20,6 @@
         %a.status__content__spoiler-link{ href: '#' }= t('statuses.show_more')
     .e-content{ lang: status.language, style: "display: #{status.spoiler_text? ? 'none' : 'block'}; direction: #{rtl_status?(status) ? 'rtl' : 'ltr'}" }<
       = Formatter.instance.format(status, custom_emojify: true)
-
       - unless status.media_attachments.empty?
         - if status.media_attachments.first.video?
           - video = status.media_attachments.first
diff --git a/app/views/tags/_features.html.haml b/app/views/tags/_features.html.haml
new file mode 100644
index 000000000..8fbc6b760
--- /dev/null
+++ b/app/views/tags/_features.html.haml
@@ -0,0 +1,25 @@
+.features-list
+  .features-list__row
+    .text
+      %h6= t 'about.features.real_conversation_title'
+      = t 'about.features.real_conversation_body'
+    .visual
+      = fa_icon 'fw comments'
+  .features-list__row
+    .text
+      %h6= t 'about.features.not_a_product_title'
+      = t 'about.features.not_a_product_body'
+    .visual
+      = fa_icon 'fw users'
+  .features-list__row
+    .text
+      %h6= t 'about.features.within_reach_title'
+      = t 'about.features.within_reach_body'
+    .visual
+      = fa_icon 'fw mobile'
+  .features-list__row
+    .text
+      %h6= t 'about.features.humane_approach_title'
+      = t 'about.features.humane_approach_body'
+    .visual
+      = fa_icon 'fw leaf'
diff --git a/app/views/tags/show.html.haml b/app/views/tags/show.html.haml
index 03f19e20a..000aa0c4d 100644
--- a/app/views/tags/show.html.haml
+++ b/app/views/tags/show.html.haml
@@ -5,48 +5,31 @@
   %script#initial-state{ type: 'application/json' }!= json_escape(@initial_state_json)
   = render 'og'
 
-.landing-page.tag-page
+.landing-page.tag-page.alternative
   .features
     .container
-      #mastodon-timeline{ data: { props: Oj.dump(default_props.merge(hashtag: @tag.name)) } }
+      .grid
+        .column-1
+          #mastodon-timeline{ data: { props: Oj.dump(default_props.merge(hashtag: @tag.name)) } }
 
-      .about-mastodon
-        .about-hashtag
-          .brand
-            = link_to root_url do
-              = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
+        .column-2
+          .about-mastodon
+            .about-hashtag.landing-page__information
+              .brand
+                = link_to root_url do
+                  = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
 
-          %p= t 'about.about_hashtag_html', hashtag: @tag.name
+              %p= t 'about.about_hashtag_html', hashtag: @tag.name
 
-          .cta
-            - if user_signed_in?
-              = link_to t('settings.back'), root_path, class: 'button button-secondary'
-            - else
-              = link_to t('auth.login'), new_user_session_path, class: 'button button-secondary'
-            = link_to t('about.learn_more'), about_path, class: 'button button-alternative'
+              .cta
+                - if user_signed_in?
+                  = link_to t('settings.back'), root_path, class: 'button button-secondary'
+                - else
+                  = link_to t('auth.login'), new_user_session_path, class: 'button button-secondary'
+                = link_to t('about.learn_more'), about_path, class: 'button button-alternative'
 
-        .features-list
-          .features-list__row
-            .text
-              %h6= t 'about.features.real_conversation_title'
-              = t 'about.features.real_conversation_body'
-            .visual
-              = fa_icon 'fw comments'
-          .features-list__row
-            .text
-              %h6= t 'about.features.not_a_product_title'
-              = t 'about.features.not_a_product_body'
-            .visual
-              = fa_icon 'fw users'
-          .features-list__row
-            .text
-              %h6= t 'about.features.within_reach_title'
-              = t 'about.features.within_reach_body'
-            .visual
-              = fa_icon 'fw mobile'
-          .features-list__row
-            .text
-              %h6= t 'about.features.humane_approach_title'
-              = t 'about.features.humane_approach_body'
-            .visual
-              = fa_icon 'fw leaf'
+            .landing-page__features.landing-page__information
+              %h3= t 'about.what_is_mastodon'
+              %p= t 'about.about_mastodon_html'
+
+              = render 'features'
diff --git a/config/application.rb b/config/application.rb
index b1cc7727a..88d0eccf2 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -13,6 +13,7 @@ require_relative '../lib/paperclip/video_transcoder'
 require_relative '../lib/paperclip/audio_transcoder'
 require_relative '../lib/mastodon/snowflake'
 require_relative '../lib/mastodon/version'
+require_relative '../lib/devise/ldap_authenticatable'
 
 Dotenv::Railtie.load
 
diff --git a/config/environments/development.rb b/config/environments/development.rb
index 59bc2c3e2..2da407c32 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -85,3 +85,9 @@ Rails.application.configure do
 end
 
 ActiveRecordQueryTrace.enabled = ENV.fetch('QUERY_TRACE_ENABLED') { false }
+
+module PrivateAddressCheck
+  def self.private_address?(*)
+    false
+  end
+end
diff --git a/config/environments/production.rb b/config/environments/production.rb
index 8979bbeca..17915d6c6 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -25,7 +25,7 @@ Rails.application.configure do
   end
 
   # Compress JavaScripts and CSS.
-  config.assets.js_compressor = Uglifier.new(mangle: false)
+  # config.assets.js_compressor = Uglifier.new(mangle: false)
   # config.assets.css_compressor = :sass
 
   # Do not fallback to assets pipeline if a precompiled asset is missed.
diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb
index ba7ad9e6c..df45dcd1f 100644
--- a/config/initializers/devise.rb
+++ b/config/initializers/devise.rb
@@ -36,6 +36,26 @@ module Devise
   mattr_accessor :pam_controlled_service
   @@pam_controlled_service = nil
 
+  mattr_accessor :check_at_sign
+  @@check_at_sign = false
+
+  mattr_accessor :ldap_authentication
+  @@ldap_authentication = false
+  mattr_accessor :ldap_host
+  @@ldap_host = nil
+  mattr_accessor :ldap_port
+  @@ldap_port = nil
+  mattr_accessor :ldap_method
+  @@ldap_method = nil
+  mattr_accessor :ldap_base
+  @@ldap_base = nil
+  mattr_accessor :ldap_uid
+  @@ldap_uid = nil
+  mattr_accessor :ldap_bind_dn
+  @@ldap_bind_dn = nil
+  mattr_accessor :ldap_password
+  @@ldap_password = nil
+
   class Strategies::PamAuthenticatable
     def valid?
       super && ::Devise.pam_authentication
@@ -45,6 +65,8 @@ end
 
 Devise.setup do |config|
   config.warden do |manager|
+    manager.default_strategies(scope: :user).unshift :ldap_authenticatable if Devise.ldap_authentication
+    manager.default_strategies(scope: :user).unshift :pam_authenticatable  if Devise.pam_authentication
     manager.default_strategies(scope: :user).unshift :two_factor_authenticatable
     manager.default_strategies(scope: :user).unshift :two_factor_backupable
   end
@@ -322,6 +344,18 @@ Devise.setup do |config|
     config.check_at_sign          = true
     config.pam_default_suffix     = ENV.fetch('PAM_DEFAULT_SUFFIX') { nil }
     config.pam_default_service    = ENV.fetch('PAM_DEFAULT_SERVICE') { 'rpam' }
-    config.pam_controlled_service = ENV.fetch('PAM_CONTROLLED_SERVICE') { 'rpam' }
+    config.pam_controlled_service = ENV.fetch('PAM_CONTROLLED_SERVICE') { nil }
+  end
+
+  if ENV['LDAP_ENABLED'] == 'true'
+    config.ldap_authentication = true
+    config.check_at_sign       = true
+    config.ldap_host           = ENV.fetch('LDAP_HOST', 'localhost')
+    config.ldap_port           = ENV.fetch('LDAP_PORT', 389).to_i
+    config.ldap_method         = ENV.fetch('LDAP_METHOD', :simple_tls).to_sym
+    config.ldap_base           = ENV.fetch('LDAP_BASE')
+    config.ldap_bind_dn        = ENV.fetch('LDAP_BIND_DN')
+    config.ldap_password       = ENV.fetch('LDAP_PASSWORD')
+    config.ldap_uid            = ENV.fetch('LDAP_UID', 'cn')
   end
 end
diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb
index b70784d79..f875fbd95 100644
--- a/config/initializers/sidekiq.rb
+++ b/config/initializers/sidekiq.rb
@@ -9,6 +9,10 @@ end
 
 Sidekiq.configure_server do |config|
   config.redis = redis_params
+
+  config.server_middleware do |chain|
+    chain.add SidekiqErrorHandler
+  end
 end
 
 Sidekiq.configure_client do |config|
diff --git a/config/locales/activerecord.ar.yml b/config/locales/activerecord.ar.yml
index d5d44aaa6..68c7fe939 100644
--- a/config/locales/activerecord.ar.yml
+++ b/config/locales/activerecord.ar.yml
@@ -6,8 +6,8 @@ ar:
         account:
           attributes:
             username:
-              invalid: فقط حروف و أرقام و تسطير سفلي
+              invalid: فقط حروف و أرقام و سطور سفلية
         status:
           attributes:
             reblog:
-              taken: المنشور موجود
+              taken: المنشور موجود مِن قبل
diff --git a/config/locales/ar.yml b/config/locales/ar.yml
index 88b4d88bb..6ec498efa 100644
--- a/config/locales/ar.yml
+++ b/config/locales/ar.yml
@@ -12,6 +12,7 @@ ar:
     domain_count_before: متصل بـ
     features:
       humane_approach_title: أسلوب يعيد الإعتبار للإنسان
+      not_a_product_body: ماستدون ليس شبكة تجارية. لا يحتوي على إعلانات و لا يقوم باستغلال البيانات و لا هو بِبُستان مُسيَّج. لا تحكم فيه وليس له أية هيئةٍ مركزيةٍ.
       not_a_product_title: إنك إنسان و لست سلعة
       real_conversation_title: مبني لتحقيق تواصل حقيقي
     generic_description: "%{domain} هو سيرفر من بين سيرفرات الشبكة"
@@ -29,6 +30,7 @@ ar:
     followers: متابِعون
     following: يتابعون
     media: الوسائط
+    moved_html: "%{name} إنتقلَ إلى %{new_profile_link} :"
     nothing_here: لا يوجد أي شيء هنا !
     people_followed_by: الأشخاص الذين يتبعهم %{name}
     people_who_follow: الأشخاص الذين يتبعون %{name}
@@ -43,7 +45,9 @@ ar:
   admin:
     account_moderation_notes:
       account: مُشرِف
+      create: إنشاء
       created_at: التاريخ
+      created_msg: تم إنشاء ملاحظة الإشراف بنجاح !
       delete: حذف
     accounts:
       are_you_sure: متأكد ؟
@@ -59,40 +63,79 @@ ar:
       email: البريد الإلكتروني
       enable: تفعيل
       enabled: مفعَّل
+      feed_url: عنوان رابط التغذية
       followers: المتابِعون
+      followers_url: عنوان رابط المتابِعين
       follows: يتابع
       ip: عنوان الإيبي
       location:
         all: الكل
+        local: المحلي
+        remote: عن بُعد
         title: الموقع
       media_attachments: الوسائط المرفقة
       moderation:
         all: الكل
+        silenced: تم كتمه
+        suspended: مُجَمَّد
+        title: الإشراف
+      moderation_notes: ملاحظات الإشراف
+      most_recent_activity: آخر نشاط حديث
       most_recent_ip: أحدث عنوان إيبي
       order:
+        alphabetic: أبجديًا
         most_recent: الأحدث
         title: الترتيب
       profile_url: رابط الملف الشخصي
       protocol: البروتوكول
+      public: عمومي
+      redownload: تحديث الصورة الرمزية
+      reset: إعادة التعيين
+      reset_password: إعادة ضبط كلمة السر
       role: التصريحات
       roles:
         admin: مدير
         moderator: مشرف
         staff: الفريق
         user: مستخدِم
+      salmon_url: عنوان رابط سالمون Salmon
       search: البحث
       statuses: المنشورات
       title: الحسابات
       username: إسم المستخدم
       web: الويب
+    action_logs:
+      actions:
+        create_custom_emoji: "%{name} قام برفع إيموجي جديد %{target}"
+        create_domain_block: "%{name} قام بحجب نطاق %{target}"
+        destroy_domain_block: "%{name} قام بإلغاء الحجب عن النطاق %{target}"
+        disable_custom_emoji: "%{name} قام بتعطيل الإيموجي %{target}"
+        enable_custom_emoji: "%{name} قام بتنشيط الإيموجي %{target}"
+        promote_user: "%{name} قام بترقية المستخدم %{target}"
+        update_custom_emoji: "%{name} قام بتحديث الإيموجي %{target}"
+      title: سِجلّ التفتيش و المعاينة
     custom_emojis:
+      by_domain: النطاق
       copy: نسخ
+      created_msg: تم إنشاء الإيموجي بنجاح !
       delete: حذف
+      disable: تعطيل
       emoji: إيموجي
       enable: تفعيل
+      image_hint: ملف PNG إلى غاية حجم 50 ك.ب
+      title: الإيموجي الخاصة
       upload: رفع
     domain_blocks:
+      add_new: إضافة نطاق جديد
       domain: النطاق
+      new:
+        create: إنشاء حظر
+        severity:
+          noop: لا شيء
+          silence: كتم
+        title: حجب نطاق جديد
+      severities:
+        noop: لا شيء
       show:
         undo: إلغاء
       undo: إلغاء
@@ -102,13 +145,26 @@ ar:
       new:
         create: إضافة نطاق
     instances:
+      account_count: الحسابات المعروفة
       domain_name: النطاق
+      reset: إعادة تعيين
       search: البحث
+      title: مثيلات الخوادم المعروفة
+    invites:
+      filter:
+        all: الكل
+        available: المتوفرة
+        expired: المنتهي صلاحيتها
+      title: الدعوات
     reports:
       are_you_sure: هل أنت متأكد ؟
       comment:
         label: تعليق
+        none: لا شيء
       delete: حذف
+      id: معرّف ID
+      nsfw:
+        'true': إخفاء الوسائط المرفقة
       report_contents: المحتويات
       reported_by: أبلغ عنه من طرف
       status: الحالة
@@ -118,40 +174,62 @@ ar:
       contact_information:
         email: البريد الإلكتروني المهني
       registrations:
+        closed_message:
+          title: رسالة التسجيلات المقفلة
         deletion:
           desc_html: السماح لأي مستخدم إغلاق حسابه
         open:
+          desc_html: السماح للجميع بإنشاء حساب
           title: فتح التسجيل
+      site_description:
+        title: وصف مثيل الخادوم
       site_terms:
         title: شروط الخدمة المخصصة
       site_title: إسم مثيل الخادم
+      thumbnail:
+        title: الصورة الرمزية المصغرة لمثيل الخادوم
       title: إعدادات الموقع
     statuses:
       back_to_account: العودة إلى صفحة الحساب
       batch:
         delete: حذف
       media:
+        hide: إخفاء الوسائط
+        show: إظهار الوسائط
         title: الوسائط
+      title: منشورات الحساب
+      with_media: بالوسائط
     subscriptions:
       confirmed: مؤكَّد
+      expires_in: تنتهي مدة صلاحيتها في
       topic: الموضوع
     title: الإدارة
   application_mailer:
+    notification_preferences: تعديل خيارات البريد الإلكتروني
     salutation: "%{name}،"
     settings: 'تغيير تفضيلات البريد الإلكتروني : %{link}'
     view: 'View:'
+    view_profile: عرض الملف الشخصي
+    view_status: عرض المنشور
   applications:
     created: تم إنشاء التطبيق بنجاح
     destroyed: تم حذف التطبيق بنجاح
     invalid_url: إن الرابط المقدم غير صالح
+    regenerate_token: إعادة توليد رمز النفاذ
+    your_token: رمز نفاذك
   auth:
     change_password: الهوية
+    confirm_email: تأكيد عنوان البريد الإلكتروني
     delete_account: حذف حساب
     didnt_get_confirmation: لم تتلق تعليمات التأكيد ؟
     forgot_password: نسيت كلمة المرور ؟
     login: تسجيل الدخول
     logout: خروج
     migrate_account: الإنتقال إلى حساب آخر
+    or_log_in_with: أو قم بتسجيل الدخول بواسطة
+    providers:
+      cas: CAS
+      saml: SAML
     register: إنشاء حساب
     resend_confirmation: إعادة إرسال تعليمات التأكيد
     reset_password: إعادة تعيين كلمة المرور
@@ -161,6 +239,8 @@ ar:
     follow: إتبع
     follow_request: 'لقد قمت بإرسال طلب متابعة إلى :'
     post_follow:
+      close: أو يمكنك إغلاق هذه النافذة.
+      return: العودة إلى الملف الشخصي للمستخدم
       web: واصل إلى الويب
     title: إتباع %{acct}
   datetime:
@@ -187,6 +267,7 @@ ar:
     '404': إنّ الصفحة التي تبحث عنها لا وجود لها أصلا.
     '410': إنّ الصفحة التي تبحث عنها لم تعد موجودة.
     '500':
+      content: نحن متأسفون، لقد حدث خطأ ما مِن جانبنا.
       title: هذه الصفحة خاطئة
   exports:
     blocks: قمت بحظر
@@ -211,15 +292,23 @@ ar:
     types:
       blocking: قائمة المحظورين
       following: قائمة المستخدمين المتبوعين
+      muting: قائمة الكتم
     upload: تحميل
   invites:
     delete: تعطيل
+    expired: إنتهت صلاحيتها
     expires_in:
       '1800': 30 دقيقة
       '21600': 6 ساعات
       '3600': ساعة
       '43200': 12 ساعة
       '86400': يوم واحد
+    expires_in_prompt: أبدا
+    generate: توليد
+    max_uses_prompt: بلا حدود
+    table:
+      expires_at: تنتهي مدة صلاحيتها في
+    title: دعوة أشخاص
   landing_strip_html: "<strong>%{name}</strong> is a user on %{link_to_root_path}. You can follow them or interact with them if you have an account anywhere in the fediverse.."
   landing_strip_signup_html: إن كنت لا تملك واحدا، يمكنك <a href="%{sign_up_path}">التسجيل مِن هنا</a>.
   lists:
@@ -233,31 +322,38 @@ ar:
     acct: username@domain للحساب الجديد
     currently_redirecting: 'تم تحويل رابط ملفك الشخصي إلى :'
     proceed: حفظ
+  moderation:
+    title: الإشراف
   notification_mailer:
     digest:
-      body: 'هذه هي الأخبار المختصرة التي قد فاتتك على %{instance}وذلك منذ آخر زيارة لك في  %{since} :'
+      body: هذا هو مُلَخَّص الرسائل التي فاتتك وذلك منذ آخر زيارة لك في  %{since}
       mention: "%{name} أشار إليك في :"
       new_followers_summary:
-        one: لقد حصلت على متابع جديد !
-        other: لقد تحصلت على %{count} متتبعين جدد ! رائع !
+        one: و لقد حصلت على متابع جديد أثناء فترة غيابك ! مرحى !
+        other: و لقد تحصلت على %{count} متتبعين جدد أثناء فترة غيابك ! رائع !
       subject:
         one: "إشعار واحد منذ زيارتك الأخيرة \U0001F418"
         other: "%{count} إشعارات جديدة منذ زيارتك الأخيرة \U0001F418"
+      title: أثناء فترة غيابك …
     favourite:
       body: 'أُعجب %{name} بمنشورك :'
       subject: أُعجِب %{name} بمنشورك
     follow:
       body: "%{name} من متتبعيك الآن !"
       subject: "%{name} من متتبعيك الآن"
+      title: متابِع جديد
     follow_request:
+      action: إدارة طلبات المتابَعة
       body: طلب %{name} متابعتك
       subject: 'متابع مُعلّق : %{name}'
+      title: طلب متابَعة جديد
     mention:
       body: 'أشار إليك %{name} في :'
       subject: لقد قام %{name} بذِكرك
     reblog:
       body: 'قام %{name} بترقية منشورك :'
       subject: قام %{name} بترقية منشورك
+      title: ترقية جديدة
   number:
     human:
       decimal_units:
@@ -304,24 +400,34 @@ ar:
       blackberry: بلاك بيري
       chrome: كروم
       edge: مايكروسوفت إيدج
+      electron: إلكترون
       firefox: فايرفكس
       generic: متصفح مجهول
       ie: إنترنت إكسبلورر
+      micro_messenger: مايكرو ميسنجر
       opera: أوبرا
+      otter: أوتر
+      phantom_js: فانتوم جي آس
       qq: متصفح كيوكيو
       safari: سفاري
+      uc_browser: متصفح يوسي براوزر
+      weibo: وايبو
     current_session: الجلسة الحالية
     description: "%{browser} على %{platform}"
     ip: عنوان الإيبي
     platforms:
+      adobe_air: أدوبي إيير
       android: أندرويد
       blackberry: بلاك بيري
       chrome_os: نظام كروم أواس
       firefox_os: نظام فايرفكس أواس
+      ios: نظام آي أواس
       linux: لينكس
       mac: ماك
       other: نظام مجهول
       windows: ويندوز
+      windows_mobile: ويندوز موبايل
+      windows_phone: ويندوز فون
     title: الجلسات
   settings:
     authorized_apps: التطبيقات المرخص لها
@@ -331,6 +437,7 @@ ar:
     export: تصدير البيانات
     followers: المتابِعون المُرَخّصون
     import: إستيراد
+    migrate: تهجير الحساب
     notifications: الإخطارات
     preferences: التفضيلات
     settings: الإعدادات
diff --git a/config/locales/ca.yml b/config/locales/ca.yml
index 0357b4abb..902536ce4 100644
--- a/config/locales/ca.yml
+++ b/config/locales/ca.yml
@@ -10,7 +10,7 @@ ca:
     contact_unavailable: N/D
     description_headline: Què es %{domain}?
     domain_count_after: altres instàncies
-    domain_count_before: Connectat a
+    domain_count_before: Connectada a
     extended_description_html: |
       <h3>Un bon lloc per les regles</h3>
       <p>Encara no s'ha configurat la descripció ampliada.</p>
@@ -29,7 +29,7 @@ ca:
     other_instances: Altres instàncies
     source_code: Codi font
     status_count_after: estats
-    status_count_before: que han escrit
+    status_count_before: Que han escrit
     user_count_after: usuaris registrats
     user_count_before: Tenim
     what_is_mastodon: Què és Mastodon?
@@ -40,40 +40,40 @@ ca:
     media: Mèdia
     moved_html: "%{name} s'ha mogut a %{new_profile_link}:"
     nothing_here: No hi ha res aquí!
-    people_followed_by: Usuaris a qui %{name} segueix
+    people_followed_by: Usuaris seguits per %{name}
     people_who_follow: Usuaris que segueixen %{name}
     posts: Toots
     posts_with_replies: Toots i respostes
     remote_follow: Seguiment remot
     reserved_username: El nom d'usuari està reservat
     roles:
-      admin: Admin
+      admin: Administrador
       moderator: Moderador
-    unfollow: Deixar de seguir
+    unfollow: Deixa de seguir
   admin:
     account_moderation_notes:
       account: Moderador
-      create: Crear
+      create: Crea
       created_at: Data
       created_msg: La nota de moderació s'ha creat correctament!
       delete: Suprimeix
       destroyed_msg: Nota de moderació destruïda amb èxit!
     accounts:
-      are_you_sure: Estàs segur?
+      are_you_sure: N'estàs segur?
       by_domain: Domini
       confirm: Confirma
       confirmed: Confirmat
       demote: Degrada
       disable: Inhabilita
-      disable_two_factor_authentication: Desactivar 2FA
-      disabled: Inhabilita
+      disable_two_factor_authentication: Desactiva 2FA
+      disabled: Inhabilitat
       display_name: Nom de visualització
       domain: Domini
-      edit: Editar
+      edit: Edita
       email: Correu electrònic
-      enable: Habilitar
+      enable: Habilita
       enabled: Habilitat
-      feed_url: URL del feed
+      feed_url: URL del canal
       followers: Seguidors
       followers_url: URL dels seguidors
       follows: Segueix
@@ -86,7 +86,7 @@ ca:
         title: Localització
       login_status: Estat d'accés
       media_attachments: Adjunts multimèdia
-      memorialize: Es converteix en memoriam
+      memorialize: Converteix-lo en memorial
       moderation:
         all: Tot
         silenced: Silenciat
@@ -101,16 +101,16 @@ ca:
         most_recent: Més recent
         title: Ordre
       outbox_url: URL de la bústia de sortida
-      perform_full_suspension: Aplicar suspensió completa
+      perform_full_suspension: Aplica una suspensió completa
       profile_url: URL del perfil
       promote: Promociona
       protocol: Protocol
       public: Públic
       push_subscription_expires: La subscripció PuSH expira
-      redownload: Refrescar avatar
-      reset: Reajustar
-      reset_password: Restablir la contrasenya
-      resubscribe: Resubscribir
+      redownload: Actualitza l'avatar
+      reset: Reinicialitza
+      reset_password: Restableix la contrasenya
+      resubscribe: Torna a subscriure
       role: Permisos
       roles:
         admin: Administrador
@@ -130,38 +130,38 @@ ca:
       title: Comptes
       undo_silenced: Deixa de silenciar
       undo_suspension: Desfés la suspensió
-      unsubscribe: Donar-se de baixa
+      unsubscribe: Cancel·la la subscripció
       username: Nom d'usuari
       web: Web
     action_logs:
       actions:
         confirm_user: "%{name} ha confirmat l'adreça de correu electrònic de l'usuari %{target}"
-        create_custom_emoji: "%{name} ha penjat un nou emoji %{target}"
-        create_domain_block: "%{name} ha bloquejat el domini %{target}"
+        create_custom_emoji: "%{name} ha pujat un nou emoji %{target}"
+        create_domain_block: "%{name} ha blocat el domini %{target}"
         create_email_domain_block: "%{name} ha afegit a la llista negra el domini del correu electrònic %{target}"
         demote_user: "%{name} ha degradat l'usuari %{target}"
-        destroy_domain_block: "%{name} ha desbloquejat el domini %{target}"
+        destroy_domain_block: "%{name} ha desblocat el domini %{target}"
         destroy_email_domain_block: "%{name} ha afegit a la llista negra el domini de correu electrònic %{target}"
-        destroy_status: "%{name} estat eliminat per %{target}"
+        destroy_status: "%{name} eliminat l'estat per %{target}"
         disable_2fa_user: "%{name} ha desactivat el requisit de dos factors per a l'usuari %{target}"
         disable_custom_emoji: "%{name} ha desactivat l'emoji %{target}"
         disable_user: "%{name} ha desactivat l'accés per a l'usuari %{target}"
         enable_custom_emoji: "%{name} ha activat l'emoji %{target}"
         enable_user: "%{name} ha activat l'accés per a l'usuari %{target}"
-        memorialize_account: "%{name} ha convertit el compte %{target} en una pàgina de memòria"
+        memorialize_account: "%{name} ha convertit el compte %{target} en una pàgina de memorial"
         promote_user: "%{name} ha promogut l'usuari %{target}"
-        reset_password_user: "%{name} restablirà la contrasenya de l'usuari %{target}"
+        reset_password_user: "%{name} ha restablert la contrasenya de l'usuari %{target}"
         resolve_report: "%{name} ha descartat l'informe %{target}"
         silence_account: "%{name} ha silenciat el compte de %{target}"
         suspend_account: "%{name} ha suspès el compte de %{target}"
         unsilence_account: "%{name} ha silenciat el compte de %{target}"
         unsuspend_account: "%{name} ha llevat la suspensió del compte de %{target}"
-        update_custom_emoji: "%{name} ha actualizat l'emoji %{target}"
-        update_status: "%{name} estat actualizat per %{target}"
+        update_custom_emoji: "%{name} ha actualitzat l'emoji %{target}"
+        update_status: "%{name} estat actualitzat per %{target}"
       title: Registre d'auditoria
     custom_emojis:
       by_domain: Domini
-      copied_msg: S'ha creat correctament la còpia local del emoji
+      copied_msg: S'ha creat correctament la còpia local de l'emoji
       copy: Copia
       copy_failed_msg: No s'ha pogut fer una còpia local d'aquest emoji
       created_msg: Emoji creat amb èxit!
@@ -175,11 +175,11 @@ ca:
       image_hint: PNG de fins a 50 KB
       listed: Enumerat
       new:
-        title: Afegeix nou emoji personalitzat
+        title: Afegeix emoji personalitzat nou
       overwrite: Sobreescriure
       shortcode: Codi curt
       shortcode_hint: Com a mínim 2 caràcters, només caràcters alfanumèrics i guions baixos
-      title: Emojis personatlitzats
+      title: Emojis personalitzats
       unlisted: Sense classificar
       update_failed_msg: No s'ha pogut actualitzar aquest emoji
       updated_msg: Emoji s'ha actualitzat correctament!
@@ -191,15 +191,15 @@ ca:
       domain: Domini
       new:
         create: Crea un bloqueig
-        hint: El bloqueig de domini no impedirà la creació de nous comptes en la base de dades, però s´aplicaran de manera retroactiva mètodes de moderació específics sobre aquests comptes.
+        hint: El bloqueig de domini no impedirà la creació de nous comptes en la base de dades, però s'aplicaran de manera retroactiva mètodes de moderació específics sobre aquests comptes.
         severity:
           desc_html: "<strong>Silenci</strong> farà les publicacions del compte invisibles a tothom que no l'estigui seguint. <strong>La suspensió</strong> eliminarà tots els continguts, multimèdia i les dades del perfil del compte. Usa <strong>Cap</strong> si només vols rebutjar el fitxers multimèdia."
           noop: Cap
           silence: Silenci
           suspend: Suspensió
-        title: Nou bloqueig de domini
+        title: Bloqueig de domini nou
       reject_media: Rebutja els fitxers multimèdia
-      reject_media_hint: Elimina els fitxers multimèdia emmagatzamats localment i impideix descarregar-ne cap en el futur. Irrellevant en les suspensions
+      reject_media_hint: Elimina els fitxers multimèdia emmagatzemats localment i impedeix baixar-ne cap en el futur. Irrellevant en les suspensions
       severities:
         noop: Cap
         silence: Silenci
@@ -215,33 +215,33 @@ ca:
         title: Desfés el bloqueig de domini de %{domain}
         undo: Desfés
       title: Bloquejos de domini
-      undo: Desfer
+      undo: Desfés
     email_domain_blocks:
-      add_new: Afegir nou
+      add_new: Afegeix
       created_msg: S'ha creat el bloc de domini de correu electrònic
       delete: Suprimeix
       destroyed_msg: S'ha eliminat correctament el bloc del domini de correu
       domain: Domini
       new:
-        create: Crear bloc
-        title: Nou bloc de domini de correu electrònic
-      title: Bloc de domini de correu electrònic
+        create: Afegeix un domini
+        title: Nova adreça de correu en la llista negra
+      title: Llista negra de correus electrònics
     instances:
       account_count: Comptes coneguts
       domain_name: Domini
-      reset: Restablir
+      reset: Restableix
       search: Cerca
       title: Instàncies conegudes
     invites:
       filter:
-        all: Tot
+        all: Totes
         available: Disponible
         expired: Caducat
         title: Filtre
       title: Convida
     reports:
       action_taken_by: Mesures adoptades per
-      are_you_sure: Estàs segur?
+      are_you_sure: N'estàs segur?
       comment:
         label: Comentari
         none: Cap
@@ -252,7 +252,7 @@ ca:
         'false': Mostra els fitxers multimèdia adjunts
         'true': Amaga els fitxers multimèdia adjunts
       report: 'Informe #%{id}'
-      report_contents: Continguts
+      report_contents: Contingut
       reported_account: Compte reportat
       reported_by: Reportat per
       resolved: Resolt
@@ -265,23 +265,23 @@ ca:
       view: Visualització
     settings:
       activity_api_enabled:
-        desc_html: Compte d'estatus publicats localment, usuaris actius i registres nous en cubs setmanals
+        desc_html: Compte d'estatus publicats localment, usuaris actius i registres nous en períodes setmanals
         title: Publica estadístiques agregades sobre l'activitat de l'usuari
       bootstrap_timeline_accounts:
-        desc_html: Separa diversos noms d'usuari amb comes. Només funcionaran els comptes locals i desbloquejats. El valor predeterminat quan està buit és tots els administradors locals..
-        title: El seguiment per defecte per als nous usuaris
+        desc_html: Separa diversos noms d'usuari amb comes. Només funcionaran els comptes locals i desblocats. El valor predeterminat quan està buit és tots els administradors locals.
+        title: El seguiment per defecte per als usuaris nous
       contact_information:
-        email: Introdueix una adreça de correu electrònic pùblica
-        username: Introdueix un nom d'usuari
+        email: Introdueix una adreça de correu electrònic píblica
+        username: Nom d'usuari del contacte
       peers_api_enabled:
         desc_html: Els noms de domini que ha trobat aquesta instància al fediverse
         title: Publica la llista d'instàncies descobertes
       registrations:
         closed_message:
-          desc_html: Apareix en la primera pàgina quan es tanquen els registres<br>Pots utilitzar etiquetes HTML
+          desc_html: Apareix en la primera pàgina quan es tanquen els registres. Pots utilitzar etiquetes HTML
           title: Missatge de registre tancat
         deletion:
-          desc_html: Permet a qualsevol esborrar el seu compte
+          desc_html: Permet a qualsevol usuari d'esborrar el seu compte
           title: Obre la supressió del compte
         min_invite_role:
           disabled: Ningú
@@ -289,6 +289,9 @@ ca:
         open:
           desc_html: Permet que qualsevol pugui crear un compte
           title: Registre obert
+      show_known_fediverse_at_about_page:
+        desc_html: Quan s'activa, mostrarà tots els toots de tot el fedivers conegut en vista prèvia. En cas contrari, només es mostraran toots locals.
+        title: Mostra el fedivers conegut en vista prèvia de la línia de temps
       show_staff_badge:
         desc_html: Mostra una insígnia de personal en la pàgina d'usuari
         title: Mostra insígnia de personal
@@ -330,47 +333,52 @@ ca:
       expires_in: Expira en
       last_delivery: Últim lliurament
       title: WebSub
-      topic: Tòpic
+      topic: Tema
     title: Administració
   admin_mailer:
     new_report:
       body: "%{reporter} ha informat de %{target}"
-      subject: Nou informe per a %{instance} (#%{id})
+      subject: Informe nou per a %{instance} (#%{id})
   application_mailer:
-    notification_preferences: Canviar preferències de correu
+    notification_preferences: Canvia les preferències de correu
     salutation: "%{name},"
     settings: 'Canvia les preferències de correu: %{link}'
-    view: 'Vista:'
-    view_profile: Veure perfil
-    view_status: Veure estat
+    view: 'Visualització:'
+    view_profile: Mostra el perfil
+    view_status: Mostra l'estat
   applications:
     created: L'aplicació s'ha creat correctament
     destroyed: L'aplicació s'ha suprimit correctament
-    invalid_url: La URL proporcionada es incorrecte
-    regenerate_token: Regenerar token d'accés
-    token_regenerated: Token d'accés s'ha generat correctament
-    warning: Aneu amb compte amb aquestes dades. No ho compartiu mai amb ningú!
-    your_token: El token d'accés
+    invalid_url: L'URL proporcionat no és correcte
+    regenerate_token: Torna a generar l'identificador d'accés
+    token_regenerated: L'identificador d'accés s'ha generat correctament
+    warning: Aneu amb compte amb aquestes dades. No les compartiu mai amb ningú!
+    your_token: El teu identificador d'accés
   auth:
     agreement_html: En inscriure't, acceptes seguir <a href="%{rules_path}">els nostres termes del servei</a> i <a href="%{terms_path}">la nostra política de privadesa</a>.
-    change_password: Canvia la contrasenya
-    delete_account: Esborra el compte
-    delete_account_html: Si vols esborrar el teu compte pots <a href="%{path}">fer-ho aquí</a>. Se't demanarà confirmació.
+    change_password: Seguretat
+    confirm_email: Confirmar correu electrònic
+    delete_account: Suprimeix el compte
+    delete_account_html: Si vols suprimir el compte pots <a href="%{path}">fer-ho aquí</a>. Se't demanarà confirmació.
     didnt_get_confirmation: No has rebut el correu de confirmació?
     forgot_password: Has oblidat la contrasenya?
-    invalid_reset_password_token: L'enllaç de restabliment de la contrasenya no és vàlid o ha caducat. Torna-ho a provar..
+    invalid_reset_password_token: L'enllaç de restabliment de la contrasenya no és vàlid o ha caducat. Torna-ho a provar.
     login: Inicia sessió
     logout: Tanca sessió
     migrate_account: Mou a un compte diferent
     migrate_account_html: Si vols redirigir aquest compte a un altre diferent, el pots  <a href="%{path}">configurar aquí</a>.
-    register: Registra't
+    or_log_in_with: O inicia sessió amb
+    providers:
+      cas: CAS
+      saml: SAML
+    register: Registre
     resend_confirmation: Torna a enviar el correu de confirmació
     reset_password: Restableix la contrasenya
-    set_new_password: Estableix nova contrasenya
+    set_new_password: Estableix una contrasenya nova
   authorize_follow:
-    error: Malauradament, ha ocorregut un error buscant el compte remot
+    error: Malauradament, ha ocorregut un error cercant el compte remot
     follow: Segueix
-    follow_request: 'Heu enviat una sol·licitud de seguiment a:'
+    follow_request: 'Has enviat una sol·licitud de seguiment a:'
     following: 'Perfecte! Ara segueixes:'
     post_follow:
       close: O bé, pots tancar aquesta finestra.
@@ -393,26 +401,26 @@ ca:
       x_seconds: "%{count} s"
   deletes:
     bad_password_msg: Bon intent hackers! La contrasenya no és correcta
-    confirm_password: Introdueix la contrasenya actual per a verificar la teva identitat
+    confirm_password: Introdueix la contrasenya actual per a verificar la identitat
     description_html: Això eliminarà de forma <strong>irreversible i permanent</strong> el contingut del teu compte i el desactivarà. El teu nom d'usuari romandrà reservat per evitar que algú volgués fer-se passar per tu.
-    proceed: Suprimir el compte
-    success_msg: El teu compte s'ha eliminat correctament
-    warning_html: Només està garantida l'eliminació d'aquesta particular instància. El contingut que ha estat àmpliament compartit que deixi petjades. Els servidors fora de línia i els que ja no estan subscrits no actualitzaran les seves bases de dades.
+    proceed: Suprimeix el compte
+    success_msg: El compte s'ha eliminat correctament
+    warning_html: Només és garantida l'eliminació d'aquesta particular instància. El contingut que s'ha compartit àmpliament deixa petjades. Els servidors fora de línia i els que ja no estan subscrits no actualitzaran les seves bases de dades.
     warning_title: Disponibilitat de contingut disseminat
   errors:
     '403': No tens permís per a veure aquesta pàgina.
     '404': La pàgina que estàs cercant no existeix.
     '410': La pàgina que estàs cercant ja no existeix.
     '422':
-      content: La verificació de seguretat ha fallat. Bloques les galetes?
+      content: La verificació de seguretat ha fallat. Tens les galetes blocades?
       title: La verificació de seguretat ha fallat
     '429': Estrangulat
     '500':
       content: Ho sentim, però alguna cosa ha fallat a la nostra banda.
-      title: Aquesta pàgina no es correcte
-    noscript_html: Per utilitzar Mastodon si us plau activa JavaScript. També podeu provar una de les <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md"> aplicacions natives</a> per Mastodon per a la vostra plataforma.
+      title: Aquesta pàgina no es correcta
+    noscript_html: Per a utilitzar Mastodon, activa el JavaScript. També pots provar una de les <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md"> aplicacions natives</a> de Mastodon per a la vostra plataforma.
   exports:
-    blocks: Persones que has bloquejat
+    blocks: Persones que has blocat
     csv: CSV
     follows: Persones que segueixes
     mutes: Persones silenciades
@@ -525,13 +533,13 @@ ca:
           quadrillion: Q
           thousand: m
           trillion: T
-          unit: ''
+          unit: " "
   pagination:
-    next: Següent
+    next: Endavant
     prev: Enrere
     truncate: "&hellip;"
   preferences:
-    languages: Idiomes
+    languages: Llengues
     other: Altre
     publishing: Publicació
     web: Web
@@ -640,7 +648,7 @@ ca:
 
       <p>Recopilem informació teva quan et registres en aquesta instància i recopilem dades quan participes en el fòrum llegint, escrivint i avaluant el contingut aquí compartit.</p>
 
-      <p>En registrar-te en aquesta instància, se't pot demanar que introduexisu el teu nom i l'adreça de correu electrònic. També pots visitar el nostre lloc sense registrar-te. La teva adreça de correu electrònic es verificarà mitjançant un correu electrònic que conté un enllaç únic. Si es visita aquest enllaç, sabem que controles l'adreça de correu electrònic.</p>
+      <p>En registrar-te en aquesta instància, se't pot demanar que introduexis el teu nom i l'adreça de correu electrònic. També pots visitar el nostre lloc sense registrar-te. La teva adreça de correu electrònic es verificarà mitjançant un correu electrònic que conté un enllaç únic. Si es visita aquest enllaç, sabem que controles l'adreça de correu electrònic.</p>
 
       <p>Quan es registra i publica, registrem l'adreça IP de la qual es va originar la publicació. També podrem conservar els registres del servidor que inclouen l'adreça IP de cada sol·licitud al nostre servidor.</p>
 
@@ -724,7 +732,7 @@ ca:
   user_mailer:
     welcome:
       edit_profile_action: Configurar perfil
-      edit_profile_step: Pots personalitzar el teu perfil penjant un avatar, un encapçalament, canviant el teu nom de visualització i molt més. Si prefereixes revisar els seguidors nous abans de que et puguin seguir, pots bloquejar el teu compte.
+      edit_profile_step: Pots personalitzar el teu perfil penjant un avatar, un encapçalament, canviant el teu nom de visualització i molt més. Si prefereixes revisar els seguidors nous abans de que et puguin seguir, pots blocar el teu compte.
       explanation: Aquests són alguns consells per començar
       final_action: Comença a publicar
       final_step: 'Comença a publicar! Fins i tot sense seguidors, els altres poden veure els teus missatges públics, per exemple, a la línia de temps local i a les etiquetes ("hashtags"). És possible que vulguis presentar-te amb l''etiqueta #introductions.'
diff --git a/config/locales/devise.ar.yml b/config/locales/devise.ar.yml
index 206bbd1da..564231a1d 100644
--- a/config/locales/devise.ar.yml
+++ b/config/locales/devise.ar.yml
@@ -18,21 +18,29 @@ ar:
     mailer:
       confirmation_instructions:
         action: للتحقق من عنوان البريد الإلكتروني
+        explanation: لقد قمت بإنشاء حساب على %{host} بواسطة عنوان البريد الإلكتروني الحالي. إنك على بعد خطوات قليلة من تفعليه. إن لم تكن من طلب ذلك، يرجى ألّا تولي إهتماما بهذه الرسالة.
+        extra_html: ندعوك إلى الإطلاع على <a href="%{terms_path}">القواعد الخاصة بمثيل الخادوم هذا</a> and <a href="%{policy_path}">و شروط الخدمة الخاصة بنا</a>.
         subject: 'ماستدون : تعليمات التأكيد لمثيل الخادوم  %{instance}'
         title: للتحقق من عنوان البريد الإلكتروني
       email_changed:
+        explanation: 'لقد تم تغيير عنوان البريد الإلكتروني الخاص بحسابك إلى :'
+        extra: إن لم تقم شخصيًا بتعديل عنوان بريدك الإلكتروني ، ذلك يعني أنّ شخصا آخر قد نَفِذَ إلى حسابك. فالرجاء قم بتعديل كلمتك السرية في الحال أو قم بالإتصال بمدير مثيل الخادوم إن كنت غير قادر على استعمال حسابك.
         subject: 'ماستدون : تم استبدال عنوان بريدك الإلكتروني'
         title: عنوان البريد الإلكتروني الجديد
       password_change:
         explanation: تم تغيير كلمة السر الخاصة بحسابك.
+        extra: إن لم تقم شخصيًا بتعديل كلمتك السرية، ذلك يعني أنّ شخصا آخر قد سيطر على حسابك. فالرجاء قم بتعديل كلمتك السرية في الحال أو قم بالإتصال بمدير مثيل الخادوم إن كنت غير قادر على استعمال حسابك.
         subject: 'ماستدون : تم تغيير كلمة المرور'
         title: تم تغيير كلمة السر
       reconfirmation_instructions:
+        explanation: ندعوك لتأكيد العنوان الجديد قصد تعديله في بريدك.
+        extra: إن لم تكن صاحب هذا الطلب ، يُرجى عدم إعارة الإهتمام لهذه الرسالة. فعنوان البريد الإلكتروني المتعلق بحساب ماستدون سوف يبقى هو مِن غير أي تعديل إلّا و فقط إن قمت بالنقر على الرابط أعلاه قصد تعديله.
         subject: 'ماستدون : تأكيد كلمة السر الخاصة بـ %{instance}'
         title: التحقق من عنوان البريد الإلكتروني
       reset_password_instructions:
         action: تغيير كلمة السر
         explanation: لقد قمت بطلب تغيير كلمة السر الخاصة بحسابك.
+        extra: إن لم تكن صاحب هذا الطلب ، يُرجى عدم إعارة الإهتمام لهذه الرسالة. فكلِمَتُك السرية تبقى هي مِن غير أي تعديل إلّا و فقط إن قمت بالنقر على الرابط أعلاه قصد إنشاء كلمة سرية جديدة.
         subject: 'ماستدون : تعليمات إستعادة كلمة المرور'
         title: إعادة تعيين كلمة السر
       unlock_instructions:
@@ -41,20 +49,29 @@ ar:
       failure: تعذرت المصادقة من %{kind} بسبب "%{reason}".
       success: تمت المصادقة بنجاح عبر حساب %{kind}.
     passwords:
+      send_instructions: إن كان عنوان بريدك الإلكتروني ضمن قاعدة بياناتنا، فسوف تتلقّى في غضون دقائق رابطا يُمكّنُك مِن استعادة كلمتك السرية على عنوان علبة البريد الإلكتروني الخاصة بك.إن لم تجد هذه الرسالة، يرجى تفقد مجلّد البريد المزعج.
+      send_paranoid_instructions: إن كان عنوان بريدك الإلكتروني ضمن قاعدة بياناتنا، فسوف تتلقّى في غضون دقائق رابطا يُمكّنُك مِن استعادة كلمتك السرية على عنوان علبة البريد الإلكتروني الخاصة بك.إن لم تجد هذه الرسالة، يرجى تفقد مجلّد البريد المزعج.
       updated: تم تغيير كلمة المرور بنجاح. أنت مسجل الآن.
       updated_not_active: تم تغيير كلمة المرور بنجاح.
     registrations:
       destroyed: إلى اللقاء ! لقد تم إلغاء حسابك. نتمنى أن نراك مجددا.
       signed_up: أهلا وسهلا ! تم تسجيل دخولك بنجاح.
       signed_up_but_inactive: لقد تمت عملية إنشاء حسابك بنجاح إلاّ أنه لا يمكننا تسجيل دخولك إلاّ بعد قيامك بتفعيله.
+      signed_up_but_locked: لقد تم تسجيل حسابك بنجاح إلّا أنه لا يمكنك تسجيل الدخول لأن حسابك مجمد.
       signed_up_but_unconfirmed: لقد تم إرسال رسالة تحتوي على رابط للتفعيل إلى عنوان بريدك الإلكتروني. بالضغط على الرابط سوف يتم تفعيل حسابك. لذا يُرجى إلقاء نظرة على ملف الرسائل غير المرغوب فيها إنْ لم تَعثُر على الرسالة السالفة الذِكر.
+      update_needs_confirmation: لقد قمت بتحديث حسابك بنجاح إلا أنه يجب علينا التأكد من صحة عنوان بريدك الإلكتروني الجديد. يرجى الإطلاع على بريدك و اتباع الرابط الذي تلقيتَه لتأكيد عنوان بريدك الإلكتروني الجديد. إن لم تتلقى تلك الرسالة ، ندعوك إلى تفقُّد مجلد البريد المزعج.
       updated: تم تحديث حسابك بنجاح.
     sessions:
       already_signed_out: تم تسجيل خروجك بنجاح.
       signed_in: تم تسجيل دخولك بنجاح.
       signed_out: تم تسجيل خروجك بنجاح.
+    unlocks:
+      send_instructions: سوف تتلقى خلال بضع دقائق رسالة إلكترونية تحتوي على التعليمات اللازمة لفك القفل عن حسابك. إن لم تتلقى تلك الرسالة ، ندعوك إلى تفقُّد مجلد البريد المزعج.
+      send_paranoid_instructions: إن كان حسابك موجود فعليًا فسوف تتلقى في غضون دقائق رسالة إلكترونية تحتوي على تعليمات تدُلُّك على كيفية فك القفل عن حسابك. إن لم تتلقى تلك الرسالة ، ندعوك إلى تفقُّد مجلد البريد المزعج.
+      unlocked: لقد تمت عملية إلغاء تجميد حسابك بنجاح. للمواصلة،  يُرجى تسجيل الدخول.
   errors:
     messages:
+      already_confirmed: قمت بتأكيده من قبل، يرجى إعادة محاولة تسجيل الدخول
       expired: إنتهت مدة صلاحيته، الرجاء طلب واحد جديد
       not_found: لا يوجد
       not_locked: ليس مقفلاً
diff --git a/config/locales/devise.ca.yml b/config/locales/devise.ca.yml
index d88db17ca..808a5dd0a 100644
--- a/config/locales/devise.ca.yml
+++ b/config/locales/devise.ca.yml
@@ -7,29 +7,29 @@ ca:
       send_paranoid_instructions: Si l'adreça de correu electrònic existeix en la nostra base de dades, en pocs minuts rebràs un correu electrònic amb instruccions sobre com confirmar l'adreça de correu.
     failure:
       already_authenticated: Ja estàs registrat.
-      inactive: el teu compte encara no s'ha activat.
+      inactive: El teu compte encara no s'ha activat.
       invalid: "%{authentication_keys} o contrasenya no són vàlids."
       last_attempt: Tens un intent més, abans que es bloqui el compte.
-      locked: el compte s'ha blocat.
+      locked: El compte s'ha blocat.
       not_found_in_database: "%{authentication_keys} o contrasenya no vàlids."
-      timeout: la sessió ha expirat. Incia sessió una altra vegada per a continuar.
+      timeout: La sessió ha expirat. Inicia sessió una altra vegada per a continuar.
       unauthenticated: Cal iniciar sessió o registrar-se abans de continuar.
       unconfirmed: Has de confirmar l'adreça de correu electrònic abans de continuar.
     mailer:
       confirmation_instructions:
-        action: Verificar l'adreça de correu
+        action: Verifica l'adreça de correu
         explanation: Has creat un compte a %{host} amb aquesta adreça de correu electrònic. Estàs a un sol clic de l'activació. Si no fos així, ignora aquest correu electrònic.
         extra_html: Si us plau consulta també <a href="%{terms_path}"> les regles de la instància</a> i <a href="%{policy_path}"> les nostres condicions de servei</a>.
         subject: 'Mastodon: Instruccions de confirmació'
         title: Verifica l'adreça de correu
       email_changed:
         explanation: 'L''adreça de correu del teu compte s''està canviant a:'
-        extra: Si no has canviat el teu correu electrònic, és probable que algú hagi accedit al teu compte. Si us plau, canvia la contrasenya immediatament o posa't en contacte amb l'administrador de l'instància si no pots accedir al teu compte.
+        extra: Si no has canviat el teu correu electrònic, és probable que algú hagi accedit al teu compte. Si us plau, canvia la contrasenya immediatament o posa't en contacte amb l'administrador de la instància si no pots accedir al teu compte.
         subject: 'Mastodon: s''ha canviat l''adreça electrònica'
-        title: Nova adreça de correu electrònic
+        title: Adreça de correu electrònic nova
       password_change:
         explanation: S'ha canviat la contrasenya del teu compte.
-        extra: Si no has canviat el teu correu electrònic, és probable que algú hagi accedit al teu compte. Si us plau, canvia la contrasenya immediatament o posa't en contacte amb l'administrador de l'instància si no pots accedir al teu compte.
+        extra: Si no has canviat el teu correu electrònic, és probable que algú hagi accedit al teu compte. Si us plau, canvia la contrasenya immediatament o posa't en contacte amb l'administrador de la instància si no pots accedir al teu compte.
         subject: 'Mastodon: Contrasenya canviada'
         title: Contrasenya canviada
       reconfirmation_instructions:
diff --git a/config/locales/devise.de.yml b/config/locales/devise.de.yml
index 91efbed50..77243ba15 100644
--- a/config/locales/devise.de.yml
+++ b/config/locales/devise.de.yml
@@ -12,12 +12,12 @@ de:
       last_attempt: Du hast noch einen Versuch, bevor dein Konto gesperrt wird.
       locked: Dein Konto ist gesperrt.
       not_found_in_database: "%{authentication_keys} oder Passwort ungültig."
-      timeout: Deine Sitzung ist abgelaufen. Bitte melde dich erneut an.
+      timeout: Deine Sitzung ist abgelaufen. Bitte melde dich erneut an, um fortzufahren.
       unauthenticated: Du musst dich anmelden oder registrieren, bevor du fortfahren kannst.
       unconfirmed: Du musst deine E-Mail-Adresse bestätigen, bevor du fortfahren kannst.
     mailer:
       confirmation_instructions:
-        action: Verifiziere E-Mailadresse
+        action: E-Mail-Adresse verifizieren
         explanation: Du hast einen Account auf %{host} mit dieser E-Mail-Adresse erstellt. Du bist nun einen Klick entfernt vor der Aktivierung. Wenn du das nicht warst, kannst du diese E-Mail ignorieren.
         extra_html: Bitte lies auch die <a href="%{terms_path}">Regeln dieser Instanz</a> und <a href="%{policy_path}">unsere Nutzungsbedingungen</a>.
         subject: 'Mastodon: Bestätigung deines Kontos bei %{instance}'
@@ -56,7 +56,7 @@ de:
       updated_not_active: Dein Passwort wurde geändert.
     registrations:
       destroyed: Dein Konto wurde gelöscht.
-      signed_up: Du hast dich erfolgreich registriert.
+      signed_up: Willkommen! Du hast dich erfolgreich registriert.
       signed_up_but_inactive: Du hast dich erfolgreich registriert. Wir konnten dich noch nicht anmelden, da dein Konto inaktiv ist.
       signed_up_but_locked: Du hast dich erfolgreich registriert. Wir konnten dich noch nicht anmelden, da dein Konto gesperrt ist.
       signed_up_but_unconfirmed: Du hast dich erfolgreich registriert. Wir konnten dich noch nicht anmelden, da dein Konto noch nicht bestätigt ist. Du erhältst in Kürze eine E-Mail. Darin ist erklärt, wie du dein Konto freischalten kannst.
diff --git a/config/locales/devise.eo.yml b/config/locales/devise.eo.yml
index bb138beb9..71dd6c1ef 100644
--- a/config/locales/devise.eo.yml
+++ b/config/locales/devise.eo.yml
@@ -2,75 +2,81 @@
 eo:
   devise:
     confirmations:
-      confirmed: Via konto estas konfirmita.
-      send_instructions: Vi ricevos instrukciojn por konfirmi vian konton post kelkaj minutoj.
-      send_paranoid_instructions: Se via retpoŝt-adreso ekzistas en nia datumbazo, vi baldaŭ ricevos retpoŝt-mesaĝon, kiu enhavas la instrukciojn por konfirmi vian konton.
+      confirmed: Via retadreso estis sukcese konfirmita.
+      send_instructions: Vi ricevos retmesaĝon kun instrukcioj por konfirmi vian retadreson ene de kelkaj minutoj. Bonvolu kontroli vian spamujon se vi ne ricevis ĉi tiun retmesaĝon.
+      send_paranoid_instructions: Se via retadreso ekzistas en nia datumbazo, vi ricevos retmesaĝon kun instrukcioj por konfirmi vian retadreson ene de kelkaj minutoj. Bonvolu kontroli vian spamujon se vi ne ricevis ĉi tiun retmesaĝon.
     failure:
-      already_authenticated: Vi jam estas ensalutita.
+      already_authenticated: Vi jam ensalutis.
       inactive: Via konto ankoraŭ ne estas konfirmita.
-      invalid: Malĝusta retpoŝt-adreso aŭ pasvorto.
+      invalid: Nevalida %{authentication_keys} aŭ pasvorto.
       last_attempt: Vi ankoraŭ povas provi unufoje antaŭ ol via konto estos ŝlosita.
       locked: Via konto estas ŝlosita.
-      not_found_in_database: Malĝusta retpoŝt-adreso aŭ pasvorto.
-      timeout: Via sesio eksiĝis. Bonvolu reensaluti por daŭrigi.
-      unauthenticated: Vi devas ensaluti aŭ membriĝi por daŭrigi.
-      unconfirmed: Vi devas konfirmi vian konton por daŭrigi.
+      not_found_in_database: Nevalida %{authentication_keys} aŭ pasvorto.
+      timeout: Via seanco eksvalidiĝis. Bonvolu ensaluti denove por daŭrigi.
+      unauthenticated: Vi devas ensaluti aŭ registriĝi antaŭ ol daŭrigi.
+      unconfirmed: Vi devas konfirmi vian retadreson antaŭ ol daŭrigi.
     mailer:
       confirmation_instructions:
-        action: Kontrolu vian retmesaĝan adreson
-        subject: Instrukcioj por konfirmi
-        title: Kontrolu la retmesaĝan adreson
+        action: Konfirmi retadreson
+        explanation: Vi kreis konton en %{host} per ĉi tiu retadreso. Nur klako restas por aktivigi ĝin. Se tio ne estis vi, bonvolu ignori ĉi tiun retmesaĝon.
+        extra_html: Bonvolu rigardi <a href="%{terms_path}">la regulojn de la nodo</a> kaj <a href="%{policy_path}">niajn uzkondiĉojn</a>.
+        subject: 'Mastodon: Konfirmaj instrukcioj por %{instance}'
+        title: Konfirmi retadreson
       email_changed:
-        explanation: 'La retmesaĝa adreso de via konto estas ŝanĝonta al:'
-        subject: 'Mastodon: retmesaĝa adreso ŝanĝiĝis'
-        title: Nova retmesaĝa adreso
+        explanation: 'La retadreso de via konto ŝanĝiĝas al:'
+        extra: Se vi ne volis ŝanĝi vian retadreson, iu verŝajne aliris al via konto. Bonvolu tuj ŝanĝi vian pasvorton aŭ kontakti la administranton de la nodo, se vi estas blokita ekster via konto.
+        subject: 'Mastodon: Retadreso ŝanĝita'
+        title: Nova retadreso
       password_change:
-        explanation: La pasvorto de via konto ŝanĝiĝis.
-        subject: 'Mastodon: via pasvorto estis ŝanĝita senprobleme'
+        explanation: La pasvorto de via konto estis ŝanĝita.
+        extra: Se vi ne ŝanĝis vian pasvorton, iu verŝajne aliris al via konto. Bonvolu ŝanĝi vian pasvorton tuj aŭ kontakti la administranton de la nodo, se vi estas blokita ekster via konto.
+        subject: 'Mastodon: Pasvorto ŝanĝita'
         title: Pasvorto ŝanĝita
       reconfirmation_instructions:
-        explanation: Retajpu la novan adreson por ŝanĝi vian retmesaĝujon.
-        subject: 'Mastodon: jesigi retmesaĝon por %{instance}'
-        title: Kontrolu la retmesaĝan adreson
+        explanation: Retajpu la novan adreson por ŝanĝi vian retadreson.
+        extra: Se ĉi tiu ŝanĝo ne estis komencita de vi, bonvolu ignori ĉi tiun retmesaĝon. La retadreso por la Mastodon-konto ne ŝanĝiĝos se vi ne aliras la supran ligilon.
+        subject: 'Mastodon: Konfirmi retadreson por %{instance}'
+        title: Kontrolu retadreson
       reset_password_instructions:
-        action: Ŝanĝi la pasvorton
+        action: Ŝanĝi pasvorton
         explanation: Vi petis novan pasvorton por via konto.
-        subject: Instrukcioj por ŝanĝi la pasvorton
-        title: Pasvorto renovigita
+        extra: Se vi ne petis ĉi tion, bonvolu ignori ĉi tiun retmesaĝon. Via pasvorto ne ŝanĝiĝos se vi ne aliras la supran ligilon kaj kreas novan.
+        subject: 'Mastodon: Instrukcioj por ŝanĝi pasvorton'
+        title: Pasvorto restarigita
       unlock_instructions:
-        subject: Instrukcioj por malŝlosi la konton
+        subject: 'Mastodon: Instrukcioj por malŝlosi'
     omniauth_callbacks:
       failure: 'Ni ne povis aŭtentigi vin per %{kind}: ''%{reason}''.'
-      success: Aŭtentigita senprobleme per %{kind}.
+      success: Aŭtentigita sukcese per %{kind}.
     passwords:
-      no_token: Vi ne povas iri al tiu paĝo per alia vojo ol retpoŝt-mesaĝo por ŝanĝi pasvorton. Se vi venas de tia retpoŝt-mesaĝo, kontrolu ke vi uzis la tutan URL.
-      send_instructions: Vi ricevos retpoŝt-mesaĝon kun instrukcioj por ŝanĝi vian pasvorton post kelkaj minutoj.
-      send_paranoid_instructions: Se via retpoŝt-adreso ekzistas en nia datumbazo, vi ricevos ligilon por ŝanĝi vian pasvorton per retpoŝt-mesaĝo.
-      updated: Via pasvorto estis redaktita senprobleme, vi nun estas ensalutita.
-      updated_not_active: Via pasvorto estis redaktita senprobleme.
+      no_token: Vi ne povas aliri al ĉi tiu paĝo alimaniere ol per retmesaĝo por ŝanĝi pasvorton. Se vi venas de tia retmesaĝo, bonvolu certiĝi, ke vi uzas la tutan URL-on donitan.
+      send_instructions: Se via retadreso ekzistas en nia datumbazo, vi ricevos ligilon por havi novan pasvorton ĉe via retadreso ene de kelkaj minutoj. Bonvolu kontroli vian spamujon se vi ne ricevis ĉi tiun retmesaĝon.
+      send_paranoid_instructions: Se via retadreso ekzistas en nia datumbazo, vi ricevos ligilon por havi novan pasvorton ĉe via retadreso ene de kelkaj minutoj. Bonvolu kontroli vian spamujon se vi ne ricevis ĉi tiun retmesaĝon.
+      updated: Via pasvorto estis sukcese ŝanĝita. Vi nun estas ensalutinta.
+      updated_not_active: Via pasvorto estis sukcese ŝanĝita.
     registrations:
-      destroyed: Ĝis! Via konto estis forigita senprobleme. Ni esperas revidi vin baldaŭ.
-      signed_up: Bonvenon! Vi membriĝis senprobleme.
-      signed_up_but_inactive: Vi bone membriĝis, sed vi ankoraŭ ne povas ensaluti ĉar via konto ne estis konfirmita.
-      signed_up_but_locked: Vi bone membriĝis, sed vi ne povas ensaluti ĉar via konto estas ŝlosita.
-      signed_up_but_unconfirmed: Retpoŝt-mesaĝo kun via ligilo por konfirmi vian konton estis sendita al via retpoŝt-adreso. Bonvolu uzi tiun ligilon por konfirmi vian konton.
-      update_needs_confirmation: Vi bone aktualigis vian konton, sed ni bezonas kontroli vian novan retpoŝt-adreson. Bonvolu kontroli viajn retpoŝt-mesaĝojn kaj uzi la ligilon por konfirmi vian novan retpoŝt-adreson.
-      updated: Via konto estis aktualigita senprobleme.
+      destroyed: Ĝis! Via konto estis sukcese forigita. Ni esperas revidi vin baldaŭ.
+      signed_up: Bonvenon! Vi sukcese registriĝis.
+      signed_up_but_inactive: Vi sukcese registriĝis. Tamen, ni ne povis ensalutigi vin, ĉar via konto ankoraŭ ne estas konfirmita.
+      signed_up_but_locked: Vi sukcese registriĝis. Tamen, ni ne povis ensalutigi vin, ĉar via konto estas ŝlosita.
+      signed_up_but_unconfirmed: Retmesaĝo kun konfirma ligilo estis sendita al via retadreso. Bonvolu sekvi la ligilon por aktivigi vian konton. Bonvolu kontroli vian spamujon, se vi ne ricevis ĉi tiun retmesaĝon.
+      update_needs_confirmation: Vi sukcese ĝisdatigis vian konton, sed ni bezonas kontroli vian novan retadreson. Bonvolu kontroli viajn retmesaĝojn kaj sekvi la konfirman ligilon por konfirmi vian novan retadreson. Bonvolu kontroli vian spamujon, se vi ne ricevis ĉi tiun retmesaĝon.
+      updated: Via konto estis sukcese ĝisdatigita.
     sessions:
-      already_signed_out: Elsalutita.
-      signed_in: Ensalutita.
-      signed_out: Elsalutita.
+      already_signed_out: Sukcese elsalutis.
+      signed_in: Sukcese ensalutis.
+      signed_out: Sukcese elsalutis.
     unlocks:
-      send_instructions: Vi ricevos retpoŝt-mesaĝon kun instrukcioj por malŝlosi vian konton post kelkaj minutoj.
-      send_paranoid_instructions: Se via retpoŝt-adreso ekzistas en nia datumbazo, vi ricevos ligilon por malŝlosi vian konton per retpoŝt-mesaĝo.
-      unlocked: Via konto estis malŝlosita senprobleme, vi nun estas ensalutita.
+      send_instructions: Vi ricevos retmesaĝon kun instrukcioj por malŝlosi vian konton ene de kelkaj minutoj. Bonvolu kontroli vian spamujon, se vi ne ricevis ĉi tiun retmesaĝon.
+      send_paranoid_instructions: Se via konto ekzistas, vi ricevos retmesaĝon kun instrukcioj por malŝlosi ĝin ene de kelkaj minutoj. Bonvolu kontroli vian spamujon se vi ne ricevis ĉi tiun retmesaĝon.
+      unlocked: Via konto estis sukcese malŝlosita. Bonvolu ensaluti por daŭrigi.
   errors:
     messages:
       already_confirmed: jam estis konfirmita, bonvolu provi ensaluti
-      confirmation_period_expired: devas esti konfirmita en %{period}, bonvolu repeti
-      expired: eksiĝis, bonvolu repeti
+      confirmation_period_expired: devas esti konfirmita ene de %{period}, bonvolu peti denove
+      expired: eksvalidiĝis, bonvolu peti denove
       not_found: ne estis trovita
       not_locked: ne estis ŝlosita
       not_saved:
-        one: '1 eraro malpermesis al tiu %{resource} esti konservita:'
-        other: "%{count} eraroj malpermesis al tiu %{resource} esti konservita:"
+        one: '1 eraro malpermesis al ĉi tiu %{resource} esti konservita:'
+        other: "%{count} eraroj malpermesis al ĉi tiu %{resource} esti konservita:"
diff --git a/config/locales/devise.hr.yml b/config/locales/devise.hr.yml
index 40e0effcf..d578e404f 100644
--- a/config/locales/devise.hr.yml
+++ b/config/locales/devise.hr.yml
@@ -17,6 +17,9 @@ hr:
     mailer:
       confirmation_instructions:
         subject: 'Mastodon: Upute za potvrđivanje'
+      email_changed:
+        subject: 'Mastodon: Email adresa je promijenjena'
+        title: Nova email adresa
       password_change:
         subject: 'Mastodon: Lozinka je promijenjena'
       reset_password_instructions:
diff --git a/config/locales/devise.hu.yml b/config/locales/devise.hu.yml
index 911ba7b94..79ee3b194 100644
--- a/config/locales/devise.hu.yml
+++ b/config/locales/devise.hu.yml
@@ -6,7 +6,7 @@ hu:
       send_instructions: Pár percen belül kapni fogsz egy e-mailt az e-mail címed megerősítéséhez szükséges lépésekről.
       send_paranoid_instructions: Ha az e-mail címed létezik az adatbázisunkban, pár percen belül kapni fogsz egy e-mailt az e-mail címed megerősítéséhez szükséges lépésekről.
     failure:
-      already_authenticated: Már bejelentkeztél
+      already_authenticated: Már bejelentkeztél.
       inactive: Fiókod még nem lett aktiválva.
       invalid: Helytelen %{authentication_keys} vagy jelszó.
       last_attempt: Már csak egy próbálkozásod maradt mielőtt a fiókod lezárásra kerül.
@@ -17,11 +17,32 @@ hu:
       unconfirmed: A folytatás előtt meg kell erősítened az e-mail címed.
     mailer:
       confirmation_instructions:
+        action: Erősítsd meg az e-mail címedet
+        explanation: Ezzel az e-mail címmel kezdeményeztek regisztrációt a(z) %{host} oldalon. Csak egy kattintás, és a felhasználói fiókdat aktiváljuk. Ha a regisztrációt nem te kezdeményezted, kérjük tekintsd ezt az e-mailt tárgytalannak.
+        extra_html: Kérjük tekintsd át a <a href="%{terms_path}">az instancia szabályzatát</a> és <a href="%{policy_path}">a felhasználási feltételeket</a>.
         subject: 'Mastodon: Megerősítési lépések'
+        title: E-mail cím megerősítése
+      email_changed:
+        explanation: 'A fiókodhoz tartozó e-mail címet az alábbira módosítod:'
+        extra: Ha nem te kezdeményezted a fiókodhoz tartozó e-mail cím módosítását, valaki hozzáférhetett a fiókodhoz. Legjobb, ha azonnal megváltoztatod a jelszavadat; ha nem férsz hozzá a fiókodhoz, vedd fel a kapcsolatot az instanciád adminisztrátorával.
+        subject: 'Mastodon: a fiókodhoz tartozó e-mail címet megváltoztattuk'
+        title: Új e-mail cím
       password_change:
+        explanation: A fiókodhoz tartozó jelszót megváltoztattuk.
+        extra: Ha nem te kezdeményezted a fiókodhoz tartozó jelszó módosítását, valaki hozzáférhetett a fiókodhoz. Legjobb, ha azonnal megváltoztatod a jelszavadat; ha nem férsz hozzá a fiókodhoz, vedd fel a kapcsolatot az instanciád adminisztrátorával.
         subject: 'Mastodon: Jelszó megváltoztatva'
+        title: Sikeres jelszó-módosítás
+      reconfirmation_instructions:
+        explanation: Az e-mail cím megváltoztatásához meg kell erősítened az új címet.
+        extra: Amennyiben nem te kezdeményezted a módosítást, kérjük tekintsd ezt az e-mailt tárgytalannak. A Mastodon fiókodhoz tartozó e-mail címed változatlan marad mindaddig, amíg rá nem kattintasz a fenti linkre.
+        subject: 'Mastodon: erősítsd meg a(z) %{instance} instanciához tartozó e-mail címed'
+        title: E-mail cím megerősítése
       reset_password_instructions:
+        action: Jelszó módosítása
+        explanation: A fiókodhoz tartozó jelszó módosítását kezdeményezted.
+        extra: Amennyiben nem te kezdeményezted a módosítást, kérjük tekintsd ezt az e-mailt tárgytalannak. A Mastodon fiókodhoz tartozó jelszavad változatlan marad mindaddig, amíg újat nem hozol létre a fenti linkre kattintva.
         subject: 'Mastodon: Jelszó visszaállítási lépések'
+        title: Jelszó visszaállítása
       unlock_instructions:
         subject: 'Mastodon: Feloldási lépések'
     omniauth_callbacks:
diff --git a/config/locales/devise.pt.yml b/config/locales/devise.pt.yml
index f55d5e5a7..5fd54ff50 100644
--- a/config/locales/devise.pt.yml
+++ b/config/locales/devise.pt.yml
@@ -40,7 +40,7 @@ pt:
       reset_password_instructions:
         action: Alterar palavra-passe
         explanation: Pediste a alteração da palavra-passe da tua conta.
-        extra: Se fizeste este pedido, por favor ignore este e-mail. A tua palavra-passe não irá mudar se não acederes ao link acima e criares uma nova.
+        extra: Se não fizeste este pedido, por favor ignora este e-mail. A tua palavra-passe não irá mudar se não acederes ao link acima e criares uma nova.
         subject: 'Mastodon: Instruções para alterar a palavra-passe'
         title: Solicitar nova palavra-passe
       unlock_instructions:
diff --git a/config/locales/devise.sk.yml b/config/locales/devise.sk.yml
index d6c76d1a3..f71f8c62c 100644
--- a/config/locales/devise.sk.yml
+++ b/config/locales/devise.sk.yml
@@ -18,11 +18,31 @@ sk:
     mailer:
       confirmation_instructions:
         action: Potvrite emailovú adresu
+        explanation: S touto email adresou ste si vytvoril/a účet na %{host}. Si iba jeden klik od jeho aktivácie. Pokiaľ ste to ale nebol/a vy, prosím ignoruj tento email.
+        extra_html: Prosím pozri sa aj na <a href="%{terms_path}"> pravidla tohto servera,</a> a <a href="%{policy_path}"> naše užívaťeľské podiemky</a>.
         subject: 'Mastodon: Potvrdzovacie inštrukcie pre %{instance}'
+        title: Potvrď emailovú adresu
+      email_changed:
+        explanation: 'Emailová adresa tvojho účtu bude zmenená na:'
+        extra: Pokiaľ si nezmenil/a svoj email, je pravdepodobné že niekto iný získal prístup k tvojmu účtu. Naliehavo preto prosím zmeň svoje heslo, alebo kontaktuj administrátora tohto serveru pokiaľ si vymknutý/á zo svojho účtu.
+        subject: 'Mastodon: Emailová adresa bola zmenená'
+        title: Nová emailová adresa
       password_change:
+        explanation: Heslo k vašemu účtu bolo zmenené.
+        extra: Pokiaľ si nezmenil/a svoje heslo, je pravdepodobné že niekto iný získal prístup k tvojmu účtu. Naliehavo preto prosím zmeň svoje heslo, alebo kontaktuj administrátora tohto serveru pokiaľ si vymknutý/á zo svojho účtu.
         subject: 'Mastodon: Heslo bolo zmenené'
+        title: Heslo bolo zmenené
+      reconfirmation_instructions:
+        explanation: Potvrď novú emailovú adresu na ktorú chceš zmeniť svoj email.
+        extra: Pokiaľ si túto akciu nevyžiadal/a, prosím ignoruj tento email. Emailová adresa pre tvoj Mastodon účet totiž nebude zmenená pokiaľ nepostúpiš na adresu uvedenú vyššie.
+        subject: 'Mastodon: Potvrďenie emailu pre %{instance}'
+        title: Overiť emailovú adresu
       reset_password_instructions:
+        action: Zmeniť heslo
+        explanation: Vyžiadal/a ste si nové heslo pre svoj účet.
+        extra: Pokiaľ si túto akciu nevyžiadal/a, prosím ignoruj tento email. Tvoje heslo nebude zmenené pokiaľ nepostúpiš na adresu uvedenú vyššie a vytvoríš si nové.
         subject: 'Mastodon: Inštrukcie pre obnovu hesla'
+        title: Nastav nové heslo
       unlock_instructions:
         subject: 'Mastodon: Inštrukcie pre odomknutie účtu'
     omniauth_callbacks:
diff --git a/config/locales/devise.sv.yml b/config/locales/devise.sv.yml
index 3ac0c6d10..456e38581 100644
--- a/config/locales/devise.sv.yml
+++ b/config/locales/devise.sv.yml
@@ -17,11 +17,32 @@ sv:
       unconfirmed: Du måste bekräfta din e-postadress innan du fortsätter.
     mailer:
       confirmation_instructions:
+        action: Verifiera e-postadress
+        explanation: Du har skapat ett konto på %{host} med den här e-postadressen. Du är ett klick bort från att aktivera det. Om det inte var du ignorerar det här e-postmeddelandet.
+        extra_html: Kolla gärna också <a href="%{terms_path}">instansens regler</a> och <a href="%{policy_path}">våra användarvillkor</a>.
         subject: 'Mastodon: Bekräftelsesinstruktioner för %{instance}'
+        title: Verifiera e-postadress
+      email_changed:
+        explanation: 'E-postadressen för ditt konto ändras till:'
+        extra: Om du inte ändrade din e-post är det troligt att någon har fått tillgång till ditt konto. Vänligen ändra ditt lösenord omedelbart eller kontakta instansadministratören om du är låst ur ditt konto.
+        subject: 'Mastodon: E-post ändrad'
+        title: Ny e-postadress
       password_change:
+        explanation: Lösenordet för ditt konto har ändrats.
+        extra: Om du inte ändrade ditt lösenord är det troligt att någon har fått tillgång till ditt konto. Vänligen ändra ditt lösenord omedelbart eller kontakta instansadministratören om du är utelåst från ditt konto.
         subject: 'Mastodon: Lösenord ändrat'
+        title: lösenordet ändrat
+      reconfirmation_instructions:
+        explanation: Bekräfta den nya adressen för att ändra din e-postadress.
+        extra: Om den här ändringen inte initierades av dig kan du ignorerar det här e-postmeddelandet. E-postadressen för Mastodon-kontot ändras inte förrän du kommer åt länken ovan.
+        subject: 'Mastodon: Bekräfta e-post för %{instance}'
+        title: Verifiera e-postadressen
       reset_password_instructions:
+        action: Ändra lösenord
+        explanation: Du begärde ett nytt lösenord för ditt konto.
+        extra: Om du inte begärt detta kan du ignorerar det här e-postmeddelandet. Ditt lösenord ändras inte förrän du öppnar länken ovan och skapar ett nytt.
         subject: 'Mastodon: Instruktioner för återställning av lösenord'
+        title: Lösenordsåterställning
       unlock_instructions:
         subject: 'Mastodon: Lås upp instruktioner'
     omniauth_callbacks:
@@ -31,7 +52,7 @@ sv:
       no_token: Du kan inte komma åt den här sidan utan att komma från ett e-postmeddelande för lösenordsåterställning. Om du kommer från ett lösenordsåterställt e-postmeddelande, var vänlig och se till att du använde hela webbadressen.
       send_instructions: Om din e-postadress finns i vår databas, får du en länk för återställning av lösenord på din e-postadress om några minuter. Kontrollera din spammapp om du inte fick det här e-postmeddelandet.
       send_paranoid_instructions: Om din e-postadress finns i vår databas, får du en länk för återställning av lösenord på din e-postadress om några minuter. Kontrollera din spammapp om du inte fick det här e-postmeddelandet.
-      updated: Your password has been changed successfully. You are now signed in.
+      updated: Ditt lösenord har ändrats framgångsrikt. Du är nu inloggad.
       updated_not_active: Ditt lösenord har ändrats. Du är nu inloggad.
     registrations:
       destroyed: Adjö! Ditt konto har blivit nerstängt. Vi hoppas att vi ses snart igen.
diff --git a/config/locales/doorkeeper.ar.yml b/config/locales/doorkeeper.ar.yml
index 107677837..d13c22386 100644
--- a/config/locales/doorkeeper.ar.yml
+++ b/config/locales/doorkeeper.ar.yml
@@ -4,7 +4,7 @@ ar:
     attributes:
       doorkeeper/application:
         name: التسمية
-        redirect_uri: Redirect URI
+        redirect_uri: عنوان التحويل
         scopes: المجالات
         website: تطبيق الويب
     errors:
@@ -33,7 +33,7 @@ ar:
       help:
         native_redirect_uri: إستخدم %{native_redirect_uri} للاختبار و التجريب محليا
         redirect_uri: إستخدم خطا واحدا لكل رابط
-        scopes: Separate scopes with spaces. Leave blank to use the default scopes.
+        scopes: تقسيم المجالات بمسافات بيضاء. بدون تحديد قيمة يعني ذلك استخدام المجالات الإفتراضية.
       index:
         application: تطبيق
         callback_url: رابط رد النداء
@@ -77,20 +77,14 @@ ar:
         title: تطبيقاتك المرخص لها
     errors:
       messages:
-        access_denied: The resource owner or authorization server denied the request.
-        credential_flow_not_configured: Resource Owner Password Credentials flow failed due to Doorkeeper.configure.resource_owner_from_credentials being unconfigured.
-        invalid_client: Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.
-        invalid_grant: The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
-        invalid_redirect_uri: The redirect uri included is not valid.
-        invalid_request: The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed.
-        invalid_resource_owner: The provided resource owner credentials are not valid, or resource owner cannot be found
-        invalid_scope: The requested scope is invalid, unknown, or malformed.
+        access_denied: لقد رفض مالك المَورِدِ أو تصريح السيرفر طلبك.
+        invalid_client: فشلت المصادقة مع العميل لأنه العميل مجهول أو لغياب المصادقة ضمن العميل أو أنّ أسلوب المصادقة غير مدعومة.
+        invalid_redirect_uri: إنّ عنوان إعادة التحويل غير صالح.
+        invalid_scope: المجال المطلوب غير صحيح أو مجهول أو مُعبَّر عنه بشكل خاطئ.
         invalid_token:
           expired: إنتهت فترة صلاحيته رمز المصادقة
           revoked: تم إبطال رمز المصادقة
           unknown: رمز المصادقة غير صالح
-        resource_owner_authenticator_not_configured: Resource Owner find failed due to Doorkeeper.configure.resource_owner_authenticator being unconfiged.
-        server_error: The authorization server encountered an unexpected condition which prevented it from fulfilling the request.
         temporarily_unavailable: تعذر على خادم التفويض معالجة الطلب و ذلك بسبب زيادة مؤقتة في التحميل أو عملية صيانة مبرمجة على الخادم.
         unauthorized_client: لا يصرح للعميل بتنفيذ هذا الطلب باستخدام هذه الطريقة.
         unsupported_grant_type: هذا النوع من منح التصريح غير معتمد في خادم الترخيص.
diff --git a/config/locales/doorkeeper.eo.yml b/config/locales/doorkeeper.eo.yml
index 8c5845392..59df52852 100644
--- a/config/locales/doorkeeper.eo.yml
+++ b/config/locales/doorkeeper.eo.yml
@@ -3,8 +3,9 @@ eo:
   activerecord:
     attributes:
       doorkeeper/application:
-        name: Nomo
-        redirect_uri: URI de plusendo
+        name: Aplikaĵa nomo
+        redirect_uri: Plusenda URI
+        scopes: Ampleksoj
         website: Aplikaĵa retejo
     errors:
       models:
@@ -19,7 +20,7 @@ eo:
     applications:
       buttons:
         authorize: Rajtigi
-        cancel: Rezigni
+        cancel: Nuligi
         destroy: Detrui
         edit: Redakti
         submit: Sendi
@@ -32,23 +33,24 @@ eo:
       help:
         native_redirect_uri: Uzu %{native_redirect_uri} por lokaj provoj
         redirect_uri: Uzu unu linion por ĉiu URI
-        scopes: Apartigu ampleksojn per spacetoj. Lasu malplena por uzi la senŝanĝajn ampleksojn.
+        scopes: Apartigu ampleksojn per spacetoj. Lasu malplena por uzi la dekomencajn ampleksojn.
       index:
         application: Aplikaĵo
-        callback_url: URL vokita per referenco
-        delete: Forviŝi
+        callback_url: Revena URL
+        delete: Forigi
         name: Nomo
-        new: Nova Aplikaĵo
+        new: Nova aplikaĵo
+        scopes: Ampleksoj
         show: Montri
         title: Viaj aplikaĵoj
       new:
         title: Nova aplikaĵo
       show:
         actions: Agoj
-        application_id: Identigo de la aplikaĵo
-        callback_urls: URL-j vokitaj per referenco
+        application_id: Klienta ŝlosilo
+        callback_urls: Revenaj URL-oj
         scopes: Ampleksoj
-        secret: Sekreto
+        secret: Klienta sekreto
         title: 'Aplikaĵo: %{name}'
     authorizations:
       buttons:
@@ -57,11 +59,11 @@ eo:
       error:
         title: Eraro okazis
       new:
-        able_to: Povos
+        able_to: Ĝi povos
         prompt: La aplikaĵo %{client_name} petas aliron al via konto
         title: Rajtigo bezonata
       show:
-        title: Copy this authorization code and paste it to the application.
+        title: Kopiu ĉi tiun rajtigan kodon kaj gluu ĝin al la aplikaĵo.
     authorized_applications:
       buttons:
         revoke: Malrajtigi
@@ -75,24 +77,24 @@ eo:
         title: Viaj rajtigitaj aplikaĵoj
     errors:
       messages:
-        access_denied: La posedanto de la rimedo aŭ la rajtiga servilo rifuzis vian peton.
+        access_denied: La posedanto de la rimedo aŭ de la rajtiga servilo rifuzis vian peton.
         credential_flow_not_configured: La sendado de la identigiloj de la posedanto de la rimedo malsukcesis ĉar Doorkeeper.configure.resource_owner_from_credentials ne estis agordita.
-        invalid_client: La aŭtentigo de la kliento malsukcesis ĉar la kliento estas nekonata, aŭ mankis peto aŭtentigi, aŭ la aŭtentig-metodo ne estas subtenata.
+        invalid_client: Klienta aŭtentigo malsukcesa pro nekonata kliento, neniu klienta aŭtentigo inkluzivita, aŭ nesubtenata aŭtentiga metodo.
         invalid_grant: La rajtiga konsento ne estas valida, ne plu estas valida, estis forigita, ne kongruas kun la plusenda URI uzita en la aŭtentiga peto, aŭ estis sendita al alia kliento.
-        invalid_redirect_uri: La plusenda URI uzita en estas valida.
+        invalid_redirect_uri: La plusenda URI uzita ne estas valida.
         invalid_request: Mankis al la peto nepra parametro, enhavas nesubtenatan parametran valoron, aŭ la peto simple estas misformita.
-        invalid_resource_owner: La donitaj identigiloj pri la posedanto de la rimedo ne estas validaj, aŭ tiu ne povas esti trovita.
-        invalid_scope: La petita amplekso ne estas valida, estas nekonata, aŭ estas misformita.
+        invalid_resource_owner: La donitaj identigiloj pri la posedanto de la rimedo ne estas validaj, aŭ tiu lasta ne povas esti trovita
+        invalid_scope: La petita amplekso estas nevalida, nekonata, aŭ misformita.
         invalid_token:
-          expired: La atingoĵetono eskiĝis.
-          revoked: La atingoĵetono estis rifuzita.
-          unknown: La atingoĵetono ne estas valida.
+          expired: La alira ĵetono eksvalidiĝis
+          revoked: La alira ĵetono estis malvalidigita
+          unknown: La alira ĵetono estas nevalida
         resource_owner_authenticator_not_configured: La posedanto de la rimedo ne povis esti trovita ĉar Doorkeeper.configure.resource_owner_authenticator ne estas agordita.
-        server_error: La rajtiga servilo rimarkis neatenditan kondiĉon, kiu malpermesis al ĝi plenumi la peton.
-        temporarily_unavailable: La rajtiga servilo ne povas nun plenumi la peton pro dumtempa superŝarĝo aŭ prizorgado de la servilo.
-        unauthorized_client: La kliento ne rajtas fari tian peton uzante tiun metodon.
+        server_error: La rajtiga servilo renkontis neatenditan problemon, kiu malpermesis al ĝi plenumi la peton.
+        temporarily_unavailable: La rajtiga servilo ne povas nun plenumi la peton pro dumtempa troŝarĝo aŭ servila prizorgado.
+        unauthorized_client: Kliento ne rajtas fari ĉi tian peton per ĉi tiu metodo.
         unsupported_grant_type: La tipo de la rajtiga konsento ne estas subtenata de la rajtiga servilo.
-        unsupported_response_type: La rajtiga servilo ne subtenas tian respondon.
+        unsupported_response_type: La rajtiga servilo ne subtenas ĉi tian respondon.
     flash:
       applications:
         create:
@@ -100,7 +102,7 @@ eo:
         destroy:
           notice: Aplikaĵo forigita.
         update:
-          notice: Aplikaĵo aktualigita.
+          notice: Aplikaĵo ĝisdatigita.
       authorized_applications:
         destroy:
           notice: Aplikaĵo malrajtigita.
diff --git a/config/locales/doorkeeper.hu.yml b/config/locales/doorkeeper.hu.yml
index 54e732f0c..fa706e100 100644
--- a/config/locales/doorkeeper.hu.yml
+++ b/config/locales/doorkeeper.hu.yml
@@ -5,6 +5,8 @@ hu:
       doorkeeper/application:
         name: Név
         redirect_uri: Visszairányító URI
+        scopes: Hatáskör
+        website: Az alkalmazás weboldala
     errors:
       models:
         doorkeeper/application:
@@ -33,9 +35,13 @@ hu:
         redirect_uri: Egy sor URI-nként
         scopes: A nézeteket szóközzel válaszd el. Hagyd üresen az alapértelmezett nézetekhez.
       index:
+        application: Alkalmazás
         callback_url: Callback URL
+        delete: Eltávolítás
         name: Név
         new: Új alkalmazás
+        scopes: Hatáskör
+        show: Mutat
         title: Alkalmazásod
       new:
         title: Új alkalmazás
@@ -67,6 +73,7 @@ hu:
         application: Alkalmazás
         created_at: Készítve
         date_format: "%Y-%m-%d %H:%M:%S"
+        scopes: Hatáskör
         title: Engedélyezett alkalmazásaid
     errors:
       messages:
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 274710d8b..15e3400f1 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -370,6 +370,7 @@ en:
     logout: Logout
     migrate_account: Move to a different account
     migrate_account_html: If you wish to redirect this account to a different one, you can <a href="%{path}">configure it here</a>.
+    or: or
     or_log_in_with: Or log in with
     providers:
       cas: CAS
@@ -554,7 +555,9 @@ en:
           trillion: T
           unit: ''
   pagination:
+    newer: Newer
     next: Next
+    older: Older
     prev: Prev
     truncate: "&hellip;"
   preferences:
@@ -776,4 +779,5 @@ en:
   users:
     invalid_email: The e-mail address is invalid
     invalid_otp_token: Invalid two-factor code
+    seamless_external_login: You are logged in via an external service, so password and e-mail settings are not available.
     signed_in_as: 'Signed in as:'
diff --git a/config/locales/eo.yml b/config/locales/eo.yml
index 6f0a7a8f2..0a8756b7d 100644
--- a/config/locales/eo.yml
+++ b/config/locales/eo.yml
@@ -1,15 +1,32 @@
 ---
 eo:
   about:
-    about_mastodon_html: Mastodon estas <em>senpaga, malfermitkoda</em> socia reto. Ĝi estas <em>sencentra</em> alia eblo al komercaj servoj. Ĝi evitigas, ke unusola firmao regu vian tutan komunikadon. Elektu servilon, kiun vi fidas. Kiu ajn estas via elekto, vi povas interagi kun ĉiuj aliaj uzantoj. Iu ajn povas krei sian propran aperaĵon de Mastodon en sia servilo, kaj partopreni en la <em>socia reto</em> tute glate.
-    about_this: Pri tiu aperaĵo
+    about_hashtag_html: Ĉi tiuj estas la publikaj mesaĝoj markitaj per <strong>#%{hashtag}</strong>. Vi povas interagi kun ili se vi havas konton ie ajn en la fediverse.
+    about_mastodon_html: Mastodon estas socia reto bazita sur malfermitaj retaj protokoloj kaj sur libera malfermitkoda programo. Ĝi estas sencentra kiel retmesaĝoj.
+    about_this: Pri
+    closed_registrations: Registriĝoj estas nuntempe fermitaj en ĉi tiu nodo. Tamen, vi povas trovi alian nodon por fari konton kaj aliri al la sama reto de tie.
     contact: Kontakti
+    contact_missing: Ne elektita
+    contact_unavailable: Ne disponebla
     description_headline: Kio estas %{domain}?
-    domain_count_after: aliaj aperaĵoj
+    domain_count_after: aliaj nodoj
     domain_count_before: Konektita al
-    hosted_on: Mastodon gastigita sur %{domain}
-    learn_more: Lernu pli
-    other_instances: Aliaj aperaĵoj
+    extended_description_html: |
+      <h3>Bona loko por reguloj</h3>
+      <p>La detala priskribo ne estis elektita.</p>
+    features:
+      humane_approach_body: Lernante de eraroj de aliaj retoj, Mastodon celas fari etikajn fasonajn elektojn por batali kontraŭ misuzado de sociaj retoj.
+      humane_approach_title: Aliro pli humana
+      not_a_product_body: Mastodon ne estas komerca reto. Neniu reklamo, neniu kolektado de datumoj, neniu privilegio. Ne estas centra aŭtoritato.
+      not_a_product_title: Vi estas homo, ne produkto
+      real_conversation_body: Per 500 disponeblaj signoj, per elektebloj pri videbleco, kaj per avertoj pri enhavo, vi povas esprimi vin tiel, kiel vi volas.
+      real_conversation_title: Konstruita por veraj konversacioj
+      within_reach_body: Pluraj aplikaĵoj por iOS, Android, kaj aliaj platformoj danke al API-medio bonveniga por programistoj permesas resti en kontakto kun viaj amikoj ĉie.
+      within_reach_title: Ĉiam kontaktebla
+    generic_description: "%{domain} estas unu servilo en la reto"
+    hosted_on: Mastodon gastigita en %{domain}
+    learn_more: Lerni pli
+    other_instances: Listo de nodoj
     source_code: Fontkodo
     status_count_after: mesaĝoj
     status_count_before: Kiu publikigis
@@ -20,250 +37,352 @@ eo:
     follow: Sekvi
     followers: Sekvantoj
     following: Sekvatoj
-    media: Kumunikiloj
+    media: Aŭdovidaĵoj
+    moved_html: "%{name} moviĝis al %{new_profile_link}:"
     nothing_here: Estas nenio ĉi tie!
     people_followed_by: Sekvatoj de %{name}
     people_who_follow: Sekvantoj de %{name}
     posts: Mesaĝoj
-    posts_with_replies: Tootoj kun respondaj
+    posts_with_replies: Mesaĝoj kaj respondoj
     remote_follow: Fore sekvi
-    reserved_username: La usantnomo estas reservis
+    reserved_username: La uzantnomo estas rezervita
     roles:
       admin: Administranto
-    unfollow: Malsekvi
+      moderator: Kontrolanto
+    unfollow: Ne plu sekvi
   admin:
+    account_moderation_notes:
+      account: Kontrolanto
+      create: Krei
+      created_at: Dato
+      created_msg: Kontrola noto sukcese kreita!
+      delete: Forigi
+      destroyed_msg: Kontrola noto sukcese detruita!
     accounts:
-      are_you_sure: Ĉu vi certe?
-      confirm: Confirmi
-      confirmed: Confirmis
+      are_you_sure: Ĉu vi certas?
+      by_domain: Domajno
+      confirm: Konfirmi
+      confirmed: Konfirmita
+      demote: Degradi
+      disable: Malebligi
       disable_two_factor_authentication: Malebligi 2FA
-      display_name: Montri nomo
+      disabled: Malebligita
+      display_name: Montrata nomo
       domain: Domajno
       edit: Redakti
       email: Retpoŝto
+      enable: Ebligi
+      enabled: Ebligita
+      feed_url: URL de la fluo
       followers: Sekvantoj
-      followers_url: Sekvantoj URL
+      followers_url: URL de la sekvantoj
       follows: Sekvatoj
+      inbox_url: Enira URL
       ip: IP
       location:
         all: Ĉio
         local: Loka
         remote: Fora
         title: Loko
-      media_attachments: Komunkiloj kunsendaĵo
+      login_status: Ensaluta stato
+      media_attachments: Ligitaj aŭdovidaĵoj
+      memorialize: Ŝanĝi al memoro
       moderation:
         all: Ĉio
-        silenced: Silentis
-        suspended: Suspendis
-        title: Moderulo
-      most_recent_activity: Ple freŝa aktiveco
-      most_recent_ip: Ple freŝa IP
-      not_subscribed: Ne abonis
+        silenced: Silentigitaj
+        suspended: Haltigitaj
+        title: Kontrolado
+      moderation_notes: Kontrolaj notoj
+      most_recent_activity: Lasta ago
+      most_recent_ip: Lasta IP
+      not_subscribed: Ne abonita
       order:
-        alphabetic: Alfabetiko
-        most_recent: Ple freŝa
-        title: Ordono
-      perform_full_suspension: Fari kompleta suspendi
-      profile_url: Profilo URL
+        alphabetic: Laŭalfabete
+        most_recent: Plej lastatempa
+        title: Ordo
+      outbox_url: Elira URL
+      perform_full_suspension: Tute haltigi
+      profile_url: Profila URL
+      promote: Plirangigi
       protocol: Protokolo
       public: Publika
-      push_subscription_expires: PuSH subscription expires
-      redownload: Refreŝigi avataro
+      push_subscription_expires: Eksvalidiĝo de la abono al PuSH
+      redownload: Aktualigi profilbildon
       reset: Restarigi
-      reset_password: Restarigi pasvorto
+      reset_password: Restarigi pasvorton
       resubscribe: Reaboni
-      salmon_url: Salmon URL
+      role: Permesoj
+      roles:
+        admin: Administranto
+        moderator: Kontrolanto
+        staff: Teamo
+        user: Uzanto
+      salmon_url: Salmon-URL
       search: Serĉi
-      shared_inbox_url: Shared Inbox URL
+      shared_inbox_url: URL de kunhavigita leterkesto
       show:
-        created_reports: Raportoj kreita de ĉi tiu konto
-        report: raporto
-        targeted_reports: Raportoj kreita al ĉi tiu konton
-      silence: Silenti
-      statuses: Statusoj
+        created_reports: Signaloj kreitaj de ĉi tiu konto
+        report: signalo
+        targeted_reports: Signaloj kreitaj de ĉi tiu konto
+      silence: Kaŝi
+      statuses: Mesaĝoj
       subscribe: Aboni
       title: Kontoj
-      undo_silenced: Malfari silenti
-      undo_suspension: Malfari suspendi
+      undo_silenced: Malfari kaŝon
+      undo_suspension: Malfari haltigon
       unsubscribe: Malaboni
       username: Uzantnomo
-      web: Ret
+      web: Reto
+    action_logs:
+      actions:
+        confirm_user: "%{name} konfirmis retadreson de uzanto %{target}"
+        create_custom_emoji: "%{name} alŝutis novan emoĝion %{target}"
+        create_domain_block: "%{name} blokis domajnon %{target}"
+        create_email_domain_block: "%{name} metis en nigran liston domajnon %{target}"
+        demote_user: "%{name} degradis uzanton %{target}"
+        destroy_domain_block: "%{name} malblokis domajnon %{target}"
+        destroy_email_domain_block: "%{name} metis en blankan liston domajnon %{target}"
+        destroy_status: "%{name} forigis mesaĝojn de %{target}"
+        disable_2fa_user: "%{name} malebligis dufaktoran aŭtentigon por uzanto %{target}"
+        disable_custom_emoji: "%{name} malebligis emoĝion %{target}"
+        disable_user: "%{name} malebligis ensaluton por uzanto %{target}"
+        enable_custom_emoji: "%{name} ebligis emoĝion %{target}"
+        enable_user: "%{name} ebligis ensaluton por uzanto %{target}"
+        memorialize_account: "%{name} ŝanĝis la konton de %{target} al memora paĝo"
+        promote_user: "%{name} plirangigis uzanton %{target}"
+        reset_password_user: "%{name} restarigis pasvorton de uzanto %{target}"
+        resolve_report: "%{name} flankmetis signalon %{target}"
+        silence_account: "%{name} kaŝis la konton de %{target}"
+        suspend_account: "%{name} haltigis la konton de %{target}"
+        unsilence_account: "%{name} malkaŝis la konton de %{target}"
+        unsuspend_account: "%{name} malhaltigis la konton de %{target}"
+        update_custom_emoji: "%{name} ĝisdatigis emoĝion %{target}"
+        update_status: "%{name} ĝisdatigis mesaĝon de %{target}"
+      title: Kontrola protokolo
     custom_emojis:
-      copied_msg: Sukcese kreis loka kopio de la emojio
-      copy: Kopi
-      copy_failed_msg: Could not make a local copy of that emoji
-      created_msg: Emojio estas kreita sukcesa!
+      by_domain: Domajno
+      copied_msg: Loka kopio de la emoĝio sukcese kreita
+      copy: Kopii
+      copy_failed_msg: Fari lokan kopion de ĉi tiu emoĝio ne eblis
+      created_msg: Emoĝio sukcese kreita!
       delete: Forigi
-      destroyed_msg: Emojio estas forigis sukcesa!
+      destroyed_msg: Emoĝio sukcese forigita!
       disable: Malebligi
-      disabled_msg: Emojio estas malebligis sukcesa
-      emoji: Emojio
+      disabled_msg: Emoĝio sukcese malebligita
+      emoji: Emoĝio
       enable: Ebligi
-      enabled_msg: Emojio estas ebligis sukcesa
+      enabled_msg: Tiu emoĝio estis sukcese ebligita
       image_hint: PNG ĝis 50KB
+      listed: Listigita
       new:
-        title: Aldoni nova kutimo emojio
-      shortcode: Malongakodo
-      shortcode_hint: At least 2 characters, only alphanumeric characters and underscores
-      title: Kutimoj emojioj
+        title: Aldoni novan propran emoĝion
+      overwrite: Anstataŭigi
+      shortcode: Mallonga kodo
+      shortcode_hint: Almenaŭ 2 signoj, nur literoj, ciferoj kaj substrekoj
+      title: Propraj emoĝioj
+      unlisted: Nelistigita
+      update_failed_msg: Ĝisdatigi tiun emoĝion ne eblis
+      updated_msg: Emoĝio sukcese ĝisdatigita!
       upload: Alŝuti
     domain_blocks:
-      add_new: Aldoni novo
-      created_msg: Domajno bloko nun estas procesita
-      destroyed_msg: Domajno bloko estas malfaris
+      add_new: Aldoni novan
+      created_msg: Domajna blokado en traktado
+      destroyed_msg: Domajna blokado malfarita
       domain: Domajno
       new:
-        create: Krei bloko
+        create: Krei blokadon
+        hint: La domajna blokado ne evitigos kreadon de novaj kontoj en la datumbazo, sed aplikos specifajn kontrolajn agojn sur ĉi tiujn kontojn aŭtomate kaj retroaktive.
         severity:
+          desc_html: "<strong>Kaŝi</strong> igos la mesaĝojn de la konto nevideblaj al tiuj, kiuj ne sekvas tiun. <strong>Haltigi</strong> forigos ĉiujn enhavojn, aŭdovidaĵojn kaj datumojn de la konto. Uzu <strong>Nenio</strong> se vi simple volas malakcepti aŭdovidaĵojn."
           noop: Nenio
-          silence: Silenti
-          suspend: Suspendi
-        title: Nova domajno bloko
-      reject_media: Reject media files
+          silence: Kaŝi
+          suspend: Haltigi
+        title: Nova domajna blokado
+      reject_media: Malakcepti aŭdovidajn dosierojn
+      reject_media_hint: Forigas aŭdovidaĵojn loke konservitajn kaj rifuzas alŝuti ajnan estonte. Senzorge pri haltigoj
       severities:
         noop: Nenio
-        silence: Silenti
-        suspend: Suspendi
+        silence: Kaŝi
+        suspend: Haltigi
       severity: Severeco
       show:
         affected_accounts:
-          one: Unu konto en la datumbazo esta afekta
-          other: "%{count} kontoj en la datumbazo esta afekta"
+          one: Unu konto en la datumbazo esta influita
+          other: "%{count} kontoj en la datumbazo estas influitaj"
         retroactive:
-          silence: Malfari silenti ĉio konton de ĉi tiu domajno
-          suspend: Malfari suspendi ĉio konton de ĉi tiu domajno
-        title: Malfari domajno bloko por %{domain}
+          silence: Malkaŝi ĉiujn kontojn, kiuj ekzistas en ĉi tiu domajno
+          suspend: Malhaltigi ĉiujn kontojn, kiuj ekzistas en ĉi tiu domajno
+        title: Malfari domajnan blokadon por %{domain}
         undo: Malfari
-      title: Domajnoj blokoj
+      title: Domajnaj blokadoj
       undo: Malfari
     email_domain_blocks:
-      add_new: Aldoni novo
-      created_msg: Retpoŝto domajno bloko estas kreita sukcesa
+      add_new: Aldoni novan
+      created_msg: Retadreso sukcese aldonita al la nigra listo
       delete: Forigi
-      destroyed_msg: Retpoŝto domajno bloko estas foriga sukcesa
+      destroyed_msg: Retadreso sukcese forigita de la nigra listo
       domain: Domajno
       new:
-        create: Aldoni bloko
-        title: Nova retpoŝto domajno bloko
-      title: Retpoŝto domajno bloko
+        create: Aldoni domajnon
+        title: Nova blokado de retadresa domajno
+      title: Nigra listo de retadresaj domajnoj
     instances:
       account_count: Konataj kontoj
       domain_name: Domajno
       reset: Restarigi
       search: Serĉi
-      title: Konataj petskriboj
+      title: Konataj nodoj
+    invites:
+      filter:
+        all: Ĉio
+        available: Disponebla
+        expired: Eksvalida
+        title: Filtri
+      title: Invitoj
     reports:
-      action_taken_by: Action taken by
-      are_you_sure: Ĉu vi certe?
+      action_taken_by: Ago farita de
+      are_you_sure: Ĉu vi certas?
       comment:
-        label: komento
+        label: Komento
         none: Nenio
       delete: Forigi
       id: ID
       mark_as_resolved: Marki kiel solvita
       nsfw:
-        'false': Ne kaŝi kumunikiloj kunsendaĵoj
-        'true': Kaŝi kumunikiloj kunsendaĵoj
-      report: 'Raporto #%{id}'
+        'false': Malkaŝi aŭdovidajn kunsendaĵojn
+        'true': Kaŝi aŭdovidajn kunsendaĵojn
+      report: 'Signalo #%{id}'
       report_contents: Enhavo
-      reported_account: Raportis konto
-      reported_by: Raporta de
+      reported_account: Signalita konto
+      reported_by: Signalita de
       resolved: Solvita
-      silence_account: Silenti konton
-      status: Statusoj
-      suspend_account: Suspendi konton
+      silence_account: Kaŝi konton
+      status: Mesaĝoj
+      suspend_account: Haltigi konton
       target: Celo
-      title: Raportoj
-      unresolved: Ne solvita
+      title: Signaloj
+      unresolved: Nesolvita
       view: Vidi
     settings:
+      activity_api_enabled:
+        desc_html: Sumo de lokaj mesaĝoj, aktivaj uzantoj, kaj novaj registriĝoj laŭsemajne
+        title: Publikigi kunmetitajn statistikojn pri la uzanta agado
       bootstrap_timeline_accounts:
-        desc_html: Disigi multaj uzantnomoj per komo. Nur lokaj kaj malsloŝi kontoj estus operaci. Defaŭlo Defaŭlo kiam malplena estas ĉio lokaj administristoj.
-        title: Defaŭltoj sakvatoj al novoj uzantoj
+        desc_html: Disigi plurajn uzantnomojn per komo. Funkcios nur por lokaj neŝlositaj kontoj. Kiam malplena, la dekomenca valoro estas ĉiuj lokaj administrantoj.
+        title: Dekomencaj sekvadoj por novaj uzantoj
       contact_information:
-        email: Afero retpoŝto
-        username: kontakto uzantnomo
+        email: Publika retadreso
+        username: Kontakta uzantnomo
+      peers_api_enabled:
+        desc_html: Nomoj de domajnoj, kiujn ĉi tiu nodo renkontis en la fediverse
+        title: Publikigi liston de malkovritaj nodoj
       registrations:
         closed_message:
-          desc_html: Vidigis sur antaŭpaĝo kian registrado estas fermis. Vi povas uzi HTML
-          title: Fermis registrado mesaĝo
+          desc_html: Montrita sur la hejma paĝo kiam registriĝoj estas fermitaj. Vi povas uzi HTML-etikedojn
+          title: Mesaĝo pri fermitaj registriĝoj
         deletion:
-          desc_html: Permesi ĉiuj forigi ilian konton
-          title: Malfermi konto forigo
+          desc_html: Permesi al iu ajn forigi propran konton
+          title: Permesi forigi konton
+        min_invite_role:
+          disabled: Neniu
+          title: Permesi invitojn de
         open:
-          desc_html: Permesi ĉiuj krei konto
-          title: Malfermi registrado
+          desc_html: Permesi iun ajn krei konton
+          title: Malfermi registriĝojn
+      show_known_fediverse_at_about_page:
+        desc_html: Kiam ŝaltita, ĝi montros mesaĝojn de la tuta konata fediverse antaŭvide. Aliokaze, ĝi montros nur lokajn mesaĝojn.
+        title: Montri konatan fediverse en tempolinia antaŭvido
+      show_staff_badge:
+        desc_html: Montri teaman insignon en paĝo de uzanto
+        title: Montri teaman insignon
       site_description:
-        title: Priskribo de petskribo
+        desc_html: Enkonduka alineo en la ĉefpaĝo kaj en informaj etikedoj. Vi povas uzi HTML-etikedojn, kiel <code>&lt;a&gt;</code> kaj <code>&lt;em&gt;</code>.
+        title: Priskribo de la nodo
       site_description_extended:
-        title: Kutimo etendis informaĵo
+        desc_html: Bona loko por viaj sintenaj reguloj, aliaj reguloj, gvidlinioj kaj aliaj aferoj, kiuj apartigas vian nodon. Vi povas uzi HTML-etikedojn
+        title: Propraj detalaj informoj
       site_terms:
-        desc_html: Vi povas skribi via politika pri privateco reguloj de servo aŭ aliaj senpagaj. Vi povas uzi HTML
-        title: Kutimoj reguloj de servo
-      site_title: Petskribo nomo
+        desc_html: Vi povas skribi vian propran privatecan politikon, viajn uzkondiĉojn aŭ aliajn leĝaĵojn. Vi povas uzi HTML-etikedojn
+        title: Propraj uzkondiĉoj
+      site_title: Nomo de la nodo
       thumbnail:
-        desc_html: Uzis por antaŭvido vojo OpenGraph kaj API. 1200x630px rekomendis
-        title: Bildeto de petskribo
+        desc_html: Uzata por antaŭvidoj per OpenGraph kaj per API. 1200x630px rekomendita
+        title: Bildeto de la nodo
       timeline_preview:
-        desc_html: Vidigi publika tempolinio sur surteriĝo paĝo
-        title: Antaŭvido de tempolinio
-      title: Retparaĝoj preferoj
+        desc_html: Montri publikan tempolinion en komenca paĝo
+        title: Tempolinia antaŭvido
+      title: Retejaj agordoj
     statuses:
-      back_to_account: Irienigi al konton paĝon
+      back_to_account: Reveni al konta paĝo
       batch:
         delete: Forigi
         nsfw_off: Malŝalti NSFW
         nsfw_on: Ŝalti NSFW
-      execute: Execute
-      failed_to_execute: Failed to execute
+      execute: Ekigi
+      failed_to_execute: Ekigo malsukcesa
       media:
-        hide: Kaŝi kumunikiloj
-        show: Vidigi kumunikiloj
-        title: Kumunikiloj
-      no_media: Neniu Kumunikilo
-      title: Kontoj statusoj
-      with_media: Kun kumunikiloj
+        hide: Kaŝi aŭdovidaĵojn
+        show: Montri aŭdovidaĵojn
+        title: Aŭdovidaĵoj
+      no_media: Neniu aŭdovidaĵo
+      title: Mesaĝoj de la konto
+      with_media: Kun aŭdovidaĵoj
     subscriptions:
-      callback_url: Callback URL
-      confirmed: Confirmis
-      expires_in: Finiĝus en
-      last_delivery: plej freŝa transdono
+      callback_url: Revena URL
+      confirmed: Konfirmita
+      expires_in: Eksvalidiĝas en
+      last_delivery: Lasta livero
       title: WebSub
-      topic: Topic
-    title: Administri
+      topic: Temo
+    title: Administrado
   admin_mailer:
     new_report:
-      body: "%{reporter} raportis %{target}"
-      subject: Nova raporto por %{instance} (#%{id})
+      body: "%{reporter} signalis %{target}"
+      subject: Nova signalo por %{instance} (#%{id})
   application_mailer:
-    settings: 'Ŝanĝi la retpoŝt-mesaĝajn preferojn: %{link}'
+    notification_preferences: Ŝanĝi retmesaĝajn preferojn
+    salutation: "%{name},"
+    settings: 'Ŝanĝi retmesaĝajn preferojn: %{link}'
     view: 'Vidi:'
+    view_profile: Vidi profilon
+    view_status: Vidi mesaĝon
   applications:
-    created: Aplikaĵo sukcesa kreis
-    destroyed: Aplikaĵo sukcesa forigis
+    created: Aplikaĵo sukcese kreita
+    destroyed: Aplikaĵo sukcese forigita
     invalid_url: La URL donita ne estas valida
-    regenerate_token: Regeneri aliron signon
-    token_regenerated: Aliro signo regeneris sukcese
-    your_token: Via aliro signo
+    regenerate_token: Rekrei aliran ĵetonon
+    token_regenerated: Alira ĵetono sukcese rekreita
+    warning: Estu tre atenta kun ĉi tiu datumo. Neniam diskonigu ĝin al iu ajn!
+    your_token: Via alira ĵetono
   auth:
-    change_password: Ŝanĝi pasvorton
+    agreement_html: Per registriĝo, vi konsentas kun <a href="%{rules_path}">la reguloj de la nodo</a> kaj <a href="%{terms_path}">niaj uzkondiĉoj</a>.
+    change_password: Sekureco
+    confirm_email: Konfirmi retadreson
     delete_account: Forigi konton
+    delete_account_html: Se vi deziras forigi vian konton, vi povas <a href="%{path}">fari tion ĉi tie</a>. Vi bezonos konfirmi vian peton.
     didnt_get_confirmation: Ĉu vi ne ricevis la instrukciojn por konfirmi?
     forgot_password: Pasvorto forgesita?
+    invalid_reset_password_token: Ĵetono por restarigi pasvorton nevalida aŭ eksvalida. Bonvolu peti novan.
     login: Ensaluti
     logout: Elsaluti
-    register: Membriĝi
+    migrate_account: Movi al alia konto
+    migrate_account_html: Se vi deziras alidirekti ĉi tiun konton al alia, vi povas <a href="%{path}">agordi ĝin ĉi tie</a>.
+    or_log_in_with: Aŭ ensaluti per
+    providers:
+      cas: CAS
+      saml: SAML
+    register: Registriĝi
     resend_confirmation: Resendi la instrukciojn por konfirmi
-    reset_password: Ŝanĝi la pasvorton
+    reset_password: Ŝanĝi pasvorton
     set_new_password: Elekti novan pasvorton
   authorize_follow:
-    error: Bedaŭrinde, okazis eraro provante konsulti la foran konton
+    error: Bedaŭrinde, estis eraro en la serĉado de la fora konto
     follow: Sekvi
-    follow_request: 'Vi sendis sekvatin peton al:'
-    following: 'Sukceso! Vi nun sekvi:'
+    follow_request: 'Vi sendis peton de sekvado al:'
+    following: 'Sukceson! Vi nun sekvas:'
     post_follow:
-      close: Aŭ, Vi justa povas fermi ĉi tion.
-      return: Ilienigi al la uzantoan profilon
+      close: Aŭ, vi povas simple fermi ĉi tiun fenestron.
+      return: Reveni al la profilo de uzanto
       web: Iri al reto
     title: Sekvi %{acct}
   datetime:
@@ -272,164 +391,368 @@ eo:
       about_x_months: "%{count}mo"
       about_x_years: "%{count}j"
       almost_x_years: "%{count}j"
-      half_a_minute: Ĵus
+      half_a_minute: Ĵuse
       less_than_x_minutes: "%{count}m"
-      less_than_x_seconds: Ĵus
+      less_than_x_seconds: Ĵuse
       over_x_years: "%{count}j"
       x_days: "%{count}t"
       x_minutes: "%{count}m"
       x_months: "%{count}mo"
       x_seconds: "%{count}s"
+  deletes:
+    bad_password_msg: Malĝusta pasvorto
+    confirm_password: Enmetu vian nunan pasvorton por konfirmi vian identecon
+    description_html: Tio <strong>porĉiame kaj neŝanĝeble</strong> forigos la enhavon de via konto kaj malaktivigos ĝin. Via uzantnomo restos rezervita por eviti postajn trompojn pri identeco.
+    proceed: Forigi konton
+    success_msg: Via konto estis sukcese forigita
+    warning_html: La forigo de la enhavo estas certa nur por ĉi tiu aparta nodo. Enhavo, kiu estis disvastigita verŝajne lasos spurojn. Eksterretaj serviloj kaj serviloj, kiuj ne abonas viajn ĝisdatigojn ne ĝisdatigos siajn datumbazojn.
+    warning_title: Disponebleco de disvastigita enhavo
+  errors:
+    '403': Vi ne havas la rajton por vidi ĉi tiun paĝon.
+    '404': La paĝo, kiun vi serĉas, ne ekzistas.
+    '410': La paĝo, kiun vi serĉas, ne plu ekzistas.
+    '422':
+      content: Sekureca konfirmo malsukcesa. Ĉu vi blokas kuketojn?
+      title: Sekureca konfirmo malsukcesa
+    '429': Datumtrafiko limigita
+    '500':
+      content: Ni bedaŭras, io malsukcesis niaflanke.
+      title: Ĉi tiu paĝo ne estas ĝusta
+    noscript_html: |-
+      Por uzi la retan aplikaĵon de Mastodon, bonvolu ebligi JavaScript. Alimaniere, provu unu el la
+      <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">operaciumaj aplikaĵoj</a> por Mastodon por via platformo.
   exports:
-    blocks: Via blokoj
+    blocks: Vi blokas
     csv: CSV
-    follows: Via sekvatoj
-    mutes: Via silentoj
-    storage: Mediaĵa konservado
+    follows: Vi sekvas
+    mutes: Vi silentigas
+    storage: Aŭdovidaĵa konservado
   followers:
     domain: Domajno
-    followers_count: Nombro de sekvatoj
-    lock_link: Ŝlosi via konton
-    purge: Forigi de sakvantoj
+    explanation_html: Se vi volas esti certa pri la privateco de viaj mesaĝoj, vi bezonas esti atenta pri tiuj, kiuj sekvas vin. <strong>Viaj privataj mesaĝoj estas liveritaj al ĉiuj nodoj, kie vi havas sekvantojn</strong>. Eble vi ŝatus kontroli ilin, kaj forigi sekvantojn, se vi ne fidas, ke via privateco estos respektita de la teamo aŭ de la programo de ĉi tiuj nodoj.
+    followers_count: Nombro de sekvantoj
+    lock_link: Ŝlosi vian konton
+    purge: Forigi el la sekvantoj
+    success:
+      one: Forigado de sekvantoj el iu domajno...
+      other: Forigado de sekvantoj el %{count} domajnoj...
+    true_privacy_html: Bonvolu atenti, ke <strong>vera privateco povas esti atingita nur per ĉifrado de komenco al fino</strong>.
+    unlocked_warning_html: Iu ajn povas eksekvi vin por tuj vidi viajn privatajn mesaĝojn. %{lock_link} por povi akcepti kaj rifuzi petojn de sekvado.
+    unlocked_warning_title: Via konto ne estas ŝlosita
   generic:
-    changes_saved_msg: Ŝanĝoj senprobleme konservitaj!
+    changes_saved_msg: Ŝanĝoj sukcese konservitaj!
     powered_by: povigita de %{link}
-    save_changes: Konservi la ŝanĝojn
+    save_changes: Konservi ŝanĝojn
     validation_errors:
       one: Io mise okazis! Bonvolu konsulti la suban erar-raporton
       other: Io mise okazis! Bonvolu konsulti la subajn %{count} erar-raportojn
   imports:
-    preface: Vi povas alporti kelkajn datumojn, kiel listojn de ĉiuj homoj kiujn vi sekvas aŭ blokas, al via konto de ĉi tiu aperaĵo, per dosiero elportita de alia aperaĵo.
-    success: Viaj datumoj estis senprobleme alportitaj kaj estos traktitaj kiel planite.
+    preface: Vi povas importi datumojn, kiujn vi eksportis el alia nodo, kiel liston de homoj, kiujn vi sekvas aŭ blokas.
+    success: Viaj datumoj estis sukcese alŝutitaj kaj estos traktitaj kiel planite
     types:
       blocking: Listo de blokitoj
       following: Listo de sekvatoj
-      muting: Listo de silentoj
-    upload: Alporti
-  landing_strip_html: "<strong>%{name}</strong> estas uzanto en %{link_to_root_path}. Vi povas sekvi tiun aŭ interagi kun tiu, se vi havas konton ie ajn en la Fediverse."
-  landing_strip_signup_html: Se vi ne havas, vi povas <a href="%{sign_up_path}">membriĝi ĉi tie.</a>.
+      muting: Listo de silentigitoj
+    upload: Alŝuti
+  in_memoriam_html: Memore
+  invites:
+    delete: Malaktivigi
+    expired: Eksvalida
+    expires_in:
+      '1800': 30 minutoj
+      '21600': 6 horoj
+      '3600': 1 horo
+      '43200': 12 horoj
+      '86400': 1 tago
+    expires_in_prompt: Neniam
+    generate: Krei
+    max_uses:
+      one: 1 uzo
+      other: "%{count} uzoj"
+    max_uses_prompt: Neniu limo
+    prompt: Krei kaj diskonigi ligilojn al aliaj por doni aliron al ĉi tiu nodo
+    table:
+      expires_at: Eksvalidiĝas
+      uses: Uzoj
+    title: Inviti homojn
+  landing_strip_html: "<strong>%{name}</strong> estas uzanto en %{link_to_root_path}. Vi povas sekvi tiun aŭ interagi kun tiu, se vi havas konton ie ajn en la fediverse."
+  landing_strip_signup_html: Se vi ne havas, vi povas <a href="%{sign_up_path}">registriĝi ĉi tie</a>.
+  lists:
+    errors:
+      limit: Vi atingis la maksimuman kvanton de listoj
   media_attachments:
     validations:
-      images_and_video: Vi ne povas alligi video al statuson kiu jam havas bilojn
-      too_many: Vi ne povas alligi pli ol 4 dosieroj
+      images_and_video: Aldoni videon al mesaĝo, kiu jam havas bildojn ne eblas
+      too_many: Aldoni pli ol 4 dosierojn ne eblas
+  migrations:
+    acct: uzantnomo@domajno de la nova konto
+    currently_redirecting: 'Via profilo alidirektos al:'
+    proceed: Konservi
+    updated_msg: Via agordo pri konta migrado estis sukcese ĝisdatigita!
+  moderation:
+    title: Kontrolado
   notification_mailer:
     digest:
-      body: 'Jen eta resumo de tio, kio okazis en %{instance}, ekde kiam vi laste vizitis en %{since}:'
+      action: Vidi ĉiujn sciigojn
+      body: Jen eta resumo de la mesaĝoj, kiujn vi mistrafis ekde via lasta vizito en %{since}
       mention: "%{name} menciis vin en:"
       new_followers_summary:
-        one: Vi ekhavis novan sekvanton! Jej!
-        other: Vi ekhavis %{count} novajn sekvantojn! Mirinde!
+        one: Ankaŭ, vi ekhavis novan sekvanton en via foresto! Jej!
+        other: Ankaŭ, vi ekhavis %{count} novajn sekvantojn en via foresto! Mirinde!
       subject:
         one: "1 nova sciigo ekde via lasta vizito \U0001F418"
         other: "%{count} novaj sciigoj ekde via lasta vizito \U0001F418"
+      title: En via foresto…
     favourite:
-      body: "%{name} favoris vian mesaĝon:"
-      subject: "%{name} favoris vian mesaĝon"
+      body: "%{name} stelumis vian mesaĝon:"
+      subject: "%{name} stelumis vian mesaĝon"
+      title: Nova stelumo
     follow:
-      body: "%{name} eksekvis vin:"
+      body: "%{name} eksekvis vin!"
       subject: "%{name} eksekvis vin"
+      title: Nova sekvanto
     follow_request:
-      body: "%{name} petis sekvi vin:"
+      action: Administri petojn de sekvado
+      body: "%{name} petis sekvi vin"
       subject: "%{name} petis sekvi vin"
+      title: Nova peto de sekvado
     mention:
+      action: Respondi
       body: "%{name} menciis vin en:"
       subject: "%{name} menciis vin"
+      title: Nova mencio
     reblog:
       body: "%{name} diskonigis vian mesaĝon:"
       subject: "%{name} diskonigis vian mesaĝon"
+      title: Nova diskonigo
   number:
     human:
       decimal_units:
         format: "%n%u"
         units:
-          billion: B
-          million: M
-          quadrillion: Q
-          thousand: K
-          trillion: T
-          unit: ''
+          billion: Md
+          million: Mn
+          quadrillion: Dd
+          thousand: m
+          trillion: Dn
+          unit: " "
   pagination:
     next: Sekva
-    prev: Malsekva
+    prev: Antaŭa
+    truncate: "&hellip;"
   preferences:
     languages: Lingvoj
-    other: Aliaj
-    publishing: Publikigi
-    web: Ret
+    other: Aliaj aferoj
+    publishing: Publikado
+    web: Reto
   push_notifications:
     favourite:
-      title: "%{name} preferitis via statuso"
+      title: "%{name} stelumis vian mesaĝon"
     follow:
-      title: "%{name} estas sekvantas vin"
+      title: "%{name} eksekvis vin"
     group:
       title: "%{count} sciigoj"
     mention:
-      action_boost: Akceli
-      action_expand: Pli
-      action_favourite: Preferi
-      title: "%{name} menciitis vin"
+      action_boost: Diskonigi
+      action_expand: Montri pli
+      action_favourite: Stelumi
+      title: "%{name} menciis vin"
     reblog:
-      title: "%{name} akcelis via statuson"
+      title: "%{name} diskonigis vian mesaĝon"
   remote_follow:
-    acct: Enmetu vian uzantnomo@aperaĵo de kie vi volas sekvi tiun uzanton
-    missing_resource: La URL de plusendado ne povis esti trovita
-    proceed: Daŭrigi por plusendi
+    acct: Enmetu vian uzantnomo@domajno de kie vi volas sekvi
+    missing_resource: La URL de plusendado ne estis trovita
+    proceed: Daŭrigi por eksekvi
     prompt: 'Vi eksekvos:'
   sessions:
-    activity: Lasta Aktiveco
+    activity: Lasta ago
     browser: Retumilo
-    current_session: Aktuala sesio
-    description: "%{browser} sur %{platform}"
-    explanation: Ĉi tiuj estas la retumiloj nun ensalutinda en via Mastodon konton.
+    browsers:
+      alipay: Alipay
+      blackberry: Blackberry
+      chrome: Chrome
+      edge: Microsoft Edge
+      electron: Electron
+      firefox: Firefox
+      generic: Nekonata retumilo
+      ie: Internet Explorer
+      micro_messenger: MicroMessenger
+      nokia: Nokia S40 Ovi Browser
+      opera: Opera
+      otter: Otter
+      phantom_js: PhantomJS
+      qq: QQ Browser
+      safari: Safari
+      uc_browser: UCBrowser
+      weibo: Weibo
+    current_session: Nuna seanco
+    description: "%{browser} en %{platform}"
+    explanation: Ĉi tiuj estas la retumiloj nun ensalutintaj al via Mastodon-konto.
     ip: IP
-    revoke: Revoki
-    revoke_success: La sesio estas revokis
-    title: Sesioj
+    platforms:
+      adobe_air: Adobe Air
+      android: Android
+      blackberry: Blackberry
+      chrome_os: ChromeOS
+      firefox_os: Firefox OS
+      ios: iOS
+      linux: Linux
+      mac: Mac
+      other: nekonata platformo
+      windows: Windows
+      windows_mobile: Windows Mobile
+      windows_phone: Windows Phone
+    revoke: Malvalidigi
+    revoke_success: Seanco sukcese malvalidigita
+    title: Seancoj
   settings:
     authorized_apps: Rajtigitaj aplikaĵoj
     back: Reveni al Mastodon
-    delete: Konto forigo
-    development: Evoluno
-    edit_profile: Redakti la profilon
-    export: Elporti datumojn
-    followers: Rajtigis sekvantoj
-    import: Alporti
-    notifications: Avizoj
+    delete: Konta forigo
+    development: Evoluigado
+    edit_profile: Redakti profilon
+    export: Eksporti datumojn
+    followers: Rajtigitaj sekvantoj
+    import: Importi
+    migrate: Konta migrado
+    notifications: Sciigoj
     preferences: Preferoj
     settings: Agordoj
     two_factor_authentication: Dufaktora aŭtentigo
-    your_apps: Via aplikaĵoj
+    your_apps: Viaj aplikaĵoj
   statuses:
     open_in_web: Malfermi retumile
-    over_character_limit: limo de %{max} signoj trapasita
+    over_character_limit: limo de %{max} signoj transpasita
     pin_errors:
-      limit: Tro multaj tootoj fiksis
-      ownership: Aliaja tooto ne povas esti fiksis
-      private: Nepublika tooto ne povas esti fixis
-      reblog: Diskonigo ne povas esti fiksis
+      limit: Vi jam atingis la maksimuman nombron de alpinglitaj mesaĝoj
+      ownership: Mesaĝo de iu alia ne povas esti alpinglita
+      private: Mesaĝo nepublika ne povas esti alpinglita
+      reblog: Diskonigo ne povas esti alpinglita
     show_more: Montri pli
+    title: '%{name}: "%{quote}"'
     visibilities:
       private: Montri nur al sekvantoj
       private_long: Montri nur al sekvantoj
       public: Publika
       public_long: Ĉiuj povas vidi
-      unlisted: Publika, sed ne aperos en publikaj tempolinioj
-      unlisted_long: Publika, sed ne aperos en publikaj tempolinioj
+      unlisted: Nelistigita
+      unlisted_long: Ĉiuj povas vidi, sed nelistigita en publikaj tempolinioj
   stream_entries:
     click_to_show: Alklaki por montri
-    pinned: Fiksis
-    reblogged: diskonigis
+    pinned: Alpinglita
+    reblogged: diskonigita
     sensitive_content: Tikla enhavo
   terms:
-    title: "%{instance} Reguloj de servo kaj Politikaj pri privatecoj"
+    body_html: |
+      <h2>Privateca politiko</h2>
+
+      <h3 id="collect">Kiujn informojn ni kolektas?</h3>
+
+      <p>Ni kolektas informojn de vi, kiam vi registriĝas en nia retejo aŭ partoprenas en la forumo per legado, skribado, kaj traktado de la enhavo diskonigita ĉi tie.</p>
+
+      <p>En registriĝo, ni povas peti al vi vian nomon kaj retadreson. Vi tamen povas viziti nian retejon sen registriĝo. Via retadreso estos validigita per retmesaĝo, kiu enhavos unikan ligilon. Se tiu ligilo estas vizitita, ni scios ke vi regas la retadreson.</p>
+
+      <p>Post registriĝo, ni registras la IP-adreson de tiu, kiu kreas mesaĝon. Ni ankaŭ povas konservi servilan historion, en kiu troviĝas la IP-adreso de ĉiu peto al nia servilo.</p>
+
+      <h3 id="use">Por kio ni uzas viajn informojn?</h3>
+
+      <p>Ajna informo, kiun ni kolektas povas esti uzata por unu el tiuj celoj:</p>
+
+      <ul>
+        <li>Proprigi vian sperton &mdash; viaj informoj helpas nin pli bone respondi al viaj propraj bezonoj.</li>
+        <li>Plibonigi nian retejon &mdash; ni daŭre klopodas por plibonigi nian retejon uzante la informojn kaj komentojn, kiujn ni ricevas de vi.</li>
+        <li>Plibonigi nian helpon al klientoj &mdash; viaj informoj helpas nin pli bone respondi al klientaj petoj kaj al subtenaj bezonoj.</li>
+        <li>Sendi periodajn retmesaĝojn &mdash; La retadreso, kiun vi donas al ni, povas esti uzata por sendi al vi informojn kaj sciigojn, kiujn vi volas ricevi pri ŝanĝoj rilate al apartaj temoj, aŭ responde al via uzantnomo, al petoj kaj al demandoj.</li>
+      </ul>
+
+      <h3 id="protect">Kiel ni protektas viajn informojn?</h3>
+
+      <p>Ni realigis diversajn sekurigajn procedojn por konservi la sekurecon de viaj personaj informoj kiam vi enmetas, sendas, aŭ aliras viajn personajn informojn.</p>
+
+      <h3 id="data-retention">Kio estas nia politiko pri konservado de datumoj?</h3>
+
+      <p>Ni honeste klopodas:</p>
+
+      <ul>
+        <li>Ne konservi servilan historion, kiu enhavas la IP-adresojn de ĉiuj petoj, dum pli ol 90 tagoj.</li>
+        <li>Ne konservi la IP-adresojn de registritaj uzantoj kaj de iliaj mesaĝoj dum pli ol 5 jaroj.</li>
+      </ul>
+
+      <h3 id="cookies">Ĉu ni uzas kuketojn?</h3>
+
+      <p>Jes. Kuketoj estas etaj dosieroj, kiujn retejo aŭ ĝia servo donas al la memoro de via komputilo, per via retumilo (se vi permesas tion). Ĉi tiuj kuketoj ebligas al la retejo rekoni vian retumilon, kaj se vi havas registritan konton, ligas ĝin al via registrita konto.</p>
+
+      <p>Ni uzas kuketojn por kompreni kaj konservi viajn preferojn por postaj vizitoj, kaj kunmeti informojn pri reteja trafiko kaj interago, por ke ni povu doni pli bonan retejan sperton kaj pli bonajn ilojn estonte. Ni povas kontrakti kun eksteraj servoj por helpi nin pli bone kompreni la vizitantojn de la retejo. Ĉi tiuj eksteraj servoj ne rajtas uzi la informojn, kiujn ni kolektis, krom por helpi nin regi kaj plibonigi nian komercon.</p>
+
+      <h3 id="disclose">Ĉu ni disdonas informojn al eksteraj personoj?</h3>
+
+      <p>Ni ne vendas, interŝanĝas aŭ transdonas al eksteraj personoj viajn persone identigeblajn informojn. Ĉi tio ne inkludas la eksterajn servojn, kiujn ni fidas, kiuj helpas nin funkciigi nian retejon, regi nian komercon, aŭ servi vin, kiom longe tiuj personoj konsentas pri la sekura konservado de ĉi tiuj informoj. Ni ankaŭ povas disdoni viajn informojn, kiam ni pensas ke tio estas nepra por respekti leĝojn, por respektigi la politikojn de nia retejo, aŭ por protekti la rajtojn, posedaĵojn, kaj sekurecon de ni kaj de aliaj. Tamen, informoj de vizitantoj, kiuj ne identigas personojn, povas esti donitaj al eksteraj personoj por merkatado, reklamado, aŭ aliaj uzoj.</p>
+
+      <h3 id="third-party">Eksteraj ligiloj</h3>
+
+      <p>Foje, laŭ nia elekto, ni povas enmeti aŭ oferti eksterajn produktojn aŭ servojn en nia retejo. Ĉi tiuj eksteraj retejoj havas apartajn kaj sendependajn privatecajn politikojn. Tial, ni havas nek responsojn nek devigojn rilate al la enhavoj kaj agadoj de ĉi tiuj ligitaj retejoj. Tamen, ni celas protekti tiujn, kiuj uzas nian retejon, kaj bonvenigas ajnan komenton pri ĉi tiuj retejoj.</p>
+
+      <h3 id="coppa">Children's Online Privacy Protection Act Compliance</h3>
+
+      <p>Niaj retejo, produktoj kaj servoj estas por tiuj, kiuj havas almenaŭ 13 jarojn. Se ĉi tiu servilo estas en Usono, kaj vi havas malpli ol 13 jarojn, pro la postuloj de COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) ne uzu ĉi tiun retejon.</p>
+
+      <h3 id="online">Privateca politiko nur rete</h3>
+
+      <p>Ĉi tiu privateca politiko validas nur por informoj kolektitaj per nia retejo kaj ne por informoj kolektitaj eksterrete.</p>
+
+      <h3 id="consent">Via konsento</h3>
+
+      <p>Per uzado de nia retejo, vi konsentas kun nia reta privateca politiko.</p>
+
+      <h3 id="changes">Ŝanĝoj al nia privateca politiko</h3>
+
+      <p>Se ni decidas ŝanĝi nian privatecan politikon, ni afiŝos tiujn ŝanĝojn en ĉi tiu paĝo.</p>
+
+      <p>Ĉi tiu dokumento estas laŭ permeso CC-BY-SA. Ĝi estis laste ĝisdatigita je 2018-02-27.</p>
+
+      <p>Originale adaptita el la <a href="https://github.com/discourse/discourse">privateca politiko de Discourse</a>.</p>
+    title: Uzkondiĉoj kaj privateca politiko de %{instance}
+  themes:
+    default: Mastodon
   time:
     formats:
-      default: "%b %d, %Y, %H:%M"
+      default: "%Y-%m-%d %H:%M"
   two_factor_authentication:
-    description_html: Se vi ebligas <strong>dufaktoran aŭtentigon</strong>, vi bezonos vian poŝtelefonon por ensaluti, ĉar ĝi kreos nombrojn, kiujn vi devos entajpi.
+    code_hint: Enmetu la kodon kreitan de via aŭtentiga aplikaĵo por konfirmi
+    description_html: Se vi ebligas <strong>dufaktoran aŭtentigon</strong>, vi bezonos vian poŝtelefonon por ensaluti, ĉar ĝi kreos nombrojn, kiujn vi devos enmeti.
     disable: Malebligi
     enable: Ebligi
-    instructions_html: "<strong>Skanu tiun QR-kodon per Google Authenticator aŭ per simila aplikaĵo de via poŝtelefono</strong>. De tiam, la aplikaĵo kreos nombrojn, kiujn vi devos entajpi."
+    enabled: Dufaktora aŭtentigo ebligita
+    enabled_success: Dufaktora aŭtentigo sukcese ebligita
+    generate_recovery_codes: Krei realirajn kodojn
+    instructions_html: "<strong>Skanu ĉi tiun QR-kodon per Google Authenticator aŭ per simila aplikaĵo en via poŝtelefono</strong>. De tiam, la aplikaĵo kreos nombrojn, kiujn vi devos enmeti."
+    lost_recovery_codes: Realiraj kodoj permesas rehavi aliron al via konto se vi perdis vian telefonon. Se vi perdis viajn realirajn kodojn, vi povas rekrei ilin ĉi tie. Viaj malnovaj realiraj kodoj iĝos eksvalidaj.
+    manual_instructions: 'Se vi ne povas skani la QR-kodon kaj bezonas enmeti ĝin mane, jen la tut-teksta sekreto:'
+    recovery_codes: Realiraj kodoj
+    recovery_codes_regenerated: Realiraj kodoj sukcese rekreitaj
+    recovery_instructions_html: Se vi perdas aliron al via telefono, vi povas uzi unu el la subaj realiraj kodoj por rehavi aliron al via konto. <strong>Konservu realirajn kodojn sekure</strong>. Ekzemple, vi povas printi ilin kaj konservi ilin kun aliaj gravaj dokumentoj.
+    setup: Agordi
+    wrong_code: La enmetita kodo estis nevalida! Ĉu la servila tempo kaj la aparata tempo ĝustas?
+  user_mailer:
+    welcome:
+      edit_profile_action: Agordi profilon
+      edit_profile_step: Vi povas proprigi vian profilon per alŝuto de profilbildo, fonbildo, ŝanĝo de via afiŝita nomo kaj pli. Se vi ŝatus kontroli novajn sekvantojn antaŭ ol ili rajtas sekvi vin, vi povas ŝlosi vian konton.
+      explanation: Jen kelkaj konsiloj por helpi vin komenci
+      final_action: Ekmesaĝi
+      final_step: 'Ekmesaĝu! Eĉ sen sekvantoj, viaj publikaj mesaĝoj povas esti vidataj de aliaj, ekzemple en la loka tempolinio kaj en la kradvortoj. Eble vi ŝatus prezenti vin per la kradvorto #introductions.'
+      full_handle: Via kompleta uzantnomo
+      full_handle_hint: Jen kion vi dirus al viaj amikoj, por ke ili mesaĝu aŭ sekvu vin de alia nodo.
+      review_preferences_action: Ŝanĝi preferojn
+      review_preferences_step: Estu certa ke vi agordis viajn preferojn, kiel kiujn retmesaĝojn vi ŝatus ricevi, aŭ kiun dekomencan privatecan nivelon vi ŝatus ke viaj mesaĝoj havu. Se tio ne ĝenas vin, vi povas ebligi aŭtomatan ekigon de GIF-oj.
+      subject: Bonvenon en Mastodon
+      tip_bridge_html: Se vi venas de Twitter, vi povas trovi viajn amikojn en Mastodon per uzo de la <a href="%{bridge_url}">ponta aplikaĵo</a>. Tamen, tio funkcias nur se ankaŭ ili uzis la pontan aplikaĵon!
+      tip_federated_timeline: La fratara tempolinio estas antaŭvido de la reto de Mastodon. Sed ĝi enhavas nur homojn, kiuj estas sekvataj de aliaj homoj de via nodo, do ĝi ne estas kompleta.
+      tip_following: Vi dekomence sekvas la administrantojn de via servilo. Por trovi pli da interesaj homoj, rigardu la lokan kaj frataran tempoliniojn.
+      tip_local_timeline: La loka tempolinio estas antaŭvido de la homoj en %{instance}. Ĉi tiuj estas viaj apudaj najbaroj!
+      tip_mobile_webapp: Se via telefona retumilo proponas al vi aldoni Mastodon al via hejma ekrano, vi povas ricevi puŝsciigojn. Tio multmaniere funkcias kiel operaciuma aplikaĵo!
+      tips: Konsiloj
+      title: Bonvenon, %{name}!
   users:
-    invalid_email: La retpoŝt-adreso ne estas valida
-    invalid_otp_token: La dufaktora aŭtentigila kodo ne estas valida
+    invalid_email: La retadreso estas nevalida
+    invalid_otp_token: Nevalida kodo de dufaktora aŭtentigo
+    signed_in_as: 'Ensalutinta kiel:'
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index 2030b282d..cc330967d 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -365,6 +365,9 @@ fr:
     migrate_account: Déplacer vers un compte différent
     migrate_account_html: Si vous voulez rediriger ce compte vers un autre, vous pouvez le <a href="%{path}">configurer ici</a>.
     or_log_in_with: Ou authentifiez-vous avec
+    providers:
+      cas: CAS
+      saml: SAML
     register: S’inscrire
     resend_confirmation: Envoyer à nouveau les consignes de confirmation
     reset_password: Réinitialiser le mot de passe
@@ -735,7 +738,7 @@ fr:
       review_preferences_action: Modifier les préférences
       review_preferences_step: Assurez-vous de définir vos préférences, telles que les courriels que vous aimeriez recevoir ou le niveau de confidentialité auquel vous aimeriez que vos messages soient soumis par défaut. Si vous n'avez pas le mal des transports, vous pouvez choisir d'activer la lecture automatique GIF.
       subject: Bienvenue sur Mastodon
-      tip_bridge_html: Si vous venez de Twitter, vous pouvez retrouver vos amis sur Mastodon en utilisant le <a href="%{bridge_url}"> 1bridge app</a> 2. Cela ne fonctionne que s'ils ont aussi utilisé cette application !
+      tip_bridge_html: Si vous venez de Twitter, vous pouvez retrouver vos amis sur Mastodon en utilisant le <a href="%{bridge_url}">bridge app</a>. Cela ne fonctionne que s'ils ont aussi utilisé cette application !
       tip_federated_timeline: La chronologie fédérée est une vue en direct du réseau Mastodon. Mais elle n'inclut que les personnes auxquelles vos voisin·es sont abonné·es, donc elle n'est pas complète.
       tip_following: Vous suivez les administrateurs et administratrices de votre serveur par défaut. Pour trouver d'autres personnes intéressantes, consultez les chronologies locales et fédérées.
       tip_local_timeline: La chronologie locale est une vue des personnes sur %{instance}. Ce sont vos voisines et voisins immédiats !
diff --git a/config/locales/gl.yml b/config/locales/gl.yml
index 5de6031fc..3333a842f 100644
--- a/config/locales/gl.yml
+++ b/config/locales/gl.yml
@@ -289,6 +289,9 @@ gl:
         open:
           desc_html: Permitir que calquera poida crear unha conta
           title: Abrir rexistro
+      show_known_fediverse_at_about_page:
+        desc_html: Si activado, mostraralle os toots de todo o fediverso coñecido nunha vista previa. Si non só mostrará os toots locais.
+        title: Mostrar vista previa do fediverso na liña temporal
       show_staff_badge:
         desc_html: Mostrar unha insignia de membresía nunha páxina de usuaria
         title: Mostrar insigna de membresía
@@ -354,6 +357,7 @@ gl:
   auth:
     agreement_html: Rexistrándose acorda seguir <a href="%{rules_path}">as normas da instancia</a> e <a href="%{terms_path}">os termos do servizo</a>.
     change_password: Seguridade
+    confirm_email: Confirmar correo-e
     delete_account: Eliminar conta
     delete_account_html: Se desexa eliminar a súa conta, pode <a href="%{path}">facelo aquí</a>. Pediráselle confirmación.
     didnt_get_confirmation: Non recibeu as instruccións de confirmación?
@@ -363,6 +367,10 @@ gl:
     logout: Desconectar
     migrate_account: Mover a unha conta diferente
     migrate_account_html: Si desexa redirixir esta conta hacia outra diferente, pode <a href="%{path}">configuralo aquí</a>.
+    or_log_in_with: ou conectar con
+    providers:
+      cas: CAS
+      saml: SAML
     register: Rexistro
     resend_confirmation: Voltar a enviar intruccións de confirmación
     reset_password: Restablecer contrasinal
@@ -465,7 +473,7 @@ gl:
       expires_at: Caduca
       uses: Usos
     title: Convidar xente
-  landing_strip_html: "<strong>%{name}</strong> é unha usuaria en %{link_to_root_path}.  Pode seguilas ou interactuar con elas si ten unha conta en algún lugar do fediverso."
+  landing_strip_html: "<strong>%{name}</strong> é unha usuaria en %{link_to_root_path}.  Pode seguila ou interactuar con ela si ten unha conta en algún lugar do fediverso."
   landing_strip_signup_html: Si non, pode <a href="%{sign_up_path}">rexistrarse aquí</a>.
   lists:
     errors:
diff --git a/config/locales/hu.yml b/config/locales/hu.yml
index 918e85d1f..de35044d4 100644
--- a/config/locales/hu.yml
+++ b/config/locales/hu.yml
@@ -158,7 +158,7 @@ hu:
         unsuspend_account: "%{name} feloldotta %{target} felhasználói fiókjának felfüggesztését"
         update_custom_emoji: "%{name} frissítette az alábbi hangulatjelet: %{target}"
         update_status: "%{name} frissítette %{target} felhasználó tülkjét"
-      title: Audit log
+      title: Audit napló
     custom_emojis:
       by_domain: Domain
       copied_msg: Sikeresen létrehoztuk a hangulatjel helyi másolatát
@@ -431,7 +431,7 @@ hu:
     unlocked_warning_title: A fiókod jelenleg nem privát
   generic:
     changes_saved_msg: Változások sikeresen elmentve!
-    powered_by: powered by %{link}
+    powered_by: működteti a %{link}
     save_changes: Változások mentése
     validation_errors:
       one: Valami nincs rendjén! Kérlek tekintsd meg a hibát alant
@@ -633,6 +633,76 @@ hu:
     reblogged: reblogolt
     sensitive_content: Szenzitív tartalom
   terms:
+    body_html: |
+      <h2>Adatvédelmi és adatkezelési nyilatkozat</h2>
+
+      <h3 id="collect">Milyen információt gyűjtünk?</h3>
+
+      <p>Az oldalra történő regisztráció és a szolgáltatás használata - olvasás, tartalom létrehozása, tartalommegosztás - során információt gyűjtünk veled kapcsolatban.</p>
+
+      <p>A regisztráció során kérhetjük nevedet és e-mail címedet. Az oldalt természetesen regisztráció nélkül is felkeresheted. Az e-mail címed megerősítése egy egyedi információt tartalmazó link segítségével történik. Mondott linkre kattintva ellenőrizzük, hogy valóban te vagy a cím kezelője.</p>
+
+      <p>Regisztrált felhasználók esetében tülkök írásakor rögzítjük a felhasználó IP-címét. A szerver napjófájlja szintén tárolhatja ezt az IP-címet, valamint a szerverre érkező minden kérés küldő-oldali IP-címét.</p>
+
+      <h3 id="use">Mire használjuk a begyűjtött információt?</h3>
+
+      <p>Minden begyűjtött információt az alábbi okokból használhatunk fel:</p>
+
+      <ul>
+        <li>A felhasználói élmény személyre szabásához &mdash; a tőled gyűjtött információ segítségével biztosíthatjuk számodra az egyedi igényeknek történő megfelelést.</li>
+        <li>Szolgáltatásunk fejlesztéséhez &mdash; folyamatosan igyekszünk fejlődni és jobbá válni, és ezt a tőled kapott adatok és visszajelzések is nagyban segítik.</li>
+        <li>Az ügyféltámogatás fejlesztéséhez &mdash; a gyűjtött adatok segítségével hatékonyabban támogathatjuk felhasználóinkat, ha azok segítségre szorulnak.</li>
+        <li>E-mail értesítések küldéséhez &mdash; a megadott e-mail címedre küldjük ki az általad igényelt értesítéseket, a szolgáltatásra vonatkozó információkat és a válaszokat a tőled beérkező megkeresésekre.</li>
+      </ul>
+
+      <h3 id="protect">Hogyan védjük a tőled gyűjtött információt?</h3>
+
+      <p>Bitonsági mechanizmusok egész sorát vetjük be annak érdekében, hogy biztosítsuk a tőled származó személyes és használatai adatok és információk biztonságát.</p>
+
+      <h3 id="data-retention">Meddig tároljuk a tőled származó adatokat?</h3>
+
+      <p>Minden tőlünk telhetőt megteszünk annak érdekében, hogy</p>
+
+      <ul>
+        <li>a szerver naplófájljaiban tárolt, a szerverre érkező kérések küldő-oldali IP-címét maximum 90 napig,</li>
+        <li>a regisztrált felhasználók tülkjeinek eredeti IP-címét pedig maximum 5 évig</li>
+      </ul>
+
+      <p>tároljuk.</p>
+
+      <h3 id="cookies">Használunk-e sütiket?</h3>
+
+      <p>Igen. A sütik olyan kisméretű fájlok, amelyeket a szolgáltatások vagy internet-szolgáltatók küldenek a felhasználó számítógépére a böngészőn keresztül (természetesen csak abban az esetben, ha a felhasználó ezt engedélyezi). Oldalunk ezen sütik segítségével ismerik fel a böngésződet és - amennyiben rendelkezel nálunk fiókkal - kötik össze azt a felhasználói fiókoddal.</p>
+
+      <p>A sütik segítségével jobban megérthetjük használati szokásaidat, eltárolhatjuk beállításaidat következő látogatásodig, valamint így mérhetjük az oldal látogatottságát és használatát, mely adatok segítenek abban, hogy jobbá tehessük az általunk nyújtott szolgáltatást. Esetenként harmadik féllel is kapcsolatba léphetünk a kinyert használati adatok jobb megértése érdekében. Ezen harmadik felek számára azonban az adatok használata szigorú feltételekhez kötött: kizárólag az engedélyünkkel és királólag a mi szolgáltatásunk fejlesztésével összefüggésben használhatják azokat.</p>
+
+      <h3 id="disclose">Milyen információt adunk ki külső szereplőknek?</h3>
+
+      <p>Soha, semmilyen körülmények között nem adunk ki, át vagy el külső szereplőknek olyan adatot, amelynek segítségével egyes felhasználóink egyedileg azonosíthatók. Ez nem vonatkozik olyan harmadik felekre, melyek jelen szolgáltatás üzemeltetésében, javításában vagy támogatásában segítségünkre vannak &ndash; ezeket a feleket azonban titoktartási szerződés köti mondott adatokkal kapcsolatban. A gyűjtött adatokat ezen felül megfelelő meghagyás megléte esetén kiadhatjuk a törvény és a rendfenntartás képviselőinek, amennyiben ezen adatoknak jog-, élet- vagy vagyonvédelmi jelentőségük van. Hirdetési- és marketing-, valamint egyéb, a fentiekben nem érintett célból csak olyan adatok adhatók ki, amelyek nem teszik lehetővé az egyes felhasználók egyedi azonosítását.</p>
+
+      <h3 id="third-party">Harmadik felekre mutató hivatkozások</h3>
+
+      <p>Esetenként elhelyezhetünk harmadik fél által ajánlott termékekre vagy szolgáltatásokra mutató hivatkozásokat az oldalon. Ezen harmadik feleknek saját, tőlünk független adatvédelmi és adatkezelési nyilatkozatuk van. Ennek értelmében az oldal üzemeltetői semmilyen felelősséget nem tudnak vállalni az ezen harmadik fél által üzemeltetett oldalak viselkedésével és tartalmával kapcsolatban. Ugyanakkor arra törekszünk, hogy mindenben saját felhasználóink érdekeit képviseljük, így minden, a fenti harmadik felekkel kacsolatos visszejelzést szívesen veszünk.</p>
+
+      <h3 id="coppa">Megfelelés a Gyermekek Online Adatvédelméről Szóló Rendeletnek</h3>
+
+      <p>Az oldal, valamint az azon keresztül nyújtott szolgáltatás a 13 éven felülieket célozza. Amennyiben ez a szerver az Amerikai Egyesült Államok területén található és te nem vagy még 13 éves, a COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Gyermekek Online Adatvédelméről Szóló Rendelet</a>) értelmében kérjük ne használd ezt az oldalt és szolgáltatást.
+
+      <h3 id="online">Az adatvédelmi és adatkezelési nyilatkozat hatálya</h3>
+
+      <p>Jelen adatvédelmi és adatkezelési nyilatkozat kizárólag az oldalunkon keresztül gyűjtött online adatokra vonatkozik, offline módon gyűjtött adatokra nem terjed ki.</p>
+
+      <h3 id="consent">Használói beleegyezés</h3>
+
+      <p>Az oldal és a szolgáltatás használatával elfogadottnak tekinted jelen adatvédelmi és adatkezelési nyilatkozatot.</p>
+
+      <h3 id="changes">A nyilatkozat módosításairól</h3>
+
+      <p>Amennyiben a jövőben módosítjuk jelen adatvédelmi és adatkezelési nyilatkozatunkat, a módosított szöveg ugyanezen oldalon lesz megtalálható.</p>
+
+      <p>Jelen dokumentum a CC-BY-SA licenc alatt érhető el. Angol eredetijének utolsó módosítása: 2013. május 31.</p>
+
+      <p>A dokumetum a <a href="https://github.com/discourse/discourse">Discourse adatvédelmi és adatkezelési nyilatkozatán</a> alapul.</p>
     title: "%{instance} Felhasználási feltételek és Adatkezelési nyilatkozat"
   themes:
     default: Mastodon
@@ -661,3 +731,20 @@ hu:
       edit_profile_step: 'Itt tudod egyedivé tenni a profilod: feltölthetsz profil- és borítóképet, megváltoztathatod a megjelenített neved és így tovább. Ha jóvá szeretnéd hagyni követőidet, mielőtt láthatják a tülkjeid, itt tudod a fiókodat zárttá tenni.'
       explanation: Néhány tipp a kezdeti lépésekhez
       final_action: Kezdj tülkölni
+      final_step: 'Kezdj tülkölni! Publikus üzeneteid még követők híján is megjelennek másoknak, például a helyi időfolyamban és a címkéknél. Kezdd például azzal, hogy bemutatkozol: használd a #bemutatkozas és az #introductions címkét a tülködben.'
+      full_handle: Teljes felhasználóneved
+      full_handle_hint: Ez az, amit megadhatsz másoknak, hogy üzenhessenek neked vagy követhessenek téged más instanciákról.
+      review_preferences_action: Beállítások módosítása
+      review_preferences_step: Tekintsd át beállításaidat, például hogy milyen értesítéseket kérsz emailben vagy hogy alapértelmezettként mi legyen a tülkjeid adatvédelmi beállítása. Ha nem vagy szédülős alkat, azt is engedélyezheted, hogy automatikusan lejátsszuk a GIF-eket.
+      subject: Üdvözöl a Mastodon
+      tip_bridge_html: Ha a Twitterről érkezel, használhatod <a href="%{bridge_url}">alkalmazásunkat</a>, amellyel megtalálhatod Twitteres barátaidat a Mastodonon. Az alkalmazás csak azon barátaidat tudja megtalálni, akik maguk is használták azt!
+      tip_federated_timeline: A nyilvános időfolyam a Mastodon ütőere, ahol minden tülk összefolyik. Nem teljes ugyan, mert csak azokat az emberek fogod látni, akiket instanciád többi felhasználója követ.
+      tip_following: Alapértelmezettként instanciád adminisztrátorait követed. Látogasd meg a helyi és a nyilvános időfolyamot, hogy más érdekes emberekre is rátalálj.
+      tip_local_timeline: A helyi időfolyam a saját instanciád (%{instance}) ütőere. Ezek a kedves emberek itt mind a szomszédaid!
+      tip_mobile_webapp: Ha a böngésződ lehetővé teszi, hogy kezdőképernyődhöz add a Mastodont, még értesítéseket is fogsz kapni &ndash; akárcsak egy igazi alkalmazás esetében!
+      tips: Tippek
+      title: Üdv a fedélzeten, %{name}!
+  users:
+    invalid_email: A megadott e-mail cím helytelen
+    invalid_otp_token: Érvénytelen ellenőrző kód
+    signed_in_as: Bejelentkezve mint
diff --git a/config/locales/ja.yml b/config/locales/ja.yml
index df0d58807..bc7dc3735 100644
--- a/config/locales/ja.yml
+++ b/config/locales/ja.yml
@@ -273,6 +273,9 @@ ja:
       contact_information:
         email: ビジネスメールアドレス
         username: 連絡先のユーザー名
+      hero:
+        desc_html: フロントページに表示されます。サイズは600x100px以上推奨です。未設定の場合、インスタンスのサムネイルが使用されます。
+        title: ヒーローイメージ
       peers_api_enabled:
         desc_html: 連合内でこのインスタンスが遭遇したドメインの名前
         title: 接続しているインスタンスのリストを公開する
@@ -289,6 +292,9 @@ ja:
         open:
           desc_html: 誰でも自由にアカウントを作成できるようにします
           title: 新規登録を受け付ける
+      show_known_fediverse_at_about_page:
+        desc_html: チェックを入れるとプレビュー欄に既知の連合先全てのトゥートを表示します。外すとローカルのトゥートだけ表示します。
+        title: タイムラインプレビューに連合タイムラインを表示する
       show_staff_badge:
         desc_html: ユーザーページにスタッフのバッジを表示します
         title: スタッフバッジを表示する
@@ -363,6 +369,7 @@ ja:
     logout: ログアウト
     migrate_account: 別のアカウントに引っ越す
     migrate_account_html: 引っ越し先を明記したい場合は<a href="%{path}">こちら</a>で設定できます。
+    or_log_in_with: または次のサービスでログイン
     register: 登録する
     resend_confirmation: 確認メールを再送する
     reset_password: パスワードを再発行
@@ -412,6 +419,13 @@ ja:
       title: このページは正しくありません
     noscript_html: Mastodonのウェブアプリケーションを利用する場合はJavaScriptを有効にしてください。またはあなたのプラットフォーム向けの<a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">Mastodonネイティブアプリ</a>を探すことができます。
   exports:
+    archive_takeout:
+      date: 日時
+      download: ダウンロード
+      hint_html: "<strong>トゥートとメディア</strong>のアーカイブをリクエストできます。 データはActivityPub形式で、対応しているソフトウェアで読み込むことができます。"
+      in_progress: 準備中...
+      request: アーカイブをリクエスト
+      size: 容量
     blocks: ブロック
     csv: CSV
     follows: フォロー
@@ -735,12 +749,16 @@ ja:
     setup: 初期設定
     wrong_code: コードが間違っています。サーバー上の時間とデバイス上の時間が一致していることを確認してください。
   user_mailer:
+    backup_ready:
+      explanation: Mastodonアカウントのアーカイブを受け付けました。今すぐダウンロードできます!
+      subject: アーカイブの準備ができました
+      title: アーカイブの取り出し
     welcome:
       edit_profile_action: プロフィールを設定
       edit_profile_step: アバター画像やヘッダー画像をアップロードしたり、表示名やその他プロフィールを変更しカスタマイズすることができます。新しいフォロワーからのフォローを許可する前に検討したい場合、アカウントを非公開にすることができます。
       explanation: 始めるにあたってのアドバイスです
       final_action: 始めましょう
-      final_step: 'さあ始めましょう!たとえフォロワーがいなくても、あなたの公開した投稿はローカルタイムラインやハッシュタグなどで誰かの目に止まるかもしれません。自己紹介をしたい時は #introductions ハッシュタグを使うといいかもしれません。'
+      final_step: 'さあ始めましょう! たとえフォロワーがいなくても、あなたの公開した投稿はローカルタイムラインやハッシュタグなどで誰かの目に止まるかもしれません。自己紹介をしたい時は #introductions ハッシュタグを使うといいかもしれません。'
       full_handle: あなたの正式なユーザー名
       full_handle_hint: これは別のインスタンスからフォローしてもらったりメッセージのやり取りをする際に、友達に伝えるといいでしょう。
       review_preferences_action: 設定の変更
@@ -752,8 +770,9 @@ ja:
       tip_local_timeline: ローカルタイムラインは %{instance} にいる人々の流れを見られるものです。彼らはあなたと同じインスタンスにいる隣人のようなものです!
       tip_mobile_webapp: もしモバイル端末のブラウザで Mastodon をホーム画面に追加できる場合、プッシュ通知を受け取ることができます。それはまるでネイティブアプリのように動作します!
       tips: 豆知識
-      title: ようこそ、 %{name}!
+      title: ようこそ、%{name} !
   users:
     invalid_email: メールアドレスが無効です
     invalid_otp_token: 二段階認証コードが間違っています
+    seamless_external_login: あなたは外部サービスを介してログインしているため、パスワードとメールアドレスの設定は利用できません。
     signed_in_as: '下記でログイン中:'
diff --git a/config/locales/nl.yml b/config/locales/nl.yml
index 0db7127bb..d964742ab 100644
--- a/config/locales/nl.yml
+++ b/config/locales/nl.yml
@@ -145,7 +145,7 @@ nl:
         destroy_status: Toot van %{target} is door %{name} verwijderd
         disable_2fa_user: Vereisten tweestapsverificatie van %{target} zijn door %{name} uitgeschakeld
         disable_custom_emoji: Emoji %{target} is door %{name} uitgeschakeld
-        disable_user: Inloggen voor %{target} is door %{name} uitgeschakeld
+        disable_user: Aanmelden voor %{target} is door %{name} uitgeschakeld
         enable_custom_emoji: Emoji %{target} is door %{name} ingeschakeld
         enable_user: Inloggen voor %{target} is door %{name} ingeschakeld
         memorialize_account: Account %{target} is door %{name} in een in-memoriampagina veranderd
@@ -289,6 +289,9 @@ nl:
         open:
           desc_html: Toestaan dat iedereen een account kan registereren
           title: Open registratie
+      show_known_fediverse_at_about_page:
+        desc_html: Wanneer ingeschakeld wordt de globale tijdlijn als voorbeeld getoond en wanneer uitgeschakeld de lokale tijdljn.
+        title: De globale tijdlijn als voorbeeld tonen
       show_staff_badge:
         desc_html: Medewerkersbadge op profielpagina tonen
         title: Medewerkersbadge tonen
@@ -306,8 +309,8 @@ nl:
         desc_html: Gebruikt als voorvertoning voor OpenGraph en de API. 1200x630px aanbevolen
         title: Thumbnail Mastodonserver
       timeline_preview:
-        desc_html: Toon de openbare tijdlijn op de startpagina
-        title: Voorbeeld tijdlijn
+        desc_html: Toon een openbare tijdlijn op de landingspagina
+        title: Tijdlijn als voorbeeld tonen
       title: Server-instellingen
     statuses:
       back_to_account: Terug naar accountpagina
@@ -354,6 +357,7 @@ nl:
   auth:
     agreement_html: Wanneer je op registreren klikt ga je akkoord met het opvolgen van <a href="%{rules_path}">de regels van deze server</a> en <a href="%{terms_path}">onze gebruikersvoorwaarden</a>.
     change_password: Beveiliging
+    confirm_email: E-mail bevestigen
     delete_account: Account verwijderen
     delete_account_html: Wanneer je jouw account graag wilt verwijderen, kan je dat <a href="%{path}">hier doen</a>. We vragen jou daar om een bevestiging.
     didnt_get_confirmation: Geen bevestigingsinstructies ontvangen?
@@ -363,6 +367,10 @@ nl:
     logout: Afmelden
     migrate_account: Naar een andere account verhuizen
     migrate_account_html: Wanneer je dit account naar een ander account wilt doorverwijzen, kun je <a href="%{path}">dit hier instellen</a>.
+    or_log_in_with: Of aanmelden met
+    providers:
+      cas: CAS
+      saml: SAML
     register: Registreren
     resend_confirmation: Verstuur de bevestigingsinstructies nogmaals
     reset_password: Wachtwoord opnieuw instellen
diff --git a/config/locales/oc.yml b/config/locales/oc.yml
index 80b103763..869118c08 100644
--- a/config/locales/oc.yml
+++ b/config/locales/oc.yml
@@ -363,6 +363,9 @@ oc:
     logout: Se desconnectar
     migrate_account: Mudar endacòm mai
     migrate_account_html: Se volètz mandar los visitors d’aqueste compte a un autre, podètz<a href="%{path}"> o configurar aquí</a>.
+    providers:
+      cas: CAS
+      saml: SAML
     register: Se marcar
     resend_confirmation: Tornar mandar las instruccions de confirmacion
     reset_password: Reïnicializar lo senhal
@@ -387,7 +390,7 @@ oc:
     - dv
     - ds
     abbr_month_names:
-    - 
+    - None
     - gen
     - feb
     - mar
@@ -413,7 +416,7 @@ oc:
       long: Lo %e %B de %Y
       short: "%e %b. de %Y"
     month_names:
-    - 
+    - None
     - de genièr
     - de febrièr
     - de març
diff --git a/config/locales/pl.yml b/config/locales/pl.yml
index 678140374..e51f1be6b 100644
--- a/config/locales/pl.yml
+++ b/config/locales/pl.yml
@@ -371,7 +371,7 @@ pl:
     logout: Wyloguj się
     migrate_account: Przenieś konto
     migrate_account_html: Jeżeli chcesz skonfigurować przekierowanie z obecnego konta na inne, możesz <a href="%{path}">skonfigurować to tutaj</a>.
-    or_log_in_with: Lub zaloguj się używając
+    or_log_in_with: Lub zaloguj się z użyciem
     providers:
       cas: CAS
       saml: SAML
@@ -420,7 +420,7 @@ pl:
       title: Sprawdzanie bezpieczeństwa nie powiodło się
     '429': Uduszono
     '500':
-      content: Przepraszamy, coś poszło nie tak…
+      content: Przepraszamy, coś poszło nie tak, po naszej stronie.
       title: Ta strona jest nieprawidłowa
     noscript_html: Aby korzystać z aplikacji Mastodon, włącz JavaScript. Możesz też skorzystać z jednej z <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md">natywnych aplikacji</a> obsługującej Twoje urządzenie.
   exports:
@@ -783,4 +783,5 @@ pl:
   users:
     invalid_email: Adres e-mail jest niepoprawny
     invalid_otp_token: Kod uwierzytelniający jest niepoprawny
+    seamless_external_login: Zalogowano z użyciem zewnętrznej usługi, więc ustawienia hasła i adresu e-mail nie są dostępne.
     signed_in_as: 'Zalogowany jako:'
diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml
index cc3876a6c..f51abeff2 100644
--- a/config/locales/pt-BR.yml
+++ b/config/locales/pt-BR.yml
@@ -633,7 +633,7 @@ pt-BR:
   stream_entries:
     click_to_show: Clique para mostrar
     pinned: Toot fixado
-    reblogged: compartilhado
+    reblogged: compartilhou
     sensitive_content: Conteúdo sensível
   terms:
     body_html: |
diff --git a/config/locales/pt.yml b/config/locales/pt.yml
index c77368e3f..455f27898 100644
--- a/config/locales/pt.yml
+++ b/config/locales/pt.yml
@@ -354,6 +354,7 @@ pt:
   auth:
     agreement_html: Registando-te concordas em seguir <a href="%{rules_path}">as regras da instância</a> e <a href="%{terms_path}">os nossos termos de serviço</a>.
     change_password: Alterar palavra-passe
+    confirm_email: Confirmar e-mail
     delete_account: Eliminar conta
     delete_account_html: Se desejas eliminar a conta, podes <a href="%{path}">continua aqui</a>. Uma confirmação será pedida.
     didnt_get_confirmation: Não recebeu o email de confirmação?
diff --git a/config/locales/simple_form.ar.yml b/config/locales/simple_form.ar.yml
index 5c68aa2bd..abed908fb 100644
--- a/config/locales/simple_form.ar.yml
+++ b/config/locales/simple_form.ar.yml
@@ -4,15 +4,19 @@ ar:
     hints:
       defaults:
         avatar: ملف PNG أو GIF أو JPG. حجمه على أقصى تصدير 2MB. سيتم تصغيره إلى 120x120px
+        digest: تُرسَل إليك بعد مُضيّ مدة مِن خمول نشاطك و فقط إذا ما تلقيت رسائل شخصية مباشِرة أثناء فترة غيابك مِن الشبكة
         display_name:
           one: <span class="name-counter">1</span> حرف متبقي
+          other: <span class="name-counter">%{count}</span> حروف متبقية
         header: ملف PNG أو GIF أو JPG. حجمه على أقصى تصدير 2MB. سيتم تصغيره إلى 700x335px
         locked: يتطلب منك الموافقة يدويا على طلبات المتابعة
         note:
           one: <span class="note-counter">1</span> حرف متبقي
           other: <span class="note-counter">%{count}</span> حروف متبقية
+        setting_noindex: ذلك يؤثر على حالة ملفك الشخصي و صفحاتك
+        setting_theme: ذلك يؤثر على الشكل الذي سيبدو عليه ماستدون عندما تقوم بالدخول مِن أي جهاز.
       imports:
-        data: ملف CSV تم تصديره من مثيل خادوم ماستدون آخر
+        data: ملف CSV تم تصديره مِن مثيل خادوم ماستدون آخر
       sessions:
         otp: قم بإدخال رمز المصادقة بخطوتين مِن هاتفك أو إستخدم أحد رموز النفاذ الإحتياطية.
       user:
@@ -30,7 +34,8 @@ ar:
         filtered_languages: اللغات التي تم تصفيتها
         header: الرأسية
         locale: اللغة
-        locked: قفل الحساب
+        locked: تجميد الحساب
+        max_uses: عدد مرات استخدام الرابط
         new_password: كلمة السر الجديدة
         note: السيرة الذاتية
         otp_attempt: رمز المصادقة بخطوتين
@@ -40,22 +45,27 @@ ar:
         setting_default_privacy: خصوصية المنشور
         setting_default_sensitive: إعتبر الوسائط دائما كمحتوى حساس
         setting_delete_modal: إظهار مربع حوار للتأكيد قبل حذف أي تبويق
+        setting_display_sensitive_media: دائمًا إظهار الوسائط الحساسة
         setting_noindex: عدم السماح لمحركات البحث بفهرسة ملفك الشخصي
         setting_reduce_motion: تخفيض عدد الصور في الوسائط المتحركة
         setting_system_font_ui: إستخدم الخطوط الإفتراضية للنظام
         setting_theme: سمة الموقع
         setting_unfollow_modal: إظهار مربع حوار للتأكيد قبل إلغاء متابعة أي حساب
         severity: القوّة
-        type: نوع الإستيراد
+        type: صيغة الإستيراد
         username: إسم المستخدم
+        username_or_email: إسم المستخدم أو كلمة السر
       interactions:
-        must_be_follower: حظر الإخطارات القادمة من الحسابات التي لا تتبعك
+        must_be_follower: حظر الإخطارات القادمة من حسابات لا تتبعك
         must_be_following: حظر الإخطارات القادمة من الحسابات التي لا تتابعها
-        must_be_following_dm: حظر الإشعارات القادمة من الأشخاص الذين لا تتابعهم
+        must_be_following_dm: حظر الرسائل المباشرة القادمة من طرف أشخاص لا تتبعهم
       notification_emails:
         digest: إرسال ملخصات عبر البريد الإلكتروني
         favourite: إبعث بريداً إلكترونيًا عندما يُعجَب أحدهم بمنشورك
         follow: إبعث بريداً إلكترونيًا عندما يتبعك أحد
+        follow_request: إبعث بريدا إلكترونيا عندما يقوم أحدهم بإرسال طلب بالمتابعة
+        mention: إبعث بريداً إلكترونيًا عندما يُشير إليك أو يذكُرك أحدهم
+        reblog: إبعث بريداً إلكترونيًا عندما يقوم أحدهم بترقية منشورك
     'no': لا
     required:
       mark: "*"
diff --git a/config/locales/simple_form.ca.yml b/config/locales/simple_form.ca.yml
index 9bb48e5be..bd4f7fae4 100644
--- a/config/locales/simple_form.ca.yml
+++ b/config/locales/simple_form.ca.yml
@@ -3,67 +3,69 @@ ca:
   simple_form:
     hints:
       defaults:
-        avatar: PNG, GIF o JPG. Màxim 2MB. Serà escalat a 120x120px
+        avatar: PNG, GIF o JPG. Màxim 2MB. S'escalarà a 120x120px
         digest: Només s'envia després d'un llarg període d'inactivitat amb un resum de les mencions que has rebut en la teva absència
         display_name:
-          one: <span class="name-counter">1</span> càracter
-          other: <span class="name-counter">%{count}</span> càracters
-        header: PNG, GIF o JPG. Màxim 2MB. Serà escalat a 700x335px
-        locked: Requereix que aprovis manualment seguidors i les publicacions seran mostrades només als teus seguidors
+          one: <span class="name-counter">1</span> càracter restant
+          other: <span class="name-counter">%{count}</span> càracters restans
+        header: PNG, GIF o JPG. Màxim 2MB. S'escalarà a 700x335px
+        locked: Requereix que aprovis manualment els seguidors
         note:
-          one: <span class="note-counter">1</span> càracter left
-          other: <span class="note-counter">%{count}</span> càracters
+          one: <span class="note-counter">1</span> càracter restant
+          other: <span class="note-counter">%{count}</span> caràcters restants
         setting_noindex: Afecta el teu perfil públic i les pàgines d'estat
-        setting_theme: Afecta la manera en què Mastodon es veu quan està connectat des de qualsevol dispositiu.
+        setting_theme: Afecta l'aspecte de Mastodon quan es visita des de qualsevol dispositiu.
       imports:
-        data: Arxiu CSV exportat desde una altra instància de Mastodon
+        data: Fitxer CSV exportat des de una altra instància de Mastodon
       sessions:
         otp: Introdueix el codi de dos factors des del teu telèfon o utilitza un dels teus codis de recuperació.
       user:
-        filtered_languages: Els idiomes seleccionats seran eliminats de les línies de temps públiques
+        filtered_languages: Les llengües seleccionades s'eliminaran de les línies de temps públiques
     labels:
       defaults:
         avatar: Avatar
-        confirm_new_password: Confirmar nova contrasenya
-        confirm_password: Confirmar contrasenya
+        confirm_new_password: Confirma la contrasenya nova
+        confirm_password: Confirma la contrasenya
         current_password: Contrasenya actual
         data: Informació
-        display_name: Mostrar nom
-        email: Direcció de correu electrònic
-        expires_in: Caduca després
-        filtered_languages: Idiomes filtrats
-        header: Img. capçalera
-        locale: Idioma
-        locked: Fer privat aquest compte
+        display_name: Nom visible
+        email: Adreça de correu electrònic
+        expires_in: Expira després
+        filtered_languages: Llengües filtrades
+        header: Capçalera
+        locale: Llengua
+        locked: Fes aquest compte privat
         max_uses: Nombre màxim d'usos
-        new_password: Nova contrasenya
+        new_password: Contrasenya nova
         note: Biografia
         otp_attempt: Codi de dos factors
         password: Contrasenya
-        setting_auto_play_gif: Auto-reproducció de GIFs animats
-        setting_boost_modal: Mostrar finestra de confirmació abans d'un retoot
-        setting_default_privacy: Privacitat de publicacions
-        setting_default_sensitive: Marca sempre els multimèdia com a sensibles
-        setting_delete_modal: Mostrar finestra de confirmació abans d'esborrar un toot
+        setting_auto_play_gif: Reproducció automàtica de GIFs animats
+        setting_boost_modal: Mostra la finestra de confirmació abans d'un retoot
+        setting_default_privacy: Privacitat de les publicacions
+        setting_default_sensitive: Marca sempre els elements multimèdia com a sensibles
+        setting_delete_modal: Mostra la finestra de confirmació abans de suprimir un toot
+        setting_display_sensitive_media: Mostra sempre els elements multimèdia marcats com a sensibles
         setting_noindex: Desactivació de la indexació del motor de cerca
         setting_reduce_motion: Redueix el moviment en animacions
-        setting_system_font_ui: Utilitzeu el tipus de lletra predeterminat del sistema
+        setting_system_font_ui: Utilitza el tipus de lletra predeterminat del sistema
         setting_theme: Tema del lloc
         setting_unfollow_modal: Mostra el diàleg de confirmació abans de deixar de seguir a algú
         severity: Severitat
-        type: Importar tipus
-        username: Nom d´usuari
+        type: Importa el tipus
+        username: Nom d'usuari
+        username_or_email: Nom d'usuari o adreça electrònica
       interactions:
-        must_be_follower: Bloquejar notificacions de persones que no et segueixen
-        must_be_following: Bloquejar notificacions de persones que no segueixes
-        must_be_following_dm: Bloqueja missatges directes de persones que no segueixes
+        must_be_follower: Blocar les notificacions de persones que no et segueixen
+        must_be_following: Bloca les notificacions de persones que no segueixes
+        must_be_following_dm: Bloca els missatges directes de persones que no segueixes
       notification_emails:
-        digest: Enviar resum de correus electrònics
-        favourite: Enviar correu electrònic quan algú marqui com a favorit en la teva publicació
-        follow: Enviar correu electrònic quan algú et segueixi
-        follow_request: Enviar correu electrònic quan algú sol·liciti seguir-te
-        mention: Enviar correu electrònic quan algú et mencioni
-        reblog: Enviar correu electrònic quan algú comparteixi la seva publicació
+        digest: Envia un resum per correu electrònic
+        favourite: Envia un correu electrònic si algú marca com a preferit el teu estat
+        follow: Envia un correu electrònic si algú et segueix
+        follow_request: Envia un correu electrònic si algú sol·licita seguir-te
+        mention: Envia un correu electrònic si algú et menciona
+        reblog: Envia un correu electrònic si algú comparteix el teu estat
     'no': 'No'
     required:
       mark: "*"
diff --git a/config/locales/simple_form.de.yml b/config/locales/simple_form.de.yml
index bb78ae21a..851a5f019 100644
--- a/config/locales/simple_form.de.yml
+++ b/config/locales/simple_form.de.yml
@@ -45,6 +45,7 @@ de:
         setting_default_privacy: Beitragssichtbarkeit
         setting_default_sensitive: Medien immer als heikel markieren
         setting_delete_modal: Bestätigungsdialog anzeigen, bevor ein Beitrag gelöscht wird
+        setting_display_sensitive_media: Medien, die als heikel markiert sind, immer anzeigen
         setting_noindex: Suchmaschinen-Indexierung verhindern
         setting_reduce_motion: Bewegung in Animationen verringern
         setting_system_font_ui: Standardschriftart des Systems verwenden
diff --git a/config/locales/simple_form.eo.yml b/config/locales/simple_form.eo.yml
index a3824d349..2bb0215d5 100644
--- a/config/locales/simple_form.eo.yml
+++ b/config/locales/simple_form.eo.yml
@@ -3,42 +3,69 @@ eo:
   simple_form:
     hints:
       defaults:
-        avatar: En la formato PNG, GIF aŭ JPG. Ĝis 2Mo. Estos malgrandigita al 120x120px
-        display_name: 30 signoj pleje
-        header: En la formato PNG, GIF aŭ JPG. Ĝis 2Mo. Estos malgrandigita al 700x335px
-        locked: Vi devos aprobi ĉiun peton de sekvado, kaj viaj mesaĝoj estos senŝanĝe nur por viaj sekvantoj.
-        note: 160 signoj pleje
+        avatar: Formato PNG, GIF aŭ JPG. Ĝis 2MB. Estos malgrandigita al 120x120px
+        digest: Sendita nur post longa tempo de neaktiveco, kaj nur se vi ricevis personan mesaĝon en via foresto
+        display_name:
+          one: <span class="name-counter">1</span> signo restas
+          other: <span class="name-counter">%{count}</span> signoj restas
+        header: Formato PNG, GIF aŭ JPG. Ĝis 2MB. Estos malgrandigita al 700x335px
+        locked: Vi devos aprobi ĉiun peton de sekvado mane
+        note:
+          one: <span class="note-counter">1</span> signo restas
+          other: <span class="note-counter">%{count}</span> signoj restas
+        setting_noindex: Influas vian publikan profilon kaj mesaĝajn paĝojn
+        setting_theme: Influas kiel Mastodon aspektas kiam vi ensalutis en ajna aparato.
       imports:
-        data: Dosiero CSV el alia aperaĵo de Mastodon
+        data: CSV-dosiero el alia nodo de Mastodon
+      sessions:
+        otp: Enmetu la kodon de dufaktora aŭtentigo el via telefono aŭ uzu unu el la realiraj kodoj.
+      user:
+        filtered_languages: Markitaj lingvoj estos elfiltritaj de publikaj tempolinioj por vi
     labels:
       defaults:
         avatar: Profilbildo
         confirm_new_password: Konfirmi novan pasvorton
-        confirm_password: Konfirmi la pasvorton
+        confirm_password: Konfirmi pasvorton
         current_password: Nuna pasvorto
         data: Datumoj
         display_name: Publika nomo
-        email: Retpoŝt-adreso
-        header: Kapbildo
+        email: Retadreso
+        expires_in: Eksvalidiĝas post
+        filtered_languages: Filtritaj lingvoj
+        header: Fonbildo
         locale: Lingvo
-        locked: Privatigi la konton
+        locked: Ŝlosi konton
+        max_uses: Maksimuma nombro de uzoj
         new_password: Nova pasvorto
         note: Sinprezento
-        otp_attempt: Dufaktora identigilo
+        otp_attempt: Kodo de dufaktora aŭtentigo
         password: Pasvorto
-        setting_default_privacy: Videbleco de la mesaĝoj
-        type: Tipo de alportado
+        setting_auto_play_gif: Aŭtomate ekigi GIF-ojn
+        setting_boost_modal: Montri fenestron por konfirmi antaŭ ol diskonigi
+        setting_default_privacy: Mesaĝa videbleco
+        setting_default_sensitive: Ĉiam marki aŭdovidaĵojn tiklaj
+        setting_delete_modal: Montri fenestron por konfirmi antaŭ ol forigi hupon
+        setting_display_sensitive_media: Ĉiam montri aŭdovidaĵon markitajn tiklaj
+        setting_noindex: Ellistiĝi de retserĉila indeksado
+        setting_reduce_motion: Malrapidigi animaciojn
+        setting_system_font_ui: Uzi la dekomencan tiparon de la sistemo
+        setting_theme: Reteja etoso
+        setting_unfollow_modal: Montri fenestron por konfirmi antaŭ ol ĉesi sekvi iun
+        severity: Graveco
+        type: Importa tipo
         username: Uzantnomo
+        username_or_email: Uzantnomo aŭ Retadreso
       interactions:
-        must_be_follower: Kaŝi la sciigojn de homoj, kiuj ne sekvas vin
-        must_be_following: Kaŝi la sciigojn de homoj, kiujn vi ne sekvas
+        must_be_follower: Bloki sciigojn de nesekvantoj
+        must_be_following: Bloki sciigojn de homoj, kiujn vi ne sekvas
+        must_be_following_dm: Bloki rektajn mesaĝojn de homoj, kiujn vi ne sekvas
       notification_emails:
-        digest: Sendi resumajn retpoŝt-mesaĝojn
-        favourite: Sendi retpoŝt-mesaĝon, kiam iu favoras mesaĝon de vi
-        follow: Sendi retpoŝt-mesaĝon, kiam iu eksekvas vin
-        follow_request: Sendi retpoŝt-mesaĝon, kiam iu petas sekvi vin
-        mention: Sendi retpoŝt-mesaĝon, kiam iu mencias vin
-        reblog: Sendi retpoŝt-mesaĝon, kiam iu diskonigas mesaĝon de vi
+        digest: Sendi resumajn retmesaĝojn
+        favourite: Sendi retmesaĝon kiam iu stelumas vian mesaĝon
+        follow: Sendi retmesaĝon kiam iu sekvas vin
+        follow_request: Sendi retmesaĝon kiam iu petas sekvi vin
+        mention: Sendi retmesaĝon kiam iu mencias vin
+        reblog: Sendi retmesaĝon kiam iu diskonigas vian mesaĝon
     'no': Ne
     required:
       mark: "*"
diff --git a/config/locales/simple_form.fr.yml b/config/locales/simple_form.fr.yml
index da405344d..4d5af1b5d 100644
--- a/config/locales/simple_form.fr.yml
+++ b/config/locales/simple_form.fr.yml
@@ -45,6 +45,7 @@ fr:
         setting_default_privacy: Confidentialité des statuts
         setting_default_sensitive: Toujours marquer les médias comme sensibles
         setting_delete_modal: Afficher une fenêtre de confirmation avant de supprimer un pouet
+        setting_display_sensitive_media: Toujours afficher les médias marqués comme sensibles
         setting_noindex: Demander aux moteurs de recherche de ne pas indexer vos informations personnelles
         setting_reduce_motion: Réduire la vitesse des animations
         setting_system_font_ui: Utiliser la police par défaut du système
@@ -53,6 +54,7 @@ fr:
         severity: Sévérité
         type: Type d’import
         username: Identifiant
+        username_or_email: Nom d'utilisateur ou courriel
       interactions:
         must_be_follower: Masquer les notifications des personnes qui ne vous suivent pas
         must_be_following: Masquer les notifications des personnes que vous ne suivez pas
diff --git a/config/locales/simple_form.gl.yml b/config/locales/simple_form.gl.yml
index 2e51cf691..57eaf5016 100644
--- a/config/locales/simple_form.gl.yml
+++ b/config/locales/simple_form.gl.yml
@@ -45,6 +45,7 @@ gl:
         setting_default_privacy: Intimidade da publicación
         setting_default_sensitive: Marcar sempre multimedia como sensible
         setting_delete_modal: Solicitar confirmación antes de eliminar unha mensaxe
+        setting_display_sensitive_media: Mostrar sempre os medios marcados como sensibles
         setting_noindex: Pedir non aparecer nas buscas dos motores de busca
         setting_reduce_motion: Reducir o movemento nas animacións
         setting_system_font_ui: Utilizar a tipografía por defecto do sistema
@@ -53,6 +54,7 @@ gl:
         severity: Severidade
         type: Tipo de importación
         username: Nome de usuaria
+        username_or_email: Nome de usuaria ou Correo-e
       interactions:
         must_be_follower: Bloquear as notificacións de non-seguidoras
         must_be_following: Bloquea as notificacións de personas que non segue
diff --git a/config/locales/simple_form.hu.yml b/config/locales/simple_form.hu.yml
index 5ecb127c7..9239205cd 100644
--- a/config/locales/simple_form.hu.yml
+++ b/config/locales/simple_form.hu.yml
@@ -30,18 +30,38 @@ hu:
         data: Adatok
         display_name: Megjelenített név
         email: E-mail cím
+        expires_in: Elévül
         filtered_languages: Szűrt nyelvek
         header: Fejléc
         locale: Nyelv
         locked: Zárt felhasználói fiók
+        max_uses: Felhasználhatóság
         new_password: Új jelszó
         note: Önéletrajz
         otp_attempt: Második-faktor kód
         password: Jelszó
+        setting_auto_play_gif: GIF-ek automatikus lejátszása
+        setting_boost_modal: Megerősítés kérése reblogolás előtt
+        setting_default_privacy: Tülkök alapártelmezett adatvédelmi szintje
+        setting_default_sensitive: Minden médiafájl megjelölése szenzitívként
+        setting_delete_modal: Megerősítés kérése tülk törlése előtt
+        setting_noindex: Megtiltom a keresőmotoroknak, hogy indexeljék a tülkjeimet
+        setting_reduce_motion: Animációk mozgásának csökkentése
+        setting_system_font_ui: Rendszer betűtípusának használata
+        setting_theme: Oldalsablon
+        setting_unfollow_modal: Megerősítés kérése mielőtt abbahagyod valaki követését
+        severity: Súlyosság
+        type: Importálás típusa
         username: Felhasználónév
+      interactions:
+        must_be_follower: Nem követőidtől érkező értesítések tiltása
+        must_be_following: Nem követettjeidtől érkező értesítések tiltása
+        must_be_following_dm: Nem követettjeidtől érkező üzenetek tiltása
       notification_emails:
+        digest: Összevont e-mailek küldése
         favourite: E-mail küldése amikor valaki kedvencnek jelöli az állapotod
         follow: E-mail küldése amikor valaki követni kezd téged
+        follow_request: E-mail küldése amikor valaki követni szeretne téged
         mention: E-mail küldése amikor valaki megemlít téged
         reblog: E-mail küldése amikor valaki reblogolja az állapotod
     'no': Nem
diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml
index 33b75e74a..fe27ae72a 100644
--- a/config/locales/simple_form.ja.yml
+++ b/config/locales/simple_form.ja.yml
@@ -41,6 +41,7 @@ ja:
         setting_default_privacy: 投稿の公開範囲
         setting_default_sensitive: メディアを常に閲覧注意としてマークする
         setting_delete_modal: トゥートを削除する前に確認ダイアログを表示する
+        setting_display_sensitive_media: 閲覧注意としてマークされたメディアも常に表示する
         setting_favourite_modal: お気に入りをする前に確認ダイアログを表示する
         setting_noindex: 検索エンジンによるインデックスを拒否する
         setting_reduce_motion: アニメーションの動きを減らす
@@ -50,6 +51,7 @@ ja:
         severity: 重大性
         type: インポートする項目
         username: ユーザー名
+        username_or_email: ユーザー名またはメールアドレス
       interactions:
         must_be_follower: フォロワー以外からの通知をブロック
         must_be_following: フォローしていないユーザーからの通知をブロック
diff --git a/config/locales/simple_form.nl.yml b/config/locales/simple_form.nl.yml
index 01ae95322..f87f39055 100644
--- a/config/locales/simple_form.nl.yml
+++ b/config/locales/simple_form.nl.yml
@@ -45,6 +45,7 @@ nl:
         setting_default_privacy: Zichtbaarheid toots
         setting_default_sensitive: Media altijd als gevoelig markeren
         setting_delete_modal: Vraag voor het verwijderen van een toot een bevestiging
+        setting_display_sensitive_media: Als gevoelig gemarkeerde media altijd tonen
         setting_noindex: Jouw toots niet door zoekmachines laten indexeren
         setting_reduce_motion: Langzamere animaties
         setting_system_font_ui: Standaardlettertype van jouw systeem gebruiken
@@ -53,6 +54,7 @@ nl:
         severity: Zwaarte
         type: Importtype
         username: gebruikersnaam
+        username_or_email: Gebruikersnaam of e-mailadres
       interactions:
         must_be_follower: Meldingen van mensen die jou niet volgen blokkeren
         must_be_following: Meldingen van mensen die jij niet volgt blokkeren
diff --git a/config/locales/simple_form.pt.yml b/config/locales/simple_form.pt.yml
index 9970247ab..1a2f19fc5 100644
--- a/config/locales/simple_form.pt.yml
+++ b/config/locales/simple_form.pt.yml
@@ -3,50 +3,69 @@ pt:
   simple_form:
     hints:
       defaults:
-        avatar: PNG, GIF ou JPG. No máximo 2MB. Vai ser reduzido para 120x120px
-        display_name: No máximo 30 caracteres
-        header: PNG, GIF or JPG. No máximo 2MB. Vai ser reduzido para 700x335px
-        locked: Requer que manualmente aproves seguidores e torna o default dos teus posts para privados (apenas seguidores)
-        note: No máximo 160 caracteres
+        avatar: PNG, GIF or JPG. Arquivos até 2MB. Vão ser reduzidos para 120x120px
+        digest: Enviado após um longo período de inatividade e apenas se foste mencionado na tua ausência
+        display_name:
+          one: <span class="name-counter">1</span> caracter restante
+          other: <span class="name-counter">%{count}</span> caracteres restantes
+        header: PNG, GIF or JPG. Arquivos até 2MB. Vão ser reduzidos para 700x335px
+        locked: Requer aprovação manual de seguidores
+        note:
+          one: <span class="note-counter">1</span> caracter restante
+          other: <span class="note-counter">%{count}</span> caracteres restantes
+        setting_noindex: Afecta o teu perfil público e as páginas das tuas publicações
+        setting_theme: Afecta a aparência do Mastodon quando entras na tua conta em qualquer dispositivo.
       imports:
-        data: Ficheiro CSV exportado de outra instância do Mastodon
+        data: Arquivo CSV exportado de outra instância do Mastodon
       sessions:
-        otp: Insere o código de autenticação em dois passos do teu telefone ou utiliza um código de recuperação de acesso.
+        otp: Inserir o código de autenticação de dois factores do teu telemóvel ou usa um dos códigos de recuperação.
+      user:
+        filtered_languages: Seleciona os idiomas que devem ser removidos das tuas timelines públicas
     labels:
       defaults:
         avatar: Imagem de Perfil
-        confirm_new_password: Confirme nova palavra-passe
-        confirm_password: Confirme a palavra-passe
+        confirm_new_password: Confirmar nova palavra-passe
+        confirm_password: Confirmar palavra-passe
         current_password: Palavra-passe actual
-        data: Data
-        display_name: Nome
-        email: Endereço de email
+        data: Dados
+        display_name: Nome Público
+        email: Endereço de e-mail
+        expires_in: Expira em
+        filtered_languages: Idiomas filtrados
         header: Cabeçalho
-        locale: Língua
-        locked: Tornar conta privada
+        locale: Idioma
+        locked: Trancar conta
+        max_uses: Número máximo de utilizações
         new_password: Nova palavra-passe
         note: Biografia
         otp_attempt: Código de autenticação em dois passos
         password: Palavra-passe
-        setting_boost_modal: Pedir confirmação antes de partilhar um post
-        setting_default_privacy: Privacidade padrão de posts
-        setting_default_sensitive: Marcar sempre media como sensível
-        setting_reduce_motion: Reduzir movimento em animações
-        severity: Severity
-        type: Import type
-        username: Utilizador
+        setting_auto_play_gif: Reproduzir GIFs automaticamente
+        setting_boost_modal: Solicitar confirmação antes de partilhar uma publicação
+        setting_default_privacy: Privacidade da publicação
+        setting_default_sensitive: Sempre marcar media como sensível
+        setting_delete_modal: Solicitar confirmação antes de eliminar uma publicação
+        setting_noindex: Não quero ser indexado por motores de pesquisa
+        setting_reduce_motion: Reduz movimento em animações
+        setting_system_font_ui: Usar a fonte padrão do teu sistema
+        setting_theme: Tema do site
+        setting_unfollow_modal: Solicitar confirmação antes de deixar de seguir alguém
+        severity: Gravidade
+        type: Tipo de importação
+        username: Nome de utilizador
       interactions:
         must_be_follower: Bloquear notificações de não-seguidores
         must_be_following: Bloquear notificações de pessoas que não segues
+        must_be_following_dm: Bloquear mensagens directas de pessoas que tu não segues
       notification_emails:
-        digest: Enviar um email da actividade nesta instância
-        favourite: Enviar email quando alguém adiciona um post teu aos favoritos
-        follow: Enviar email quando alguém te segue
-        follow_request: Enviar um email quando alguém solicitar ser o teu seguidor
-        mention: Enviar email quando alguém te menciona
-        reblog: Enviar email quando alguém partilhar um post teu
+        digest: Enviar e-mails de resumo
+        favourite: Enviar e-mail quando alguém adiciona uma publicação tua aos favoritos
+        follow: Enviar e-mail quando alguém te segue
+        follow_request: Enviar e-mail quando alguém solicita ser teu seguidor
+        mention: Enviar e-mail quando alguém te menciona
+        reblog: Enviar e-mail quando alguém partilha uma publicação tua
     'no': Não
     required:
       mark: "*"
-      text: necessário
+      text: obrigatório
     'yes': Sim
diff --git a/config/locales/simple_form.sk.yml b/config/locales/simple_form.sk.yml
index 0ff4d1356..1ef8f2c80 100644
--- a/config/locales/simple_form.sk.yml
+++ b/config/locales/simple_form.sk.yml
@@ -35,7 +35,7 @@ sk:
         header: Obrázok v hlavičke
         locale: Jazyk
         locked: Zamknúť účet
-        max_uses: Maximálny počet použití
+        max_uses: Maximálne možno použiť
         new_password: Nové heslo
         note: O vás
         otp_attempt: Dvoj-faktorový (2FA) kód
@@ -45,18 +45,20 @@ sk:
         setting_default_privacy: Nastavenie súkromia príspevkov
         setting_default_sensitive: Označiť každý obrázok/video/súbor ako chúlostivý
         setting_delete_modal: Zobrazovať potvrdzovacie okno pred zmazaním toot-u
+        setting_display_sensitive_media: Vždy zobrazovať médiá označované ako senzitívne
         setting_noindex: Nezaradzovať vaše príspevky do indexácie pre vyhľadávanie
         setting_reduce_motion: Redukovať pohyb v animáciách
-        setting_system_font_ui: Použiť štandardný systémový font
+        setting_system_font_ui: Použiť základné systémové písmo
         setting_theme: Vzhľad
         setting_unfollow_modal: Zobrazovať potvrdzovacie okno pred skončením sledovania iného používateľa
         severity: Závažnosť
         type: Typ importu
         username: Používateľské meno
+        username_or_email: Prezívka, alebo Email
       interactions:
         must_be_follower: Blokovať notifikácie pod používateľov, ktorí vás nesledujú
         must_be_following: Blokovať notifikácie od ľudí ktorý vás nesledujú
-        must_be_following_dm: Blokovať priame správy od ľudí ktorých nesleduješ
+        must_be_following_dm: Blokovať súkromné správy od ľudí ktorých nesleduješ
       notification_emails:
         digest: Posielať súhrnné emaily
         favourite: Poslať email ak niekto označí váš príspevok ako obľúbený
diff --git a/config/locales/simple_form.sv.yml b/config/locales/simple_form.sv.yml
index 5869a3cc6..5f71c7571 100644
--- a/config/locales/simple_form.sv.yml
+++ b/config/locales/simple_form.sv.yml
@@ -53,6 +53,7 @@ sv:
         severity: Strikthet
         type: Importtyp
         username: Användarnamn
+        username_or_email: Användarnamn eller e-mail
       interactions:
         must_be_follower: Blockera meddelanden från icke-följare
         must_be_following: Blockera meddelanden från personer du inte följer
diff --git a/config/locales/sk.yml b/config/locales/sk.yml
index 853988546..5e5dd42e9 100644
--- a/config/locales/sk.yml
+++ b/config/locales/sk.yml
@@ -265,6 +265,7 @@ sk:
       view: Zobraziť
     settings:
       activity_api_enabled:
+        desc_html: Sčítanie lokálne publikovaných príspevkov, aktívnych užívateľov, a nových registrácii, v týždenných intervaloch
         title: Vydať hromadné štatistiky o užívateľskej aktivite
       bootstrap_timeline_accounts:
         desc_html: Ak je prezývok viacero, každú oddeľte čiarkou. Možno zadať iba miestne, odomknuté účty. Pokiaľ necháte prázdne, je to pre všetkých miestnych administrátorov.
@@ -278,7 +279,7 @@ sk:
       registrations:
         closed_message:
           desc_html: Toto sa zobrazí na hlavnej stránke v prípade že sú registrácie uzavreté. Možno tu použiť aj HTML kód
-          title: Správa o uzatvorených registráciách
+          title: Správa o uzavretých registráciách
         deletion:
           desc_html: Dovoľiť každému aby si mohli zmazať svok účet
           title: Sprístupniť možnosť vymazať si účet
@@ -288,11 +289,14 @@ sk:
         open:
           desc_html: Povoliť každému aby si mohli vytvoriť účet
           title: Verejná registrácia
+      show_known_fediverse_at_about_page:
+        desc_html: Pokiaľ je zapnuté, bude v ukážke osi možné nahliadnúť statusy z celého známeho fediversa. V opačnom prípade tam budú ukázané iba statusy z lokálnej osi.
+        title: Ukázať celé známe fediversum ako ukážku osi
       show_staff_badge:
         desc_html: Zobraziť moderátorsku značku na užívateľovej stránke
         title: Zobraziť značku moderátora
       site_description:
-        desc_html: Oboznamujúci paragraf na hlavnej stránke a pri meta tagoch. Môžete použiť HTML kód, presnejšie  <code>&lt; a&gt;</code> and <code>&lt; em&gt; </code>.
+        desc_html: Oboznamujúci paragraf na hlavnej stránke a pri meta tagoch. Môžete použiť HTML kód, presnejšie  <code>&lt; a&gt;</code> a <code>&lt; em&gt; </code>.
         title: Popis instancie
       site_description_extended:
         desc_html: Toto je vhodné miesto pre vaše pravidlá, oboznámenia a iné veci, ktorými je vaša instancia špecifická. Je možné tu používať HTML kód
@@ -337,6 +341,7 @@ sk:
       subject: Nový report pre %{instance} (#%{id})
   application_mailer:
     notification_preferences: Zmeniť e-mailové voľby
+    salutation: "%{name},"
     settings: 'Zmeniť e-mailové voľby: %{link}'
     view: 'Zobraziť:'
     view_profile: Zobraziť profil
@@ -352,6 +357,7 @@ sk:
   auth:
     agreement_html: V rámci registrácie súhlasíte, že sa budete riadiť  <a href="%{rules_path}"> 1 pravidlami tejto instancie</a> 2 a taktiež <a href="%{terms_path}"> 3 našími servisnými podmienkami </a> 4.
     change_password: Zabezpečenie
+    confirm_email: Potvrdiť email
     delete_account: Vymazať účet
     delete_account_html: Pokiaľ si želáte vymazať svoj účet, môžete tak <a href="%{path}"> 1 urobiť tu</a> 2. Budete požiadaný/á o potvrdenie tohto kroku.
     didnt_get_confirmation: Neobdŕžali ste kroky pre potvrdenie?
@@ -361,11 +367,16 @@ sk:
     logout: Odhlásiť sa
     migrate_account: Presunúť sa na iný účet
     migrate_account_html: Pokiaľ si želáte presmerovať tento účet na nejaký iný, môžete <a href="%{path}"> tak urobiť tu</a>.
+    or_log_in_with: Alebo prihlásiť z
+    providers:
+      cas: CAS
+      saml: SAML
     register: Zaregistrovať sa
     resend_confirmation: Poslať potvrdzujúce pokyny znovu
     reset_password: Resetovať heslo
     set_new_password: Nastaviť nové heslo
   authorize_follow:
+    error: Naneštastie nastala chyba pri hľadaní vzdialeného účtu
     follow: Následovať
     follow_request: 'Poslali ste požiadavku následovať užívateľa:'
     following: 'Podarilo sa! Teraz už následujete užívateľa:'
@@ -376,13 +387,25 @@ sk:
     title: Následovať %{acct}
   datetime:
     distance_in_words:
+      about_x_hours: "%{count}hod"
+      about_x_months: "%{count}mesiace"
+      about_x_years: "%{count}rok"
+      almost_x_years: "%{count}rok"
       half_a_minute: Len teraz
       less_than_x_seconds: Len teraz
+      over_x_years: "%{count}rok"
+      x_days: "%{count}dni"
+      x_minutes: ''
+      x_months: "%{count}mesiace"
+      x_seconds: "%{count}sek"
   deletes:
+    bad_password_msg: Dobrý pokus, hakeri! Nesprávne heslo
     confirm_password: Napíšte svoje terajšie heslo pre overenie vašej identity
+    description_html: Týmto <strong> natrvalo, nenavrátiteľne </strong> vymažeš obsah tvojho účtu, a deaktivuješ ho. Tvoja prezývka ale ostane rezervovaná ako prevencia pred budúcimi impersonáciami.
     proceed: Vymazať účet
     success_msg: Váš účet bol úspešne vymazaný
     warning_html: Iba vymazanie obsahu z tejto konkrétnej instancie je garantované. Obsah ktorý bol zdieľaný široko=ďaleko pravdepodobne zanechá nejaké stopy. Servery ktoré sú offline a tie ktoré vás ignorujú nezaktualizujú svoje databázy.
+    warning_title: Dostupnosť distribuovaného obsahu
   errors:
     '403': Nemáte dostatočné povolenie na zobrazenie tejto stránky.
     '404': Stránka ktorú ste hľadali neexistuje.
@@ -390,22 +413,118 @@ sk:
     '422':
       content: Bezpečtnostné overenie zlyhalo. Blokujete cookies?
       title: Bezpečtnostné overenie zlyhalo
+    '429': Zamlčané
     '500':
       content: Ospravedlňujeme sa. Niečo sa pokazilo na našom konci.
       title: Táto stránka nieje v poriadku
+    noscript_html: Aby bolo možné používať Mastodon web aplikáciu, prosím povoľte JavaScript. Alebo skúste jednu z <a href="https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md"> aplikácii </a> dostupných pre vašu platformu.
   exports:
     blocks: Blokujete
+    csv: CSV
     follows: Následujete
     mutes: Stíšili ste
+    storage: Úložisko médii
   followers:
     domain: Doména
+    explanation_html: Pokiaľ chceš zaručiť súkromie svojích príspevkov, musíš mať na vedomí, kto ťa sleduje. <strong> Tvoje súkromné príspevky sú doručené na každý server z ktorého ťa niekto následuje. </strong> Takže možno by si ich chcel/a skontrolovať, a odstrániť tých následovníkov, čo sú na serveroch ktorím nedôveruješ, že ich moderátori, alebo úpravbuy kódu budú tiež rešpektovať tvoje súkromie.
     followers_count: Počet následovateľov
     lock_link: Zamknite svoj účet
+    purge: Odstrániť následovateľa
+    success:
+      one: Počas utišovania sledovateľov z jednej domény...
+      other: Počas utišovania sledovateľov z %{count} domén...
     true_privacy_html: Prosím majte na vedomí, <strong> 1 že ozajstné súkromie sa dá dosiahnúť iba za pomoci end-to-end enkrypcie</strong> 2.
+    unlocked_warning_html: Hocikto ťa môže následovať aby mohol/a ihneď vidieť tvoje súkromné príspevky. %{lock_link} aby si mohla skontrolovať a odmietať sledovateľov.
+    unlocked_warning_title: Tvoj účet nieje zamknutý
+  generic:
+    changes_saved_msg: Zmeny boli úspešne uložené!
+    powered_by: poháňané vďaka %{link}
+    save_changes: Uložiť zmeny
+    validation_errors:
+      one: Niečo nieje úplne v poriadku! Prosím skontroluj chybu
+      other: Niečo ešte stále nieje v poriadku! Prosím skontroluj všetky %{count} chyby
+  imports:
+    preface: Môžeš importovať dáta ktoré si exportoval/a z iného Mastodon serveru, ako sú napríklad zoznamy ľudí ktorých sleduješ, alebo blokuješ.
+    success: Tvoje dáta boli nahraté úspešne, a budú teraz spracované v danom čase
+    types:
+      blocking: Zoznam blokovaných
+      following: Zoznam sledovaných
+      muting: Zoznam ignorovaných
+    upload: Nahrať
+  in_memoriam_html: V pamäti.
+  invites:
+    delete: Deaktivovať
+    expired: Neplatné
+    expires_in:
+      '1800': 30 minút
+      '21600': 6 hodín
+      '3600': 1 hodina
+      '43200': 12 hodín
+      '86400': 1 deň
+    expires_in_prompt: Nikdy
+    generate: Vygeneruj
+    max_uses:
+      one: jedno použitie
+      other: "%{count} použití"
+    max_uses_prompt: Bez limitov
+    prompt: Vygeneruj a zdieľaj linky s ostatnými aby mali umožnený prístup k tomuto serveru
+    table:
+      expires_at: Vyprší
+      uses: Používa
+    title: Pozvať ľudí
+  landing_strip_html: "<strong>%{name}</strong> je užívateľ na serveri %{link_to_root_path}. Ty ich môžeš následovať a môžeš s nimi interaktovať pokiaľ máš účet hocikde v rámci fediversa."
+  landing_strip_signup_html: Pokiaľ ešte nemáš, môžeš <a href="%{sign_up_path}">si tu vytvoriť účet</a>.
+  lists:
+    errors:
+      limit: Dosiahli ste maximálny možný počet zoznamov
+  media_attachments:
+    validations:
+      images_and_video: K príspevku ktorý už obsahuje obrázky nemôžeš priložiť video
+      too_many: Nemôžeš priložiť viac ako 4 súbory
+  migrations:
+    acct: prezývka@doména nového účtu
+    currently_redirecting: 'Tvoj profil má nastavené presmerovanie na:'
+    proceed: Uložiť
+    updated_msg: Tvoje nastavenia pre presmerovanie účtu boli úspešne aktualizované!
+  moderation:
+    title: Moderovanie
+  notification_mailer:
+    digest:
+      action: Zobraziť všetky notifikácie
+      body: Tu nájdete krátky súhrn správ ktoré ste zmeškali od svojej poslednj návštevi od %{since}
+      mention: "%{name} ťa spomenul/a v:"
+      new_followers_summary:
+        one: Taktiež, získal/a si jedného nového následovníka zatiaľ čo si bol/a preč. Yay!
+        other: Taktiež, získal/a si %{count} nových následovníkov za tú dobu čo si bol/a preč. Yay!
+      subject:
+        one: "1 nová notifikácia od tvojej poslednej návštevy \U0001F418"
+        other: "%{count} nové notifikácie od tvojej poslednej návštevy \U0001F418"
+      title: Zatiaľ čo si bol/a preč…
+    favourite:
+      body: 'Tvoj príspevok bol uložený medi obľúbené užívateľa %{name}:'
+      subject: "%{name} si obľúbil/a tvoj príspevok"
+      title: Nové obľúbené
+    follow:
+      body: "%{name} ťa teraz následuje!"
+      subject: "%{name} ťa teraz následuje"
+      title: Nový sledovateľ
+    follow_request:
+      action: Spravuj žiadosti o sledovanie
+      body: "%{name} žiada povolenie ťa následovať"
+      subject: "%{name} ťa žiadá o možnosť sledovania"
+      title: Nová žiadosť o sledovanie
+    mention:
+      action: Odpovedať
+      body: "%{name} ťa spomenul/a v:"
+      subject: Boli ste spomenutí užívateľom %{name}
+      title: Nové spomenutie
   settings:
     authorized_apps: Autorizované aplikácie
     back: Naspäť na stránku
+  user_mailer:
+    welcome:
+      final_step: 'Začnite písať! Aj bez následovníkov budú vaše verejné správy videné ostatnými, napríklad na lokálnej osi a pod haštagmi. Môžete sa ostatným predstaviť pod haštagom #introductions.'
   users:
     invalid_email: Emailová adresa je neplatná
-    invalid_otp_token: Neplatný 2FA kód
+    invalid_otp_token: Neplatný kód pre dvojfaktorovú autentikáciu
     signed_in_as: 'Prihlásený ako:'
diff --git a/config/locales/sv.yml b/config/locales/sv.yml
index d20e8ba9f..1e79b63e5 100644
--- a/config/locales/sv.yml
+++ b/config/locales/sv.yml
@@ -289,6 +289,9 @@ sv:
         open:
           desc_html: Tillåt alla att skapa ett konto
           title: Öppen registrering
+      show_known_fediverse_at_about_page:
+        desc_html: När den växlas, kommer toots från hela fediverse visas på förhandsvisning. Annars visas bara lokala toots.
+        title: Visa det kända fediverse på tidslinjens förhandsgranskning
       show_staff_badge:
         desc_html: Visa en personalbricka på en användarsida
         title: Visa personalbricka
@@ -354,6 +357,7 @@ sv:
   auth:
     agreement_html: Genom att registrera dig godkänner du att följa <a href="%{rules_path}">instansens regler</a> och <a href="%{terms_path}">våra användarvillkor</a>.
     change_password: Säkerhet
+    confirm_email: Bekräfta e-postadress
     delete_account: Ta bort konto
     delete_account_html: Om du vill radera ditt konto kan du <a href="%{path}">fortsätta här</a>. Du kommer att bli ombedd att bekräfta.
     didnt_get_confirmation: Fick inte instruktioner om bekräftelse?
@@ -363,6 +367,10 @@ sv:
     logout: Logga ut
     migrate_account: Flytta till ett annat konto
     migrate_account_html: Om du vill omdirigera detta konto till ett annat, kan du <a href="%{path}">konfigurera det här</a>.
+    or_log_in_with: Eller logga in med
+    providers:
+      cas: CAS
+      saml: SAML
     register: Registrera
     resend_confirmation: Skicka instruktionerna om bekräftelse igen
     reset_password: Återställ lösenord
diff --git a/db/schema.rb b/db/schema.rb
index a22e86837..a0187d5a6 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -547,6 +547,7 @@ ActiveRecord::Schema.define(version: 20180211015820) do
   add_foreign_key "account_moderation_notes", "accounts", column: "target_account_id"
   add_foreign_key "accounts", "accounts", column: "moved_to_account_id", on_delete: :nullify
   add_foreign_key "admin_action_logs", "accounts", on_delete: :cascade
+  add_foreign_key "backups", "users", on_delete: :nullify
   add_foreign_key "blocks", "accounts", column: "target_account_id", name: "fk_9571bfabc1", on_delete: :cascade
   add_foreign_key "blocks", "accounts", name: "fk_4269e03e65", on_delete: :cascade
   add_foreign_key "conversation_mutes", "accounts", name: "fk_225b4212bb", on_delete: :cascade
diff --git a/lib/devise/ldap_authenticatable.rb b/lib/devise/ldap_authenticatable.rb
new file mode 100644
index 000000000..531abdbbe
--- /dev/null
+++ b/lib/devise/ldap_authenticatable.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+if ENV['LDAP_ENABLED'] == 'true'
+  require 'net/ldap'
+  require 'devise/strategies/authenticatable'
+
+  module Devise
+    module Strategies
+      class LdapAuthenticatable < Authenticatable
+        def authenticate!
+          if params[:user]
+            ldap = Net::LDAP.new(
+              host: Devise.ldap_host,
+              port: Devise.ldap_port,
+              base: Devise.ldap_base,
+              encryption: {
+                method: Devise.ldap_method,
+                tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS,
+              },
+              auth: {
+                method: :simple,
+                username: Devise.ldap_bind_dn,
+                password: Devise.ldap_password,
+              },
+              connect_timeout: 10
+            )
+
+            if (user_info = ldap.bind_as(base: Devise.ldap_base, filter: "(#{Devise.ldap_uid}=#{email})", password: password))
+              user = User.ldap_get_user(user_info.first)
+              success!(user)
+            else
+              return fail(:invalid_login)
+            end
+          end
+        end
+
+        def email
+          params[:user][:email]
+        end
+
+        def password
+          params[:user][:password]
+        end
+      end
+    end
+  end
+
+  Warden::Strategies.add(:ldap_authenticatable, Devise::Strategies::LdapAuthenticatable)
+end
diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb
index 3a67bfb23..4150b39b6 100644
--- a/lib/mastodon/version.rb
+++ b/lib/mastodon/version.rb
@@ -9,7 +9,7 @@ module Mastodon
     end
 
     def minor
-      2
+      3
     end
 
     def patch
@@ -21,7 +21,7 @@ module Mastodon
     end
 
     def flags
-      ''
+      'rc1'
     end
 
     def to_a
diff --git a/lib/tasks/mastodon.rake b/lib/tasks/mastodon.rake
index d2e4f38a9..9202b4839 100644
--- a/lib/tasks/mastodon.rake
+++ b/lib/tasks/mastodon.rake
@@ -23,7 +23,7 @@ namespace :mastodon do
       prompt.say('Single user mode disables registrations and redirects the landing page to your public profile.')
       env['SINGLE_USER_MODE'] = prompt.yes?('Do you want to enable single user mode?', default: false)
 
-      %w(SECRET_KEY_BASE PAPERCLIP_SECRET OTP_SECRET).each do |key|
+      %w(SECRET_KEY_BASE OTP_SECRET).each do |key|
         env[key] = SecureRandom.hex(64)
       end
 
@@ -476,8 +476,10 @@ namespace :mastodon do
       time_ago = ENV.fetch('NUM_DAYS') { 7 }.to_i.days.ago
 
       MediaAttachment.where.not(remote_url: '').where.not(file_file_name: nil).where('created_at < ?', time_ago).find_each do |media|
-        media.file.destroy
-        media.save
+        if media.file.exists?
+          media.file.destroy
+          media.save
+        end
       end
     end
 
@@ -494,9 +496,13 @@ namespace :mastodon do
       accounts = accounts.where(domain: ENV['DOMAIN']) if ENV['DOMAIN'].present?
 
       accounts.find_each do |account|
-        account.reset_avatar!
-        account.reset_header!
-        account.save
+        begin
+          account.reset_avatar!
+          account.reset_header!
+          account.save
+        rescue Paperclip::Error
+          puts "Error resetting avatar and header for account #{username}@#{domain}"
+        end
       end
     end
   end
diff --git a/package.json b/package.json
index 277e5bb63..38b517f04 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "mastodon",
-  "license": "AGPL-3.0",
+  "license": "AGPL-3.0-or-later",
   "engines": {
     "node": ">=6"
   },
diff --git a/spec/lib/activitypub/activity/flag_spec.rb b/spec/lib/activitypub/activity/flag_spec.rb
new file mode 100644
index 000000000..3f082a813
--- /dev/null
+++ b/spec/lib/activitypub/activity/flag_spec.rb
@@ -0,0 +1,37 @@
+require 'rails_helper'
+
+RSpec.describe ActivityPub::Activity::Flag do
+  let(:sender)  { Fabricate(:account, domain: 'example.com') }
+  let(:flagged) { Fabricate(:account) }
+  let(:status)  { Fabricate(:status, account: flagged, uri: 'foobar') }
+
+  let(:json) do
+    {
+      '@context': 'https://www.w3.org/ns/activitystreams',
+      id: nil,
+      type: 'Flag',
+      content: 'Boo!!',
+      actor: ActivityPub::TagManager.instance.uri_for(sender),
+      object: [
+        ActivityPub::TagManager.instance.uri_for(flagged),
+        ActivityPub::TagManager.instance.uri_for(status),
+      ],
+    }.with_indifferent_access
+  end
+
+  describe '#perform' do
+    subject { described_class.new(json, sender) }
+
+    before do
+      subject.perform
+    end
+
+    it 'creates a report' do
+      report = Report.find_by(account: sender, target_account: flagged)
+
+      expect(report).to_not be_nil
+      expect(report.comment).to eq 'Boo!!'
+      expect(report.status_ids).to eq [status.id]
+    end
+  end
+end
diff --git a/spec/lib/request_spec.rb b/spec/lib/request_spec.rb
index 782f14b18..dc7daa52c 100644
--- a/spec/lib/request_spec.rb
+++ b/spec/lib/request_spec.rb
@@ -38,17 +38,32 @@ describe Request do
   end
 
   describe '#perform' do
-    before do
-      stub_request(:get, 'http://example.com')
-      subject.perform
-    end
+    context 'with valid host' do
+      before do
+        stub_request(:get, 'http://example.com')
+        subject.perform
+      end
+
+      it 'executes a HTTP request' do
+        expect(a_request(:get, 'http://example.com')).to have_been_made.once
+      end
 
-    it 'executes a HTTP request' do
-      expect(a_request(:get, 'http://example.com')).to have_been_made.once
+      it 'sets headers' do
+        expect(a_request(:get, 'http://example.com').with(headers: subject.headers)).to have_been_made
+      end
     end
 
-    it 'sets headers' do
-      expect(a_request(:get, 'http://example.com').with(headers: subject.headers)).to have_been_made
+    context 'with private host' do
+      around do |example|
+        WebMock.disable!
+        example.run
+        WebMock.enable!
+      end
+
+      it 'raises Mastodon::ValidationError' do
+        allow(IPSocket).to receive(:getaddress).with('example.com').and_return('0.0.0.0')
+        expect{ subject.perform }.to raise_error Mastodon::ValidationError
+      end
     end
   end
 end
diff --git a/spec/services/report_service_spec.rb b/spec/services/report_service_spec.rb
new file mode 100644
index 000000000..2f926ef00
--- /dev/null
+++ b/spec/services/report_service_spec.rb
@@ -0,0 +1,25 @@
+require 'rails_helper'
+
+RSpec.describe ReportService do
+  subject { described_class.new }
+
+  let(:source_account) { Fabricate(:account) }
+
+  context 'for a remote account' do
+    let(:remote_account) { Fabricate(:account, domain: 'example.com', protocol: :activitypub, inbox_url: 'http://example.com/inbox') }
+
+    before do
+      stub_request(:post, 'http://example.com/inbox').to_return(status: 200)
+    end
+
+    it 'sends ActivityPub payload when forward is true' do
+      subject.call(source_account, remote_account, forward: true)
+      expect(a_request(:post, 'http://example.com/inbox')).to have_been_made
+    end
+
+    it 'does not send anything when forward is false' do
+      subject.call(source_account, remote_account, forward: false)
+      expect(a_request(:post, 'http://example.com/inbox')).to_not have_been_made
+    end
+  end
+end