diff --git a/.circleci/config.yml b/.circleci/config.yml
index e8bfde2994629f53eb8e038586ed38e6247f7217..2355d9d7d81baeff71ae65ca83c80e569b1f7e90 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -174,8 +174,7 @@ jobs:
     steps:
       - *attach_workspace
       - run: bundle exec i18n-tasks check-normalized
-      - run: bundle exec i18n-tasks unused
-      - run: bundle exec i18n-tasks missing -t plural
+      - run: bundle exec i18n-tasks unused -l en
       - run: bundle exec i18n-tasks check-consistent-interpolations
 
 workflows:
diff --git a/.codeclimate.yml b/.codeclimate.yml
index a704597649c32e233953cd0e9851c64fbff15256..571507a542548e760209164d6dadaa6ad7a3aef3 100644
--- a/.codeclimate.yml
+++ b/.codeclimate.yml
@@ -30,8 +30,8 @@ plugins:
     channel: eslint-5
   rubocop:
     enabled: true
-    channel: rubocop-0-54
-  scss-lint:
+    channel: rubocop-0-71
+  sass-lint:
     enabled: true
 exclude_patterns:
 - spec/
diff --git a/.dependabot/config.yml b/.dependabot/config.yml
new file mode 100644
index 0000000000000000000000000000000000000000..07929aa07b97c0992f57b8aef63c0e84b9c673fe
--- /dev/null
+++ b/.dependabot/config.yml
@@ -0,0 +1,10 @@
+version: 1
+
+update_configs:
+  - package_manager: "ruby:bundler"
+    directory: "/"
+    update_schedule: "weekly"
+
+  - package_manager: "javascript"
+    directory: "/"
+    update_schedule: "weekly"
diff --git a/.env.production.sample b/.env.production.sample
index d1164efdc0cce0882d2ec0cf594c3e59921d065d..d66b0505095821de1beb2f4a2e9a6c05b3454121 100644
--- a/.env.production.sample
+++ b/.env.production.sample
@@ -10,6 +10,7 @@ DB_NAME=postgres
 DB_PASS=
 DB_PORT=5432
 # Optional ElasticSearch configuration
+# You may also set ES_PREFIX to share the same cluster between multiple Mastodon servers (falls back to REDIS_NAMESPACE if not set)
 # ES_ENABLED=true
 # ES_HOST=es
 # ES_PORT=9200
diff --git a/.eslintrc.js b/.eslintrc.js
index 56e3d0530f5918e63b5e00729d777401c603a2bb..177496d3a3d5931643064e996fe524a9c17067ff 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -41,6 +41,11 @@ module.exports = {
       'node_modules',
       '\\.(css|scss|json)$',
     ],
+    'import/resolver': {
+      node: {
+        paths: ['app/javascript'],
+      },
+    },
   },
 
   rules: {
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000000000000000000000000000000000000..91ee92a2e56f2dac973cc4cbb7680082edf939f8
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,2 @@
+patreon: mastodon
+open_collective: mastodon
diff --git a/.rubocop.yml b/.rubocop.yml
index 59e8a757ac12ae9a2df6489e85a96cf2cbbf6d85..8bd4c867f41c710243f0cb744ba538957b6320d8 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -1,3 +1,6 @@
+require:
+  - rubocop-rails
+
 AllCops:
   TargetRubyVersion: 2.3
   Exclude:
@@ -80,7 +83,10 @@ Rails/HttpStatus:
 Rails/Exit:
   Exclude:
     - 'lib/mastodon/*'
-    - 'lib/cli'
+    - 'lib/cli.rb'
+
+Rails/HelperInstanceVariable:
+  Enabled: false
 
 Style/ClassAndModuleChildren:
   Enabled: false
diff --git a/.ruby-version b/.ruby-version
index e70b4523ae7ffe8aa3cac8ecd1b093fba5a98737..6a6a3d8e35c7a98eaeb47d4212cc13d1d8938003 100644
--- a/.ruby-version
+++ b/.ruby-version
@@ -1 +1 @@
-2.6.0
+2.6.1
diff --git a/.sass-lint.yml b/.sass-lint.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a84adff3fba2f2852015acc6a2fe5176d4b6f0a5
--- /dev/null
+++ b/.sass-lint.yml
@@ -0,0 +1,37 @@
+# Linter Documentation:
+# https://github.com/sasstools/sass-lint/tree/v1.13.1/docs/options
+
+files:
+  include: app/javascript/styles/**/*.scss
+  ignore:
+    - app/javascript/styles/mastodon/reset.scss
+
+rules:
+  # Disallows
+  no-color-literals: 0
+  no-css-comments: 0
+  no-duplicate-properties: 0
+  no-ids: 0
+  no-important: 0
+  no-mergeable-selectors: 0
+  no-misspelled-properties: 0
+  no-qualifying-elements: 0
+  no-transition-all: 0
+  no-vendor-prefixes: 0
+
+  # Nesting
+  force-element-nesting: 0
+  force-attribute-nesting: 0
+  force-pseudo-nesting: 0
+
+  # Name Formats
+  class-name-format: 0
+  leading-zero: 0
+
+  # Style Guide
+  attribute-quotes: 0
+  hex-length: 0
+  indentation: 0
+  nesting-depth: 0
+  property-sort-order: 0
+  quotes: 0
diff --git a/.scss-lint.yml b/.scss-lint.yml
deleted file mode 100644
index 5d7cc4da51c65d7236950934edc58c12b3023461..0000000000000000000000000000000000000000
--- a/.scss-lint.yml
+++ /dev/null
@@ -1,264 +0,0 @@
-# Linter Documentation:
-# https://github.com/brigade/scss-lint/blob/v0.42.2/lib/scss_lint/linter/README.md
-
-scss_files: 'app/javascript/styles/**/*.scss'
-
-exclude:
-  - app/javascript/styles/reset.scss
-
-linters:
-  # Reports when you use improper spacing around ! (the "bang") in !default,
-  # !global, !important, and !optional flags.
-  BangFormat:
-    enabled: false
-
-  # Whether or not to prefer `border: 0` over `border: none`.
-  BorderZero:
-    enabled: false
-
-  # Reports when you define a rule set using a selector with chained classes
-  # (a.k.a. adjoining classes).
-  ChainedClasses:
-    enabled: false
-
-  # Prefer hexadecimal color codes over color keywords.
-  # (e.g. `color: green` is a color keyword)
-  ColorKeyword:
-    enabled: false
-
-  # Prefer color literals (keywords or hexadecimal codes) to be used only in
-  # variable declarations. They should be referred to via variables everywhere
-  # else.
-  ColorVariable:
-    enabled: true
-
-  # Which form of comments to prefer in CSS.
-  Comment:
-    enabled: false
-
-  # Reports @debug statements (which you probably left behind accidentally).
-  DebugStatement:
-    enabled: false
-
-  # Rule sets should be ordered as follows:
-  # - @extend declarations
-  # - @include declarations without inner @content
-  # - properties, @include declarations with inner @content
-  # - nested rule sets.
-  DeclarationOrder:
-    enabled: false
-
-  # `scss-lint:disable` control comments should be preceded by a comment
-  # explaining why these linters are being disabled for this file.
-  # See https://github.com/brigade/scss-lint#disabling-linters-via-source for
-  # more information.
-  DisableLinterReason:
-    enabled: true
-
-  # Reports when you define the same property twice in a single rule set.
-  DuplicateProperty:
-    enabled: false
-
-  # Separate rule, function, and mixin declarations with empty lines.
-  EmptyLineBetweenBlocks:
-    enabled: true
-
-  # Reports when you have an empty rule set.
-  EmptyRule:
-    enabled: true
-
-  # Reports when you have an @extend directive.
-  ExtendDirective:
-    enabled: false
-
-  # Files should always have a final newline. This results in better diffs
-  # when adding lines to the file, since SCM systems such as git won't
-  # think that you touched the last line.
-  FinalNewline:
-    enabled: false
-
-  # HEX colors should use three-character values where possible.
-  HexLength:
-    enabled: false
-
-  # HEX color values should use lower-case colors to differentiate between
-  # letters and numbers, e.g. `#E3E3E3` vs. `#e3e3e3`.
-  HexNotation:
-    enabled: true
-
-  # Avoid using ID selectors.
-  IdSelector:
-    enabled: false
-
-  # The basenames of @imported SCSS partials should not begin with an
-  # underscore and should not include the filename extension.
-  ImportPath:
-    enabled: false
-
-  # Avoid using !important in properties. It is usually indicative of a
-  # misunderstanding of CSS specificity and can lead to brittle code.
-  ImportantRule:
-    enabled: false
-
-  # Indentation should always be done in increments of 2 spaces.
-  Indentation:
-    enabled: true
-    width: 2
-
-  # Don't write leading zeros for numeric values with a decimal point.
-  LeadingZero:
-    enabled: false
-
-  # Reports when you define the same selector twice in a single sheet.
-  MergeableSelector:
-    enabled: false
-
-  # Functions, mixins, variables, and placeholders should be declared
-  # with all lowercase letters and hyphens instead of underscores.
-  NameFormat:
-    enabled: false
-
-  # Avoid nesting selectors too deeply.
-  NestingDepth:
-    enabled: false
-
-  # Always use placeholder selectors in @extend.
-  PlaceholderInExtend:
-    enabled: false
-
-  # Sort properties in a strict order.
-  PropertySortOrder:
-    enabled: false
-
-  # Reports when you use an unknown or disabled CSS property
-  # (ignoring vendor-prefixed properties).
-  PropertySpelling:
-    enabled: false
-
-  # Configure which units are allowed for property values.
-  PropertyUnits:
-    enabled: false
-
-  # Pseudo-elements, like ::before, and ::first-letter, should be declared
-  # with two colons. Pseudo-classes, like :hover and :first-child, should
-  # be declared with one colon.
-  PseudoElement:
-    enabled: true
-
-  # Avoid qualifying elements in selectors (also known as "tag-qualifying").
-  QualifyingElement:
-    enabled: false
-
-  # Don't write selectors with a depth of applicability greater than 3.
-  SelectorDepth:
-    enabled: false
-
-  # Selectors should always use hyphenated-lowercase, rather than camelCase or
-  # snake_case.
-  SelectorFormat:
-    enabled: false
-    convention: hyphenated_lowercase
-
-  # Prefer the shortest shorthand form possible for properties that support it.
-  Shorthand:
-    enabled: true
-
-  # Each property should have its own line, except in the special case of
-  # single line rulesets.
-  SingleLinePerProperty:
-    enabled: true
-    allow_single_line_rule_sets: true
-
-  # Split selectors onto separate lines after each comma, and have each
-  # individual selector occupy a single line.
-  SingleLinePerSelector:
-    enabled: true
-
-  # Commas in lists should be followed by a space.
-  SpaceAfterComma:
-    enabled: false
-
-  # Properties should be formatted with a single space separating the colon
-  # from the property's value.
-  SpaceAfterPropertyColon:
-    enabled: true
-
-  # Properties should be formatted with no space between the name and the
-  # colon.
-  SpaceAfterPropertyName:
-    enabled: true
-
-  # Variables should be formatted with a single space separating the colon
-  # from the variable's value.
-  SpaceAfterVariableColon:
-    enabled: true
-
-  # Variables should be formatted with no space between the name and the
-  # colon.
-  SpaceAfterVariableName:
-    enabled: false
-
-  # Operators should be formatted with a single space on both sides of an
-  # infix operator.
-  SpaceAroundOperator:
-    enabled: true
-
-  # Opening braces should be preceded by a single space.
-  SpaceBeforeBrace:
-    enabled: true
-
-  # Parentheses should not be padded with spaces.
-  SpaceBetweenParens:
-    enabled: false
-
-  # Enforces that string literals should be written with a consistent form
-  # of quotes (single or double).
-  StringQuotes:
-    enabled: false
-
-  # Property values, @extend, @include, and @import directives, and variable
-  # declarations should always end with a semicolon.
-  TrailingSemicolon:
-    enabled: true
-
-  # Reports lines containing trailing whitespace.
-  TrailingWhitespace:
-    enabled: true
-
-  # Don't write trailing zeros for numeric values with a decimal point.
-  TrailingZero:
-    enabled: false
-
-  # Don't use the `all` keyword to specify transition properties.
-  TransitionAll:
-    enabled: false
-
-  # Numeric values should not contain unnecessary fractional portions.
-  UnnecessaryMantissa:
-    enabled: false
-
-  # Do not use parent selector references (&) when they would otherwise
-  # be unnecessary.
-  UnnecessaryParentReference:
-    enabled: false
-
-  # URLs should be valid and not contain protocols or domain names.
-  UrlFormat:
-    enabled: true
-
-  # URLs should always be enclosed within quotes.
-  UrlQuotes:
-    enabled: true
-
-  # Properties, like color and font, are easier to read and maintain
-  # when defined using variables rather than literals.
-  VariableForProperty:
-    enabled: false
-
-  # Avoid vendor prefixes. Or rather: don't write them yourself.
-  VendorPrefix:
-    enabled: false
-
-  # Omit length units on zero values, e.g. `0px` vs. `0`.
-  ZeroUnit:
-    enabled: true
diff --git a/.yarnclean b/.yarnclean
index f2de52869c823b5ebe58acc9067eeca1c16dd916..0cc2b50d7be17dd5e19bf6f4d937765b7379c938 100644
--- a/.yarnclean
+++ b/.yarnclean
@@ -43,4 +43,4 @@ Gruntfile.js
 
 # for specific ignore
 !.svgo.yml
-
+!sass-lint/**/*.yml
diff --git a/AUTHORS.md b/AUTHORS.md
index 1bcf455b11f1b10e450c6b760aa901d72a3c9a74..8d3aaf480d5a25dddbe368e9f75b6c298bd97672 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -6,35 +6,35 @@ and provided thanks to the work of the following contributors:
 
 * [Gargron](https://github.com/Gargron)
 * [ykzts](https://github.com/ykzts)
-* [akihikodaki](https://github.com/akihikodaki)
 * [ThibG](https://github.com/ThibG)
+* [akihikodaki](https://github.com/akihikodaki)
 * [mjankowski](https://github.com/mjankowski)
+* [dependabot[bot]](https://github.com/apps/dependabot)
 * [unarist](https://github.com/unarist)
 * [m4sk1n](https://github.com/m4sk1n)
-* [dependabot[bot]](https://github.com/apps/dependabot)
 * [yiskah](https://github.com/yiskah)
 * [nolanlawson](https://github.com/nolanlawson)
-* [sorin-davidoi](https://github.com/sorin-davidoi)
 * [ysksn](https://github.com/ysksn)
+* [sorin-davidoi](https://github.com/sorin-davidoi)
 * [abcang](https://github.com/abcang)
 * [lynlynlynx](https://github.com/lynlynlynx)
-* [alpaca-tc](https://github.com/alpaca-tc)
 * [mayaeh](https://github.com/mayaeh)
 * [renatolond](https://github.com/renatolond)
+* [alpaca-tc](https://github.com/alpaca-tc)
 * [nclm](https://github.com/nclm)
 * [ineffyble](https://github.com/ineffyble)
 * [jeroenpraat](https://github.com/jeroenpraat)
 * [blackle](https://github.com/blackle)
 * [Quent-in](https://github.com/Quent-in)
 * [JantsoP](https://github.com/JantsoP)
+* [Kjwon15](https://github.com/Kjwon15)
 * [mabkenar](https://github.com/mabkenar)
 * [nullkal](https://github.com/nullkal)
 * [yookoala](https://github.com/yookoala)
-* [Kjwon15](https://github.com/Kjwon15)
 * [shuheiktgw](https://github.com/shuheiktgw)
 * [ashfurrow](https://github.com/ashfurrow)
-* [Quenty31](https://github.com/Quenty31)
 * [zunda](https://github.com/zunda)
+* [Quenty31](https://github.com/Quenty31)
 * [eramdam](https://github.com/eramdam)
 * [takayamaki](https://github.com/takayamaki)
 * [masarakki](https://github.com/masarakki)
@@ -45,30 +45,33 @@ and provided thanks to the work of the following contributors:
 * [stephenburgess8](https://github.com/stephenburgess8)
 * [Wonderfall](https://github.com/Wonderfall)
 * [matteoaquila](https://github.com/matteoaquila)
-* [rkarabut](https://github.com/rkarabut)
 * [yukimochi](https://github.com/yukimochi)
+* [rkarabut](https://github.com/rkarabut)
 * [Artoria2e5](https://github.com/Artoria2e5)
+* [nightpool](https://github.com/nightpool)
 * [marrus-sh](https://github.com/marrus-sh)
 * [krainboltgreene](https://github.com/krainboltgreene)
-* [patf](https://github.com/patf)
+* [pfigel](https://github.com/pfigel)
 * [Aldarone](https://github.com/Aldarone)
 * [BoFFire](https://github.com/BoFFire)
 * [clworld](https://github.com/clworld)
 * [dracos](https://github.com/dracos)
 * [SerCom_KC](mailto:sercom-kc@users.noreply.github.com)
 * [Sylvhem](https://github.com/Sylvhem)
-* [nightpool](https://github.com/nightpool)
 * [MasterGroosha](https://github.com/MasterGroosha)
 * [JeanGauthier](https://github.com/JeanGauthier)
 * [kschaper](https://github.com/kschaper)
 * [MaciekBaron](https://github.com/MaciekBaron)
 * [MitarashiDango](mailto:mitarashidango@users.noreply.github.com)
 * [beatrix-bitrot](https://github.com/beatrix-bitrot)
+* [Aditoo17](https://github.com/Aditoo17)
 * [adbelle](https://github.com/adbelle)
 * [evanminto](https://github.com/evanminto)
 * [MightyPork](https://github.com/MightyPork)
 * [yhirano55](https://github.com/yhirano55)
+* [rinsuki](https://github.com/rinsuki)
 * [camponez](https://github.com/camponez)
+* [hinaloe](https://github.com/hinaloe)
 * [SerCom-KC](https://github.com/SerCom-KC)
 * [aschmitz](https://github.com/aschmitz)
 * [devkral](https://github.com/devkral)
@@ -77,6 +80,7 @@ and provided thanks to the work of the following contributors:
 * [johnsudaar](https://github.com/johnsudaar)
 * [trebmuh](https://github.com/trebmuh)
 * [Rakib Hasan](mailto:rmhasan@gmail.com)
+* [ashleyhull-versent](https://github.com/ashleyhull-versent)
 * [lindwurm](https://github.com/lindwurm)
 * [victorhck](mailto:victorhck@geeko.site)
 * [voidsatisfaction](https://github.com/voidsatisfaction)
@@ -92,20 +96,21 @@ and provided thanks to the work of the following contributors:
 * [dunn](https://github.com/dunn)
 * [xqus](https://github.com/xqus)
 * [hugogameiro](https://github.com/hugogameiro)
+* [ariasuni](https://github.com/ariasuni)
 * [pfm-eyesightjp](https://github.com/pfm-eyesightjp)
 * [fakenine](https://github.com/fakenine)
 * [tsuwatch](https://github.com/tsuwatch)
 * [victorhck](https://github.com/victorhck)
-* [ashleyhull-versent](https://github.com/ashleyhull-versent)
 * [kedamaDQ](https://github.com/kedamaDQ)
 * [puckipedia](https://github.com/puckipedia)
+* [trwnh](https://github.com/trwnh)
 * [fvh-P](https://github.com/fvh-P)
-* [contraexemplo](https://github.com/contraexemplo)
+* [Anna e só](mailto:contraexemplos@gmail.com)
+* [BenLubar](https://github.com/BenLubar)
 * [kazu9su](https://github.com/kazu9su)
 * [Komic](https://github.com/Komic)
 * [lmorchard](https://github.com/lmorchard)
 * [diomed](https://github.com/diomed)
-* [ariasuni](https://github.com/ariasuni)
 * [Neetshin](mailto:neetshin@neetsh.in)
 * [rainyday](https://github.com/rainyday)
 * [ProgVal](https://github.com/ProgVal)
@@ -114,7 +119,7 @@ and provided thanks to the work of the following contributors:
 * [goofy-bz](mailto:goofy@babelzilla.org)
 * [kadiix](https://github.com/kadiix)
 * [kodacs](https://github.com/kodacs)
-* [rtucker](https://github.com/rtucker)
+* [JMendyk](https://github.com/JMendyk)
 * [KScl](https://github.com/KScl)
 * [sterdev](https://github.com/sterdev)
 * [TheKinrar](https://github.com/TheKinrar)
@@ -125,16 +130,17 @@ and provided thanks to the work of the following contributors:
 * [fhemberger](https://github.com/fhemberger)
 * [greysteil](https://github.com/greysteil)
 * [hensmith](https://github.com/hensmith)
-* [hinaloe](https://github.com/hinaloe)
 * [d6rkaiz](https://github.com/d6rkaiz)
 * [Reverite](https://github.com/Reverite)
-* [JMendyk](https://github.com/JMendyk)
 * [JohnD28](https://github.com/JohnD28)
 * [znz](https://github.com/znz)
+* [marek-lach](https://github.com/marek-lach)
 * [Naouak](https://github.com/Naouak)
 * [pawelngei](https://github.com/pawelngei)
+* [rtucker](https://github.com/rtucker)
 * [reneklacan](https://github.com/reneklacan)
 * [ekiru](https://github.com/ekiru)
+* [noellabo](https://github.com/noellabo)
 * [tcitworld](https://github.com/tcitworld)
 * [geta6](https://github.com/geta6)
 * [happycoloredbanana](https://github.com/happycoloredbanana)
@@ -144,9 +150,8 @@ and provided thanks to the work of the following contributors:
 * [noraworld](https://github.com/noraworld)
 * [theboss](https://github.com/theboss)
 * [178inaba](https://github.com/178inaba)
-* [Aditoo17](https://github.com/Aditoo17)
 * [alyssais](https://github.com/alyssais)
-* [kodnaplakal](https://github.com/kodnaplakal)
+* [hiphref](https://github.com/hiphref)
 * [stalker314314](https://github.com/stalker314314)
 * [huertanix](https://github.com/huertanix)
 * [genesixx](https://github.com/genesixx)
@@ -162,11 +167,11 @@ and provided thanks to the work of the following contributors:
 * [pierreozoux](https://github.com/pierreozoux)
 * [qguv](https://github.com/qguv)
 * [Ram Lmn](mailto:ramlmn@users.noreply.github.com)
+* [sascha-sl](https://github.com/sascha-sl)
 * [harukasan](https://github.com/harukasan)
 * [stamak](https://github.com/stamak)
-* [noellabo](https://github.com/noellabo)
 * [Technowix](mailto:technowix@users.noreply.github.com)
-* [Eychics](https://github.com/Eychics)
+* [Zoeille](https://github.com/Zoeille)
 * [Thor Harald Johansen](mailto:thj@thj.no)
 * [0x70b1a5](https://github.com/0x70b1a5)
 * [gled-rs](https://github.com/gled-rs)
@@ -179,21 +184,20 @@ and provided thanks to the work of the following contributors:
 * [hoodie](mailto:hoodiekitten@outlook.com)
 * [luzi82](https://github.com/luzi82)
 * [duxovni](https://github.com/duxovni)
-* [trwnh](https://github.com/trwnh)
+* [tmm576](https://github.com/tmm576)
 * [unsmell](https://github.com/unsmell)
 * [valerauko](https://github.com/valerauko)
 * [chriswmartin](https://github.com/chriswmartin)
 * [vahnj](https://github.com/vahnj)
 * [ikuradon](https://github.com/ikuradon)
 * [AndreLewin](https://github.com/AndreLewin)
-* [rinsuki](https://github.com/rinsuki)
 * [0xflotus](https://github.com/0xflotus)
 * [redtachyons](https://github.com/redtachyons)
 * [thurloat](https://github.com/thurloat)
 * [aaribaud](https://github.com/aaribaud)
+* [pointlessone](https://github.com/pointlessone)
 * [Andrew](mailto:andrewlchronister@gmail.com)
 * [estuans](https://github.com/estuans)
-* [BenLubar](https://github.com/BenLubar)
 * [dissolve](https://github.com/dissolve)
 * [PurpleBooth](https://github.com/PurpleBooth)
 * [bradurani](https://github.com/bradurani)
@@ -216,6 +220,7 @@ and provided thanks to the work of the following contributors:
 * [ErikXXon](https://github.com/ErikXXon)
 * [ian-kelling](https://github.com/ian-kelling)
 * [immae](https://github.com/immae)
+* [J0WI](https://github.com/J0WI)
 * [foozmeat](https://github.com/foozmeat)
 * [jasonrhodes](https://github.com/jasonrhodes)
 * [Jason Snell](mailto:jason@newrelic.com)
@@ -230,6 +235,7 @@ and provided thanks to the work of the following contributors:
 * [Lorenz Diener](mailto:halcyon@icosahedron.website)
 * [alimony](https://github.com/alimony)
 * [mig5](https://github.com/mig5)
+* [moritzheiber](https://github.com/moritzheiber)
 * [ndarville](https://github.com/ndarville)
 * [Abzol](https://github.com/Abzol)
 * [pwoolcoc](https://github.com/pwoolcoc)
@@ -238,9 +244,10 @@ and provided thanks to the work of the following contributors:
 * [ignisf](https://github.com/ignisf)
 * [raymestalez](https://github.com/raymestalez)
 * [remram44](https://github.com/remram44)
-* [sascha-sl](https://github.com/sascha-sl)
+* [sts10](https://github.com/sts10)
 * [u1-liquid](https://github.com/u1-liquid)
 * [sim6](https://github.com/sim6)
+* [Sir-Boops](https://github.com/Sir-Boops)
 * [stemid](https://github.com/stemid)
 * [sumdog](https://github.com/sumdog)
 * [ThomasLeister](https://github.com/ThomasLeister)
@@ -288,6 +295,7 @@ and provided thanks to the work of the following contributors:
 * [857b](https://github.com/857b)
 * [insom](https://github.com/insom)
 * [tachyons](https://github.com/tachyons)
+* [acid-chicken](https://github.com/acid-chicken)
 * [Esteth](https://github.com/Esteth)
 * [unascribed](https://github.com/unascribed)
 * [Aguay-val](https://github.com/Aguay-val)
@@ -297,7 +305,6 @@ and provided thanks to the work of the following contributors:
 * [unleashed](https://github.com/unleashed)
 * [alxrcs](https://github.com/alxrcs)
 * [console-cowboy](https://github.com/console-cowboy)
-* [pointlessone](https://github.com/pointlessone)
 * [Alkarex](https://github.com/Alkarex)
 * [a2](https://github.com/a2)
 * [0xa](https://github.com/0xa)
@@ -310,8 +317,11 @@ and provided thanks to the work of the following contributors:
 * [Andreas Drop](mailto:andy@remline.de)
 * [andi1984](https://github.com/andi1984)
 * [schas002](https://github.com/schas002)
+* [contraexemplo](https://github.com/contraexemplo)
 * [abackstrom](https://github.com/abackstrom)
+* [armandfardeau](https://github.com/armandfardeau)
 * [jumbosushi](https://github.com/jumbosushi)
+* [aurelien-reeves](https://github.com/aurelien-reeves)
 * [ayumin](https://github.com/ayumin)
 * [BaptisteGelez](https://github.com/BaptisteGelez)
 * [bzg](https://github.com/bzg)
@@ -329,6 +339,7 @@ and provided thanks to the work of the following contributors:
 * [Motoma](https://github.com/Motoma)
 * [chriswk](https://github.com/chriswk)
 * [csu](https://github.com/csu)
+* [clarfon](https://github.com/clarfon)
 * [kklleemm](https://github.com/kklleemm)
 * [colindean](https://github.com/colindean)
 * [dachinat](https://github.com/dachinat)
@@ -351,11 +362,13 @@ and provided thanks to the work of the following contributors:
 * [eai04191](https://github.com/eai04191)
 * [d3vgru](https://github.com/d3vgru)
 * [Elizafox](https://github.com/Elizafox)
+* [enewhuis](https://github.com/enewhuis)
 * [ericblade](https://github.com/ericblade)
 * [mikoim](https://github.com/mikoim)
 * [espenronnevik](https://github.com/espenronnevik)
 * [Finariel](https://github.com/Finariel)
 * [siuying](https://github.com/siuying)
+* [zoc](https://github.com/zoc)
 * [fwenzel](https://github.com/fwenzel)
 * [GenbuHase](https://github.com/GenbuHase)
 * [hattori6789](https://github.com/hattori6789)
@@ -416,6 +429,7 @@ and provided thanks to the work of the following contributors:
 * [martymcguire](https://github.com/martymcguire)
 * [marvinkopf](https://github.com/marvinkopf)
 * [otsune](https://github.com/otsune)
+* [mbugowski](https://github.com/mbugowski)
 * [Mathias B](mailto:10813340+mathias-b@users.noreply.github.com)
 * [matt-auckland](https://github.com/matt-auckland)
 * [webroo](https://github.com/webroo)
@@ -434,10 +448,10 @@ and provided thanks to the work of the following contributors:
 * [premist](https://github.com/premist)
 * [Mnkai](https://github.com/Mnkai)
 * [mitchhentges](https://github.com/mitchhentges)
-* [moritzheiber](https://github.com/moritzheiber)
 * [mouse-reeve](https://github.com/mouse-reeve)
 * [Mozinet-fr](https://github.com/Mozinet-fr)
 * [lae](https://github.com/lae)
+* [nosada](https://github.com/nosada)
 * [Nanamachi](https://github.com/Nanamachi)
 * [orinthe](https://github.com/orinthe)
 * [NecroTechno](https://github.com/NecroTechno)
@@ -454,21 +468,22 @@ and provided thanks to the work of the following contributors:
 * [noppa](https://github.com/noppa)
 * [Otakan951](https://github.com/Otakan951)
 * [fahy](https://github.com/fahy)
-* [PatrickRWells](https://github.com/PatrickRWells)
-* [Pangoraw](https://github.com/Pangoraw)
-* [peterkeen](https://github.com/peterkeen)
-* [pgate](https://github.com/pgate)
-* [retokromer](https://github.com/retokromer)
-* [rfwatson](https://github.com/rfwatson)
-* [rfreebern](https://github.com/rfreebern)
+* [PatrickRWells](mailto:32802366+patrickrwells@users.noreply.github.com)
+* [Paul](mailto:naydex.mc+github@gmail.com)
+* [Pete Keen](mailto:pete@petekeen.net)
+* [Pierre-Morgan Gate](mailto:pgate@users.noreply.github.com)
+* [Ratmir Karabut](mailto:rkarabut@sfmodern.ru)
+* [Reto Kromer](mailto:retokromer@users.noreply.github.com)
+* [Rey Tucker](mailto:git@reytucker.us)
+* [Rob Watson](mailto:rfwatson@users.noreply.github.com)
+* [Ryan Freebern](mailto:ryan@freebern.org)
 * [Ryan Wade](mailto:ryan.wade@protonmail.com)
-* [sylph01](https://github.com/sylph01)
-* [S-H-GAMELINKS](https://github.com/S-H-GAMELINKS)
-* [staticsafe](https://github.com/staticsafe)
-* [snwh](https://github.com/snwh)
-* [sts10](https://github.com/sts10)
-* [skoji](https://github.com/skoji)
-* [ScienJus](https://github.com/ScienJus)
+* [Ryo Kajiwara](mailto:kfe-fecn6.prussian@s01.info)
+* [S.H](mailto:gamelinks007@gmail.com)
+* [Sadiq Saif](mailto:staticsafe@users.noreply.github.com)
+* [Sam Hewitt](mailto:hewittsamuel@gmail.com)
+* [Satoshi KOJIMA](mailto:skoji@mac.com)
+* [ScienJus](mailto:i@scienjus.com)
 * [Scott Larkin](mailto:scott@codeclimate.com)
 * [Sebastian Hübner](mailto:imolein@users.noreply.github.com)
 * [Sebastian Morr](mailto:sebastian@morr.cc)
@@ -480,9 +495,9 @@ and provided thanks to the work of the following contributors:
 * [Sho Kusano](mailto:rosylilly@aduca.org)
 * [Shouko Yu](mailto:imshouko@gmail.com)
 * [Sina Mashek](mailto:sina@mashek.xyz)
-* [Sir-Boops](mailto:admin@boops.me)
 * [Soshi Kato](mailto:mail@sossii.com)
 * [Spanky](mailto:2788886+spankyworks@users.noreply.github.com)
+* [Stanislas](mailto:angristan@pm.me)
 * [StefOfficiel](mailto:pichard.stephane@free.fr)
 * [Steven Tappert](mailto:admin@dark-it.net)
 * [Svetlozar Todorov](mailto:svetlik@users.noreply.github.com)
@@ -532,6 +547,7 @@ and provided thanks to the work of the following contributors:
 * [fsubal](mailto:fsubal@users.noreply.github.com)
 * [fusshi-](mailto:dikky1218@users.noreply.github.com)
 * [gentaro](mailto:gentaroooo@gmail.com)
+* [gol-cha](mailto:info@mevo.xyz)
 * [hakoai](mailto:hk--76@qa2.so-net.ne.jp)
 * [haosbvnker](mailto:github@chaosbunker.com)
 * [isati](mailto:phil@juchnowi.cz)
@@ -545,16 +561,18 @@ and provided thanks to the work of the following contributors:
 * [karlyeurl](mailto:karl.yeurl@gmail.com)
 * [kedama](mailto:32974885+kedamadq@users.noreply.github.com)
 * [kodai](mailto:shirafuta.kodai@gmail.com)
+* [koyu](mailto:me@koyu.space)
 * [kuro5hin](mailto:rusty@kuro5hin.org)
 * [luzpaz](mailto:luzpaz@users.noreply.github.com)
 * [maxypy](mailto:maxime@mpigou.fr)
 * [mhe](mailto:mail@marcus-herrmann.com)
+* [mike castleman](mailto:m@mlcastle.net)
 * [mimikun](mailto:dzdzble_effort_311@outlook.jp)
+* [mohemohe](mailto:mohemohe@users.noreply.github.com)
 * [mshrtkch](mailto:mshrtkch@users.noreply.github.com)
 * [muan](mailto:muan@github.com)
 * [namelessGonbai](mailto:43787036+namelessgonbai@users.noreply.github.com)
 * [neetshin](mailto:neetshin@neetsh.in)
-* [nightpool](mailto:nightpool@users.noreply.github.com)
 * [rch850](mailto:rich850@gmail.com)
 * [roikale](mailto:roikale@users.noreply.github.com)
 * [rysiekpl](mailto:rysiek@hackerspace.pl)
@@ -589,243 +607,338 @@ This document is provided for informational purposes only. Since it is only upda
 
 Following people have contributed to translation of Mastodon:
 
+- **Albanian**
+  - Besnik Bleta
+  - Aditoo
 - **Arabic**
   - ButterflyOfFire
+  - Aditoo
+  - Amrz0
 - **Asturian**
   - ButterflyOfFire
   - Enol P.
+  - Aditoo
 - **Basque**
+  - Osoitz
+  - Aditoo
   - Aitzol
   - ButterflyOfFire
-  - Gorka Azkarate
-  - Osoitz
   - Peru Iparragirre
+  - Gorka Azkarate
+- **Bengali**
+  - dxwc
 - **Bulgarian**
   - ButterflyOfFire
+  - Aditoo
 - **Catalan**
+  - spla
+  - Aditoo
   - ButterflyOfFire
   - Joan Montané
   - Jose Luis
-  - spla
 - **Chinese (Hong Kong)**
   - ButterflyOfFire
   - Luzi Leung
+  - Aditoo
 - **Chinese (Simplified)**
   - Allen Zhong
   - ButterflyOfFire
   - SerCom_KC
+  - martialarts
+  - Kaitian Xie
+  - Aditoo
+  - pan93412
 - **Chinese (Traditional)**
+  - Aditoo
   - ButterflyOfFire
   - James58899
-  - Jeff Huang
+  - pan93412
   - S1ttidoe477
   - SHA265
+  - Jeff Huang
 - **Corsican**
   - Alix D. R.
+  - Aditoo
   - ButterflyOfFire
 - **Croatian**
   - ButterflyOfFire
+  - Aditoo
 - **Czech**
-  - ButterflyOfFire
-  - Lorem Ipsum
+  - Aditoo
   - Marek Ľach
-- **Danish**
   - ButterflyOfFire
+- **Danish**
+  - Einhjeriar
   - Rasmus Sæderup
+  - Aditoo
+  - ButterflyOfFire
 - **Dutch**
+  - Albakham
   - ButterflyOfFire
-  - Jelv
   - jeroenpraat
   - rscmbbng
+  - Aditoo
+  - Jelv
 - **English**
   - ButterflyOfFire
   - Renato "Lond" Cerqueira
+- **English (United Kingdom)**
+  - Albakham
 - **Esperanto**
+  - Aditoo
   - ButterflyOfFire
+  - Becci Cat
   - Jeong Arm
-  - Martin Bodin
   - Mélanie Chauvel
   - Vanege
+  - Martin Bodin
   - tuxayo/Victor Grousset
 - **Finnish**
   - ButterflyOfFire
-  - Jonne Arjoranta
-  - S Heija
+  - Mikko Poussu
   - Taru Luojola
+  - S Heija
+  - Aditoo
+  - Jonne Arjoranta
 - **French**
-  - Alda Marteau-Hardi
+  - Albakham
   - Alix D. R.
-  - Baptiste Jonglez
   - ButterflyOfFire
-  - Franck Paul
-  - Jean-Baptiste Holcroft
-  - Jonathan Chan
-  - Letiteuf55
-  - Martin Bodin
+  - codl
+  - Leia
+  - Alda Marteau-Hardi
   - Mélanie Chauvel
-  - Olivier Humbert
   - Paul Marques Mota
-  - Sylvhem
+  - azenet
+  - Olivier Humbert
+  - Aditoo
+  - Jonathan Chan
+  - Letiteuf55
+  - Baptiste Jonglez
+  - goofy-mdn
+  - Jean-Baptiste Holcroft
   - Technowix
-  - Thibaut Girka
+  - Martin Bodin
   - Théodore
-  - azenet
-  - codl
+  - Thibaut Girka
+  - Franck Paul
+  - Sylvhem
 - **Galician**
   - ButterflyOfFire
   - Xose M.
+  - Aditoo
   - manequim
 - **Georgian**
   - ButterflyOfFire
+  - Aditoo
 - **German**
-  - Benedikt Geißler
+  - Aditoo
   - ButterflyOfFire
   - Daniel
-  - Eugen Rochko
-  - Koyu Berteon
-  - Patrick Figel
-  - Weblate Admin
   - averageunicorn
-  - ePirat
-  - koyu
+  - Koyu Berteon
   - larsreineke
+  - koyu
+  - Austin Jones
   - lilo
+  - Benedikt Geißler
+  - ePirat
+  - Eugen Rochko
+  - Weblate Admin
+  - Patrick Figel
 - **Greek**
+  - Dimitris Maroulidis
   - Antonis
+  - Aditoo
   - ButterflyOfFire
-  - Dimitris Maroulidis
   - Konstantinos Grevenitis
 - **Hebrew**
   - ButterflyOfFire
+  - Aditoo
   - Ira
   - Yaron Shahrabani
 - **Hungarian**
-  - Adam Paszternak
   - ButterflyOfFire
+  - Adam Paszternak
+  - Aditoo
   - Tibike Miklós
 - **Ido**
   - ButterflyOfFire
+  - Aditoo
 - **Indonesian**
-  - Alfiana Sibuea
+  - afachri
   - ButterflyOfFire
   - Dito Kurnia Pratama
   - Eirworks
-  - afachri
+  - Aditoo
+  - Alfiana Sibuea
   - se7entime
+- **Irish**
+  - Albakham
+  - Kevin Houlihan
 - **Italian**
   - Alessandro Levati
+  - Albakham
   - ButterflyOfFire
+  - Marcin Mikołajczak
+  - Aditoo
   - Giuseppe Pignataro
   - Stefano
 - **Japanese**
-  - ButterflyOfFire
-  - Kumasun Morino
-  - Yamagishi Kazutoshi
+  - Hinaloe
+  - 小鳥遊まりあ
   - mayaeh
   - osapon
-  - unarist
-  - 小鳥遊まりあ
   - 森の子リスのミーコの大冒険
-- **Korean**
+  - Kumasun Morino
+  - Yamagishi Kazutoshi
+  - Aditoo
   - ButterflyOfFire
   - Jeong Arm
+  - unarist
+- **Kazakh**
+  - arshat
+  - Aditoo
+- **Korean**
+  - Aditoo
+  - Jeong Arm
+  - ButterflyOfFire
   - Minori Hiraoka
   - Yamagishi Kazutoshi
+- **Lithuanian**
+  - Sarunas Medeikis
 - **Malay**
-  - ButterflyOfFire
   - Muhammad Nur Hidayat (MNH48)
+  - Aditoo
+  - ButterflyOfFire
 - **Norwegian (old code)**
   - ButterflyOfFire
   - Espen Rønnevik
+  - Aditoo
   - Tale
 - **Occitan**
+  - Aditoo
   - ButterflyOfFire
-  - Maxenç
   - Quenti2
   - Quentí
+  - Maxenç
 - **Persian**
-  - ButterflyOfFire
   - Masoud Abkenar
+  - Aditoo
+  - ButterflyOfFire
 - **Polish**
+  - Aditoo
+  - Albakham
   - ButterflyOfFire
-  - Jakub Mendyk
+  - Stasiek Michalski
   - Marcin Mikołajczak
+  - Jakub Mendyk
   - Marek Ľach
-  - Stasiek Michalski
   - krkk
 - **Portuguese**
+  - Albakham
+  - João Pinheiro
+  - manequim
+  - Aditoo
   - ButterflyOfFire
   - Hugo Gameiro
-  - manequim
 - **Portuguese (Brazil)**
-  - André Andrade
+  - Aditoo
+  - Albakham
   - Anna e só
-  - ButterflyOfFire
   - Renato "Lond" Cerqueira
-- **Romanian**
+  - André Andrade
   - ButterflyOfFire
+- **Romanian**
   - adrianbblk
+  - ButterflyOfFire
+  - Aditoo
 - **Russian**
-  - Andrew Zyabin
+  - Albakham
   - ButterflyOfFire
   - Evgeny Petrov
+  - Aditoo
+  - Павел Гастелло
+  - Andrew Zyabin
   - Yaron Shahrabani
 - **Serbian**
   - Branko Kokanovic
   - Burekz Finezt
+  - Aditoo
   - ButterflyOfFire
 - **Serbian (latin)**
   - ButterflyOfFire
+  - Aditoo
 - **Slovak**
+  - Aditoo
   - ButterflyOfFire
   - Ivan Pleva
-  - Lorem Ipsum
   - Marek Ľach
   - Peter
 - **Slovenian**
-  - ButterflyOfFire
   - Kristijan Tkalec
+  - Aditoo
+  - ButterflyOfFire
 - **Spanish**
-  - Angeles Broullón
-  - Antón López
+  - Albakham
   - ButterflyOfFire
   - Carlos Mondragon
+  - Antón López
+  - Max Winkler
+  - Pablo de la Concepción Sanz
+  - Sergio Soriano
+  - Angeles Broullón
+  - Lothar Wolf
+  - Aditoo
   - David Charte
   - Emmanuel
-  - Lothar Wolf
-  - Pablo de la Concepción Sanz
 - **Swedish**
   - ButterflyOfFire
-  - Elias MÃ¥rtenson
   - Isak Holmström
   - Shellkr
+  - Aditoo
+  - Elias MÃ¥rtenson
   - Stefan Midjich
   - Tim Stahel
+  - Jonas Hultén
 - **Telugu**
+  - avndp
+  - Ranjith Tellakula
+  - Aditoo
   - ButterflyOfFire
   - Joseph Nuthalapati
-  - Ranjith Tellakula
-  - avndp
 - **Thai**
   - ButterflyOfFire
+  - parnikkapore
+  - Thai Localization
+  - Aditoo
 - **Turkish**
+  - Ali Demirtas
   - ButterflyOfFire
+  - Aditoo
 - **Ukrainian**
+  - alexcleac
   - ButterflyOfFire
+  - Aditoo
   - Ivan Verchenko
-  - alexcleac
 - **Welsh**
-  - ButterflyOfFire
+  - carl morris
   - Jaz-Michael King
-  - Kevin Beynon
   - Owain Rhys Lewis
-  - Renato "Lond" Cerqueira
   - Rhoslyn Prys
-  - carl morris
+  - Aditoo
+  - ButterflyOfFire
+  - Renato "Lond" Cerqueira
+  - Albakham
+  - Kevin Beynon
 - **Armenian**
+  - Aditoo
   - ButterflyOfFire
 - **Latvian**
+  - Aditoo
   - ButterflyOfFire
+  - Maigonis
 - **Tamil**
+  - Aditoo
   - ButterflyOfFire
   - Prasanna Venkadesh
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3bafbe1e9e11142715c94bd34cf1f9a4fcbca675..a17fbf8f06385677eb05801b422998bb6613b9ea 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,411 @@ Changelog
 
 All notable changes to this project will be documented in this file.
 
+## [2.9.3] - 2019-08-10
+### Added
+
+- Add GIF and WebP support for custom emojis ([Gargron](https://github.com/tootsuite/mastodon/pull/11519))
+- Add logout link to dropdown menu in web UI ([koyuawsmbrtn](https://github.com/tootsuite/mastodon/pull/11353))
+- Add indication that text search is unavailable in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11112), [ThibG](https://github.com/tootsuite/mastodon/pull/11202))
+- Add `suffix` to `Mastodon::Version` to help forks ([clarfon](https://github.com/tootsuite/mastodon/pull/11407))
+- Add on-hover animation to animated custom emoji in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11348), [ThibG](https://github.com/tootsuite/mastodon/pull/11404), [ThibG](https://github.com/tootsuite/mastodon/pull/11522))
+- Add custom emoji support in profile metadata labels ([ThibG](https://github.com/tootsuite/mastodon/pull/11350))
+
+### Changed
+
+- Change default interface of web and streaming from 0.0.0.0 to 127.0.0.1 ([Gargron](https://github.com/tootsuite/mastodon/pull/11302), [zunda](https://github.com/tootsuite/mastodon/pull/11378), [Gargron](https://github.com/tootsuite/mastodon/pull/11351), [zunda](https://github.com/tootsuite/mastodon/pull/11326))
+- Change the retry limit of web push notifications ([highemerly](https://github.com/tootsuite/mastodon/pull/11292))
+- Change ActivityPub deliveries to not retry HTTP 501 errors ([Gargron](https://github.com/tootsuite/mastodon/pull/11233))
+- Change language detection to include hashtags as words ([Gargron](https://github.com/tootsuite/mastodon/pull/11341))
+- Change terms and privacy policy pages to always be accessible ([Gargron](https://github.com/tootsuite/mastodon/pull/11334))
+- Change robots tag to include `noarchive` when user opts out of indexing ([Kjwon15](https://github.com/tootsuite/mastodon/pull/11421))
+
+### Fixed
+
+- Fix account domain block not clearing out notifications ([Gargron](https://github.com/tootsuite/mastodon/pull/11393))
+- Fix incorrect locale sometimes being detected for browser ([Gargron](https://github.com/tootsuite/mastodon/pull/8657))
+- Fix crash when saving invalid domain name ([Gargron](https://github.com/tootsuite/mastodon/pull/11528))
+- Fix pinned statuses REST API returning pagination headers ([Gargron](https://github.com/tootsuite/mastodon/pull/11526))
+- Fix "cancel follow request" button having unreadable text in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/11521))
+- Fix image uploads being blank when canvas read access is blocked ([ThibG](https://github.com/tootsuite/mastodon/pull/11499))
+- Fix avatars not being animated on hover when not logged in ([ThibG](https://github.com/tootsuite/mastodon/pull/11349))
+- Fix overzealous sanitization of HTML lists ([ThibG](https://github.com/tootsuite/mastodon/pull/11354))
+- Fix block crashing when a follow request exists ([ThibG](https://github.com/tootsuite/mastodon/pull/11288))
+- Fix backup service crashing when an attachment is missing ([ThibG](https://github.com/tootsuite/mastodon/pull/11241))
+- Fix account moderation action always sending e-mail notification ([Gargron](https://github.com/tootsuite/mastodon/pull/11242))
+- Fix swiping columns on mobile sometimes failing in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11200))
+- Fix wrong actor URI being serialized into poll updates ([ThibG](https://github.com/tootsuite/mastodon/pull/11194))
+- Fix statsd UDP sockets not being cleaned up in Sidekiq ([Gargron](https://github.com/tootsuite/mastodon/pull/11230))
+- Fix expiration date of filters being set to "never" when editing them ([ThibG](https://github.com/tootsuite/mastodon/pull/11204))
+- Fix support for MP4 files that are actually M4V files ([Gargron](https://github.com/tootsuite/mastodon/pull/11210))
+- Fix `alerts` not being typecast correctly in push subscription in REST API ([Gargron](https://github.com/tootsuite/mastodon/pull/11343))
+- Fix some notices staying on unrelated pages ([ThibG](https://github.com/tootsuite/mastodon/pull/11364))
+- Fix unboosting sometimes preventing a boost from reappearing on feed ([ThibG](https://github.com/tootsuite/mastodon/pull/11405), [Gargron](https://github.com/tootsuite/mastodon/pull/11450))
+- Fix only one middle dot being recognized in hashtags ([Gargron](https://github.com/tootsuite/mastodon/pull/11345), [ThibG](https://github.com/tootsuite/mastodon/pull/11363))
+- Fix unnecessary SQL query performed on unauthenticated requests ([Gargron](https://github.com/tootsuite/mastodon/pull/11179))
+- Fix incorrect timestamp displayed on featured tags ([Kjwon15](https://github.com/tootsuite/mastodon/pull/11477))
+- Fix privacy dropdown active state when dropdown is placed on top of it ([ThibG](https://github.com/tootsuite/mastodon/pull/11495))
+- Fix filters not being applied to poll options ([ThibG](https://github.com/tootsuite/mastodon/pull/11174))
+- Fix keyboard navigation on various dropdowns ([ThibG](https://github.com/tootsuite/mastodon/pull/11511), [ThibG](https://github.com/tootsuite/mastodon/pull/11492), [ThibG](https://github.com/tootsuite/mastodon/pull/11491))
+- Fix keyboard navigation in modals ([ThibG](https://github.com/tootsuite/mastodon/pull/11493))
+- Fix image conversation being non-deterministic due to timestamps ([Gargron](https://github.com/tootsuite/mastodon/pull/11408))
+- Fix web UI performance ([ThibG](https://github.com/tootsuite/mastodon/pull/11211), [ThibG](https://github.com/tootsuite/mastodon/pull/11234))
+- Fix scrolling to compose form when not necessary in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11246), [ThibG](https://github.com/tootsuite/mastodon/pull/11182))
+- Fix save button being enabled when list title is empty in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11475))
+- Fix poll expiration not being pre-filled on delete & redraft in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11203))
+- Fix content warning sometimes being set when not requested in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11206))
+
+### Security
+
+- Fix invites not being disabled upon account suspension ([ThibG](https://github.com/tootsuite/mastodon/pull/11412))
+- Fix blocked domains still being able to fill database with account records ([Gargron](https://github.com/tootsuite/mastodon/pull/11219))
+
+## [2.9.2] - 2019-06-22
+### Added
+
+- Add `short_description` and `approval_required` to `GET /api/v1/instance` ([Gargron](https://github.com/tootsuite/mastodon/pull/11146))
+
+### Changed
+
+- Change camera icon to paperclip icon in upload form ([koyuawsmbrtn](https://github.com/tootsuite/mastodon/pull/11149))
+
+### Fixed
+
+- Fix audio-only OGG and WebM files not being processed as such ([Gargron](https://github.com/tootsuite/mastodon/pull/11151))
+- Fix audio not being downloaded from remote servers ([Gargron](https://github.com/tootsuite/mastodon/pull/11145))
+
+## [2.9.1] - 2019-06-22
+### Added
+
+- Add moderation API ([Gargron](https://github.com/tootsuite/mastodon/pull/9387))
+- Add audio uploads ([Gargron](https://github.com/tootsuite/mastodon/pull/11123), [Gargron](https://github.com/tootsuite/mastodon/pull/11141))
+
+### Changed
+
+- Change domain blocks to automatically support subdomains ([Gargron](https://github.com/tootsuite/mastodon/pull/11138))
+- Change Nanobox configuration to bring it up to date ([danhunsaker](https://github.com/tootsuite/mastodon/pull/11083))
+
+### Removed
+
+- Remove expensive counters from federation page in admin UI ([Gargron](https://github.com/tootsuite/mastodon/pull/11139))
+
+### Fixed
+
+- Fix converted media being saved with original extension and mime type ([Gargron](https://github.com/tootsuite/mastodon/pull/11130))
+- Fix layout of identity proofs settings ([acid-chicken](https://github.com/tootsuite/mastodon/pull/11126))
+- Fix active scope only returning suspended users ([ThibG](https://github.com/tootsuite/mastodon/pull/11111))
+- Fix sanitizer making block level elements unreadable ([Gargron](https://github.com/tootsuite/mastodon/pull/10836))
+- Fix label for site theme not being translated in admin UI ([palindromordnilap](https://github.com/tootsuite/mastodon/pull/11121))
+- Fix statuses not being filtered irreversibly in web UI under some circumstances ([ThibG](https://github.com/tootsuite/mastodon/pull/11113))
+- Fix scrolling behaviour in compose form ([ThibG](https://github.com/tootsuite/mastodon/pull/11093))
+
+## [2.9.0] - 2019-06-13
+### Added
+
+- **Add single-column mode in web UI** ([Gargron](https://github.com/tootsuite/mastodon/pull/10807), [Gargron](https://github.com/tootsuite/mastodon/pull/10848), [Gargron](https://github.com/tootsuite/mastodon/pull/11003), [Gargron](https://github.com/tootsuite/mastodon/pull/10961), [Hanage999](https://github.com/tootsuite/mastodon/pull/10915), [noellabo](https://github.com/tootsuite/mastodon/pull/10917), [abcang](https://github.com/tootsuite/mastodon/pull/10859), [Gargron](https://github.com/tootsuite/mastodon/pull/10820), [Gargron](https://github.com/tootsuite/mastodon/pull/10835), [Gargron](https://github.com/tootsuite/mastodon/pull/10809), [Gargron](https://github.com/tootsuite/mastodon/pull/10963), [noellabo](https://github.com/tootsuite/mastodon/pull/10883), [Hanage999](https://github.com/tootsuite/mastodon/pull/10839))
+- Add waiting time to the list of pending accounts in admin UI ([Gargron](https://github.com/tootsuite/mastodon/pull/10985))
+- Add a keyboard shortcut to hide/show media in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/10647), [Gargron](https://github.com/tootsuite/mastodon/pull/10838), [ThibG](https://github.com/tootsuite/mastodon/pull/10872))
+- Add `account_id` param to `GET /api/v1/notifications` ([pwoolcoc](https://github.com/tootsuite/mastodon/pull/10796))
+- Add confirmation modal for unboosting toots in web UI ([aurelien-reeves](https://github.com/tootsuite/mastodon/pull/10287))
+- Add emoji suggestions to content warning and poll option fields in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/10555))
+- Add `source` attribute to response of `DELETE /api/v1/statuses/:id` ([ThibG](https://github.com/tootsuite/mastodon/pull/10669))
+- Add some caching for HTML versions of public status pages ([ThibG](https://github.com/tootsuite/mastodon/pull/10701))
+- Add button to conveniently copy OAuth code ([ThibG](https://github.com/tootsuite/mastodon/pull/11065))
+
+### Changed
+
+- **Change default layout to single column in web UI** ([Gargron](https://github.com/tootsuite/mastodon/pull/10847))
+- **Change light theme** ([Gargron](https://github.com/tootsuite/mastodon/pull/10992), [Gargron](https://github.com/tootsuite/mastodon/pull/10996), [yuzulabo](https://github.com/tootsuite/mastodon/pull/10754), [Gargron](https://github.com/tootsuite/mastodon/pull/10845))
+- **Change preferences page into appearance, notifications, and other** ([Gargron](https://github.com/tootsuite/mastodon/pull/10977), [Gargron](https://github.com/tootsuite/mastodon/pull/10988))
+- Change priority of delete activity forwards for replies and reblogs ([Gargron](https://github.com/tootsuite/mastodon/pull/11002))
+- Change Mastodon logo to use primary text color of the given theme ([Gargron](https://github.com/tootsuite/mastodon/pull/10994))
+- Change reblogs counter to be updated when boosted privately ([Gargron](https://github.com/tootsuite/mastodon/pull/10964))
+- Change bio limit from 160 to 500 characters ([trwnh](https://github.com/tootsuite/mastodon/pull/10790))
+- Change API rate limiting to reduce allowed unauthenticated requests ([ThibG](https://github.com/tootsuite/mastodon/pull/10860), [hinaloe](https://github.com/tootsuite/mastodon/pull/10868), [mayaeh](https://github.com/tootsuite/mastodon/pull/10867))
+- Change help text of `tootctl emoji import` command to specify a gzipped TAR archive is required ([dariusk](https://github.com/tootsuite/mastodon/pull/11000))
+- Change web UI to hide poll options behind content warnings ([ThibG](https://github.com/tootsuite/mastodon/pull/10983))
+- Change silencing to ensure local effects and remote effects are the same for silenced local users ([ThibG](https://github.com/tootsuite/mastodon/pull/10575))
+- Change `tootctl domains purge` to remove custom emoji as well ([Kjwon15](https://github.com/tootsuite/mastodon/pull/10721))
+- Change Docker image to keep `apt` working ([SuperSandro2000](https://github.com/tootsuite/mastodon/pull/10830))
+
+### Removed
+
+- Remove `dist-upgrade` from Docker image ([SuperSandro2000](https://github.com/tootsuite/mastodon/pull/10822))
+
+### Fixed
+
+- Fix RTL layout not being RTL within the columns area in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/10990))
+- Fix display of alternative text when a media attachment is not available in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/10981))
+- Fix not being able to directly switch between list timelines in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/10973))
+- Fix media sensitivity not being maintained in delete & redraft in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/10980))
+- Fix emoji picker being always displayed in web UI ([noellabo](https://github.com/tootsuite/mastodon/pull/10979), [yuzulabo](https://github.com/tootsuite/mastodon/pull/10801), [wcpaez](https://github.com/tootsuite/mastodon/pull/10978))
+- Fix potential private status leak through caching ([ThibG](https://github.com/tootsuite/mastodon/pull/10969))
+- Fix refreshing featured toots when the new collection is empty in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/10971))
+- Fix undoing domain block also undoing individual moderation on users from before the domain block ([ThibG](https://github.com/tootsuite/mastodon/pull/10660))
+- Fix time not being local in the audit log ([yuzulabo](https://github.com/tootsuite/mastodon/pull/10751))
+- Fix statuses removed by moderation re-appearing on subsequent fetches ([Kjwon15](https://github.com/tootsuite/mastodon/pull/10732))
+- Fix misattribution of inlined announces if `attributedTo` isn't present in ActivityPub ([ThibG](https://github.com/tootsuite/mastodon/pull/10967))
+- Fix `GET /api/v1/polls/:id` not requiring authentication for non-public polls ([Gargron](https://github.com/tootsuite/mastodon/pull/10960))
+- Fix handling of blank poll options in ActivityPub ([ThibG](https://github.com/tootsuite/mastodon/pull/10946))
+- Fix avatar preview aspect ratio on edit profile page ([Kjwon15](https://github.com/tootsuite/mastodon/pull/10931))
+- Fix web push notifications not being sent for polls ([ThibG](https://github.com/tootsuite/mastodon/pull/10864))
+- Fix cut off letters in last paragraph of statuses in web UI ([ariasuni](https://github.com/tootsuite/mastodon/pull/10821))
+- Fix list not being automatically unpinned when it returns 404 in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/11045))
+- Fix login sometimes redirecting to paths that are not pages ([Gargron](https://github.com/tootsuite/mastodon/pull/11019))
+
+## [2.8.4] - 2019-05-24
+### Fixed
+
+- Fix delivery not retrying on some inbox errors that should be retriable ([ThibG](https://github.com/tootsuite/mastodon/pull/10812))
+- Fix unnecessary 5 minute cooldowns on signature verifications in some cases ([ThibG](https://github.com/tootsuite/mastodon/pull/10813))
+- Fix possible race condition when processing statuses ([ThibG](https://github.com/tootsuite/mastodon/pull/10815))
+
+### Security
+
+- Require specific OAuth scopes for specific endpoints of the streaming API, instead of merely requiring a token for all endpoints, and allow using WebSockets protocol negotiation to specify the access token instead of using a query string ([ThibG](https://github.com/tootsuite/mastodon/pull/10818))
+
+## [2.8.3] - 2019-05-19
+### Added
+
+- Add `og:image:alt` OpenGraph tag ([BenLubar](https://github.com/tootsuite/mastodon/pull/10779))
+- Add clickable area below avatar in statuses in web UI ([Dar13](https://github.com/tootsuite/mastodon/pull/10766))
+- Add crossed-out eye icon on account gallery in web UI ([Kjwon15](https://github.com/tootsuite/mastodon/pull/10715))
+- Add media description tooltip to thumbnails in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/10713))
+
+### Changed
+
+- Change "mark as sensitive" button into a checkbox for clarity ([ThibG](https://github.com/tootsuite/mastodon/pull/10748))
+
+### Fixed
+
+- Fix bug allowing users to publicly boost their private statuses ([ThibG](https://github.com/tootsuite/mastodon/pull/10775), [ThibG](https://github.com/tootsuite/mastodon/pull/10783))
+- Fix performance in formatter by a little ([ThibG](https://github.com/tootsuite/mastodon/pull/10765))
+- Fix some colors in the light theme ([yuzulabo](https://github.com/tootsuite/mastodon/pull/10754))
+- Fix some colors of the high contrast theme ([yuzulabo](https://github.com/tootsuite/mastodon/pull/10711))
+- Fix ambivalent active state of poll refresh button in web UI ([MaciekBaron](https://github.com/tootsuite/mastodon/pull/10720))
+- Fix duplicate posting being possible from web UI ([hinaloe](https://github.com/tootsuite/mastodon/pull/10785))
+- Fix "invited by" not showing up in admin UI ([ThibG](https://github.com/tootsuite/mastodon/pull/10791))
+
+## [2.8.2] - 2019-05-05
+### Added
+
+- Add `SOURCE_TAG` environment variable ([ushitora-anqou](https://github.com/tootsuite/mastodon/pull/10698))
+
+### Fixed
+
+- Fix cropped hero image on frontpage ([BaptisteGelez](https://github.com/tootsuite/mastodon/pull/10702))
+- Fix blurhash gem not compiling on some operating systems ([Gargron](https://github.com/tootsuite/mastodon/pull/10700))
+- Fix unexpected CSS animations in some browsers ([ThibG](https://github.com/tootsuite/mastodon/pull/10699))
+- Fix closing video modal scrolling timelines to top ([ThibG](https://github.com/tootsuite/mastodon/pull/10695))
+
+## [2.8.1] - 2019-05-04
+### Added
+
+- Add link to existing domain block when trying to block an already-blocked domain ([ThibG](https://github.com/tootsuite/mastodon/pull/10663))
+- Add button to view context to media modal when opened from account gallery in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/10676))
+- Add ability to create multiple-choice polls in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/10603))
+- Add `GITHUB_REPOSITORY` and `SOURCE_BASE_URL` environment variables ([rosylilly](https://github.com/tootsuite/mastodon/pull/10600))
+- Add `/interact/` paths to `robots.txt` ([ThibG](https://github.com/tootsuite/mastodon/pull/10666))
+- Add `blurhash` to the Attachment entity in the REST API ([Gargron](https://github.com/tootsuite/mastodon/pull/10630))
+
+### Changed
+
+- Change hidden media to be shown as a blurhash-based colorful gradient instead of a black box in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/10630))
+- Change rejected media to be shown as a blurhash-based gradient instead of a list of filenames in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/10630))
+- Change e-mail whitelist/blacklist to not be checked when invited ([Gargron](https://github.com/tootsuite/mastodon/pull/10683))
+- Change cache header of REST API results to no-cache ([ThibG](https://github.com/tootsuite/mastodon/pull/10655))
+- Change the "mark media as sensitive" button to be more obvious in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/10673), [Gargron](https://github.com/tootsuite/mastodon/pull/10682))
+- Change account gallery in web UI to display 3 columns, open media modal ([Gargron](https://github.com/tootsuite/mastodon/pull/10667), [Gargron](https://github.com/tootsuite/mastodon/pull/10674))
+
+### Fixed
+
+- Fix LDAP/PAM/SAML/CAS users not being pre-approved ([Gargron](https://github.com/tootsuite/mastodon/pull/10621))
+- Fix accounts created through tootctl not being always pre-approved ([Gargron](https://github.com/tootsuite/mastodon/pull/10684))
+- Fix Sidekiq retrying ActivityPub processing jobs that fail validation ([ThibG](https://github.com/tootsuite/mastodon/pull/10614))
+- Fix toots not being scrolled into view sometimes through keyboard selection ([ThibG](https://github.com/tootsuite/mastodon/pull/10593))
+- Fix expired invite links being usable to bypass approval mode ([ThibG](https://github.com/tootsuite/mastodon/pull/10657))
+- Fix not being able to save e-mail preference for new pending accounts ([Gargron](https://github.com/tootsuite/mastodon/pull/10622))
+- Fix upload progressbar when image resizing is involved ([ThibG](https://github.com/tootsuite/mastodon/pull/10632))
+- Fix block action not automatically cancelling pending follow request ([ThibG](https://github.com/tootsuite/mastodon/pull/10633))
+- Fix stoplight logging to stderr separate from Rails logger ([Gargron](https://github.com/tootsuite/mastodon/pull/10624))
+- Fix sign up button not saying sign up when invite is used ([Gargron](https://github.com/tootsuite/mastodon/pull/10623))
+- Fix health checks in Docker Compose configuration ([fabianonline](https://github.com/tootsuite/mastodon/pull/10553))
+- Fix modal items not being scrollable on touch devices ([kedamaDQ](https://github.com/tootsuite/mastodon/pull/10605))
+- Fix Keybase configuration using wrong domain when a web domain is used ([BenLubar](https://github.com/tootsuite/mastodon/pull/10565))
+- Fix avatar GIFs not being animated on-hover on public profiles ([hyenagirl64](https://github.com/tootsuite/mastodon/pull/10549))
+- Fix OpenGraph parser not understanding some valid property meta tags ([da2x](https://github.com/tootsuite/mastodon/pull/10604))
+- Fix wrong fonts being displayed when Roboto is installed on user's machine ([ThibG](https://github.com/tootsuite/mastodon/pull/10594))
+- Fix confirmation modals being too narrow for a secondary action button ([ThibG](https://github.com/tootsuite/mastodon/pull/10586))
+
+## [2.8.0] - 2019-04-10
+### Added
+
+- Add polls ([Gargron](https://github.com/tootsuite/mastodon/pull/10111), [ThibG](https://github.com/tootsuite/mastodon/pull/10155), [Gargron](https://github.com/tootsuite/mastodon/pull/10184), [ThibG](https://github.com/tootsuite/mastodon/pull/10196), [Gargron](https://github.com/tootsuite/mastodon/pull/10248), [ThibG](https://github.com/tootsuite/mastodon/pull/10255), [ThibG](https://github.com/tootsuite/mastodon/pull/10322), [Gargron](https://github.com/tootsuite/mastodon/pull/10138), [Gargron](https://github.com/tootsuite/mastodon/pull/10139), [Gargron](https://github.com/tootsuite/mastodon/pull/10144), [Gargron](https://github.com/tootsuite/mastodon/pull/10145),[Gargron](https://github.com/tootsuite/mastodon/pull/10146), [Gargron](https://github.com/tootsuite/mastodon/pull/10148), [Gargron](https://github.com/tootsuite/mastodon/pull/10151), [ThibG](https://github.com/tootsuite/mastodon/pull/10150), [Gargron](https://github.com/tootsuite/mastodon/pull/10168), [Gargron](https://github.com/tootsuite/mastodon/pull/10165), [Gargron](https://github.com/tootsuite/mastodon/pull/10172), [Gargron](https://github.com/tootsuite/mastodon/pull/10170), [Gargron](https://github.com/tootsuite/mastodon/pull/10171), [Gargron](https://github.com/tootsuite/mastodon/pull/10186), [Gargron](https://github.com/tootsuite/mastodon/pull/10189), [ThibG](https://github.com/tootsuite/mastodon/pull/10200), [rinsuki](https://github.com/tootsuite/mastodon/pull/10203), [Gargron](https://github.com/tootsuite/mastodon/pull/10213), [Gargron](https://github.com/tootsuite/mastodon/pull/10246), [Gargron](https://github.com/tootsuite/mastodon/pull/10265), [Gargron](https://github.com/tootsuite/mastodon/pull/10261), [ThibG](https://github.com/tootsuite/mastodon/pull/10333), [Gargron](https://github.com/tootsuite/mastodon/pull/10352), [ThibG](https://github.com/tootsuite/mastodon/pull/10140), [ThibG](https://github.com/tootsuite/mastodon/pull/10142), [ThibG](https://github.com/tootsuite/mastodon/pull/10141), [ThibG](https://github.com/tootsuite/mastodon/pull/10162), [ThibG](https://github.com/tootsuite/mastodon/pull/10161), [ThibG](https://github.com/tootsuite/mastodon/pull/10158), [ThibG](https://github.com/tootsuite/mastodon/pull/10156), [ThibG](https://github.com/tootsuite/mastodon/pull/10160), [Gargron](https://github.com/tootsuite/mastodon/pull/10185), [Gargron](https://github.com/tootsuite/mastodon/pull/10188), [ThibG](https://github.com/tootsuite/mastodon/pull/10195), [ThibG](https://github.com/tootsuite/mastodon/pull/10208), [Gargron](https://github.com/tootsuite/mastodon/pull/10187), [ThibG](https://github.com/tootsuite/mastodon/pull/10214), [ThibG](https://github.com/tootsuite/mastodon/pull/10209))
+- Add follows & followers managing UI ([Gargron](https://github.com/tootsuite/mastodon/pull/10268), [Gargron](https://github.com/tootsuite/mastodon/pull/10308), [Gargron](https://github.com/tootsuite/mastodon/pull/10404), [Gargron](https://github.com/tootsuite/mastodon/pull/10293))
+- Add identity proof integration with Keybase ([Gargron](https://github.com/tootsuite/mastodon/pull/10297), [xgess](https://github.com/tootsuite/mastodon/pull/10375), [Gargron](https://github.com/tootsuite/mastodon/pull/10338), [Gargron](https://github.com/tootsuite/mastodon/pull/10350), [Gargron](https://github.com/tootsuite/mastodon/pull/10414))
+- Add option to overwrite imported data instead of merging ([Gargron](https://github.com/tootsuite/mastodon/pull/9962))
+- Add featured hashtags to profiles ([Gargron](https://github.com/tootsuite/mastodon/pull/9755), [Gargron](https://github.com/tootsuite/mastodon/pull/10167), [Gargron](https://github.com/tootsuite/mastodon/pull/10249), [ThibG](https://github.com/tootsuite/mastodon/pull/10034))
+- Add admission-based registrations mode ([Gargron](https://github.com/tootsuite/mastodon/pull/10250), [ThibG](https://github.com/tootsuite/mastodon/pull/10269), [Gargron](https://github.com/tootsuite/mastodon/pull/10264), [ThibG](https://github.com/tootsuite/mastodon/pull/10321), [Gargron](https://github.com/tootsuite/mastodon/pull/10349), [Gargron](https://github.com/tootsuite/mastodon/pull/10469))
+- Add support for WebP uploads ([acid-chicken](https://github.com/tootsuite/mastodon/pull/9879))
+- Add "copy link" item to status action bars in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/9983))
+- Add list title editing in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/9748))
+- Add a "Block & Report" button to the block confirmation dialog in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/10360))
+- Add disappointed elephant when the page crashes in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/10275))
+- Add ability to upload multiple files at once in web UI ([tmm576](https://github.com/tootsuite/mastodon/pull/9856))
+- Add indication when you are not allowed to follow an account in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/10420), [Gargron](https://github.com/tootsuite/mastodon/pull/10491))
+- Add validations to admin settings to catch common mistakes ([Gargron](https://github.com/tootsuite/mastodon/pull/10348), [ThibG](https://github.com/tootsuite/mastodon/pull/10354))
+- Add `type`, `limit`, `offset`, `min_id`, `max_id`, `account_id` to search API ([Gargron](https://github.com/tootsuite/mastodon/pull/10091))
+- Add a preferences API so apps can share basic behaviours ([Gargron](https://github.com/tootsuite/mastodon/pull/10109))
+- Add `visibility` param to reblog REST API ([Gargron](https://github.com/tootsuite/mastodon/pull/9851), [ThibG](https://github.com/tootsuite/mastodon/pull/10302))
+- Add `allowfullscreen` attribute to OEmbed iframe ([rinsuki](https://github.com/tootsuite/mastodon/pull/10370))
+- Add `blocked_by` relationship to the REST API ([Gargron](https://github.com/tootsuite/mastodon/pull/10373))
+- Add `tootctl statuses remove` to sweep unreferenced statuses ([Gargron](https://github.com/tootsuite/mastodon/pull/10063))
+- Add `tootctl search deploy` to avoid ugly rake task syntax ([Gargron](https://github.com/tootsuite/mastodon/pull/10403))
+- Add `tootctl self-destruct` to shut down server gracefully ([Gargron](https://github.com/tootsuite/mastodon/pull/10367))
+- Add option to hide application used to toot ([ThibG](https://github.com/tootsuite/mastodon/pull/9897), [rinsuki](https://github.com/tootsuite/mastodon/pull/9994), [hinaloe](https://github.com/tootsuite/mastodon/pull/10086))
+- Add `DB_SSLMODE` configuration variable ([sascha-sl](https://github.com/tootsuite/mastodon/pull/10210))
+- Add click-to-copy UI to invites page ([Gargron](https://github.com/tootsuite/mastodon/pull/10259))
+- Add self-replies fetching ([ThibG](https://github.com/tootsuite/mastodon/pull/10106), [ThibG](https://github.com/tootsuite/mastodon/pull/10128), [ThibG](https://github.com/tootsuite/mastodon/pull/10175), [ThibG](https://github.com/tootsuite/mastodon/pull/10201))
+- Add rate limit for media proxy requests ([Gargron](https://github.com/tootsuite/mastodon/pull/10490))
+- Add `tootctl emoji purge` ([Gargron](https://github.com/tootsuite/mastodon/pull/10481))
+- Add `tootctl accounts approve` ([Gargron](https://github.com/tootsuite/mastodon/pull/10480))
+- Add `tootctl accounts reset-relationships` ([noellabo](https://github.com/tootsuite/mastodon/pull/10483))
+
+### Changed
+
+- Change design of landing page ([Gargron](https://github.com/tootsuite/mastodon/pull/10232), [Gargron](https://github.com/tootsuite/mastodon/pull/10260), [ThibG](https://github.com/tootsuite/mastodon/pull/10284), [ThibG](https://github.com/tootsuite/mastodon/pull/10291), [koyuawsmbrtn](https://github.com/tootsuite/mastodon/pull/10356), [Gargron](https://github.com/tootsuite/mastodon/pull/10245))
+- Change design of profile column in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/10337), [Aditoo17](https://github.com/tootsuite/mastodon/pull/10387), [ThibG](https://github.com/tootsuite/mastodon/pull/10390), [mayaeh](https://github.com/tootsuite/mastodon/pull/10379), [ThibG](https://github.com/tootsuite/mastodon/pull/10411))
+- Change language detector threshold from 140 characters to 4 words ([Gargron](https://github.com/tootsuite/mastodon/pull/10376))
+- Change language detector to always kick in for non-latin alphabets ([Gargron](https://github.com/tootsuite/mastodon/pull/10276))
+- Change icons of features on admin dashboard ([Gargron](https://github.com/tootsuite/mastodon/pull/10366))
+- Change DNS timeouts from 1s to 5s ([ThibG](https://github.com/tootsuite/mastodon/pull/10238))
+- Change Docker image to use Ubuntu with jemalloc ([Sir-Boops](https://github.com/tootsuite/mastodon/pull/10100), [BenLubar](https://github.com/tootsuite/mastodon/pull/10212))
+- Change public pages to be cacheable by proxies ([BenLubar](https://github.com/tootsuite/mastodon/pull/9059))
+- Change the 410 gone response for suspended accounts to be cacheable by proxies ([ThibG](https://github.com/tootsuite/mastodon/pull/10339))
+- Change web UI to not not empty timeline of blocked users on block ([ThibG](https://github.com/tootsuite/mastodon/pull/10359))
+- Change JSON serializer to remove unused `@context` values ([Gargron](https://github.com/tootsuite/mastodon/pull/10378))
+- Change GIFV file size limit to be the same as for other videos ([rinsuki](https://github.com/tootsuite/mastodon/pull/9924))
+- Change Webpack to not use @babel/preset-env to compile node_modules ([ykzts](https://github.com/tootsuite/mastodon/pull/10289))
+- Change web UI to use new Web Share Target API ([gol-cha](https://github.com/tootsuite/mastodon/pull/9963))
+- Change ActivityPub reports to have persistent URIs ([ThibG](https://github.com/tootsuite/mastodon/pull/10303))
+- Change `tootctl accounts cull --dry-run` to list accounts that would be deleted ([BenLubar](https://github.com/tootsuite/mastodon/pull/10460))
+- Change format of CSV exports of follows and mutes to include extra settings ([ThibG](https://github.com/tootsuite/mastodon/pull/10495), [ThibG](https://github.com/tootsuite/mastodon/pull/10335))
+- Change ActivityPub collections to be cacheable by proxies ([ThibG](https://github.com/tootsuite/mastodon/pull/10467))
+- Change REST API and public profiles to not return follows/followers for users that have blocked you ([Gargron](https://github.com/tootsuite/mastodon/pull/10491))
+- Change the groupings of menu items in settings navigation ([Gargron](https://github.com/tootsuite/mastodon/pull/10533))
+
+### Removed
+
+- Remove zopfli compression to speed up Webpack from 6min to 1min ([nolanlawson](https://github.com/tootsuite/mastodon/pull/10288))
+- Remove stats.json generation to speed up Webpack ([nolanlawson](https://github.com/tootsuite/mastodon/pull/10290))
+
+### Fixed
+
+- Fix public timelines being broken by new toots when they are not mounted in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/10131))
+- Fix quick filter settings not being saved when selecting a different filter in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/10296))
+- Fix remote interaction dialogs being indexed by search engines ([Gargron](https://github.com/tootsuite/mastodon/pull/10240))
+- Fix maxed-out invites not showing up as expired in UI ([Gargron](https://github.com/tootsuite/mastodon/pull/10274))
+- Fix scrollbar styles on compose textarea ([Gargron](https://github.com/tootsuite/mastodon/pull/10292))
+- Fix timeline merge workers being queued for remote users ([Gargron](https://github.com/tootsuite/mastodon/pull/10355))
+- Fix alternative relay support regression ([Gargron](https://github.com/tootsuite/mastodon/pull/10398))
+- Fix trying to fetch keys of unknown accounts on a self-delete from them ([ThibG](https://github.com/tootsuite/mastodon/pull/10326))
+- Fix CAS `:service_validate_url` option ([enewhuis](https://github.com/tootsuite/mastodon/pull/10328))
+- Fix race conditions when creating backups ([ThibG](https://github.com/tootsuite/mastodon/pull/10234))
+- Fix whitespace not being stripped out of username before validation ([aurelien-reeves](https://github.com/tootsuite/mastodon/pull/10239))
+- Fix n+1 query when deleting status ([Gargron](https://github.com/tootsuite/mastodon/pull/10247))
+- Fix exiting follows not being rejected when suspending a remote account ([ThibG](https://github.com/tootsuite/mastodon/pull/10230))
+- Fix the underlying button element in a disabled icon button not being disabled ([ThibG](https://github.com/tootsuite/mastodon/pull/10194))
+- Fix race condition when streaming out deleted statuses ([ThibG](https://github.com/tootsuite/mastodon/pull/10280))
+- Fix performance of admin federation UI by caching account counts ([Gargron](https://github.com/tootsuite/mastodon/pull/10374))
+- Fix JS error on pages that don't define a CSRF token ([hinaloe](https://github.com/tootsuite/mastodon/pull/10383))
+- Fix `tootctl accounts cull` sometimes removing accounts that are temporarily unreachable ([BenLubar](https://github.com/tootsuite/mastodon/pull/10460))
+
+## [2.7.4] - 2019-03-05
+### Fixed
+
+- Fix web UI not cleaning up notifications after block ([Gargron](https://github.com/tootsuite/mastodon/pull/10108))
+- Fix redundant HTTP requests when resolving private statuses ([ThibG](https://github.com/tootsuite/mastodon/pull/10115))
+- Fix performance of account media query ([abcang](https://github.com/tootsuite/mastodon/pull/10121))
+- Fix mention processing for unknown accounts ([ThibG](https://github.com/tootsuite/mastodon/pull/10125))
+- Fix getting started column not scrolling on short screens ([trwnh](https://github.com/tootsuite/mastodon/pull/10075))
+- Fix direct messages pagination in the web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/10126))
+- Fix serialization of Announce activities ([ThibG](https://github.com/tootsuite/mastodon/pull/10129))
+- Fix home timeline perpetually reloading when empty in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/10130))
+- Fix lists export ([ThibG](https://github.com/tootsuite/mastodon/pull/10136))
+- Fix edit profile page crash for suspended-then-unsuspended users ([ThibG](https://github.com/tootsuite/mastodon/pull/10178))
+
+## [2.7.3] - 2019-02-23
+### Added
+
+- Add domain filter to the admin federation page ([ThibG](https://github.com/tootsuite/mastodon/pull/10071))
+- Add quick link from admin account view to block/unblock instance ([ThibG](https://github.com/tootsuite/mastodon/pull/10073))
+
+### Fixed
+
+- Fix video player width not being updated to fit container width ([ThibG](https://github.com/tootsuite/mastodon/pull/10069))
+- Fix domain filter being shown in admin page when local filter is active ([ThibG](https://github.com/tootsuite/mastodon/pull/10074))
+- Fix crash when conversations have no valid participants ([ThibG](https://github.com/tootsuite/mastodon/pull/10078))
+- Fix error when performing admin actions on no statuses ([ThibG](https://github.com/tootsuite/mastodon/pull/10094))
+
+### Changed
+
+- Change custom emojis to randomize stored file name ([hinaloe](https://github.com/tootsuite/mastodon/pull/10090))
+
+## [2.7.2] - 2019-02-17
+### Added
+
+- Add support for IPv6 in e-mail validation ([zoc](https://github.com/tootsuite/mastodon/pull/10009))
+- Add record of IP address used for signing up ([ThibG](https://github.com/tootsuite/mastodon/pull/10026))
+- Add tight rate-limit for API deletions (30 per 30 minutes) ([Gargron](https://github.com/tootsuite/mastodon/pull/10042))
+- Add support for embedded `Announce` objects attributed to the same actor ([ThibG](https://github.com/tootsuite/mastodon/pull/9998), [Gargron](https://github.com/tootsuite/mastodon/pull/10065))
+- Add spam filter for `Create` and `Announce` activities ([Gargron](https://github.com/tootsuite/mastodon/pull/10005), [Gargron](https://github.com/tootsuite/mastodon/pull/10041), [Gargron](https://github.com/tootsuite/mastodon/pull/10062))
+- Add `registrations` attribute to `GET /api/v1/instance` ([Gargron](https://github.com/tootsuite/mastodon/pull/10060))
+- Add `vapid_key` to `POST /api/v1/apps` and `GET /api/v1/apps/verify_credentials` ([Gargron](https://github.com/tootsuite/mastodon/pull/10058))
+
+### Fixed
+
+- Fix link color and add link underlines in high-contrast theme ([Gargron](https://github.com/tootsuite/mastodon/pull/9949), [Gargron](https://github.com/tootsuite/mastodon/pull/10028))
+- Fix unicode characters in URLs not being linkified ([JMendyk](https://github.com/tootsuite/mastodon/pull/8447), [hinaloe](https://github.com/tootsuite/mastodon/pull/9991))
+- Fix URLs linkifier grabbing ending quotation as part of the link ([Gargron](https://github.com/tootsuite/mastodon/pull/9997))
+- Fix authorized applications page design ([rinsuki](https://github.com/tootsuite/mastodon/pull/9969))
+- Fix custom emojis not showing up in share page emoji picker ([rinsuki](https://github.com/tootsuite/mastodon/pull/9970))
+- Fix too liberal application of whitespace in toots ([trwnh](https://github.com/tootsuite/mastodon/pull/9968))
+- Fix misleading e-mail hint being displayed in admin view ([ThibG](https://github.com/tootsuite/mastodon/pull/9973))
+- Fix tombstones not being cleared out ([abcang](https://github.com/tootsuite/mastodon/pull/9978))
+- Fix some timeline jumps ([ThibG](https://github.com/tootsuite/mastodon/pull/9982), [ThibG](https://github.com/tootsuite/mastodon/pull/10001), [rinsuki](https://github.com/tootsuite/mastodon/pull/10046))
+- Fix content warning input taking keyboard focus even when hidden ([hinaloe](https://github.com/tootsuite/mastodon/pull/10017))
+- Fix hashtags select styling in default and high-contrast themes ([Gargron](https://github.com/tootsuite/mastodon/pull/10029))
+- Fix style regressions on landing page ([Gargron](https://github.com/tootsuite/mastodon/pull/10030))
+- Fix hashtag column not subscribing to stream on mount ([Gargron](https://github.com/tootsuite/mastodon/pull/10040))
+- Fix relay enabling/disabling not resetting inbox availability status ([Gargron](https://github.com/tootsuite/mastodon/pull/10048))
+- Fix mutes, blocks, domain blocks and follow requests not paginating ([Gargron](https://github.com/tootsuite/mastodon/pull/10057))
+- Fix crash on public hashtag pages when streaming fails ([ThibG](https://github.com/tootsuite/mastodon/pull/10061))
+
+### Changed
+
+- Change icon for unlisted visibility level ([clarcharr](https://github.com/tootsuite/mastodon/pull/9952))
+- Change queue of actor deletes from push to pull for non-follower recipients ([ThibG](https://github.com/tootsuite/mastodon/pull/10016))
+- Change robots.txt to exclude media proxy URLs ([nightpool](https://github.com/tootsuite/mastodon/pull/10038))
+- Change upload description input to allow line breaks ([BenLubar](https://github.com/tootsuite/mastodon/pull/10036))
+- Change `dist/mastodon-streaming.service` to recommend running node without intermediary npm command ([nolanlawson](https://github.com/tootsuite/mastodon/pull/10032))
+- Change conversations to always show names of other participants ([Gargron](https://github.com/tootsuite/mastodon/pull/10047))
+- Change buttons on timeline preview to open the interaction dialog ([Gargron](https://github.com/tootsuite/mastodon/pull/10054))
+- Change error graphic to hover-to-play ([Gargron](https://github.com/tootsuite/mastodon/pull/10055))
+
+## [2.7.1] - 2019-01-28
+### Fixed
+
+- Fix SSO authentication not working due to missing agreement boolean ([Gargron](https://github.com/tootsuite/mastodon/pull/9915))
+- Fix slow fallback of CopyAccountStats migration setting stats to 0 ([Gargron](https://github.com/tootsuite/mastodon/pull/9930))
+- Fix wrong command in migration error message ([angristan](https://github.com/tootsuite/mastodon/pull/9877))
+- Fix initial value of volume slider in video player and handle volume changes ([ThibG](https://github.com/tootsuite/mastodon/pull/9929))
+- Fix missing hotkeys for notifications ([ThibG](https://github.com/tootsuite/mastodon/pull/9927))
+- Fix being able to attach unattached media created by other users ([ThibG](https://github.com/tootsuite/mastodon/pull/9921))
+- Fix unrescued SSL error during link verification ([renatolond](https://github.com/tootsuite/mastodon/pull/9914))
+- Fix Firefox scrollbar color regression ([trwnh](https://github.com/tootsuite/mastodon/pull/9908))
+- Fix scheduled status with media immediately creating a status ([ThibG](https://github.com/tootsuite/mastodon/pull/9894))
+- Fix missing strong style for landing page description ([Kjwon15](https://github.com/tootsuite/mastodon/pull/9892))
+
 ## [2.7.0] - 2019-01-20
 ### Added
 
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index b55729a9ba2da8ef06eed1f26f10f89092f81148..76f5121984ca15c80dfa5363bb17c37b76f3f15e 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,7 +1,7 @@
 Contributing
 ============
 
-Thank you for considering contributing to Mastodon 🐘 
+Thank you for considering contributing to Mastodon 🐘
 
 You can contribute in the following ways:
 
@@ -10,15 +10,17 @@ You can contribute in the following ways:
 - Contributing code to Mastodon by fixing bugs or implementing features
 - Improving the documentation
 
+If your contributions are accepted into Mastodon, you can request to be paid through [our OpenCollective](https://opencollective.com/mastodon).
+
 ## Bug reports
 
 Bug reports and feature suggestions can be submitted to [GitHub Issues](https://github.com/tootsuite/mastodon/issues). Please make sure that you are not submitting duplicates, and that a similar report or request has not already been resolved or rejected in the past using the search function. Please also use descriptive, concise titles.
 
 ## Translations
 
-You can submit translations via [Weblate](https://weblate.joinmastodon.org/). They are periodically merged into the codebase.
+You can submit translations via [Crowdin](https://crowdin.com/project/mastodon). They are periodically merged into the codebase.
 
-[![Mastodon translation statistics by language](https://weblate.joinmastodon.org/widgets/mastodon/-/multi-auto.svg)](https://weblate.joinmastodon.org/)
+[![Crowdin](https://d322cqt584bo4o.cloudfront.net/mastodon/localized.svg)][crowdin]
 
 ## Pull requests
 
diff --git a/Dockerfile b/Dockerfile
index 19090533757c5260aff2366a962498734bd5983f..d8c7e0f0c53ef2de2588aac1b8489e51439cafe1 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,90 +1,127 @@
-FROM node:8.15-alpine as node
-FROM ruby:2.6-alpine3.8
-
-LABEL maintainer="https://github.com/tootsuite/mastodon" \
-      description="Your self-hosted, globally interconnected microblogging community"
-
+FROM ubuntu:18.04 as build-dep
+
+# Use bash for the shell
+SHELL ["bash", "-c"]
+
+# Install Node
+ENV NODE_VER="8.15.0"
+RUN	echo "Etc/UTC" > /etc/localtime && \
+	apt update && \
+	apt -y install wget make gcc g++ python && \
+	cd ~ && \
+	wget https://nodejs.org/download/release/v$NODE_VER/node-v$NODE_VER.tar.gz && \
+	tar xf node-v$NODE_VER.tar.gz && \
+	cd node-v$NODE_VER && \
+	./configure --prefix=/opt/node && \
+	make -j$(nproc) > /dev/null && \
+	make install
+
+# Install jemalloc
+ENV JE_VER="5.1.0"
+RUN apt update && \
+	apt -y install autoconf && \
+	cd ~ && \
+	wget https://github.com/jemalloc/jemalloc/archive/$JE_VER.tar.gz && \
+	tar xf $JE_VER.tar.gz && \
+	cd jemalloc-$JE_VER && \
+	./autogen.sh && \
+	./configure --prefix=/opt/jemalloc && \
+	make -j$(nproc) > /dev/null && \
+	make install_bin install_include install_lib
+
+# Install ruby
+ENV RUBY_VER="2.6.1"
+ENV CPPFLAGS="-I/opt/jemalloc/include"
+ENV LDFLAGS="-L/opt/jemalloc/lib/"
+RUN apt update && \
+	apt -y install build-essential \
+		bison libyaml-dev libgdbm-dev libreadline-dev \
+		libncurses5-dev libffi-dev zlib1g-dev libssl-dev && \
+	cd ~ && \
+	wget https://cache.ruby-lang.org/pub/ruby/${RUBY_VER%.*}/ruby-$RUBY_VER.tar.gz && \
+	tar xf ruby-$RUBY_VER.tar.gz && \
+	cd ruby-$RUBY_VER && \
+	./configure --prefix=/opt/ruby \
+	  --with-jemalloc \
+	  --with-shared \
+	  --disable-install-doc && \
+	ln -s /opt/jemalloc/lib/* /usr/lib/ && \
+	make -j$(nproc) > /dev/null && \
+	make install
+
+ENV PATH="${PATH}:/opt/ruby/bin:/opt/node/bin"
+
+RUN npm install -g yarn && \
+	gem install bundler && \
+	apt update && \
+	apt -y install git libicu-dev libidn11-dev \
+	libpq-dev libprotobuf-dev protobuf-compiler
+
+COPY Gemfile* package.json yarn.lock /opt/mastodon/
+
+RUN cd /opt/mastodon && \
+	bundle install -j$(nproc) --deployment --without development test && \
+	yarn install --pure-lockfile
+
+FROM ubuntu:18.04
+
+# Copy over all the langs needed for runtime
+COPY --from=build-dep /opt/node /opt/node
+COPY --from=build-dep /opt/ruby /opt/ruby
+COPY --from=build-dep /opt/jemalloc /opt/jemalloc
+
+# Add more PATHs to the PATH
+ENV PATH="${PATH}:/opt/ruby/bin:/opt/node/bin:/opt/mastodon/bin"
+
+# Create the mastodon user
 ARG UID=991
 ARG GID=991
-
-ENV PATH=/mastodon/bin:$PATH \
-    RAILS_SERVE_STATIC_FILES=true \
-    RAILS_ENV=production \
-    NODE_ENV=production
-
-ARG LIBICONV_VERSION=1.15
-ARG LIBICONV_DOWNLOAD_SHA256=ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178
-
-EXPOSE 3000 4000
-
-WORKDIR /mastodon
-
-COPY --from=node /usr/local/bin/node /usr/local/bin/node
-COPY --from=node /usr/local/lib/node_modules /usr/local/lib/node_modules
-COPY --from=node /usr/local/bin/npm /usr/local/bin/npm
-COPY --from=node /opt/yarn-* /opt/yarn
-
-RUN apk -U upgrade \
- && apk add -t build-dependencies \
-    build-base \
-    icu-dev \
-    libidn-dev \
-    libressl \
-    libtool \
-    libxml2-dev \
-    libxslt-dev \
-    postgresql-dev \
-    protobuf-dev \
-    python \
- && apk add \
-    ca-certificates \
-    ffmpeg \
-    file \
-    git \
-    icu-libs \
-    imagemagick \
-    libidn \
-    libpq \
-    libxml2 \
-    libxslt \
-    protobuf \
-    tini \
-    tzdata \
- && update-ca-certificates \
- && ln -s /opt/yarn/bin/yarn /usr/local/bin/yarn \
- && ln -s /opt/yarn/bin/yarnpkg /usr/local/bin/yarnpkg \
- && mkdir -p /tmp/src /opt \
- && wget -O libiconv.tar.gz "https://ftp.gnu.org/pub/gnu/libiconv/libiconv-$LIBICONV_VERSION.tar.gz" \
- && echo "$LIBICONV_DOWNLOAD_SHA256 *libiconv.tar.gz" | sha256sum -c - \
- && tar -xzf libiconv.tar.gz -C /tmp/src \
- && rm libiconv.tar.gz \
- && cd /tmp/src/libiconv-$LIBICONV_VERSION \
- && ./configure --prefix=/usr/local \
- && make -j$(getconf _NPROCESSORS_ONLN)\
- && make install \
- && libtool --finish /usr/local/lib \
- && cd /mastodon \
- && rm -rf /tmp/* /var/cache/apk/*
-
-COPY Gemfile Gemfile.lock package.json yarn.lock .yarnclean /mastodon/
-
-RUN bundle config build.nokogiri --use-system-libraries --with-iconv-lib=/usr/local/lib --with-iconv-include=/usr/local/include \
- && bundle install -j$(getconf _NPROCESSORS_ONLN) --deployment --without test development \
- && yarn install --pure-lockfile --ignore-engines \
- && yarn cache clean
-
-RUN addgroup -g ${GID} mastodon && adduser -h /mastodon -s /bin/sh -D -G mastodon -u ${UID} mastodon \
- && mkdir -p /mastodon/public/system /mastodon/public/assets /mastodon/public/packs \
- && chown -R mastodon:mastodon /mastodon/public
-
-COPY . /mastodon
-
-RUN chown -R mastodon:mastodon /mastodon
-
-VOLUME /mastodon/public/system
-
+RUN apt update && \
+	echo "Etc/UTC" > /etc/localtime && \
+	ln -s /opt/jemalloc/lib/* /usr/lib/ && \
+	apt install -y whois wget && \
+	addgroup --gid $GID mastodon && \
+	useradd -m -u $UID -g $GID -d /opt/mastodon mastodon && \
+	echo "mastodon:`head /dev/urandom | tr -dc A-Za-z0-9 | head -c 24 | mkpasswd -s -m sha-256`" | chpasswd
+
+# Install mastodon runtime deps
+RUN apt -y --no-install-recommends install \
+	  libssl1.1 libpq5 imagemagick ffmpeg \
+	  libicu60 libprotobuf10 libidn11 libyaml-0-2 \
+	  file ca-certificates tzdata libreadline7 && \
+	apt -y install gcc && \
+	ln -s /opt/mastodon /mastodon && \
+	gem install bundler && \
+	rm -rf /var/cache && \
+	rm -rf /var/lib/apt/lists/*
+
+# Add tini
+ENV TINI_VERSION="0.18.0"
+ENV TINI_SUM="12d20136605531b09a2c2dac02ccee85e1b874eb322ef6baf7561cd93f93c855"
+ADD https://github.com/krallin/tini/releases/download/v${TINI_VERSION}/tini /tini
+RUN echo "$TINI_SUM tini" | sha256sum -c -
+RUN chmod +x /tini
+
+# Copy over mastodon source, and dependencies from building, and set permissions
+COPY --chown=mastodon:mastodon . /opt/mastodon
+COPY --from=build-dep --chown=mastodon:mastodon /opt/mastodon /opt/mastodon
+
+# Run mastodon services in prod mode
+ENV RAILS_ENV="production"
+ENV NODE_ENV="production"
+
+# Tell rails to serve static files
+ENV RAILS_SERVE_STATIC_FILES="true"
+ENV BIND="0.0.0.0"
+
+# Set the run user
 USER mastodon
 
-RUN OTP_SECRET=precompile_placeholder SECRET_KEY_BASE=precompile_placeholder bundle exec rails assets:precompile
+# Precompile assets
+RUN cd ~ && \
+	OTP_SECRET=precompile_placeholder SECRET_KEY_BASE=precompile_placeholder rails assets:precompile && \
+	yarn cache clean
 
-ENTRYPOINT ["/sbin/tini", "--"]
+# Set the work dir and the container entry point
+WORKDIR /opt/mastodon
+ENTRYPOINT ["/tini", "--"]
diff --git a/Gemfile b/Gemfile
index d17ff1a51c3820b8e8ed4481a2296df385e7950f..b72f550eb9ea3a32144ae7e9e78f30d0751b5fc5 100644
--- a/Gemfile
+++ b/Gemfile
@@ -6,31 +6,32 @@ ruby '>= 2.4.0', '< 2.7.0'
 gem 'pkg-config', '~> 1.3'
 
 gem 'puma', '~> 3.12'
-gem 'rails', '~> 5.2.2'
+gem 'rails', '~> 5.2.3'
 gem 'thor', '~> 0.20'
 
 gem 'hamlit-rails', '~> 0.2'
 gem 'pg', '~> 1.1'
 gem 'makara', '~> 0.4'
 gem 'pghero', '~> 2.2'
-gem 'dotenv-rails', '~> 2.6'
+gem 'dotenv-rails', '~> 2.7'
 
-gem 'aws-sdk-s3', '~> 1.30', require: false
+gem 'aws-sdk-s3', '~> 1.42', require: false
 gem 'fog-core', '<= 2.1.0'
 gem 'fog-openstack', '~> 0.3', require: false
 gem 'paperclip', '~> 6.0'
 gem 'paperclip-av-transcoder', '~> 0.6'
 gem 'streamio-ffmpeg', '~> 3.0'
+gem 'blurhash', '~> 0.1'
 
 gem 'active_model_serializers', '~> 0.10'
-gem 'addressable', '~> 2.5'
-gem 'bootsnap', '~> 1.3', require: false
+gem 'addressable', '~> 2.6'
+gem 'bootsnap', '~> 1.4', require: false
 gem 'browser'
 gem 'charlock_holmes', '~> 0.7.6'
 gem 'iso-639'
 gem 'chewy', '~> 5.0'
-gem 'cld3', '~> 3.2.3'
-gem 'devise', '~> 4.5'
+gem 'cld3', '~> 3.2.4'
+gem 'devise', '~> 4.6'
 gem 'devise-two-factor', '~> 3.0'
 
 group :pam_authentication, optional: true do
@@ -42,7 +43,7 @@ gem 'omniauth-cas', '~> 1.1'
 gem 'omniauth-saml', '~> 1.10'
 gem 'omniauth', '~> 1.9'
 
-gem 'doorkeeper', '~> 5.0'
+gem 'doorkeeper', '~> 5.1'
 gem 'fast_blank', '~> 1.0'
 gem 'fastimage'
 gem 'goldfinger', '~> 2.1'
@@ -52,7 +53,7 @@ gem 'htmlentities', '~> 4.3'
 gem 'http', '~> 3.3'
 gem 'http_accept_language', '~> 2.1'
 gem 'http_parser.rb', '~> 0.6', git: 'https://github.com/tmm1/http_parser.rb', ref: '54b17ba8c7d8d20a16dfc65d1775241833219cf2'
-gem 'httplog', '~> 1.2'
+gem 'httplog', '~> 1.3'
 gem 'idn-ruby', require: 'idn'
 gem 'kaminari', '~> 1.1'
 gem 'link_header', '~> 0.0'
@@ -61,11 +62,11 @@ gem 'nokogiri', '~> 1.10'
 gem 'nsa', '~> 0.2'
 gem 'oj', '~> 3.7'
 gem 'ostatus2', '~> 2.0'
-gem 'ox', '~> 2.10'
+gem 'ox', '~> 2.11'
 gem 'posix-spawn', git: 'https://github.com/rtomayko/posix-spawn', ref: '58465d2e213991f8afb13b984854a49fcdcc980c'
 gem 'pundit', '~> 2.0'
 gem 'premailer-rails'
-gem 'rack-attack', '~> 5.4'
+gem 'rack-attack', '~> 6.0'
 gem 'rack-cors', '~> 1.0', require: 'rack/cors'
 gem 'rails-i18n', '~> 5.1'
 gem 'rails-settings-cached', '~> 0.6'
@@ -81,12 +82,12 @@ gem 'simple-navigation', '~> 4.0'
 gem 'simple_form', '~> 4.1'
 gem 'sprockets-rails', '~> 3.2', require: 'sprockets/railtie'
 gem 'stoplight', '~> 2.1.3'
-gem 'strong_migrations', '~> 0.3'
+gem 'strong_migrations', '~> 0.4'
 gem 'tty-command', '~> 0.8', require: false
-gem 'tty-prompt', '~> 0.18', require: false
+gem 'tty-prompt', '~> 0.19', require: false
 gem 'twitter-text', '~> 1.14'
-gem 'tzinfo-data', '~> 1.2018'
-gem 'webpacker', '~> 3.5'
+gem 'tzinfo-data', '~> 1.2019'
+gem 'webpacker', '~> 4.0'
 gem 'webpush'
 
 gem 'json-ld', '~> 3.0'
@@ -95,9 +96,9 @@ gem 'rdf-normalize', '~> 0.3'
 
 group :development, :test do
   gem 'fabrication', '~> 2.20'
-  gem 'fuubar', '~> 2.3'
+  gem 'fuubar', '~> 2.4'
   gem 'i18n-tasks', '~> 0.9', require: false
-  gem 'pry-byebug', '~> 3.6'
+  gem 'pry-byebug', '~> 3.7'
   gem 'pry-rails', '~> 0.3'
   gem 'rspec-rails', '~> 3.8'
 end
@@ -107,30 +108,30 @@ group :production, :test do
 end
 
 group :test do
-  gem 'capybara', '~> 3.12'
+  gem 'capybara', '~> 3.24'
   gem 'climate_control', '~> 0.2'
   gem 'faker', '~> 1.9'
-  gem 'microformats', '~> 4.0'
+  gem 'microformats', '~> 4.1'
   gem 'rails-controller-testing', '~> 1.0'
   gem 'rspec-sidekiq', '~> 3.0'
   gem 'simplecov', '~> 0.16', require: false
-  gem 'webmock', '~> 3.5'
-  gem 'parallel_tests', '~> 2.27'
+  gem 'webmock', '~> 3.6'
+  gem 'parallel_tests', '~> 2.29'
 end
 
 group :development do
-  gem 'active_record_query_trace', '~> 1.5'
+  gem 'active_record_query_trace', '~> 1.6'
   gem 'annotate', '~> 2.7'
   gem 'better_errors', '~> 2.5'
   gem 'binding_of_caller', '~> 0.7'
-  gem 'bullet', '~> 5.9'
+  gem 'bullet', '~> 6.0'
   gem 'letter_opener', '~> 1.7'
   gem 'letter_opener_web', '~> 1.3'
   gem 'memory_profiler'
-  gem 'rubocop', '~> 0.63', require: false
-  gem 'brakeman', '~> 4.4', require: false
+  gem 'rubocop', '~> 0.71', require: false
+  gem 'rubocop-rails', '~> 2.0', require: false
+  gem 'brakeman', '~> 4.5', require: false
   gem 'bundler-audit', '~> 0.6', require: false
-  gem 'scss_lint', '~> 0.57', require: false
 
   gem 'capistrano', '~> 3.11'
   gem 'capistrano-rails', '~> 1.4'
@@ -142,7 +143,7 @@ group :development do
 end
 
 group :production do
-  gem 'lograge', '~> 0.10'
+  gem 'lograge', '~> 0.11'
   gem 'redis-rails', '~> 5.0'
 end
 
diff --git a/Gemfile.lock b/Gemfile.lock
index acb4b8dda98fe5377ec88c9a2767fc66ce0fac8b..bda915dfada1079d7c415b6cca7aae0aa9bfeeff 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -15,59 +15,59 @@ GIT
 GEM
   remote: https://rubygems.org/
   specs:
-    actioncable (5.2.2)
-      actionpack (= 5.2.2)
+    actioncable (5.2.3)
+      actionpack (= 5.2.3)
       nio4r (~> 2.0)
       websocket-driver (>= 0.6.1)
-    actionmailer (5.2.2)
-      actionpack (= 5.2.2)
-      actionview (= 5.2.2)
-      activejob (= 5.2.2)
+    actionmailer (5.2.3)
+      actionpack (= 5.2.3)
+      actionview (= 5.2.3)
+      activejob (= 5.2.3)
       mail (~> 2.5, >= 2.5.4)
       rails-dom-testing (~> 2.0)
-    actionpack (5.2.2)
-      actionview (= 5.2.2)
-      activesupport (= 5.2.2)
+    actionpack (5.2.3)
+      actionview (= 5.2.3)
+      activesupport (= 5.2.3)
       rack (~> 2.0)
       rack-test (>= 0.6.3)
       rails-dom-testing (~> 2.0)
       rails-html-sanitizer (~> 1.0, >= 1.0.2)
-    actionview (5.2.2)
-      activesupport (= 5.2.2)
+    actionview (5.2.3)
+      activesupport (= 5.2.3)
       builder (~> 3.1)
       erubi (~> 1.4)
       rails-dom-testing (~> 2.0)
       rails-html-sanitizer (~> 1.0, >= 1.0.3)
-    active_model_serializers (0.10.8)
+    active_model_serializers (0.10.9)
       actionpack (>= 4.1, < 6)
       activemodel (>= 4.1, < 6)
       case_transform (>= 0.2)
       jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
-    active_record_query_trace (1.5.4)
-    activejob (5.2.2)
-      activesupport (= 5.2.2)
+    active_record_query_trace (1.6.2)
+    activejob (5.2.3)
+      activesupport (= 5.2.3)
       globalid (>= 0.3.6)
-    activemodel (5.2.2)
-      activesupport (= 5.2.2)
-    activerecord (5.2.2)
-      activemodel (= 5.2.2)
-      activesupport (= 5.2.2)
+    activemodel (5.2.3)
+      activesupport (= 5.2.3)
+    activerecord (5.2.3)
+      activemodel (= 5.2.3)
+      activesupport (= 5.2.3)
       arel (>= 9.0)
-    activestorage (5.2.2)
-      actionpack (= 5.2.2)
-      activerecord (= 5.2.2)
+    activestorage (5.2.3)
+      actionpack (= 5.2.3)
+      activerecord (= 5.2.3)
       marcel (~> 0.3.1)
-    activesupport (5.2.2)
+    activesupport (5.2.3)
       concurrent-ruby (~> 1.0, >= 1.0.2)
       i18n (>= 0.7, < 2)
       minitest (~> 5.1)
       tzinfo (~> 1.1)
-    addressable (2.5.2)
+    addressable (2.6.0)
       public_suffix (>= 2.0.2, < 4.0)
     airbrussh (1.3.0)
       sshkit (>= 1.6.1, != 1.7.0)
-    annotate (2.7.4)
-      activerecord (>= 3.2, < 6.0)
+    annotate (2.7.5)
+      activerecord (>= 3.2, < 7.0)
       rake (>= 10.4, < 13.0)
     arel (9.0.0)
     ast (2.4.0)
@@ -75,41 +75,44 @@ GEM
       encryptor (~> 3.0.0)
     av (0.9.0)
       cocaine (~> 0.5.3)
-    aws-eventstream (1.0.1)
-    aws-partitions (1.131.0)
-    aws-sdk-core (3.45.0)
-      aws-eventstream (~> 1.0)
+    aws-eventstream (1.0.3)
+    aws-partitions (1.175.0)
+    aws-sdk-core (3.55.0)
+      aws-eventstream (~> 1.0, >= 1.0.2)
       aws-partitions (~> 1.0)
-      aws-sigv4 (~> 1.0)
+      aws-sigv4 (~> 1.1)
       jmespath (~> 1.0)
-    aws-sdk-kms (1.13.0)
-      aws-sdk-core (~> 3, >= 3.39.0)
-      aws-sigv4 (~> 1.0)
-    aws-sdk-s3 (1.30.1)
-      aws-sdk-core (~> 3, >= 3.39.0)
+    aws-sdk-kms (1.21.0)
+      aws-sdk-core (~> 3, >= 3.53.0)
+      aws-sigv4 (~> 1.1)
+    aws-sdk-s3 (1.42.0)
+      aws-sdk-core (~> 3, >= 3.53.0)
       aws-sdk-kms (~> 1)
-      aws-sigv4 (~> 1.0)
-    aws-sigv4 (1.0.3)
+      aws-sigv4 (~> 1.1)
+    aws-sigv4 (1.1.0)
+      aws-eventstream (~> 1.0, >= 1.0.2)
     bcrypt (3.1.12)
     benchmark-ips (2.7.2)
-    better_errors (2.5.0)
+    better_errors (2.5.1)
       coderay (>= 1.0.0)
       erubi (>= 1.0.0)
       rack (>= 0.9.0)
     binding_of_caller (0.8.0)
       debug_inspector (>= 0.0.1)
-    bootsnap (1.3.2)
+    blurhash (0.1.3)
+      ffi (~> 1.10.0)
+    bootsnap (1.4.4)
       msgpack (~> 1.0)
-    brakeman (4.4.0)
+    brakeman (4.5.1)
     browser (2.5.3)
     builder (3.2.3)
-    bullet (5.9.0)
+    bullet (6.0.0)
       activesupport (>= 3.0.0)
       uniform_notifier (~> 1.11)
     bundler-audit (0.6.1)
       bundler (>= 1.2.0, < 3)
       thor (~> 0.18)
-    byebug (10.0.2)
+    byebug (11.0.0)
     capistrano (3.11.0)
       airbrussh (>= 1.0.0)
       i18n
@@ -126,13 +129,13 @@ GEM
       sshkit (~> 1.3)
     capistrano-yarn (2.0.2)
       capistrano (~> 3.0)
-    capybara (3.12.0)
+    capybara (3.24.0)
       addressable
       mini_mime (>= 0.1.3)
       nokogiri (~> 1.8)
       rack (>= 1.6.0)
       rack-test (>= 0.6.3)
-      regexp_parser (~> 1.2)
+      regexp_parser (~> 1.5)
       xpath (~> 3.2)
     case_transform (0.2)
       activesupport
@@ -142,13 +145,13 @@ GEM
       elasticsearch (>= 2.0.0)
       elasticsearch-dsl
     chunky_png (1.3.10)
-    cld3 (3.2.3)
-      ffi (>= 1.1.0, < 1.10.0)
+    cld3 (3.2.4)
+      ffi (>= 1.1.0, < 1.11.0)
     climate_control (0.2.0)
     cocaine (0.5.8)
       climate_control (>= 0.0.3, < 1.0)
     coderay (1.1.2)
-    concurrent-ruby (1.1.4)
+    concurrent-ruby (1.1.5)
     connection_pool (2.2.2)
     crack (0.4.3)
       safe_yaml (~> 1.0.0)
@@ -164,7 +167,7 @@ GEM
       rack (>= 1)
       rake (> 10, < 13)
       thor (~> 0.19)
-    devise (4.5.0)
+    devise (4.6.2)
       bcrypt (~> 3.0)
       orm_adapter (~> 0.1)
       railties (>= 4.1.0, < 6.0)
@@ -183,12 +186,12 @@ GEM
     docile (1.3.0)
     domain_name (0.5.20180417)
       unf (>= 0.0.5, < 1.0.0)
-    doorkeeper (5.0.2)
-      railties (>= 4.2)
-    dotenv (2.6.0)
-    dotenv-rails (2.6.0)
-      dotenv (= 2.6.0)
-      railties (>= 3.2, < 6.0)
+    doorkeeper (5.1.0)
+      railties (>= 5)
+    dotenv (2.7.2)
+    dotenv-rails (2.7.2)
+      dotenv (= 2.7.2)
+      railties (>= 3.2, < 6.1)
     elasticsearch (6.0.2)
       elasticsearch-api (= 6.0.2)
       elasticsearch-transport (= 6.0.2)
@@ -204,14 +207,14 @@ GEM
     et-orbi (1.1.6)
       tzinfo
     excon (0.62.0)
-    fabrication (2.20.1)
-    faker (1.9.1)
+    fabrication (2.20.2)
+    faker (1.9.3)
       i18n (>= 0.7)
     faraday (0.15.0)
       multipart-post (>= 1.2, < 3)
     fast_blank (1.0.0)
     fastimage (2.1.5)
-    ffi (1.9.25)
+    ffi (1.10.0)
     fog-core (2.1.0)
       builder
       excon (~> 0.58)
@@ -228,32 +231,32 @@ GEM
     fugit (1.1.6)
       et-orbi (~> 1.1, >= 1.1.6)
       raabro (~> 1.1)
-    fuubar (2.3.2)
+    fuubar (2.4.1)
       rspec-core (~> 3.0)
       ruby-progressbar (~> 1.4)
     get_process_mem (0.2.3)
-    globalid (0.4.1)
+    globalid (0.4.2)
       activesupport (>= 4.2.0)
     goldfinger (2.1.0)
       addressable (~> 2.5)
       http (~> 3.0)
       nokogiri (~> 1.8)
       oj (~> 3.0)
-    hamlit (2.8.8)
+    hamlit (2.9.3)
       temple (>= 0.8.0)
       thor
       tilt
-    hamlit-rails (0.2.0)
+    hamlit-rails (0.2.3)
       actionpack (>= 4.0.1)
       activesupport (>= 4.0.1)
       hamlit (>= 1.2.0)
       railties (>= 4.0.1)
     hamster (3.0.0)
       concurrent-ruby (~> 1.0)
-    hashdiff (0.3.7)
+    hashdiff (0.4.0)
     hashie (3.6.0)
     heapy (0.1.4)
-    highline (2.0.0)
+    highline (2.0.1)
     hiredis (0.6.3)
     hkdf (0.3.0)
     htmlentities (4.3.4)
@@ -266,12 +269,12 @@ GEM
       domain_name (~> 0.5)
     http-form_data (2.1.1)
     http_accept_language (2.1.1)
-    httplog (1.2.0)
+    httplog (1.3.1)
       rack (>= 1.0)
       rainbow (>= 2.0.0)
-    i18n (1.5.2)
+    i18n (1.6.0)
       concurrent-ruby (~> 1.0)
-    i18n-tasks (0.9.28)
+    i18n-tasks (0.9.29)
       activesupport (>= 4.0.2)
       ast (>= 2.1.0)
       erubi
@@ -290,8 +293,8 @@ GEM
     json-ld (3.0.2)
       multi_json (~> 1.12)
       rdf (>= 2.2.8, < 4.0)
-    json-ld-preloaded (3.0.0)
-      json-ld (>= 2.2, < 4.0)
+    json-ld-preloaded (3.0.2)
+      json-ld (~> 3.0)
       multi_json (~> 1.12)
       rdf (~> 3.0)
     jsonapi-renderer (0.2.0)
@@ -317,7 +320,7 @@ GEM
       letter_opener (~> 1.0)
       railties (>= 3.2)
     link_header (0.0.8)
-    lograge (0.10.0)
+    lograge (0.11.2)
       actionpack (>= 4)
       activesupport (>= 4)
       railties (>= 4)
@@ -327,34 +330,34 @@ GEM
       nokogiri (>= 1.5.9)
     mail (2.7.1)
       mini_mime (>= 0.1.1)
-    makara (0.4.0)
+    makara (0.4.1)
       activerecord (>= 3.0.0)
     marcel (0.3.3)
       mimemagic (~> 0.3.2)
     mario-redis-lock (1.2.1)
       redis (>= 3.0.5)
-    memory_profiler (0.9.12)
+    memory_profiler (0.9.13)
     method_source (0.9.2)
-    microformats (4.0.7)
-      json
-      nokogiri
+    microformats (4.1.0)
+      json (~> 2.1)
+      nokogiri (~> 1.8, >= 1.8.3)
     mime-types (3.2.2)
       mime-types-data (~> 3.2015)
     mime-types-data (3.2018.0812)
-    mimemagic (0.3.2)
+    mimemagic (0.3.3)
     mini_mime (1.0.1)
     mini_portile2 (2.4.0)
     minitest (5.11.3)
-    msgpack (1.2.4)
+    msgpack (1.2.10)
     multi_json (1.13.1)
     multipart-post (2.0.0)
-    necromancer (0.4.0)
+    necromancer (0.5.0)
     net-ldap (0.16.1)
     net-scp (1.2.1)
       net-ssh (>= 2.6.5)
     net-ssh (5.0.2)
     nio4r (2.3.1)
-    nokogiri (1.10.1)
+    nokogiri (1.10.3)
       mini_portile2 (~> 2.4.0)
     nokogumbo (2.0.0)
       nokogiri (~> 1.8, >= 1.8.4)
@@ -363,7 +366,7 @@ GEM
       concurrent-ruby (~> 1.0, >= 1.0.2)
       sidekiq (>= 3.5)
       statsd-ruby (~> 1.4, >= 1.4.0)
-    oj (3.7.7)
+    oj (3.7.12)
     omniauth (1.9.0)
       hashie (>= 3.4.6, < 3.7.0)
       rack (>= 1.6.2, < 3)
@@ -379,7 +382,7 @@ GEM
       addressable (~> 2.5)
       http (~> 3.0)
       nokogiri (~> 1.8)
-    ox (2.10.0)
+    ox (2.11.0)
     paperclip (6.0.0)
       activemodel (>= 4.2.0)
       activesupport (>= 4.2.0)
@@ -389,19 +392,18 @@ GEM
     paperclip-av-transcoder (0.6.4)
       av (~> 0.9.0)
       paperclip (>= 2.5.2)
-    parallel (1.12.1)
-    parallel_tests (2.27.1)
+    parallel (1.17.0)
+    parallel_tests (2.29.0)
       parallel
-    parser (2.6.0.0)
+    parser (2.6.3.0)
       ast (~> 2.4.0)
     pastel (0.7.2)
       equatable (~> 0.5.0)
       tty-color (~> 0.4.0)
     pg (1.1.4)
-    pghero (2.2.0)
+    pghero (2.2.1)
       activerecord
-    pkg-config (1.3.2)
-    powerpack (0.1.2)
+    pkg-config (1.3.7)
     premailer (1.11.1)
       addressable
       css_parser (>= 1.6.0)
@@ -413,38 +415,38 @@ GEM
     pry (0.12.2)
       coderay (~> 1.1.0)
       method_source (~> 0.9.0)
-    pry-byebug (3.6.0)
-      byebug (~> 10.0)
+    pry-byebug (3.7.0)
+      byebug (~> 11.0)
       pry (~> 0.10)
     pry-rails (0.3.9)
       pry (>= 0.10.4)
-    public_suffix (3.0.3)
-    puma (3.12.0)
-    pundit (2.0.0)
+    public_suffix (3.1.0)
+    puma (3.12.1)
+    pundit (2.0.1)
       activesupport (>= 3.0.0)
     raabro (1.1.6)
-    rack (2.0.6)
-    rack-attack (5.4.2)
+    rack (2.0.7)
+    rack-attack (6.0.0)
       rack (>= 1.0, < 3)
-    rack-cors (1.0.2)
+    rack-cors (1.0.3)
     rack-protection (2.0.5)
       rack
-    rack-proxy (0.6.4)
+    rack-proxy (0.6.5)
       rack
     rack-test (1.1.0)
       rack (>= 1.0, < 3)
-    rails (5.2.2)
-      actioncable (= 5.2.2)
-      actionmailer (= 5.2.2)
-      actionpack (= 5.2.2)
-      actionview (= 5.2.2)
-      activejob (= 5.2.2)
-      activemodel (= 5.2.2)
-      activerecord (= 5.2.2)
-      activestorage (= 5.2.2)
-      activesupport (= 5.2.2)
+    rails (5.2.3)
+      actioncable (= 5.2.3)
+      actionmailer (= 5.2.3)
+      actionpack (= 5.2.3)
+      actionview (= 5.2.3)
+      activejob (= 5.2.3)
+      activemodel (= 5.2.3)
+      activerecord (= 5.2.3)
+      activestorage (= 5.2.3)
+      activesupport (= 5.2.3)
       bundler (>= 1.3.0)
-      railties (= 5.2.2)
+      railties (= 5.2.3)
       sprockets-rails (>= 2.0.0)
     rails-controller-testing (1.0.4)
       actionpack (>= 5.0.1.x)
@@ -455,28 +457,25 @@ GEM
       nokogiri (>= 1.6)
     rails-html-sanitizer (1.0.4)
       loofah (~> 2.2, >= 2.2.2)
-    rails-i18n (5.1.2)
+    rails-i18n (5.1.3)
       i18n (>= 0.7, < 2)
       railties (>= 5.0, < 6)
     rails-settings-cached (0.6.6)
       rails (>= 4.2.0)
-    railties (5.2.2)
-      actionpack (= 5.2.2)
-      activesupport (= 5.2.2)
+    railties (5.2.3)
+      actionpack (= 5.2.3)
+      activesupport (= 5.2.3)
       method_source
       rake (>= 0.8.7)
       thor (>= 0.19.0, < 2.0)
     rainbow (3.0.0)
     rake (12.3.2)
-    rb-fsevent (0.10.3)
-    rb-inotify (0.9.10)
-      ffi (>= 0.5.0, < 2)
     rdf (3.0.9)
       hamster (~> 3.0)
       link_header (~> 0.0, >= 0.0.8)
     rdf-normalize (0.3.3)
       rdf (>= 2.2, < 4.0)
-    redis (4.1.0)
+    redis (4.1.2)
     redis-actionpack (5.0.2)
       actionpack (>= 4.0, < 6)
       redis-rack (>= 1, < 3)
@@ -495,12 +494,12 @@ GEM
       redis-store (>= 1.2, < 2)
     redis-store (1.5.0)
       redis (>= 2.2, < 5)
-    regexp_parser (1.3.0)
+    regexp_parser (1.5.1)
     request_store (1.4.1)
       rack (>= 1.4)
-    responders (2.4.0)
-      actionpack (>= 4.2.0, < 5.3)
-      railties (>= 4.2.0, < 5.3)
+    responders (2.4.1)
+      actionpack (>= 4.2.0, < 6.0)
+      railties (>= 4.2.0, < 6.0)
     rotp (2.1.2)
     rpam2 (4.0.2)
     rqrcode (0.10.1)
@@ -513,7 +512,7 @@ GEM
     rspec-mocks (3.8.0)
       diff-lcs (>= 1.2.0, < 2.0)
       rspec-support (~> 3.8.0)
-    rspec-rails (3.8.1)
+    rspec-rails (3.8.2)
       actionpack (>= 3.0)
       activesupport (>= 3.0)
       railties (>= 3.0)
@@ -525,33 +524,27 @@ GEM
       rspec-core (~> 3.0, >= 3.0.0)
       sidekiq (>= 2.4.0)
     rspec-support (3.8.0)
-    rubocop (0.63.0)
+    rubocop (0.71.0)
       jaro_winkler (~> 1.5.1)
       parallel (~> 1.10)
-      parser (>= 2.5, != 2.5.1.1)
-      powerpack (~> 0.1)
+      parser (>= 2.6)
       rainbow (>= 2.2.2, < 4.0)
       ruby-progressbar (~> 1.7)
-      unicode-display_width (~> 1.4.0)
-    ruby-progressbar (1.10.0)
+      unicode-display_width (>= 1.4.0, < 1.7)
+    rubocop-rails (2.0.1)
+      rack (>= 1.1)
+      rubocop (>= 0.70.0)
+    ruby-progressbar (1.10.1)
     ruby-saml (1.9.0)
       nokogiri (>= 1.5.10)
     rufus-scheduler (3.5.2)
       fugit (~> 1.1, >= 1.1.5)
-    safe_yaml (1.0.4)
+    safe_yaml (1.0.5)
     sanitize (5.0.0)
       crass (~> 1.0.2)
       nokogiri (>= 1.8.0)
       nokogumbo (~> 2.0)
-    sass (3.6.0)
-      sass-listen (~> 4.0.0)
-    sass-listen (4.0.0)
-      rb-fsevent (~> 0.9, >= 0.9.4)
-      rb-inotify (~> 0.9, >= 0.9.7)
-    scss_lint (0.57.1)
-      rake (>= 0.9, < 13)
-      sass (~> 3.5, >= 3.5.5)
-    sidekiq (5.2.5)
+    sidekiq (5.2.7)
       connection_pool (~> 2.2, >= 2.2.2)
       rack (>= 1.5.0)
       rack-protection (>= 1.5.0)
@@ -563,9 +556,9 @@ GEM
       rufus-scheduler (~> 3.2)
       sidekiq (>= 3)
       tilt (>= 1.4.0)
-    sidekiq-unique-jobs (6.0.8)
+    sidekiq-unique-jobs (6.0.13)
       concurrent-ruby (~> 1.0, >= 1.0.5)
-      sidekiq (>= 4.0, < 6.0)
+      sidekiq (>= 4.0, < 7.0)
       thor (~> 0)
     simple-navigation (4.0.5)
       activesupport (>= 2.3.2)
@@ -592,54 +585,51 @@ GEM
     stoplight (2.1.3)
     streamio-ffmpeg (3.0.2)
       multi_json (~> 1.8)
-    strong_migrations (0.3.1)
-      activerecord (>= 3.2.0)
-    temple (0.8.0)
+    strong_migrations (0.4.0)
+      activerecord (>= 5)
+    temple (0.8.1)
     terminal-table (1.8.0)
       unicode-display_width (~> 1.1, >= 1.1.1)
     terrapin (0.6.0)
       climate_control (>= 0.0.3, < 1.0)
     thor (0.20.3)
     thread_safe (0.3.6)
-    tilt (2.0.8)
-    timers (4.2.0)
+    tilt (2.0.9)
     tty-color (0.4.3)
     tty-command (0.8.2)
       pastel (~> 0.7.0)
-    tty-cursor (0.6.0)
-    tty-prompt (0.18.1)
-      necromancer (~> 0.4.0)
+    tty-cursor (0.7.0)
+    tty-prompt (0.19.0)
+      necromancer (~> 0.5.0)
       pastel (~> 0.7.0)
-      timers (~> 4.0)
-      tty-cursor (~> 0.6.0)
-      tty-reader (~> 0.5.0)
-    tty-reader (0.5.0)
-      tty-cursor (~> 0.6.0)
-      tty-screen (~> 0.6.4)
+      tty-reader (~> 0.6.0)
+    tty-reader (0.6.0)
+      tty-cursor (~> 0.7)
+      tty-screen (~> 0.7)
       wisper (~> 2.0.0)
-    tty-screen (0.6.5)
+    tty-screen (0.7.0)
     twitter-text (1.14.7)
       unf (~> 0.1.0)
     tzinfo (1.2.5)
       thread_safe (~> 0.1)
-    tzinfo-data (1.2018.9)
+    tzinfo-data (1.2019.1)
       tzinfo (>= 1.0.0)
     unf (0.1.4)
       unf_ext
     unf_ext (0.0.7.5)
-    unicode-display_width (1.4.1)
+    unicode-display_width (1.6.0)
     uniform_notifier (1.12.1)
-    warden (1.2.7)
-      rack (>= 1.0)
-    webmock (3.5.1)
+    warden (1.2.8)
+      rack (>= 2.0.6)
+    webmock (3.6.0)
       addressable (>= 2.3.6)
       crack (>= 0.3.2)
-      hashdiff
-    webpacker (3.5.5)
+      hashdiff (>= 0.4.0, < 2.0.0)
+    webpacker (4.0.7)
       activesupport (>= 4.2)
       rack-proxy (>= 0.6.1)
       railties (>= 4.2)
-    webpush (0.3.6)
+    webpush (0.3.8)
       hkdf (~> 0.2)
       jwt (~> 2.0)
     websocket-driver (0.7.0)
@@ -654,40 +644,41 @@ PLATFORMS
 
 DEPENDENCIES
   active_model_serializers (~> 0.10)
-  active_record_query_trace (~> 1.5)
-  addressable (~> 2.5)
+  active_record_query_trace (~> 1.6)
+  addressable (~> 2.6)
   annotate (~> 2.7)
-  aws-sdk-s3 (~> 1.30)
+  aws-sdk-s3 (~> 1.42)
   better_errors (~> 2.5)
   binding_of_caller (~> 0.7)
-  bootsnap (~> 1.3)
-  brakeman (~> 4.4)
+  blurhash (~> 0.1)
+  bootsnap (~> 1.4)
+  brakeman (~> 4.5)
   browser
-  bullet (~> 5.9)
+  bullet (~> 6.0)
   bundler-audit (~> 0.6)
   capistrano (~> 3.11)
   capistrano-rails (~> 1.4)
   capistrano-rbenv (~> 2.1)
   capistrano-yarn (~> 2.0)
-  capybara (~> 3.12)
+  capybara (~> 3.24)
   charlock_holmes (~> 0.7.6)
   chewy (~> 5.0)
-  cld3 (~> 3.2.3)
+  cld3 (~> 3.2.4)
   climate_control (~> 0.2)
   concurrent-ruby
   derailed_benchmarks
-  devise (~> 4.5)
+  devise (~> 4.6)
   devise-two-factor (~> 3.0)
   devise_pam_authenticatable2 (~> 9.2)
-  doorkeeper (~> 5.0)
-  dotenv-rails (~> 2.6)
+  doorkeeper (~> 5.1)
+  dotenv-rails (~> 2.7)
   fabrication (~> 2.20)
   faker (~> 1.9)
   fast_blank (~> 1.0)
   fastimage
   fog-core (<= 2.1.0)
   fog-openstack (~> 0.3)
-  fuubar (~> 2.3)
+  fuubar (~> 2.4)
   goldfinger (~> 2.1)
   hamlit-rails (~> 0.2)
   hiredis (~> 0.6)
@@ -695,7 +686,7 @@ DEPENDENCIES
   http (~> 3.3)
   http_accept_language (~> 2.1)
   http_parser.rb (~> 0.6)!
-  httplog (~> 1.2)
+  httplog (~> 1.3)
   i18n-tasks (~> 0.9)
   idn-ruby
   iso-639
@@ -705,11 +696,11 @@ DEPENDENCIES
   letter_opener (~> 1.7)
   letter_opener_web (~> 1.3)
   link_header (~> 0.0)
-  lograge (~> 0.10)
+  lograge (~> 0.11)
   makara (~> 0.4)
   mario-redis-lock (~> 1.2)
   memory_profiler
-  microformats (~> 4.0)
+  microformats (~> 4.1)
   mime-types (~> 3.2)
   net-ldap (~> 0.10)
   nokogiri (~> 1.10)
@@ -719,23 +710,23 @@ DEPENDENCIES
   omniauth-cas (~> 1.1)
   omniauth-saml (~> 1.10)
   ostatus2 (~> 2.0)
-  ox (~> 2.10)
+  ox (~> 2.11)
   paperclip (~> 6.0)
   paperclip-av-transcoder (~> 0.6)
-  parallel_tests (~> 2.27)
+  parallel_tests (~> 2.29)
   pg (~> 1.1)
   pghero (~> 2.2)
   pkg-config (~> 1.3)
   posix-spawn!
   premailer-rails
   private_address_check (~> 0.5)
-  pry-byebug (~> 3.6)
+  pry-byebug (~> 3.7)
   pry-rails (~> 0.3)
   puma (~> 3.12)
   pundit (~> 2.0)
-  rack-attack (~> 5.4)
+  rack-attack (~> 6.0)
   rack-cors (~> 1.0)
-  rails (~> 5.2.2)
+  rails (~> 5.2.3)
   rails-controller-testing (~> 1.0)
   rails-i18n (~> 5.1)
   rails-settings-cached (~> 0.6)
@@ -746,9 +737,9 @@ DEPENDENCIES
   rqrcode (~> 0.10)
   rspec-rails (~> 3.8)
   rspec-sidekiq (~> 3.0)
-  rubocop (~> 0.63)
+  rubocop (~> 0.71)
+  rubocop-rails (~> 2.0)
   sanitize (~> 5.0)
-  scss_lint (~> 0.57)
   sidekiq (~> 5.2)
   sidekiq-bulk (~> 0.2.0)
   sidekiq-scheduler (~> 3.0)
@@ -760,18 +751,18 @@ DEPENDENCIES
   stackprof
   stoplight (~> 2.1.3)
   streamio-ffmpeg (~> 3.0)
-  strong_migrations (~> 0.3)
+  strong_migrations (~> 0.4)
   thor (~> 0.20)
   tty-command (~> 0.8)
-  tty-prompt (~> 0.18)
+  tty-prompt (~> 0.19)
   twitter-text (~> 1.14)
-  tzinfo-data (~> 1.2018)
-  webmock (~> 3.5)
-  webpacker (~> 3.5)
+  tzinfo-data (~> 1.2019)
+  webmock (~> 3.6)
+  webpacker (~> 4.0)
   webpush
 
 RUBY VERSION
-   ruby 2.6.0p0
+   ruby 2.6.1p33
 
 BUNDLED WITH
    1.17.3
diff --git a/Procfile b/Procfile
index b18e4b6be55cd92e9313933845aeced388c0fd60..d48b0373b05233df9cb41d2d1a0b33a7feb16529 100644
--- a/Procfile
+++ b/Procfile
@@ -1,2 +1,14 @@
-web: bundle exec puma -C config/puma.rb
+web: if [ "$RUN_STREAMING" != "true" ]; then BIND=0.0.0.0 bundle exec puma -C config/puma.rb; else BIND=0.0.0.0 node ./streaming; fi
 worker: bundle exec sidekiq
+
+# For the streaming API, you need a separate app that shares Postgres and Redis:
+#
+# heroku create
+# heroku buildpacks:add heroku/nodejs
+# heroku config:set RUN_STREAMING=true
+# heroku addons:attach <main-app>::DATABASE
+# heroku addons:attach <main-app>::REDIS
+#
+# and let the main app use the separate app:
+#
+# heroku config:set STREAMING_API_BASE_URL=wss://<streaming-app>.herokuapp.com -a <main-app>
diff --git a/README.md b/README.md
index 6c4918e6f237bd78590a3703827e307cce647457..2d18a4ee22aa06d717c752e3af55c5d8eea0d869 100644
--- a/README.md
+++ b/README.md
@@ -4,13 +4,13 @@
 [![GitHub release](https://img.shields.io/github/release/tootsuite/mastodon.svg)][releases]
 [![Build Status](https://img.shields.io/circleci/project/github/tootsuite/mastodon.svg)][circleci]
 [![Code Climate](https://img.shields.io/codeclimate/maintainability/tootsuite/mastodon.svg)][code_climate]
-[![Translation status](https://weblate.joinmastodon.org/widgets/mastodon/-/svg-badge.svg)][weblate]
+[![Crowdin](https://d322cqt584bo4o.cloudfront.net/mastodon/localized.svg)][crowdin]
 [![Docker Pulls](https://img.shields.io/docker/pulls/tootsuite/mastodon.svg)][docker]
 
 [releases]: https://github.com/tootsuite/mastodon/releases
 [circleci]: https://circleci.com/gh/tootsuite/mastodon
 [code_climate]: https://codeclimate.com/github/tootsuite/mastodon
-[weblate]: https://weblate.joinmastodon.org/engage/mastodon/
+[crowdin]: https://crowdin.com/project/mastodon
 [docker]: https://hub.docker.com/r/tootsuite/mastodon/
 
 Mastodon is a **free, open-source social network server** based on ActivityPub. Follow friends and discover new ones. Publish anything you want: links, pictures, text, video. All servers of Mastodon are interoperable as a federated network, i.e. users on one server can seamlessly communicate with users from another one. This includes non-Mastodon software that also implements ActivityPub!
@@ -21,7 +21,7 @@ Click below to **learn more** in a video:
 
 [youtube_demo]: https://www.youtube.com/watch?v=IPSbNdBmWKE
 
-## Navigation 
+## Navigation
 
 - [Project homepage 🐘](https://joinmastodon.org)
 - [Support the development via Patreon][patreon]
@@ -80,13 +80,13 @@ A **Vagrant** configuration is included for development purposes.
 
 Mastodon is **free, open source software** licensed under **AGPLv3**.
 
-You can open issues for bugs you've found or features you think are missing. You can also submit pull requests to this repository, or submit translations using Weblate. To get started, take a look at [CONTRIBUTING.md](CONTRIBUTING.md)
+You can open issues for bugs you've found or features you think are missing. You can also submit pull requests to this repository, or submit translations using Weblate. To get started, take a look at [CONTRIBUTING.md](CONTRIBUTING.md). If your contributions are accepted into Mastodon, you can request to be paid through [our OpenCollective](https://opencollective.com/mastodon).
 
 **IRC channel**: #mastodon on irc.freenode.net
 
 ## License
 
-Copyright (C) 2016-2018 Eugen Rochko & other Mastodon contributors (see [AUTHORS.md](AUTHORS.md))
+Copyright (C) 2016-2019 Eugen Rochko & other Mastodon contributors (see [AUTHORS.md](AUTHORS.md))
 
 This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
 
diff --git a/Vagrantfile b/Vagrantfile
index f9839fffb9cb3cc392d059743327df8ee08edadf..c4941f673138788a09b57b4afc5b425bf56a5cfd 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -44,7 +44,18 @@ sudo apt-get install \
 
 # Install rvm
 read RUBY_VERSION < .ruby-version
-gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
+
+gpg_command="gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB"
+$($gpg_command)
+if [ $? -ne 0 ];then
+  echo "GPG command failed, This prevented RVM from installing."
+  echo "Retrying once..." && $($gpg_command)
+  if [ $? -ne 0 ];then
+    echo "GPG failed for the second time, please ensure network connectivity."
+    echo "Exiting..." && exit 1
+  fi
+fi
+
 curl -sSL https://raw.githubusercontent.com/rvm/rvm/stable/binscripts/rvm-installer | bash -s stable --ruby=$RUBY_VERSION
 source /home/vagrant/.rvm/scripts/rvm
 
diff --git a/app/chewy/statuses_index.rb b/app/chewy/statuses_index.rb
index d3104172c485d1d7b3feaf006857993425bd27c6..f5983a5a5f489d119c373e9c32e814ec2afa633c 100644
--- a/app/chewy/statuses_index.rb
+++ b/app/chewy/statuses_index.rb
@@ -31,7 +31,7 @@ class StatusesIndex < Chewy::Index
     },
   }
 
-  define_type ::Status.unscoped.without_reblogs do
+  define_type ::Status.unscoped.without_reblogs.includes(:media_attachments) do
     crutch :mentions do |collection|
       data = ::Mention.where(status_id: collection.map(&:id)).pluck(:status_id, :account_id)
       data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) }
@@ -48,14 +48,14 @@ class StatusesIndex < Chewy::Index
     end
 
     root date_detection: false do
+      field :id, type: 'long'
       field :account_id, type: 'long'
 
-      field :text, type: 'text', value: ->(status) { [status.spoiler_text, Formatter.instance.plaintext(status)].join("\n\n") } do
+      field :text, type: 'text', value: ->(status) { [status.spoiler_text, Formatter.instance.plaintext(status)].concat(status.media_attachments.map(&:description)).concat(status.preloadable_poll ? status_preloadable_poll.options : []).join("\n\n") } do
         field :stemmed, type: 'text', analyzer: 'content'
       end
 
       field :searchable_by, type: 'long', value: ->(status, crutches) { status.searchable_by(crutches) }
-      field :created_at, type: 'date'
     end
   end
 end
diff --git a/app/controllers/about_controller.rb b/app/controllers/about_controller.rb
index 0dbf0283d206e8959c2fbdfaab78835128deedfb..9f608a851c6467df8f26d59a7dc6145b79f26b04 100644
--- a/app/controllers/about_controller.rb
+++ b/app/controllers/about_controller.rb
@@ -1,26 +1,27 @@
 # frozen_string_literal: true
 
 class AboutController < ApplicationController
-  before_action :set_body_classes
+  layout 'public'
+
   before_action :set_instance_presenter, only: [:show, :more, :terms]
 
+  skip_before_action :check_user_permissions, only: [:more, :terms]
+
   def show
-    serializable_resource = ActiveModelSerializers::SerializableResource.new(InitialStatePresenter.new(initial_state_params), serializer: InitialStateSerializer)
-    @initial_state_json   = serializable_resource.to_json
+    @hide_navbar = true
   end
 
-  def more
-    render layout: 'public'
-  end
+  def more; end
 
-  def terms
-    render layout: 'public'
-  end
+  def terms; end
 
   private
 
   def new_user
-    User.new.tap(&:build_account)
+    User.new.tap do |user|
+      user.build_account
+      user.build_invite_request
+    end
   end
 
   helper_method :new_user
@@ -28,15 +29,4 @@ class AboutController < ApplicationController
   def set_instance_presenter
     @instance_presenter = InstancePresenter.new
   end
-
-  def set_body_classes
-    @body_classes = 'with-modals'
-  end
-
-  def initial_state_params
-    {
-      settings: { known_fediverse: Setting.show_known_fediverse_at_about_page },
-      token: current_session&.token,
-    }
-  end
 end
diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb
index f788a907893059ca3abad0e94745115863d9495f..73a4b1859c34ea9efda760cc91292f5ad7856836 100644
--- a/app/controllers/accounts_controller.rb
+++ b/app/controllers/accounts_controller.rb
@@ -10,6 +10,8 @@ class AccountsController < ApplicationController
   def show
     respond_to do |format|
       format.html do
+        mark_cacheable! unless user_signed_in?
+
         @body_classes      = 'with-modals'
         @pinned_statuses   = []
         @endorsed_accounts = @account.endorsed_accounts.to_a.sample(4)
@@ -30,18 +32,20 @@ class AccountsController < ApplicationController
       end
 
       format.atom do
+        mark_cacheable!
+
         @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
 
       format.rss do
+        mark_cacheable!
+
         @statuses = cache_collection(default_statuses.without_reblogs.without_replies.limit(PAGE_SIZE), Status)
         render xml: RSS::AccountSerializer.render(@account, @statuses)
       end
 
       format.json do
-        skip_session!
-
         render_cached_json(['activitypub', 'actor', @account], content_type: 'application/activity+json') do
           ActiveModelSerializers::SerializableResource.new(@account, serializer: ActivityPub::ActorSerializer, adapter: ActivityPub::Adapter)
         end
@@ -52,11 +56,12 @@ class AccountsController < ApplicationController
   private
 
   def show_pinned_statuses?
-    [replies_requested?, media_requested?, params[:max_id].present?, params[:min_id].present?].none?
+    [replies_requested?, media_requested?, tag_requested?, params[:max_id].present?, params[:min_id].present?].none?
   end
 
   def filtered_statuses
     default_statuses.tap do |statuses|
+      statuses.merge!(hashtag_scope)    if tag_requested?
       statuses.merge!(only_media_scope) if media_requested?
       statuses.merge!(no_replies_scope) unless replies_requested?
     end
@@ -78,12 +83,21 @@ class AccountsController < ApplicationController
     Status.without_replies
   end
 
-  def set_account
-    @account = Account.find_local!(params[:username])
+  def hashtag_scope
+    tag = Tag.find_normalized(params[:tag])
+
+    if tag
+      Status.tagged_with(tag.id)
+    else
+      Status.none
+    end
+  end
+
+  def username_param
+    params[:username]
   end
 
   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
 
@@ -92,7 +106,9 @@ class AccountsController < ApplicationController
   end
 
   def pagination_url(max_id: nil, min_id: nil)
-    if media_requested?
+    if tag_requested?
+      short_account_tag_url(@account, params[:tag], max_id: max_id, min_id: min_id)
+    elsif media_requested?
       short_account_media_url(@account, max_id: max_id, min_id: min_id)
     elsif replies_requested?
       short_account_with_replies_url(@account, max_id: max_id, min_id: min_id)
@@ -109,6 +125,10 @@ class AccountsController < ApplicationController
     request.path.ends_with?('/with_replies')
   end
 
+  def tag_requested?
+    request.path.ends_with?(Addressable::URI.parse("/tagged/#{params[:tag]}").normalize)
+  end
+
   def filtered_status_page(params)
     if params[:min_id].present?
       filtered_statuses.paginate_by_min_id(PAGE_SIZE, params[:min_id]).reverse
diff --git a/app/controllers/activitypub/collections_controller.rb b/app/controllers/activitypub/collections_controller.rb
index 995da9c55dc0858f814d56f584c27e8a9274003c..012c3c53885846e6ca5d33387e2c6dc0d1926285 100644
--- a/app/controllers/activitypub/collections_controller.rb
+++ b/app/controllers/activitypub/collections_controller.rb
@@ -6,13 +6,17 @@ class ActivityPub::CollectionsController < Api::BaseController
   before_action :set_account
   before_action :set_size
   before_action :set_statuses
+  before_action :set_cache_headers
 
   def show
-    render json: collection_presenter,
-           serializer: ActivityPub::CollectionSerializer,
-           adapter: ActivityPub::Adapter,
-           content_type: 'application/activity+json',
-           skip_activities: true
+    render_cached_json(['activitypub', 'collection', @account, params[:id]], content_type: 'application/activity+json') do
+      ActiveModelSerializers::SerializableResource.new(
+        collection_presenter,
+        serializer: ActivityPub::CollectionSerializer,
+        adapter: ActivityPub::Adapter,
+        skip_activities: true
+      )
+    end
   end
 
   private
diff --git a/app/controllers/activitypub/inboxes_controller.rb b/app/controllers/activitypub/inboxes_controller.rb
index 8f5e1887ea427525bb72bca04d1405d756978d57..a0b7532c2e0ccedd25ba86504d635eea4ec519ea 100644
--- a/app/controllers/activitypub/inboxes_controller.rb
+++ b/app/controllers/activitypub/inboxes_controller.rb
@@ -2,11 +2,14 @@
 
 class ActivityPub::InboxesController < Api::BaseController
   include SignatureVerification
+  include JsonLdHelper
 
   before_action :set_account
 
   def create
-    if signed_request_account
+    if unknown_deleted_account?
+      head 202
+    elsif signed_request_account
       upgrade_account
       process_payload
       head 202
@@ -17,12 +20,22 @@ class ActivityPub::InboxesController < Api::BaseController
 
   private
 
+  def unknown_deleted_account?
+    json = Oj.load(body, mode: :strict)
+    json['type'] == 'Delete' && json['actor'].present? && json['actor'] == value_or_id(json['object']) && !Account.where(uri: json['actor']).exists?
+  rescue Oj::ParseError
+    false
+  end
+
   def set_account
     @account = Account.find_local!(params[:account_username]) if params[:account_username]
   end
 
   def body
-    @body ||= request.body.read
+    return @body if defined?(@body)
+    @body = request.body.read.force_encoding('UTF-8')
+    request.body.rewind if request.body.respond_to?(:rewind)
+    @body
   end
 
   def upgrade_account
@@ -36,6 +49,6 @@ class ActivityPub::InboxesController < Api::BaseController
   end
 
   def process_payload
-    ActivityPub::ProcessingWorker.perform_async(signed_request_account.id, body.force_encoding('UTF-8'), @account&.id)
+    ActivityPub::ProcessingWorker.perform_async(signed_request_account.id, body, @account&.id)
   end
 end
diff --git a/app/controllers/activitypub/outboxes_controller.rb b/app/controllers/activitypub/outboxes_controller.rb
index be4289b21c3f58531416b9914015bdc455d0ce59..5147afbf7822f8fb7651dc0b97081042a39a6a53 100644
--- a/app/controllers/activitypub/outboxes_controller.rb
+++ b/app/controllers/activitypub/outboxes_controller.rb
@@ -7,8 +7,11 @@ class ActivityPub::OutboxesController < Api::BaseController
 
   before_action :set_account
   before_action :set_statuses
+  before_action :set_cache_headers
 
   def show
+    expires_in 1.minute, public: true unless page_requested?
+
     render json: outbox_presenter, serializer: ActivityPub::OutboxSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
   end
 
diff --git a/app/controllers/admin/accounts_controller.rb b/app/controllers/admin/accounts_controller.rb
index 562fba9960dd21d8e9ceeb7cee72302a847bf8a7..0c7760d779932c83fe7ec18f9dbbc83f5f6602b0 100644
--- a/app/controllers/admin/accounts_controller.rb
+++ b/app/controllers/admin/accounts_controller.rb
@@ -2,9 +2,9 @@
 
 module Admin
   class AccountsController < BaseController
-    before_action :set_account, only: [:show, :subscribe, :unsubscribe, :redownload, :remove_avatar, :remove_header, :enable, :unsilence, :unsuspend, :memorialize]
+    before_action :set_account, only: [:show, :subscribe, :unsubscribe, :redownload, :remove_avatar, :remove_header, :enable, :unsilence, :unsuspend, :memorialize, :approve, :reject]
     before_action :require_remote_account!, only: [:subscribe, :unsubscribe, :redownload]
-    before_action :require_local_account!, only: [:enable, :memorialize]
+    before_action :require_local_account!, only: [:enable, :memorialize, :approve, :reject]
 
     def index
       authorize :account, :index?
@@ -45,6 +45,18 @@ module Admin
       redirect_to admin_account_path(@account.id)
     end
 
+    def approve
+      authorize @account.user, :approve?
+      @account.user.approve!
+      redirect_to admin_pending_accounts_path
+    end
+
+    def reject
+      authorize @account.user, :reject?
+      SuspendAccountService.new.call(@account, including_user: true, destroy: true, skip_distribution: true)
+      redirect_to admin_pending_accounts_path
+    end
+
     def unsilence
       authorize @account, :unsilence?
       @account.unsilence!
@@ -114,6 +126,8 @@ module Admin
         :remote,
         :by_domain,
         :active,
+        :pending,
+        :disabled,
         :silenced,
         :suspended,
         :username,
diff --git a/app/controllers/admin/custom_emojis_controller.rb b/app/controllers/admin/custom_emojis_controller.rb
index d61bafdf02d7d9b696d25db8bb96059f3b752451..f77699166769fd07cd21815444b9093adcc2bb3f 100644
--- a/app/controllers/admin/custom_emojis_controller.rb
+++ b/app/controllers/admin/custom_emojis_controller.rb
@@ -5,6 +5,9 @@ module Admin
     before_action :set_custom_emoji, except: [:index, :new, :create]
     before_action :set_filter_params
 
+    include ObfuscateFilename
+    obfuscate_filename [:custom_emoji, :image]
+
     def index
       authorize :custom_emoji, :index?
       @custom_emojis = filtered_custom_emojis.eager_load(:local_counterpart).page(params[:page])
diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb
index bb923c18594c78fee477a00eee9238466e715a4e..f23ed15086214372da97698925986669d6891636 100644
--- a/app/controllers/admin/dashboard_controller.rb
+++ b/app/controllers/admin/dashboard_controller.rb
@@ -10,7 +10,7 @@ module Admin
       @interactions_week     = Redis.current.get("activity:interactions:#{current_week}") || 0
       @relay_enabled         = Relay.enabled.exists?
       @single_user_mode      = Rails.configuration.x.single_user_mode
-      @registrations_enabled = Setting.open_registrations
+      @registrations_enabled = Setting.registrations_mode != 'none'
       @deletions_enabled     = Setting.open_deletion
       @invites_enabled       = Setting.min_invite_role == 'user'
       @search_enabled        = Chewy.enabled?
@@ -29,6 +29,7 @@ module Admin
       @hidden_service        = ENV['ALLOW_ACCESS_TO_HIDDEN_SERVICE'] == 'true'
       @trending_hashtags     = TrendingTags.get(7)
       @profile_directory     = Setting.profile_directory
+      @timeline_preview      = Setting.timeline_preview
     end
 
     private
diff --git a/app/controllers/admin/domain_blocks_controller.rb b/app/controllers/admin/domain_blocks_controller.rb
index 5f307ddeeca04564e75a93c18bc64656c0f2dd79..7129656dabfe5e9674cff9cfd82800a468ec8d45 100644
--- a/app/controllers/admin/domain_blocks_controller.rb
+++ b/app/controllers/admin/domain_blocks_controller.rb
@@ -13,13 +13,25 @@ module Admin
       authorize :domain_block, :create?
 
       @domain_block = DomainBlock.new(resource_params)
+      existing_domain_block = resource_params[:domain].present? ? DomainBlock.rule_for(resource_params[:domain]) : nil
 
-      if @domain_block.save
-        DomainBlockWorker.perform_async(@domain_block.id)
-        log_action :create, @domain_block
-        redirect_to admin_instances_path(limited: '1'), notice: I18n.t('admin.domain_blocks.created_msg')
-      else
+      if existing_domain_block.present? && !@domain_block.stricter_than?(existing_domain_block)
+        @domain_block.save
+        flash.now[:alert] = I18n.t('admin.domain_blocks.existing_domain_block_html', name: existing_domain_block.domain, unblock_url: admin_domain_block_path(existing_domain_block)).html_safe # rubocop:disable Rails/OutputSafety
+        @domain_block.errors[:domain].clear
         render :new
+      else
+        if existing_domain_block.present?
+          @domain_block = existing_domain_block
+          @domain_block.update(resource_params)
+        end
+        if @domain_block.save
+          DomainBlockWorker.perform_async(@domain_block.id)
+          log_action :create, @domain_block
+          redirect_to admin_instances_path(limited: '1'), notice: I18n.t('admin.domain_blocks.created_msg')
+        else
+          render :new
+        end
       end
     end
 
@@ -29,7 +41,7 @@ module Admin
 
     def destroy
       authorize @domain_block, :destroy?
-      UnblockDomainService.new.call(@domain_block, retroactive_unblock?)
+      UnblockDomainService.new.call(@domain_block)
       log_action :destroy, @domain_block
       redirect_to admin_instances_path(limited: '1'), notice: I18n.t('admin.domain_blocks.destroyed_msg')
     end
@@ -41,11 +53,7 @@ module Admin
     end
 
     def resource_params
-      params.require(:domain_block).permit(:domain, :severity, :reject_media, :reject_reports, :retroactive)
-    end
-
-    def retroactive_unblock?
-      ActiveRecord::Type.lookup(:boolean).cast(resource_params[:retroactive])
+      params.require(:domain_block).permit(:domain, :severity, :reject_media, :reject_reports)
     end
   end
 end
diff --git a/app/controllers/admin/instances_controller.rb b/app/controllers/admin/instances_controller.rb
index 431ce6f4de1768696e2d0ff5880dd26711eb1844..7888e844fb5abc0a2840ca7795e9462870e28650 100644
--- a/app/controllers/admin/instances_controller.rb
+++ b/app/controllers/admin/instances_controller.rb
@@ -18,7 +18,7 @@ module Admin
       @blocks_count    = Block.where(target_account: Account.where(domain: params[:id])).count
       @available       = DeliveryFailureTracker.available?(Account.select(:shared_inbox_url).where(domain: params[:id]).first&.shared_inbox_url)
       @media_storage   = MediaAttachment.where(account: Account.where(domain: params[:id])).sum(:file_file_size)
-      @domain_block    = DomainBlock.find_by(domain: params[:id])
+      @domain_block    = DomainBlock.rule_for(params[:id])
     end
 
     private
@@ -38,7 +38,7 @@ module Admin
     end
 
     def filter_params
-      params.permit(:limited)
+      params.permit(:limited, :by_domain)
     end
   end
 end
diff --git a/app/controllers/admin/pending_accounts_controller.rb b/app/controllers/admin/pending_accounts_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b62a9bc8466af9b72d74b5ae524f9fdcf71ab181
--- /dev/null
+++ b/app/controllers/admin/pending_accounts_controller.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+module Admin
+  class PendingAccountsController < BaseController
+    before_action :set_accounts, only: :index
+
+    def index
+      @form = Form::AccountBatch.new
+    end
+
+    def batch
+      @form = Form::AccountBatch.new(form_account_batch_params.merge(current_account: current_account, action: action_from_button))
+      @form.save
+    rescue ActionController::ParameterMissing
+      flash[:alert] = I18n.t('admin.accounts.no_account_selected')
+    ensure
+      redirect_to admin_pending_accounts_path(current_params)
+    end
+
+    def approve_all
+      Form::AccountBatch.new(current_account: current_account, account_ids: User.pending.pluck(:account_id), action: 'approve').save
+      redirect_to admin_pending_accounts_path(current_params)
+    end
+
+    def reject_all
+      Form::AccountBatch.new(current_account: current_account, account_ids: User.pending.pluck(:account_id), action: 'reject').save
+      redirect_to admin_pending_accounts_path(current_params)
+    end
+
+    private
+
+    def set_accounts
+      @accounts = Account.joins(:user).merge(User.pending.recent).includes(user: :invite_request).page(params[:page])
+    end
+
+    def form_account_batch_params
+      params.require(:form_account_batch).permit(:action, account_ids: [])
+    end
+
+    def action_from_button
+      if params[:approve]
+        'approve'
+      elsif params[:reject]
+        'reject'
+      end
+    end
+
+    def current_params
+      params.slice(:page).permit(:page)
+    end
+  end
+end
diff --git a/app/controllers/admin/reported_statuses_controller.rb b/app/controllers/admin/reported_statuses_controller.rb
index d3c2f5e9e9fb704a6dd1ec7a4247e76e84150cb0..3ba9f5df21e8d47db5c016d9ec47d58ae444d7f0 100644
--- a/app/controllers/admin/reported_statuses_controller.rb
+++ b/app/controllers/admin/reported_statuses_controller.rb
@@ -10,6 +10,10 @@ module Admin
       @form         = Form::StatusBatch.new(form_status_batch_params.merge(current_account: current_account, action: action_from_button))
       flash[:alert] = I18n.t('admin.statuses.failed_to_execute') unless @form.save
 
+      redirect_to admin_report_path(@report)
+    rescue ActionController::ParameterMissing
+      flash[:alert] = I18n.t('admin.statuses.no_status_selected')
+
       redirect_to admin_report_path(@report)
     end
 
diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb
index 4a049fc235638a649dad3f4045e6c2a521f36b84..dc1c79b7fd7747c5e88726d089700352de88b235 100644
--- a/app/controllers/admin/settings_controller.rb
+++ b/app/controllers/admin/settings_controller.rb
@@ -2,85 +2,29 @@
 
 module Admin
   class SettingsController < BaseController
-    ADMIN_SETTINGS = %w(
-      site_contact_username
-      site_contact_email
-      site_title
-      site_short_description
-      site_description
-      site_extended_description
-      site_terms
-      open_registrations
-      closed_registrations_message
-      open_deletion
-      timeline_preview
-      show_staff_badge
-      bootstrap_timeline_accounts
-      theme
-      thumbnail
-      hero
-      mascot
-      min_invite_role
-      activity_api_enabled
-      peers_api_enabled
-      show_known_fediverse_at_about_page
-      preview_sensitive_media
-      custom_css
-      profile_directory
-    ).freeze
-
-    BOOLEAN_SETTINGS = %w(
-      open_registrations
-      open_deletion
-      timeline_preview
-      show_staff_badge
-      activity_api_enabled
-      peers_api_enabled
-      show_known_fediverse_at_about_page
-      preview_sensitive_media
-      profile_directory
-    ).freeze
-
-    UPLOAD_SETTINGS = %w(
-      thumbnail
-      hero
-      mascot
-    ).freeze
-
     def edit
       authorize :settings, :show?
+
       @admin_settings = Form::AdminSettings.new
     end
 
     def update
       authorize :settings, :update?
 
-      settings_params.each do |key, value|
-        if UPLOAD_SETTINGS.include?(key)
-          upload = SiteUpload.where(var: key).first_or_initialize(var: key)
-          upload.update(file: value)
-        else
-          setting = Setting.where(var: key).first_or_initialize(var: key)
-          setting.update(value: value_for_update(key, value))
-        end
-      end
+      @admin_settings = Form::AdminSettings.new(settings_params)
 
-      flash[:notice] = I18n.t('generic.changes_saved_msg')
-      redirect_to edit_admin_settings_path
+      if @admin_settings.save
+        flash[:notice] = I18n.t('generic.changes_saved_msg')
+        redirect_to edit_admin_settings_path
+      else
+        render :edit
+      end
     end
 
     private
 
     def settings_params
-      params.require(:form_admin_settings).permit(ADMIN_SETTINGS)
-    end
-
-    def value_for_update(key, value)
-      if BOOLEAN_SETTINGS.include?(key)
-        value == '1'
-      else
-        value
-      end
+      params.require(:form_admin_settings).permit(*Form::AdminSettings::KEYS)
     end
   end
 end
diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb
index a1dd30918f34550758f1b5c3d7d38c1bfd0a1b8d..eca558f4216ee1f8e565867a6dfe39ee5420463b 100644
--- a/app/controllers/api/base_controller.rb
+++ b/app/controllers/api/base_controller.rb
@@ -9,6 +9,8 @@ class Api::BaseController < ApplicationController
   skip_before_action :store_current_location
   skip_before_action :check_user_permissions
 
+  before_action :set_cache_headers
+
   protect_from_forgery with: :null_session
 
   rescue_from ActiveRecord::RecordInvalid, Mastodon::ValidationError do |e|
@@ -73,7 +75,9 @@ class Api::BaseController < ApplicationController
     elsif current_user.disabled?
       render json: { error: 'Your login is currently disabled' }, status: 403
     elsif !current_user.confirmed?
-      render json: { error: 'Email confirmation is not completed' }, status: 403
+      render json: { error: 'Your login is missing a confirmed e-mail address' }, status: 403
+    elsif !current_user.approved?
+      render json: { error: 'Your login is currently pending approval' }, status: 403
     else
       set_user_activity
     end
@@ -86,4 +90,8 @@ class Api::BaseController < ApplicationController
   def authorize_if_got_token!(*scopes)
     doorkeeper_authorize!(*scopes) if doorkeeper_token
   end
+
+  def set_cache_headers
+    response.headers['Cache-Control'] = 'no-cache, no-store, max-age=0, must-revalidate'
+  end
 end
diff --git a/app/controllers/api/proofs_controller.rb b/app/controllers/api/proofs_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a84ad2014fe7320135257bdec73943ec55f47952
--- /dev/null
+++ b/app/controllers/api/proofs_controller.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+class Api::ProofsController < Api::BaseController
+  before_action :set_account
+  before_action :set_provider
+  before_action :check_account_approval
+  before_action :check_account_suspension
+
+  def index
+    render json: @account, serializer: @provider.serializer_class
+  end
+
+  private
+
+  def set_provider
+    @provider = ProofProvider.find(params[:provider]) || raise(ActiveRecord::RecordNotFound)
+  end
+
+  def set_account
+    @account = Account.find_local!(params[:username])
+  end
+
+  def check_account_approval
+    not_found if @account.user_pending?
+  end
+
+  def check_account_suspension
+    gone if @account.suspended?
+  end
+end
diff --git a/app/controllers/api/v1/accounts/follower_accounts_controller.rb b/app/controllers/api/v1/accounts/follower_accounts_controller.rb
index ec15debb0cf4646f640477765acfc126af3a2e29..2dabb8398c13165effa3cec8194ba138cfd2b50a 100644
--- a/app/controllers/api/v1/accounts/follower_accounts_controller.rb
+++ b/app/controllers/api/v1/accounts/follower_accounts_controller.rb
@@ -19,11 +19,15 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController
   end
 
   def load_accounts
-    return [] if @account.user_hides_network? && current_account.id != @account.id
+    return [] if hide_results?
 
     default_accounts.merge(paginated_follows).to_a
   end
 
+  def hide_results?
+    (@account.user_hides_network? && current_account.id != @account.id) || (current_account && @account.blocking?(current_account))
+  end
+
   def default_accounts
     Account.includes(:active_relationships, :account_stat).references(:active_relationships)
   end
diff --git a/app/controllers/api/v1/accounts/following_accounts_controller.rb b/app/controllers/api/v1/accounts/following_accounts_controller.rb
index f3e112f2c3e2e80714d43697015f5dbf09bf9958..44e89804b377e40a470182cb3ba2038d1050362b 100644
--- a/app/controllers/api/v1/accounts/following_accounts_controller.rb
+++ b/app/controllers/api/v1/accounts/following_accounts_controller.rb
@@ -19,11 +19,15 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController
   end
 
   def load_accounts
-    return [] if @account.user_hides_network? && current_account.id != @account.id
+    return [] if hide_results?
 
     default_accounts.merge(paginated_follows).to_a
   end
 
+  def hide_results?
+    (@account.user_hides_network? && current_account.id != @account.id) || (current_account && @account.blocking?(current_account))
+  end
+
   def default_accounts
     Account.includes(:passive_relationships, :account_stat).references(:passive_relationships)
   end
diff --git a/app/controllers/api/v1/accounts/identity_proofs_controller.rb b/app/controllers/api/v1/accounts/identity_proofs_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..bea51ae1194c73c3e75f1d4f6cb4da1b527f361b
--- /dev/null
+++ b/app/controllers/api/v1/accounts/identity_proofs_controller.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class Api::V1::Accounts::IdentityProofsController < Api::BaseController
+  before_action :require_user!
+  before_action :set_account
+
+  respond_to :json
+
+  def index
+    @proofs = @account.identity_proofs.active
+    render json: @proofs, each_serializer: REST::IdentityProofSerializer
+  end
+
+  private
+
+  def set_account
+    @account = Account.find(params[:account_id])
+  end
+end
diff --git a/app/controllers/api/v1/accounts/search_controller.rb b/app/controllers/api/v1/accounts/search_controller.rb
index 91c9f154728e48affef0f316f2f0749f888fd80b..4217b527a59377f8da19e1ca344518c19b7c83a5 100644
--- a/app/controllers/api/v1/accounts/search_controller.rb
+++ b/app/controllers/api/v1/accounts/search_controller.rb
@@ -16,10 +16,11 @@ class Api::V1::Accounts::SearchController < Api::BaseController
   def account_search
     AccountSearchService.new.call(
       params[:q],
-      limit_param(DEFAULT_ACCOUNTS_LIMIT),
       current_account,
+      limit: limit_param(DEFAULT_ACCOUNTS_LIMIT),
       resolve: truthy_param?(:resolve),
-      following: truthy_param?(:following)
+      following: truthy_param?(:following),
+      offset: params[:offset]
     )
   end
 end
diff --git a/app/controllers/api/v1/accounts/statuses_controller.rb b/app/controllers/api/v1/accounts/statuses_controller.rb
index 6c2a5c141431c17d579cf6f2d4c017086b702bd2..13cb4caf1203c03b018fa42bf152fbd3a8494b63 100644
--- a/app/controllers/api/v1/accounts/statuses_controller.rb
+++ b/app/controllers/api/v1/accounts/statuses_controller.rb
@@ -3,7 +3,8 @@
 class Api::V1::Accounts::StatusesController < Api::BaseController
   before_action -> { authorize_if_got_token! :read, :'read:statuses' }
   before_action :set_account
-  after_action :insert_pagination_headers
+
+  after_action :insert_pagination_headers, unless: -> { truthy_param?(:pinned) }
 
   respond_to :json
 
@@ -33,6 +34,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
     statuses.merge!(only_media_scope) if truthy_param?(:only_media)
     statuses.merge!(no_replies_scope) if truthy_param?(:exclude_replies)
     statuses.merge!(no_reblogs_scope) if truthy_param?(:exclude_reblogs)
+    statuses.merge!(hashtag_scope)    if params[:tagged].present?
 
     statuses
   end
@@ -50,9 +52,9 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
     # Also, Avoid getting slow by not narrowing down by `statuses.account_id`.
     # When narrowing down by `statuses.account_id`, `index_statuses_20180106` will be used
     # and the table will be joined by `Merge Semi Join`, so the query will be slow.
-    Status.joins(:media_attachments).merge(@account.media_attachments).permitted_for(@account, current_account)
-          .paginate_by_max_id(limit_param(DEFAULT_STATUSES_LIMIT), params[:max_id], params[:since_id])
-          .reorder(id: :desc).distinct(:id).pluck(:id)
+    @account.statuses.joins(:media_attachments).merge(@account.media_attachments).permitted_for(@account, current_account)
+            .paginate_by_max_id(limit_param(DEFAULT_STATUSES_LIMIT), params[:max_id], params[:since_id])
+            .reorder(id: :desc).distinct(:id).pluck(:id)
   end
 
   def pinned_scope
@@ -67,6 +69,16 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
     Status.without_reblogs
   end
 
+  def hashtag_scope
+    tag = Tag.find_normalized(params[:tagged])
+
+    if tag
+      Status.tagged_with(tag.id)
+    else
+      Status.none
+    end
+  end
+
   def pagination_params(core_params)
     params.slice(:limit, :only_media, :exclude_replies).permit(:limit, :only_media, :exclude_replies).merge(core_params)
   end
diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb
index 2ccbc3cbbdf50e1d64cd6292a3bdb133b29759c5..b0c62778e6563abe7894ff52e9493a1a377a89ab 100644
--- a/app/controllers/api/v1/accounts_controller.rb
+++ b/app/controllers/api/v1/accounts_controller.rb
@@ -80,6 +80,10 @@ class Api::V1::AccountsController < Api::BaseController
   end
 
   def check_enabled_registrations
-    forbidden if single_user_mode? || !Setting.open_registrations
+    forbidden if single_user_mode? || !allowed_registrations?
+  end
+
+  def allowed_registrations?
+    Setting.registrations_mode != 'none'
   end
 end
diff --git a/app/controllers/api/v1/admin/account_actions_controller.rb b/app/controllers/api/v1/admin/account_actions_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..29c9b7107bf1a1cec4c065036d991abb8a177f08
--- /dev/null
+++ b/app/controllers/api/v1/admin/account_actions_controller.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+class Api::V1::Admin::AccountActionsController < Api::BaseController
+  before_action -> { doorkeeper_authorize! :'admin:write', :'admin:write:accounts' }
+  before_action :require_staff!
+  before_action :set_account
+
+  def create
+    account_action                 = Admin::AccountAction.new(resource_params)
+    account_action.target_account  = @account
+    account_action.current_account = current_account
+    account_action.save!
+
+    render_empty
+  end
+
+  private
+
+  def set_account
+    @account = Account.find(params[:account_id])
+  end
+
+  def resource_params
+    params.permit(
+      :type,
+      :report_id,
+      :warning_preset_id,
+      :text,
+      :send_email_notification
+    )
+  end
+end
diff --git a/app/controllers/api/v1/admin/accounts_controller.rb b/app/controllers/api/v1/admin/accounts_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c306180ca25169a355b980a0237e479e5e7eaa1f
--- /dev/null
+++ b/app/controllers/api/v1/admin/accounts_controller.rb
@@ -0,0 +1,128 @@
+# frozen_string_literal: true
+
+class Api::V1::Admin::AccountsController < Api::BaseController
+  include Authorization
+  include AccountableConcern
+
+  LIMIT = 100
+
+  before_action -> { doorkeeper_authorize! :'admin:read', :'admin:read:accounts' }, only: [:index, :show]
+  before_action -> { doorkeeper_authorize! :'admin:write', :'admin:write:accounts' }, except: [:index, :show]
+  before_action :require_staff!
+  before_action :set_accounts, only: :index
+  before_action :set_account, except: :index
+  before_action :require_local_account!, only: [:enable, :approve, :reject]
+
+  after_action :insert_pagination_headers, only: :index
+
+  FILTER_PARAMS = %i(
+    local
+    remote
+    by_domain
+    active
+    pending
+    disabled
+    silenced
+    suspended
+    username
+    display_name
+    email
+    ip
+    staff
+  ).freeze
+
+  PAGINATION_PARAMS = (%i(limit) + FILTER_PARAMS).freeze
+
+  def index
+    authorize :account, :index?
+    render json: @accounts, each_serializer: REST::Admin::AccountSerializer
+  end
+
+  def show
+    authorize @account, :show?
+    render json: @account, serializer: REST::Admin::AccountSerializer
+  end
+
+  def enable
+    authorize @account.user, :enable?
+    @account.user.enable!
+    log_action :enable, @account.user
+    render json: @account, serializer: REST::Admin::AccountSerializer
+  end
+
+  def approve
+    authorize @account.user, :approve?
+    @account.user.approve!
+    render json: @account, serializer: REST::Admin::AccountSerializer
+  end
+
+  def reject
+    authorize @account.user, :reject?
+    SuspendAccountService.new.call(@account, including_user: true, destroy: true, skip_distribution: true)
+    render json: @account, serializer: REST::Admin::AccountSerializer
+  end
+
+  def unsilence
+    authorize @account, :unsilence?
+    @account.unsilence!
+    log_action :unsilence, @account
+    render json: @account, serializer: REST::Admin::AccountSerializer
+  end
+
+  def unsuspend
+    authorize @account, :unsuspend?
+    @account.unsuspend!
+    log_action :unsuspend, @account
+    render json: @account, serializer: REST::Admin::AccountSerializer
+  end
+
+  private
+
+  def set_accounts
+    @accounts = filtered_accounts.order(id: :desc).includes(user: [:invite_request, :invite]).paginate_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
+  end
+
+  def set_account
+    @account = Account.find(params[:id])
+  end
+
+  def filtered_accounts
+    AccountFilter.new(filter_params).results
+  end
+
+  def filter_params
+    params.permit(*FILTER_PARAMS)
+  end
+
+  def insert_pagination_headers
+    set_pagination_headers(next_path, prev_path)
+  end
+
+  def next_path
+    api_v1_admin_accounts_url(pagination_params(max_id: pagination_max_id)) if records_continue?
+  end
+
+  def prev_path
+    api_v1_admin_accounts_url(pagination_params(min_id: pagination_since_id)) unless @accounts.empty?
+  end
+
+  def pagination_max_id
+    @accounts.last.id
+  end
+
+  def pagination_since_id
+    @accounts.first.id
+  end
+
+  def records_continue?
+    @accounts.size == limit_param(LIMIT)
+  end
+
+  def pagination_params(core_params)
+    params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params)
+  end
+
+  def require_local_account!
+    forbidden unless @account.local? && @account.user.present?
+  end
+end
diff --git a/app/controllers/api/v1/admin/reports_controller.rb b/app/controllers/api/v1/admin/reports_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1d48d3160fc7b28e54bf5f1932ddd53ef3ef1aac
--- /dev/null
+++ b/app/controllers/api/v1/admin/reports_controller.rb
@@ -0,0 +1,108 @@
+# frozen_string_literal: true
+
+class Api::V1::Admin::ReportsController < Api::BaseController
+  include Authorization
+  include AccountableConcern
+
+  LIMIT = 100
+
+  before_action -> { doorkeeper_authorize! :'admin:read', :'admin:read:reports' }, only: [:index, :show]
+  before_action -> { doorkeeper_authorize! :'admin:write', :'admin:write:reports' }, except: [:index, :show]
+  before_action :require_staff!
+  before_action :set_reports, only: :index
+  before_action :set_report, except: :index
+
+  after_action :insert_pagination_headers, only: :index
+
+  FILTER_PARAMS = %i(
+    resolved
+    account_id
+    target_account_id
+  ).freeze
+
+  PAGINATION_PARAMS = (%i(limit) + FILTER_PARAMS).freeze
+
+  def index
+    authorize :report, :index?
+    render json: @reports, each_serializer: REST::Admin::ReportSerializer
+  end
+
+  def show
+    authorize @report, :show?
+    render json: @report, serializer: REST::Admin::ReportSerializer
+  end
+
+  def assign_to_self
+    authorize @report, :update?
+    @report.update!(assigned_account_id: current_account.id)
+    log_action :assigned_to_self, @report
+    render json: @report, serializer: REST::Admin::ReportSerializer
+  end
+
+  def unassign
+    authorize @report, :update?
+    @report.update!(assigned_account_id: nil)
+    log_action :unassigned, @report
+    render json: @report, serializer: REST::Admin::ReportSerializer
+  end
+
+  def reopen
+    authorize @report, :update?
+    @report.unresolve!
+    log_action :reopen, @report
+    render json: @report, serializer: REST::Admin::ReportSerializer
+  end
+
+  def resolve
+    authorize @report, :update?
+    @report.resolve!(current_account)
+    log_action :resolve, @report
+    render json: @report, serializer: REST::Admin::ReportSerializer
+  end
+
+  private
+
+  def set_reports
+    @reports = filtered_reports.order(id: :desc).with_accounts.paginate_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
+  end
+
+  def set_report
+    @report = Report.find(params[:id])
+  end
+
+  def filtered_reports
+    ReportFilter.new(filter_params).results
+  end
+
+  def filter_params
+    params.permit(*FILTER_PARAMS)
+  end
+
+  def insert_pagination_headers
+    set_pagination_headers(next_path, prev_path)
+  end
+
+  def next_path
+    api_v1_admin_reports_url(pagination_params(max_id: pagination_max_id)) if records_continue?
+  end
+
+  def prev_path
+    api_v1_admin_reports_url(pagination_params(min_id: pagination_since_id)) unless @reports.empty?
+  end
+
+  def pagination_max_id
+    @reports.last.id
+  end
+
+  def pagination_since_id
+    @reports.first.id
+  end
+
+  def records_continue?
+    @reports.size == limit_param(LIMIT)
+  end
+
+  def pagination_params(core_params)
+    params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params)
+  end
+end
diff --git a/app/controllers/api/v1/apps/credentials_controller.rb b/app/controllers/api/v1/apps/credentials_controller.rb
index e469c7d210459ed1139b602669603c00955407da..8b63d0490d173af483469c21eb0391d984b42913 100644
--- a/app/controllers/api/v1/apps/credentials_controller.rb
+++ b/app/controllers/api/v1/apps/credentials_controller.rb
@@ -6,6 +6,6 @@ class Api::V1::Apps::CredentialsController < Api::BaseController
   respond_to :json
 
   def show
-    render json: doorkeeper_token.application, serializer: REST::StatusSerializer::ApplicationSerializer
+    render json: doorkeeper_token.application, serializer: REST::ApplicationSerializer, fields: %i(name website vapid_key)
   end
 end
diff --git a/app/controllers/api/v1/custom_emojis_controller.rb b/app/controllers/api/v1/custom_emojis_controller.rb
index 7bac27da4b78dd3689f16794751c525f1870e029..1bb19a09d33ec4e3581f245154a001d2713b96d6 100644
--- a/app/controllers/api/v1/custom_emojis_controller.rb
+++ b/app/controllers/api/v1/custom_emojis_controller.rb
@@ -3,6 +3,8 @@
 class Api::V1::CustomEmojisController < Api::BaseController
   respond_to :json
 
+  skip_before_action :set_cache_headers
+
   def index
     render_cached_json('api:v1:custom_emojis', expires_in: 1.minute) do
       ActiveModelSerializers::SerializableResource.new(CustomEmoji.local.where(disabled: false), each_serializer: REST::CustomEmojiSerializer)
diff --git a/app/controllers/api/v1/instances/activity_controller.rb b/app/controllers/api/v1/instances/activity_controller.rb
index e14e0aee8341c1d7819b50f6f51ac2ebb0caac62..09edfe365b07df3c057e3ca63f5dcb2a0c973ac3 100644
--- a/app/controllers/api/v1/instances/activity_controller.rb
+++ b/app/controllers/api/v1/instances/activity_controller.rb
@@ -2,6 +2,7 @@
 
 class Api::V1::Instances::ActivityController < Api::BaseController
   before_action :require_enabled_api!
+  skip_before_action :set_cache_headers
 
   respond_to :json
 
diff --git a/app/controllers/api/v1/instances/peers_controller.rb b/app/controllers/api/v1/instances/peers_controller.rb
index 2070c487df12bfc3f9d46e3bca623166d76ff4a5..a8891d126bfd379895bc9eeea87b691d7ba926cc 100644
--- a/app/controllers/api/v1/instances/peers_controller.rb
+++ b/app/controllers/api/v1/instances/peers_controller.rb
@@ -2,6 +2,7 @@
 
 class Api::V1::Instances::PeersController < Api::BaseController
   before_action :require_enabled_api!
+  skip_before_action :set_cache_headers
 
   respond_to :json
 
diff --git a/app/controllers/api/v1/instances_controller.rb b/app/controllers/api/v1/instances_controller.rb
index 5686e8d7c394e5a5c510fd0e28a465f133c68204..8c83a180149cab1a7b85e62a1c2ce35fdd798fd1 100644
--- a/app/controllers/api/v1/instances_controller.rb
+++ b/app/controllers/api/v1/instances_controller.rb
@@ -2,6 +2,7 @@
 
 class Api::V1::InstancesController < Api::BaseController
   respond_to :json
+  skip_before_action :set_cache_headers
 
   def show
     render_cached_json('api:v1:instances', expires_in: 5.minutes) do
diff --git a/app/controllers/api/v1/notifications_controller.rb b/app/controllers/api/v1/notifications_controller.rb
index e2dec62afaef4a4d07cf982649369f6042515239..bf3002e79f5a5230e197be96846b15a9574ee7a9 100644
--- a/app/controllers/api/v1/notifications_controller.rb
+++ b/app/controllers/api/v1/notifications_controller.rb
@@ -44,7 +44,7 @@ class Api::V1::NotificationsController < Api::BaseController
   end
 
   def browserable_account_notifications
-    current_account.notifications.browserable(exclude_types)
+    current_account.notifications.browserable(exclude_types, from_account)
   end
 
   def target_statuses_from_notifications
@@ -81,6 +81,10 @@ class Api::V1::NotificationsController < Api::BaseController
     val
   end
 
+  def from_account
+    params[:account_id]
+  end
+
   def pagination_params(core_params)
     params.slice(:limit, :exclude_types).permit(:limit, exclude_types: []).merge(core_params)
   end
diff --git a/app/controllers/api/v1/polls/votes_controller.rb b/app/controllers/api/v1/polls/votes_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3fa0b6a760787c7d44a6422d9f2ba756f8eb4d8b
--- /dev/null
+++ b/app/controllers/api/v1/polls/votes_controller.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+class Api::V1::Polls::VotesController < Api::BaseController
+  include Authorization
+
+  before_action -> { doorkeeper_authorize! :write, :'write:statuses' }
+  before_action :require_user!
+  before_action :set_poll
+
+  respond_to :json
+
+  def create
+    VoteService.new.call(current_account, @poll, vote_params[:choices])
+    render json: @poll, serializer: REST::PollSerializer
+  end
+
+  private
+
+  def set_poll
+    @poll = Poll.attached.find(params[:poll_id])
+    authorize @poll.status, :show?
+  rescue Mastodon::NotPermittedError
+    raise ActiveRecord::RecordNotFound
+  end
+
+  def vote_params
+    params.permit(choices: [])
+  end
+end
diff --git a/app/controllers/api/v1/polls_controller.rb b/app/controllers/api/v1/polls_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..031e6d42d668e380e917127203df72b647236d14
--- /dev/null
+++ b/app/controllers/api/v1/polls_controller.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+class Api::V1::PollsController < Api::BaseController
+  include Authorization
+
+  before_action -> { authorize_if_got_token! :read, :'read:statuses' }, only: :show
+  before_action :set_poll
+  before_action :refresh_poll
+
+  respond_to :json
+
+  def show
+    render json: @poll, serializer: REST::PollSerializer, include_results: true
+  end
+
+  private
+
+  def set_poll
+    @poll = Poll.attached.find(params[:id])
+    authorize @poll.status, :show?
+  rescue Mastodon::NotPermittedError
+    raise ActiveRecord::RecordNotFound
+  end
+
+  def refresh_poll
+    ActivityPub::FetchRemotePollService.new.call(@poll, current_account) if user_signed_in? && @poll.possibly_stale?
+  end
+end
diff --git a/app/controllers/api/v1/preferences_controller.rb b/app/controllers/api/v1/preferences_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..077d39f5d740a4533bb83f62c79a6edfff12b362
--- /dev/null
+++ b/app/controllers/api/v1/preferences_controller.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+class Api::V1::PreferencesController < Api::BaseController
+  before_action -> { doorkeeper_authorize! :read, :'read:accounts' }
+  before_action :require_user!
+
+  respond_to :json
+
+  def index
+    render json: current_account, serializer: REST::PreferencesSerializer
+  end
+end
diff --git a/app/controllers/api/v1/push/subscriptions_controller.rb b/app/controllers/api/v1/push/subscriptions_controller.rb
index 1a19bd0ef6e9fd0c7c12481da0cdd8ef8faf310a..1b658f87083d5f293986fc2f99b125dbc0a2661a 100644
--- a/app/controllers/api/v1/push/subscriptions_controller.rb
+++ b/app/controllers/api/v1/push/subscriptions_controller.rb
@@ -51,6 +51,6 @@ class Api::V1::Push::SubscriptionsController < Api::BaseController
 
   def data_params
     return {} if params[:data].blank?
-    params.require(:data).permit(alerts: [:follow, :favourite, :reblog, :mention])
+    params.require(:data).permit(alerts: [:follow, :favourite, :reblog, :mention, :poll])
   end
 end
diff --git a/app/controllers/api/v1/search_controller.rb b/app/controllers/api/v1/search_controller.rb
index dc1a37599e6256ef04eef074bc09c53def1451cb..6131cbbb69fb1250ea102112ac51d0ebe04d200a 100644
--- a/app/controllers/api/v1/search_controller.rb
+++ b/app/controllers/api/v1/search_controller.rb
@@ -3,7 +3,7 @@
 class Api::V1::SearchController < Api::BaseController
   include Authorization
 
-  RESULTS_LIMIT = 5
+  RESULTS_LIMIT = 20
 
   before_action -> { doorkeeper_authorize! :read, :'read:search' }
   before_action :require_user!
@@ -11,30 +11,22 @@ class Api::V1::SearchController < Api::BaseController
   respond_to :json
 
   def index
-    @search = Search.new(search)
+    @search = Search.new(search_results)
     render json: @search, serializer: REST::SearchSerializer
   end
 
   private
 
-  def search
-    search_results.tap do |search|
-      search[:statuses].keep_if do |status|
-        begin
-          authorize status, :show?
-        rescue Mastodon::NotPermittedError
-          false
-        end
-      end
-    end
-  end
-
   def search_results
     SearchService.new.call(
       params[:q],
-      RESULTS_LIMIT,
-      truthy_param?(:resolve),
-      current_account
+      current_account,
+      limit_param(RESULTS_LIMIT),
+      search_params.merge(resolve: truthy_param?(:resolve))
     )
   end
+
+  def search_params
+    params.permit(:type, :offset, :min_id, :max_id, :account_id)
+  end
 end
diff --git a/app/controllers/api/v1/statuses/reblogs_controller.rb b/app/controllers/api/v1/statuses/reblogs_controller.rb
index 04847a6b76f137efa7ef94e28aa32b7ec9e526cc..ed4f551003d670061f58f75382af1fb6aa8542d6 100644
--- a/app/controllers/api/v1/statuses/reblogs_controller.rb
+++ b/app/controllers/api/v1/statuses/reblogs_controller.rb
@@ -9,7 +9,7 @@ class Api::V1::Statuses::ReblogsController < Api::BaseController
   respond_to :json
 
   def create
-    @status = ReblogService.new.call(current_user.account, status_for_reblog)
+    @status = ReblogService.new.call(current_user.account, status_for_reblog, reblog_params)
     render json: @status, serializer: REST::StatusSerializer
   end
 
@@ -32,4 +32,8 @@ class Api::V1::Statuses::ReblogsController < Api::BaseController
   def status_for_destroy
     current_user.account.statuses.where(reblog_of_id: params[:status_id]).first!
   end
+
+  def reblog_params
+    params.permit(:visibility)
+  end
 end
diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb
index 29b420c67525f7560d6f01bdee9e1d24ce26c668..b0e134554f81292dc231dc620a2c9f8234b35a8e 100644
--- a/app/controllers/api/v1/statuses_controller.rb
+++ b/app/controllers/api/v1/statuses_controller.rb
@@ -53,6 +53,7 @@ class Api::V1::StatusesController < Api::BaseController
                                          visibility: status_params[:visibility],
                                          scheduled_at: status_params[:scheduled_at],
                                          application: doorkeeper_token.application,
+                                         poll: status_params[:poll],
                                          idempotency: request.headers['Idempotency-Key'])
 
     render json: @status, serializer: @status.is_a?(ScheduledStatus) ? REST::ScheduledStatusSerializer : REST::StatusSerializer
@@ -64,7 +65,7 @@ class Api::V1::StatusesController < Api::BaseController
 
     RemovalWorker.perform_async(@status.id)
 
-    render_empty
+    render json: @status, serializer: REST::StatusSerializer, source_requested: true
   end
 
   private
@@ -73,12 +74,25 @@ class Api::V1::StatusesController < Api::BaseController
     @status = Status.find(params[:id])
     authorize @status, :show?
   rescue Mastodon::NotPermittedError
-    # Reraise in order to get a 404 instead of a 403 error code
     raise ActiveRecord::RecordNotFound
   end
 
   def status_params
-    params.permit(:status, :in_reply_to_id, :sensitive, :spoiler_text, :visibility, :scheduled_at, media_ids: [])
+    params.permit(
+      :status,
+      :in_reply_to_id,
+      :sensitive,
+      :spoiler_text,
+      :visibility,
+      :scheduled_at,
+      media_ids: [],
+      poll: [
+        :multiple,
+        :hide_totals,
+        :expires_in,
+        options: [],
+      ]
+    )
   end
 
   def pagination_params(core_params)
diff --git a/app/controllers/api/v1/timelines/tag_controller.rb b/app/controllers/api/v1/timelines/tag_controller.rb
index 92c32c1784b2e2c56a689c0284294f0c26a298a0..9adc4ad29129242480e3b33f54ffa9cf97251634 100644
--- a/app/controllers/api/v1/timelines/tag_controller.rb
+++ b/app/controllers/api/v1/timelines/tag_controller.rb
@@ -14,7 +14,7 @@ class Api::V1::Timelines::TagController < Api::BaseController
   private
 
   def load_tag
-    @tag = Tag.find_by(name: params[:id].downcase)
+    @tag = Tag.find_normalized(params[:id])
   end
 
   def load_statuses
diff --git a/app/controllers/api/v2/search_controller.rb b/app/controllers/api/v2/search_controller.rb
index 2e91d68ee30b173ca7acd25525cda7f1bd3ca2dc..9aa6edc6969eb2bbda1b7bbcea3ce00aa8062d58 100644
--- a/app/controllers/api/v2/search_controller.rb
+++ b/app/controllers/api/v2/search_controller.rb
@@ -2,7 +2,7 @@
 
 class Api::V2::SearchController < Api::V1::SearchController
   def index
-    @search = Search.new(search)
+    @search = Search.new(search_results)
     render json: @search, serializer: REST::V2::SearchSerializer
   end
 end
diff --git a/app/controllers/api/web/push_subscriptions_controller.rb b/app/controllers/api/web/push_subscriptions_controller.rb
index fe8e42580880821c7bd6de725aae459a85b7c735..d8153e082feafdf2e2608492cf227fa93bcbb9e4 100644
--- a/app/controllers/api/web/push_subscriptions_controller.rb
+++ b/app/controllers/api/web/push_subscriptions_controller.rb
@@ -22,6 +22,7 @@ class Api::Web::PushSubscriptionsController < Api::Web::BaseController
         favourite: alerts_enabled,
         reblog: alerts_enabled,
         mention: alerts_enabled,
+        poll: alerts_enabled,
       },
     }
 
@@ -57,6 +58,6 @@ class Api::Web::PushSubscriptionsController < Api::Web::BaseController
   end
 
   def data_params
-    @data_params ||= params.require(:data).permit(alerts: [:follow, :favourite, :reblog, :mention])
+    @data_params ||= params.require(:data).permit(alerts: [:follow, :favourite, :reblog, :mention, :poll])
   end
 end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index b54e7b008eeb06283bb7b7a94e39ddb6a4dbaf97..6b8411402beebba71d71eb87d7fdf03065f25ebc 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -91,11 +91,15 @@ class ApplicationController < ActionController::Base
   end
 
   def current_account
-    @current_account ||= current_user.try(:account)
+    return @current_account if defined?(@current_account)
+
+    @current_account = current_user&.account
   end
 
   def current_session
-    @current_session ||= SessionActivation.find_by(session_id: cookies.signed['_session_id'])
+    return @current_session if defined?(@current_session)
+
+    @current_session = SessionActivation.find_by(session_id: cookies.signed['_session_id']) if cookies.signed['_session_id'].present?
   end
 
   def current_theme
@@ -126,11 +130,7 @@ class ApplicationController < ActionController::Base
   def respond_with_error(code)
     respond_to do |format|
       format.any  { head code }
-
-      format.html do
-        set_locale
-        render "errors/#{code}", layout: 'error', status: code
-      end
+      format.html { render "errors/#{code}", layout: 'error', status: code }
     end
   end
 
@@ -151,7 +151,7 @@ class ApplicationController < ActionController::Base
     response.headers['Vary'] = 'Accept'
   end
 
-  def skip_session!
-    request.session_options[:skip] = true
+  def mark_cacheable!
+    expires_in 0, public: true
   end
 end
diff --git a/app/controllers/auth/registrations_controller.rb b/app/controllers/auth/registrations_controller.rb
index f2a832542fe5489dc8cce2e1670bd054d9071c5c..83797cf1f7600d1e09a57f67a492058ba1355e70 100644
--- a/app/controllers/auth/registrations_controller.rb
+++ b/app/controllers/auth/registrations_controller.rb
@@ -10,6 +10,10 @@ class Auth::RegistrationsController < Devise::RegistrationsController
   before_action :set_instance_presenter, only: [:new, :create, :update]
   before_action :set_body_classes, only: [:new, :create, :edit, :update]
 
+  def new
+    super(&:build_invite_request)
+  end
+
   def destroy
     not_found
   end
@@ -24,16 +28,17 @@ class Auth::RegistrationsController < Devise::RegistrationsController
   def build_resource(hash = nil)
     super(hash)
 
-    resource.locale      = I18n.locale
-    resource.invite_code = params[:invite_code] if resource.invite_code.blank?
-    resource.agreement   = true
+    resource.locale             = I18n.locale
+    resource.invite_code        = params[:invite_code] if resource.invite_code.blank?
+    resource.agreement          = true
+    resource.current_sign_in_ip = request.remote_ip
 
     resource.build_account if resource.account.nil?
   end
 
   def configure_sign_up_params
     devise_parameter_sanitizer.permit(:sign_up) do |u|
-      u.permit({ account_attributes: [:username] }, :email, :password, :password_confirmation, :invite_code)
+      u.permit({ account_attributes: [:username], invite_request_attributes: [:text] }, :email, :password, :password_confirmation, :invite_code)
     end
   end
 
@@ -64,7 +69,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController
   end
 
   def allowed_registrations?
-    Setting.open_registrations || @invite&.valid_for_use?
+    Setting.registrations_mode != 'none' || @invite&.valid_for_use?
   end
 
   def invite_code
@@ -86,7 +91,8 @@ class Auth::RegistrationsController < Devise::RegistrationsController
   end
 
   def set_invite
-    @invite = invite_code.present? ? Invite.find_by(code: invite_code) : nil
+    invite = invite_code.present? ? Invite.find_by(code: invite_code) : nil
+    @invite = invite&.valid_for_use? ? invite : nil
   end
 
   def determine_layout
diff --git a/app/controllers/concerns/account_controller_concern.rb b/app/controllers/concerns/account_controller_concern.rb
index 6c27ef330b90b8a40499d1a84ba5edb4373f82ed..1c422096c63516647c650a5943a6293196859d46 100644
--- a/app/controllers/concerns/account_controller_concern.rb
+++ b/app/controllers/concerns/account_controller_concern.rb
@@ -7,16 +7,18 @@ module AccountControllerConcern
 
   included do
     layout 'public'
+
     before_action :set_account
+    before_action :check_account_approval
+    before_action :check_account_suspension
     before_action :set_instance_presenter
     before_action :set_link_headers
-    before_action :check_account_suspension
   end
 
   private
 
   def set_account
-    @account = Account.find_local!(params[:account_username])
+    @account = Account.find_local!(username_param)
   end
 
   def set_instance_presenter
@@ -33,6 +35,10 @@ module AccountControllerConcern
     )
   end
 
+  def username_param
+    params[:account_username]
+  end
+
   def webfinger_account_link
     [
       webfinger_account_url,
@@ -58,7 +64,14 @@ module AccountControllerConcern
     webfinger_url(resource: @account.to_webfinger_s)
   end
 
+  def check_account_approval
+    not_found if @account.user_pending?
+  end
+
   def check_account_suspension
-    gone if @account.suspended?
+    if @account.suspended?
+      expires_in(3.minutes, public: true)
+      gone
+    end
   end
 end
diff --git a/app/controllers/concerns/localized.rb b/app/controllers/concerns/localized.rb
index 145549bcd286ac40f16294ae725199fb926dc1f3..b43859d9d626be53b13af0a3f93fda55ad5fdd36 100644
--- a/app/controllers/concerns/localized.rb
+++ b/app/controllers/concerns/localized.rb
@@ -4,16 +4,19 @@ module Localized
   extend ActiveSupport::Concern
 
   included do
-    before_action :set_locale
+    around_action :set_locale
   end
 
   private
 
   def set_locale
-    I18n.locale = default_locale
-    I18n.locale = current_user.locale if user_signed_in?
-  rescue I18n::InvalidLocale
-    I18n.locale = default_locale
+    locale   = current_user.locale if respond_to?(:user_signed_in?) && user_signed_in?
+    locale ||= session[:locale] ||= default_locale
+    locale   = default_locale unless I18n.available_locales.include?(locale.to_sym)
+
+    I18n.with_locale(locale) do
+      yield
+    end
   end
 
   def default_locale
diff --git a/app/controllers/concerns/signature_verification.rb b/app/controllers/concerns/signature_verification.rb
index 91566c4fad95ca2401af4022047fd1ea579cdc11..90a57197c00bde2a1512e524887f69bba1b66640 100644
--- a/app/controllers/concerns/signature_verification.rb
+++ b/app/controllers/concerns/signature_verification.rb
@@ -43,13 +43,7 @@ module SignatureVerification
       return
     end
 
-    account_stoplight = Stoplight("source:#{request.ip}") { account_from_key_id(signature_params['keyId']) }
-      .with_fallback { nil }
-      .with_threshold(1)
-      .with_cool_off_time(5.minutes.seconds)
-      .with_error_handler { |error, handle| error.is_a?(HTTP::Error) ? handle.call(error) : raise(error) }
-
-    account = account_stoplight.run
+    account = account_from_key_id(signature_params['keyId'])
 
     if account.nil?
       @signature_verification_failure_reason = "Public key not found for key #{signature_params['keyId']}"
@@ -62,13 +56,7 @@ module SignatureVerification
 
     return account unless verify_signature(account, signature, compare_signed_string).nil?
 
-    account_stoplight = Stoplight("source:#{request.ip}") { account.possibly_stale? ? account.refresh! : account_refresh_key(account) }
-      .with_fallback { nil }
-      .with_threshold(1)
-      .with_cool_off_time(5.minutes.seconds)
-      .with_error_handler { |error, handle| error.is_a?(HTTP::Error) ? handle.call(error) : raise(error) }
-
-    account = account_stoplight.run
+    account = stoplight_wrap_request { account.possibly_stale? ? account.refresh! : account_refresh_key(account) }
 
     if account.nil?
       @signature_verification_failure_reason = "Public key not found for key #{signature_params['keyId']}"
@@ -136,14 +124,23 @@ module SignatureVerification
 
   def account_from_key_id(key_id)
     if key_id.start_with?('acct:')
-      ResolveAccountService.new.call(key_id.gsub(/\Aacct:/, ''))
+      stoplight_wrap_request { ResolveAccountService.new.call(key_id.gsub(/\Aacct:/, '')) }
     elsif !ActivityPub::TagManager.instance.local_uri?(key_id)
       account   = ActivityPub::TagManager.instance.uri_to_resource(key_id, Account)
-      account ||= ActivityPub::FetchRemoteKeyService.new.call(key_id, id: false)
+      account ||= stoplight_wrap_request { ActivityPub::FetchRemoteKeyService.new.call(key_id, id: false) }
       account
     end
   end
 
+  def stoplight_wrap_request(&block)
+    Stoplight("source:#{request.remote_ip}", &block)
+      .with_fallback { nil }
+      .with_threshold(1)
+      .with_cool_off_time(5.minutes.seconds)
+      .with_error_handler { |error, handle| error.is_a?(HTTP::Error) ? handle.call(error) : raise(error) }
+      .run
+  end
+
   def account_refresh_key(account)
     return if account.local? || !account.activitypub?
     ActivityPub::FetchRemoteAccountService.new.call(account.uri, only_key: true)
diff --git a/app/controllers/custom_css_controller.rb b/app/controllers/custom_css_controller.rb
index 31e501609d809738ebf56af4166fda4b72a64947..6e80feaf837fac3c21d8ef8fd2c0b6f31d0c5b12 100644
--- a/app/controllers/custom_css_controller.rb
+++ b/app/controllers/custom_css_controller.rb
@@ -1,10 +1,11 @@
 # frozen_string_literal: true
 
 class CustomCssController < ApplicationController
+  skip_before_action :store_current_location
+
   before_action :set_cache_headers
 
   def show
-    skip_session!
     render plain: Setting.custom_css || '', content_type: 'text/css'
   end
 end
diff --git a/app/controllers/directories_controller.rb b/app/controllers/directories_controller.rb
index ff7ff4a428154fb8b178689a73339d47f8164155..5949076740fac499b0f3842bca6c3021b6c8d69f 100644
--- a/app/controllers/directories_controller.rb
+++ b/app/controllers/directories_controller.rb
@@ -32,7 +32,7 @@ class DirectoriesController < ApplicationController
   end
 
   def set_accounts
-    @accounts = Account.discoverable.page(params[:page]).per(40).tap do |query|
+    @accounts = Account.discoverable.by_recent_status.page(params[:page]).per(40).tap do |query|
       query.merge!(Account.tagged_with(@tag.id)) if @tag
     end
   end
diff --git a/app/controllers/emojis_controller.rb b/app/controllers/emojis_controller.rb
index 5d306e6005f1ee8eb244f09b9709b2a0821a6d23..3feb081325fb1f21c640a3cdcf9b11655c080fb3 100644
--- a/app/controllers/emojis_controller.rb
+++ b/app/controllers/emojis_controller.rb
@@ -7,8 +7,6 @@ class EmojisController < ApplicationController
   def show
     respond_to do |format|
       format.json do
-        skip_session!
-
         render_cached_json(['activitypub', 'emoji', @emoji], content_type: 'application/activity+json') do
           ActiveModelSerializers::SerializableResource.new(@emoji, serializer: ActivityPub::EmojiSerializer, adapter: ActivityPub::Adapter)
         end
diff --git a/app/controllers/follower_accounts_controller.rb b/app/controllers/follower_accounts_controller.rb
index 99cb3676f1e30dec6bef4508f430e3315d742d96..415abe10c100756003126a7c602f9f94ac058f24 100644
--- a/app/controllers/follower_accounts_controller.rb
+++ b/app/controllers/follower_accounts_controller.rb
@@ -3,9 +3,13 @@
 class FollowerAccountsController < ApplicationController
   include AccountControllerConcern
 
+  before_action :set_cache_headers
+
   def index
     respond_to do |format|
       format.html do
+        mark_cacheable! unless user_signed_in?
+
         next if @account.user_hides_network?
 
         follows
@@ -15,6 +19,8 @@ class FollowerAccountsController < ApplicationController
       format.json do
         raise Mastodon::NotPermittedError if params[:page].present? && @account.user_hides_network?
 
+        expires_in 3.minutes, public: true if params[:page].blank?
+
         render json: collection_presenter,
                serializer: ActivityPub::CollectionSerializer,
                adapter: ActivityPub::Adapter,
diff --git a/app/controllers/following_accounts_controller.rb b/app/controllers/following_accounts_controller.rb
index 03c4b10469b0ba6b3075085b67b6f199ba9fd88f..948725664196e4bebd19bf7641945bf86a44c1f6 100644
--- a/app/controllers/following_accounts_controller.rb
+++ b/app/controllers/following_accounts_controller.rb
@@ -3,9 +3,13 @@
 class FollowingAccountsController < ApplicationController
   include AccountControllerConcern
 
+  before_action :set_cache_headers
+
   def index
     respond_to do |format|
       format.html do
+        mark_cacheable! unless user_signed_in?
+
         next if @account.user_hides_network?
 
         follows
@@ -15,6 +19,8 @@ class FollowingAccountsController < ApplicationController
       format.json do
         raise Mastodon::NotPermittedError if params[:page].present? && @account.user_hides_network?
 
+        expires_in 3.minutes, public: true if params[:page].blank?
+
         render json: collection_presenter,
                serializer: ActivityPub::CollectionSerializer,
                adapter: ActivityPub::Adapter,
diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb
index b5d6460f9fc1a2dfca8a904a661a5db55b924e89..85622a7b59ecb52772d2875efed930faa20a9680 100644
--- a/app/controllers/home_controller.rb
+++ b/app/controllers/home_controller.rb
@@ -50,7 +50,7 @@ class HomeController < ApplicationController
       push_subscription: current_account.user.web_push_subscription(current_session),
       current_account: current_account,
       token: current_session.token,
-      admin: Account.find_local(Setting.site_contact_username),
+      admin: Account.find_local(Setting.site_contact_username.strip.gsub(/\A@/, '')),
     }
   end
 
@@ -58,7 +58,7 @@ class HomeController < ApplicationController
     if request.path.start_with?('/web')
       new_user_session_path
     elsif single_user_mode?
-      short_account_path(Account.local.where(suspended: false).first)
+      short_account_path(Account.local.without_suspended.first)
     else
       about_path
     end
diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb
index fdb3a0962a2ac4f53f7ec443be4ea60c3e33c771..de5280305e90cd00877ea029b03a8047653cfe09 100644
--- a/app/controllers/invites_controller.rb
+++ b/app/controllers/invites_controller.rb
@@ -39,7 +39,7 @@ class InvitesController < ApplicationController
   private
 
   def invites
-    Invite.where(user: current_user).order(id: :desc)
+    current_user.invites.order(id: :desc)
   end
 
   def resource_params
diff --git a/app/controllers/manifests_controller.rb b/app/controllers/manifests_controller.rb
index ac267c229459b24ad94ffcf579a9e23ec1f2fa23..332d845d8252c831a08bdde32fc100829d6d93cd 100644
--- a/app/controllers/manifests_controller.rb
+++ b/app/controllers/manifests_controller.rb
@@ -1,6 +1,8 @@
 # frozen_string_literal: true
 
 class ManifestsController < ApplicationController
+  skip_before_action :store_current_location
+
   def show
     render json: InstancePresenter.new, serializer: ManifestSerializer
   end
diff --git a/app/controllers/media_controller.rb b/app/controllers/media_controller.rb
index 8e1624ce1b449b627f227df85a616c8f021dbb81..d44b52d2624d7994569f4850d7372103f6c494d2 100644
--- a/app/controllers/media_controller.rb
+++ b/app/controllers/media_controller.rb
@@ -3,8 +3,12 @@
 class MediaController < ApplicationController
   include Authorization
 
+  skip_before_action :store_current_location
+
   before_action :set_media_attachment
   before_action :verify_permitted_status!
+  before_action :check_playable, only: :player
+  before_action :allow_iframing, only: :player
 
   content_security_policy only: :player do |p|
     p.frame_ancestors(false)
@@ -16,8 +20,6 @@ class MediaController < ApplicationController
 
   def player
     @body_classes = 'player'
-    response.headers['X-Frame-Options'] = 'ALLOWALL'
-    raise ActiveRecord::RecordNotFound unless @media_attachment.video? || @media_attachment.gifv?
   end
 
   private
@@ -32,4 +34,12 @@ class MediaController < ApplicationController
     # Reraise in order to get a 404 instead of a 403 error code
     raise ActiveRecord::RecordNotFound
   end
+
+  def check_playable
+    not_found unless @media_attachment.larger_media_format?
+  end
+
+  def allow_iframing
+    response.headers['X-Frame-Options'] = 'ALLOWALL'
+  end
 end
diff --git a/app/controllers/media_proxy_controller.rb b/app/controllers/media_proxy_controller.rb
index d820b257e0ac65605776c7dc7f3f3a30b50db9af..8fc18dd0602a9067d16e25efa454578170038148 100644
--- a/app/controllers/media_proxy_controller.rb
+++ b/app/controllers/media_proxy_controller.rb
@@ -3,6 +3,8 @@
 class MediaProxyController < ApplicationController
   include RoutingHelper
 
+  skip_before_action :store_current_location
+
   def show
     RedisLock.acquire(lock_options) do |lock|
       if lock.acquired?
@@ -37,6 +39,6 @@ class MediaProxyController < ApplicationController
   end
 
   def reject_media?
-    DomainBlock.find_by(domain: @media_attachment.account.domain)&.reject_media?
+    DomainBlock.reject_media?(@media_attachment.account.domain)
   end
 end
diff --git a/app/controllers/oauth/authorized_applications_controller.rb b/app/controllers/oauth/authorized_applications_controller.rb
index 0c28d194bc82c8c1643ba0aaffd827f19b97d42b..f3d2353669464c0e91af032fe46168fdfc31a14f 100644
--- a/app/controllers/oauth/authorized_applications_controller.rb
+++ b/app/controllers/oauth/authorized_applications_controller.rb
@@ -5,6 +5,7 @@ class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio
 
   before_action :store_current_location
   before_action :authenticate_resource_owner!
+  before_action :set_body_classes
 
   include Localized
 
@@ -15,6 +16,10 @@ class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio
 
   private
 
+  def set_body_classes
+    @body_classes = 'admin'
+  end
+
   def store_current_location
     store_location_for(:user, request.url)
   end
diff --git a/app/controllers/public_timelines_controller.rb b/app/controllers/public_timelines_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..53d4472d88da355af4d67d23501117dbfb0fee35
--- /dev/null
+++ b/app/controllers/public_timelines_controller.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+class PublicTimelinesController < ApplicationController
+  layout 'public'
+
+  before_action :check_enabled
+  before_action :set_body_classes
+  before_action :set_instance_presenter
+
+  def show
+    respond_to do |format|
+      format.html do
+        @initial_state_json = ActiveModelSerializers::SerializableResource.new(
+          InitialStatePresenter.new(settings: { known_fediverse: Setting.show_known_fediverse_at_about_page }, token: current_session&.token),
+          serializer: InitialStateSerializer
+        ).to_json
+      end
+    end
+  end
+
+  private
+
+  def check_enabled
+    raise ActiveRecord::RecordNotFound unless Setting.timeline_preview
+  end
+
+  def set_body_classes
+    @body_classes = 'with-modals'
+  end
+
+  def set_instance_presenter
+    @instance_presenter = InstancePresenter.new
+  end
+end
diff --git a/app/controllers/relationships_controller.rb b/app/controllers/relationships_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e6705c3275584b105f0ce8b9f3a64bb777af528b
--- /dev/null
+++ b/app/controllers/relationships_controller.rb
@@ -0,0 +1,104 @@
+# frozen_string_literal: true
+
+class RelationshipsController < ApplicationController
+  layout 'admin'
+
+  before_action :authenticate_user!
+  before_action :set_accounts, only: :show
+  before_action :set_body_classes
+
+  helper_method :following_relationship?, :followed_by_relationship?, :mutual_relationship?
+
+  def show
+    @form = Form::AccountBatch.new
+  end
+
+  def update
+    @form = Form::AccountBatch.new(form_account_batch_params.merge(current_account: current_account, action: action_from_button))
+    @form.save
+  rescue ActionController::ParameterMissing
+    # Do nothing
+  ensure
+    redirect_to relationships_path(current_params)
+  end
+
+  private
+
+  def set_accounts
+    @accounts = relationships_scope.page(params[:page]).per(40)
+  end
+
+  def relationships_scope
+    scope = begin
+      if following_relationship?
+        current_account.following.eager_load(:account_stat).reorder(nil)
+      else
+        current_account.followers.eager_load(:account_stat).reorder(nil)
+      end
+    end
+
+    scope.merge!(Follow.recent)             if params[:order].blank? || params[:order] == 'recent'
+    scope.merge!(Account.by_recent_status)  if params[:order] == 'active'
+    scope.merge!(mutual_relationship_scope) if mutual_relationship?
+    scope.merge!(moved_account_scope)       if params[:status] == 'moved'
+    scope.merge!(primary_account_scope)     if params[:status] == 'primary'
+    scope.merge!(by_domain_scope)           if params[:by_domain].present?
+    scope.merge!(dormant_account_scope)     if params[:activity] == 'dormant'
+
+    scope
+  end
+
+  def mutual_relationship_scope
+    Account.where(id: current_account.following)
+  end
+
+  def moved_account_scope
+    Account.where.not(moved_to_account_id: nil)
+  end
+
+  def primary_account_scope
+    Account.where(moved_to_account_id: nil)
+  end
+
+  def dormant_account_scope
+    AccountStat.where(last_status_at: nil).or(AccountStat.where(AccountStat.arel_table[:last_status_at].lt(1.month.ago)))
+  end
+
+  def by_domain_scope
+    Account.where(domain: params[:by_domain])
+  end
+
+  def form_account_batch_params
+    params.require(:form_account_batch).permit(:action, account_ids: [])
+  end
+
+  def following_relationship?
+    params[:relationship].blank? || params[:relationship] == 'following'
+  end
+
+  def mutual_relationship?
+    params[:relationship] == 'mutual'
+  end
+
+  def followed_by_relationship?
+    params[:relationship] == 'followed_by'
+  end
+
+  def current_params
+    params.slice(:page, :status, :relationship, :by_domain, :activity, :order).permit(:page, :status, :relationship, :by_domain, :activity, :order)
+  end
+
+  def action_from_button
+    if params[:unfollow]
+      'unfollow'
+    elsif params[:remove_from_followers]
+      'remove_from_followers'
+    elsif params[:block_domains]
+      'block_domains'
+    end
+  end
+
+  def set_body_classes
+    @body_classes = 'admin'
+  end
+end
diff --git a/app/controllers/settings/exports_controller.rb b/app/controllers/settings/exports_controller.rb
index 0135f21890dd0e81bd0bbd9290b669603e1388f1..3012fbf775600ad3a9dfb6149fab2e2eaf11ff04 100644
--- a/app/controllers/settings/exports_controller.rb
+++ b/app/controllers/settings/exports_controller.rb
@@ -13,11 +13,25 @@ class Settings::ExportsController < Settings::BaseController
   end
 
   def create
-    authorize :backup, :create?
+    raise Mastodon::NotPermittedError unless user_signed_in?
+
+    backup = nil
+
+    RedisLock.acquire(lock_options) do |lock|
+      if lock.acquired?
+        authorize :backup, :create?
+        backup = current_user.backups.create!
+      else
+        raise Mastodon::RaceConditionError
+      end
+    end
 
-    backup = current_user.backups.create!
     BackupWorker.perform_async(backup.id)
 
     redirect_to settings_export_path
   end
+
+  def lock_options
+    { redis: Redis.current, key: "backup:#{current_user.id}" }
+  end
 end
diff --git a/app/controllers/settings/featured_tags_controller.rb b/app/controllers/settings/featured_tags_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3a3241425d6066e0876e71c24ca0076be9028247
--- /dev/null
+++ b/app/controllers/settings/featured_tags_controller.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+class Settings::FeaturedTagsController < Settings::BaseController
+  layout 'admin'
+
+  before_action :authenticate_user!
+  before_action :set_featured_tags, only: :index
+  before_action :set_featured_tag, except: [:index, :create]
+  before_action :set_most_used_tags, only: :index
+
+  def index
+    @featured_tag = FeaturedTag.new
+  end
+
+  def create
+    @featured_tag = current_account.featured_tags.new(featured_tag_params)
+    @featured_tag.reset_data
+
+    if @featured_tag.save
+      redirect_to settings_featured_tags_path
+    else
+      set_featured_tags
+      set_most_used_tags
+
+      render :index
+    end
+  end
+
+  def destroy
+    @featured_tag.destroy!
+    redirect_to settings_featured_tags_path
+  end
+
+  private
+
+  def set_featured_tag
+    @featured_tag = current_account.featured_tags.find(params[:id])
+  end
+
+  def set_featured_tags
+    @featured_tags = current_account.featured_tags.order(statuses_count: :desc).reject(&:new_record?)
+  end
+
+  def set_most_used_tags
+    @most_used_tags = Tag.most_used(current_account).where.not(id: @featured_tags.map(&:id)).limit(10)
+  end
+
+  def featured_tag_params
+    params.require(:featured_tag).permit(:name)
+  end
+end
diff --git a/app/controllers/settings/follower_domains_controller.rb b/app/controllers/settings/follower_domains_controller.rb
deleted file mode 100644
index ce8ec985d62b5772a09f0ce3ee058b4b1606fd35..0000000000000000000000000000000000000000
--- a/app/controllers/settings/follower_domains_controller.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# frozen_string_literal: true
-
-class Settings::FollowerDomainsController < Settings::BaseController
-  layout 'admin'
-
-  before_action :authenticate_user!
-
-  def show
-    @account = current_account
-    @domains = current_account.followers.reorder(Arel.sql('MIN(follows.id) DESC')).group('accounts.domain').select('accounts.domain, count(accounts.id) as accounts_from_domain').page(params[:page]).per(10)
-  end
-
-  def update
-    domains = bulk_params[:select] || []
-
-    AfterAccountDomainBlockWorker.push_bulk(domains) do |domain|
-      [current_account.id, domain]
-    end
-
-    redirect_to settings_follower_domains_path, notice: I18n.t('followers.success', count: domains.size)
-  end
-
-  private
-
-  def bulk_params
-    params.permit(select: [])
-  end
-end
diff --git a/app/controllers/settings/identity_proofs_controller.rb b/app/controllers/settings/identity_proofs_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a749d80204dac59fb07f26705bce1fca28d87406
--- /dev/null
+++ b/app/controllers/settings/identity_proofs_controller.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+class Settings::IdentityProofsController < Settings::BaseController
+  layout 'admin'
+
+  before_action :authenticate_user!
+  before_action :check_required_params, only: :new
+
+  def index
+    @proofs = AccountIdentityProof.where(account: current_account).order(provider: :asc, provider_username: :asc)
+    @proofs.each(&:refresh!)
+  end
+
+  def new
+    @proof = current_account.identity_proofs.new(
+      token: params[:token],
+      provider: params[:provider],
+      provider_username: params[:provider_username]
+    )
+
+    if current_account.username.casecmp(params[:username]).zero?
+      render layout: 'auth'
+    else
+      flash[:alert] = I18n.t('identity_proofs.errors.wrong_user', proving: params[:username], current: current_account.username)
+      redirect_to settings_identity_proofs_path
+    end
+  end
+
+  def create
+    @proof = current_account.identity_proofs.where(provider: resource_params[:provider], provider_username: resource_params[:provider_username]).first_or_initialize(resource_params)
+    @proof.token = resource_params[:token]
+
+    if @proof.save
+      PostStatusService.new.call(current_user.account, text: post_params[:status_text]) if publish_proof?
+      redirect_to @proof.on_success_path(params[:user_agent])
+    else
+      flash[:alert] = I18n.t('identity_proofs.errors.failed', provider: @proof.provider.capitalize)
+      redirect_to settings_identity_proofs_path
+    end
+  end
+
+  private
+
+  def check_required_params
+    redirect_to settings_identity_proofs_path unless [:provider, :provider_username, :username, :token].all? { |k| params[k].present? }
+  end
+
+  def resource_params
+    params.require(:account_identity_proof).permit(:provider, :provider_username, :token)
+  end
+
+  def publish_proof?
+    ActiveModel::Type::Boolean.new.cast(post_params[:post_status])
+  end
+
+  def post_params
+    params.require(:account_identity_proof).permit(:post_status, :status_text)
+  end
+end
diff --git a/app/controllers/settings/notifications_controller.rb b/app/controllers/settings/notifications_controller.rb
deleted file mode 100644
index da8a03d96491d815c2844ed4fb8ef74c8dda2f94..0000000000000000000000000000000000000000
--- a/app/controllers/settings/notifications_controller.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-class Settings::NotificationsController < Settings::BaseController
-  layout 'admin'
-
-  before_action :authenticate_user!
-
-  def show; end
-
-  def update
-    user_settings.update(user_settings_params.to_h)
-
-    if current_user.save
-      redirect_to settings_notifications_path, notice: I18n.t('generic.changes_saved_msg')
-    else
-      render :show
-    end
-  end
-
-  private
-
-  def user_settings
-    UserSettingsDecorator.new(current_user)
-  end
-
-  def user_settings_params
-    params.require(:user).permit(
-      notification_emails: %i(follow follow_request reblog favourite mention digest report),
-      interactions: %i(must_be_follower must_be_following must_be_following_dm)
-    )
-  end
-end
diff --git a/app/controllers/settings/preferences/appearance_controller.rb b/app/controllers/settings/preferences/appearance_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..80ea57bd2d21d7490caed4d027db9d2379877eb5
--- /dev/null
+++ b/app/controllers/settings/preferences/appearance_controller.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class Settings::Preferences::AppearanceController < Settings::PreferencesController
+  private
+
+  def after_update_redirect_path
+    settings_preferences_appearance_path
+  end
+end
diff --git a/app/controllers/settings/preferences/notifications_controller.rb b/app/controllers/settings/preferences/notifications_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a16ae6a672ab3a389fade3992b3d2ff40015f90b
--- /dev/null
+++ b/app/controllers/settings/preferences/notifications_controller.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class Settings::Preferences::NotificationsController < Settings::PreferencesController
+  private
+
+  def after_update_redirect_path
+    settings_preferences_notifications_path
+  end
+end
diff --git a/app/controllers/settings/preferences/other_controller.rb b/app/controllers/settings/preferences/other_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..07eb89a76235dc81d954b7b28b7beb096cf16455
--- /dev/null
+++ b/app/controllers/settings/preferences/other_controller.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class Settings::Preferences::OtherController < Settings::PreferencesController
+  private
+
+  def after_update_redirect_path
+    settings_preferences_other_path
+  end
+end
diff --git a/app/controllers/settings/preferences_controller.rb b/app/controllers/settings/preferences_controller.rb
index 41df3bde2fcda328a4ef003543aca4ba602486c3..110debd6e5855a266d8c760060e3678d0122e072 100644
--- a/app/controllers/settings/preferences_controller.rb
+++ b/app/controllers/settings/preferences_controller.rb
@@ -12,7 +12,7 @@ class Settings::PreferencesController < Settings::BaseController
 
     if current_user.update(user_params)
       I18n.locale = current_user.locale
-      redirect_to settings_preferences_path, notice: I18n.t('generic.changes_saved_msg')
+      redirect_to after_update_redirect_path, notice: I18n.t('generic.changes_saved_msg')
     else
       render :show
     end
@@ -20,6 +20,10 @@ class Settings::PreferencesController < Settings::BaseController
 
   private
 
+  def after_update_redirect_path
+    settings_preferences_path
+  end
+
   def user_settings
     UserSettingsDecorator.new(current_user)
   end
@@ -48,8 +52,10 @@ class Settings::PreferencesController < Settings::BaseController
       :setting_theme,
       :setting_hide_network,
       :setting_aggregate_reblogs,
-      notification_emails: %i(follow follow_request reblog favourite mention digest report),
-      interactions: %i(must_be_follower must_be_following)
+      :setting_show_application,
+      :setting_advanced_layout,
+      notification_emails: %i(follow follow_request reblog favourite mention digest report pending_account),
+      interactions: %i(must_be_follower must_be_following must_be_following_dm)
     )
   end
 end
diff --git a/app/controllers/settings/profiles_controller.rb b/app/controllers/settings/profiles_controller.rb
index db9081fdf012a7029456c5c51ff3b1e072ad3ea1..8b640cdca1c1bad8ac9c9fb063f73f709a3f5b8d 100644
--- a/app/controllers/settings/profiles_controller.rb
+++ b/app/controllers/settings/profiles_controller.rb
@@ -32,6 +32,6 @@ class Settings::ProfilesController < Settings::BaseController
   end
 
   def set_account
-    @account = current_user.account
+    @account = current_account
   end
 end
diff --git a/app/controllers/settings/sessions_controller.rb b/app/controllers/settings/sessions_controller.rb
index 11b150ffd3ae0f5da9038e717eb9353f15740824..84ebb21f2cce31ff3014c12df957fc540680a3ca 100644
--- a/app/controllers/settings/sessions_controller.rb
+++ b/app/controllers/settings/sessions_controller.rb
@@ -1,6 +1,7 @@
 # frozen_string_literal: true
 
 class Settings::SessionsController < Settings::BaseController
+  before_action :authenticate_user!
   before_action :set_session, only: :destroy
 
   def destroy
diff --git a/app/controllers/settings/two_factor_authentication/confirmations_controller.rb b/app/controllers/settings/two_factor_authentication/confirmations_controller.rb
index d87117a50a846c3a31023db36c2ef47cc63020a4..02652a36c988bd67e6aecbeb4a0ac6971d0a71ce 100644
--- a/app/controllers/settings/two_factor_authentication/confirmations_controller.rb
+++ b/app/controllers/settings/two_factor_authentication/confirmations_controller.rb
@@ -14,7 +14,7 @@ module Settings
 
       def create
         if current_user.validate_and_consume_otp!(confirmation_params[:code])
-          flash[:notice] = I18n.t('two_factor_authentication.enabled_success')
+          flash.now[:notice] = I18n.t('two_factor_authentication.enabled_success')
 
           current_user.otp_required_for_login = true
           @recovery_codes = current_user.generate_otp_backup_codes!
diff --git a/app/controllers/settings/two_factor_authentication/recovery_codes_controller.rb b/app/controllers/settings/two_factor_authentication/recovery_codes_controller.rb
index c78166c6542e722b09091f2338c272f62145cb10..874bf532ba567f2cfeac6f109003c51fc89a0e13 100644
--- a/app/controllers/settings/two_factor_authentication/recovery_codes_controller.rb
+++ b/app/controllers/settings/two_factor_authentication/recovery_codes_controller.rb
@@ -10,7 +10,7 @@ module Settings
       def create
         @recovery_codes = current_user.generate_otp_backup_codes!
         current_user.save!
-        flash[:notice] = I18n.t('two_factor_authentication.recovery_codes_regenerated')
+        flash.now[:notice] = I18n.t('two_factor_authentication.recovery_codes_regenerated')
         render :index
       end
     end
diff --git a/app/controllers/shares_controller.rb b/app/controllers/shares_controller.rb
index 9ef1e07491d0d2660074b4ca4473e9f2c72ec0b4..af605b98f701fce34dfbc5f15815d48134f5f888 100644
--- a/app/controllers/shares_controller.rb
+++ b/app/controllers/shares_controller.rb
@@ -21,7 +21,7 @@ class SharesController < ApplicationController
       push_subscription: current_account.user.web_push_subscription(current_session),
       current_account: current_account,
       token: current_session.token,
-      admin: Account.find_local(Setting.site_contact_username),
+      admin: Account.find_local(Setting.site_contact_username.strip.gsub(/\A@/, '')),
       text: text,
     }
   end
diff --git a/app/controllers/statuses_controller.rb b/app/controllers/statuses_controller.rb
index 15d59fd89345cdc408377586f166a6262b5a5455..ef26691b296c34895b76cb8ea63297428ae1fc20 100644
--- a/app/controllers/statuses_controller.rb
+++ b/app/controllers/statuses_controller.rb
@@ -18,6 +18,7 @@ class StatusesController < ApplicationController
   before_action :redirect_to_original, only: [:show]
   before_action :set_referrer_policy_header, only: [:show]
   before_action :set_cache_headers
+  before_action :set_replies, only: [:replies]
 
   content_security_policy only: :embed do |p|
     p.frame_ancestors(false)
@@ -26,6 +27,8 @@ class StatusesController < ApplicationController
   def show
     respond_to do |format|
       format.html do
+        expires_in 10.seconds, public: true if current_account.nil?
+
         @body_classes = 'with-modals'
 
         set_ancestors
@@ -35,8 +38,6 @@ class StatusesController < ApplicationController
       end
 
       format.json do
-        skip_session! unless @stream_entry.hidden?
-
         render_cached_json(['activitypub', 'note', @status], content_type: 'application/activity+json', public: !@stream_entry.hidden?) do
           ActiveModelSerializers::SerializableResource.new(@status, serializer: ActivityPub::NoteSerializer, adapter: ActivityPub::Adapter)
         end
@@ -45,8 +46,6 @@ class StatusesController < ApplicationController
   end
 
   def activity
-    skip_session!
-
     render_cached_json(['activitypub', 'activity', @status], content_type: 'application/activity+json', public: !@stream_entry.hidden?) do
       ActiveModelSerializers::SerializableResource.new(@status, serializer: ActivityPub::ActivitySerializer, adapter: ActivityPub::Adapter)
     end
@@ -55,7 +54,6 @@ class StatusesController < ApplicationController
   def embed
     raise ActiveRecord::RecordNotFound if @status.hidden?
 
-    skip_session!
     expires_in 180, public: true
     response.headers['X-Frame-Options'] = 'ALLOWALL'
     @autoplay = ActiveModel::Type::Boolean.new.cast(params[:autoplay])
@@ -63,8 +61,35 @@ class StatusesController < ApplicationController
     render 'stream_entries/embed', layout: 'embedded'
   end
 
+  def replies
+    render json: replies_collection_presenter,
+           serializer: ActivityPub::CollectionSerializer,
+           adapter: ActivityPub::Adapter,
+           content_type: 'application/activity+json',
+           skip_activities: true
+  end
+
   private
 
+  def replies_collection_presenter
+    page = ActivityPub::CollectionPresenter.new(
+      id: replies_account_status_url(@account, @status, page_params),
+      type: :unordered,
+      part_of: replies_account_status_url(@account, @status),
+      next: next_page,
+      items: @replies.map { |status| status.local ? status : status.id }
+    )
+    if page_requested?
+      page
+    else
+      ActivityPub::CollectionPresenter.new(
+        id: replies_account_status_url(@account, @status),
+        type: :unordered,
+        first: page
+      )
+    end
+  end
+
   def create_descendant_thread(starting_depth, statuses)
     depth = starting_depth + statuses.size
     if depth < DESCENDANTS_DEPTH_LIMIT
@@ -174,4 +199,27 @@ class StatusesController < ApplicationController
     return if @status.public_visibility? || @status.unlisted_visibility?
     response.headers['Referrer-Policy'] = 'origin'
   end
+
+  def page_requested?
+    params[:page] == 'true'
+  end
+
+  def set_replies
+    @replies = page_params[:other_accounts] ? Status.where.not(account_id: @account.id) : @account.statuses
+    @replies = @replies.where(in_reply_to_id: @status.id, visibility: [:public, :unlisted])
+    @replies = @replies.paginate_by_min_id(DESCENDANTS_LIMIT, params[:min_id])
+  end
+
+  def next_page
+    last_reply = @replies.last
+    return if last_reply.nil?
+    same_account = last_reply.account_id == @account.id
+    return unless same_account || @replies.size == DESCENDANTS_LIMIT
+    same_account = false unless @replies.size == DESCENDANTS_LIMIT
+    replies_account_status_url(@account, @status, page: true, min_id: last_reply.id, other_accounts: !same_account)
+  end
+
+  def page_params
+    { page: true, other_accounts: params[:other_accounts], min_id: params[:min_id] }.compact
+  end
 end
diff --git a/app/controllers/stream_entries_controller.rb b/app/controllers/stream_entries_controller.rb
index 8568b151cfaa4ed400feb70adcd3d1f04582caa5..0f7e9e0f569f174aa2593e7cefcde987789a7803 100644
--- a/app/controllers/stream_entries_controller.rb
+++ b/app/controllers/stream_entries_controller.rb
@@ -15,14 +15,13 @@ class StreamEntriesController < ApplicationController
   def show
     respond_to do |format|
       format.html do
-        redirect_to short_account_status_url(params[:account_username], @stream_entry.activity) if @type == 'status'
+        expires_in 5.minutes, public: true unless @stream_entry.hidden?
+
+        redirect_to short_account_status_url(params[:account_username], @stream_entry.activity)
       end
 
       format.atom do
-        unless @stream_entry.hidden?
-          skip_session!
-          expires_in 3.minutes, public: true
-        end
+        expires_in 3.minutes, public: true unless @stream_entry.hidden?
 
         render xml: OStatus::AtomSerializer.render(OStatus::AtomSerializer.new.entry(@stream_entry, true))
       end
@@ -50,7 +49,7 @@ class StreamEntriesController < ApplicationController
 
   def set_stream_entry
     @stream_entry = @account.stream_entries.where(activity_type: 'Status').find(params[:id])
-    @type         = @stream_entry.activity_type.downcase
+    @type         = 'status'
 
     raise ActiveRecord::RecordNotFound if @stream_entry.activity.nil?
     authorize @stream_entry.activity, :show? if @stream_entry.hidden?
diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb
index 4694c823a42c80968de3351f1f8b90c35a0c0160..66b18490117833a176ded1f937776f226ec348b1 100644
--- a/app/controllers/tags_controller.rb
+++ b/app/controllers/tags_controller.rb
@@ -9,12 +9,14 @@ class TagsController < ApplicationController
   before_action :set_instance_presenter
 
   def show
-    @tag = Tag.find_by!(name: params[:id].downcase)
+    @tag = Tag.find_normalized!(params[:id])
 
     respond_to do |format|
       format.html do
-        serializable_resource = ActiveModelSerializers::SerializableResource.new(InitialStatePresenter.new(initial_state_params), serializer: InitialStateSerializer)
-        @initial_state_json   = serializable_resource.to_json
+        @initial_state_json = ActiveModelSerializers::SerializableResource.new(
+          InitialStatePresenter.new(settings: {}, token: current_session&.token),
+          serializer: InitialStateSerializer
+        ).to_json
       end
 
       format.rss do
@@ -25,8 +27,7 @@ class TagsController < ApplicationController
       end
 
       format.json do
-        @statuses = HashtagQueryService.new.call(@tag, params.slice(:any, :all, :none), current_account, params[:local])
-                                       .paginate_by_max_id(PAGE_SIZE, params[:max_id])
+        @statuses = HashtagQueryService.new.call(@tag, params.slice(:any, :all, :none), current_account, params[:local]).paginate_by_max_id(PAGE_SIZE, params[:max_id])
         @statuses = cache_collection(@statuses, Status)
 
         render json: collection_presenter,
@@ -55,11 +56,4 @@ class TagsController < ApplicationController
       items: @statuses.map { |s| ActivityPub::TagManager.instance.uri_for(s) }
     )
   end
-
-  def initial_state_params
-    {
-      settings: {},
-      token: current_session&.token,
-    }
-  end
 end
diff --git a/app/controllers/well_known/keybase_proof_config_controller.rb b/app/controllers/well_known/keybase_proof_config_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..eb41e586f84843d7557afcc50952d43285bd4e0d
--- /dev/null
+++ b/app/controllers/well_known/keybase_proof_config_controller.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+module WellKnown
+  class KeybaseProofConfigController < ActionController::Base
+    def show
+      render json: {}, serializer: ProofProvider::Keybase::ConfigSerializer
+    end
+  end
+end
diff --git a/app/helpers/admin/action_logs_helper.rb b/app/helpers/admin/action_logs_helper.rb
index 359d60b60e29484703be2fee8b72e24403deda09..e5fbb1500e997dc82084941380453e8a6b863113 100644
--- a/app/helpers/admin/action_logs_helper.rb
+++ b/app/helpers/admin/action_logs_helper.rb
@@ -9,42 +9,6 @@ module Admin::ActionLogsHelper
     end
   end
 
-  def linkable_log_target(record)
-    case record.class.name
-    when 'Account'
-      link_to record.acct, admin_account_path(record.id)
-    when 'User'
-      link_to record.account.acct, admin_account_path(record.account_id)
-    when 'CustomEmoji'
-      record.shortcode
-    when 'Report'
-      link_to "##{record.id}", admin_report_path(record)
-    when 'DomainBlock', 'EmailDomainBlock'
-      link_to record.domain, "https://#{record.domain}"
-    when 'Status'
-      link_to record.account.acct, TagManager.instance.url_for(record)
-    when 'AccountWarning'
-      link_to record.target_account.acct, admin_account_path(record.target_account_id)
-    end
-  end
-
-  def log_target_from_history(type, attributes)
-    case type
-    when 'CustomEmoji'
-      attributes['shortcode']
-    when 'DomainBlock', 'EmailDomainBlock'
-      link_to attributes['domain'], "https://#{attributes['domain']}"
-    when 'Status'
-      tmp_status = Status.new(attributes.except('reblogs_count', 'favourites_count'))
-
-      if tmp_status.account
-        link_to tmp_status.account&.acct || "##{tmp_status.account_id}", admin_account_path(tmp_status.account_id)
-      else
-        I18n.t('admin.action_logs.deleted_status')
-      end
-    end
-  end
-
   def relevant_log_changes(log)
     if log.target_type == 'CustomEmoji' && [:enable, :disable, :destroy].include?(log.action)
       log.recorded_changes.slice('domain')
@@ -111,4 +75,40 @@ module Admin::ActionLogsHelper
   def opposite_verbs?(log)
     %w(DomainBlock EmailDomainBlock AccountWarning).include?(log.target_type)
   end
+
+  def linkable_log_target(record)
+    case record.class.name
+    when 'Account'
+      link_to record.acct, admin_account_path(record.id)
+    when 'User'
+      link_to record.account.acct, admin_account_path(record.account_id)
+    when 'CustomEmoji'
+      record.shortcode
+    when 'Report'
+      link_to "##{record.id}", admin_report_path(record)
+    when 'DomainBlock', 'EmailDomainBlock'
+      link_to record.domain, "https://#{record.domain}"
+    when 'Status'
+      link_to record.account.acct, TagManager.instance.url_for(record)
+    when 'AccountWarning'
+      link_to record.target_account.acct, admin_account_path(record.target_account_id)
+    end
+  end
+
+  def log_target_from_history(type, attributes)
+    case type
+    when 'CustomEmoji'
+      attributes['shortcode']
+    when 'DomainBlock', 'EmailDomainBlock'
+      link_to attributes['domain'], "https://#{attributes['domain']}"
+    when 'Status'
+      tmp_status = Status.new(attributes.except('reblogs_count', 'favourites_count'))
+
+      if tmp_status.account
+        link_to tmp_status.account&.acct || "##{tmp_status.account_id}", admin_account_path(tmp_status.account_id)
+      else
+        I18n.t('admin.action_logs.deleted_status')
+      end
+    end
+  end
 end
diff --git a/app/helpers/admin/dashboard_helper.rb b/app/helpers/admin/dashboard_helper.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4ee2cdef473f545cb0a43ac05c7a02f9a471379c
--- /dev/null
+++ b/app/helpers/admin/dashboard_helper.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+module Admin::DashboardHelper
+  def feature_hint(feature, enabled)
+    indicator   = safe_join([enabled ? t('simple_form.yes') : t('simple_form.no'), fa_icon('power-off fw')], ' ')
+    class_names = enabled ? 'pull-right positive-hint' : 'pull-right neutral-hint'
+
+    safe_join([feature, content_tag(:span, indicator, class: class_names)])
+  end
+end
diff --git a/app/helpers/admin/filter_helper.rb b/app/helpers/admin/filter_helper.rb
index 97beb587fce1496b4b0fb8c2e4882ba79304ad7f..0bda25974f0def86c916634bcd6c610fd3134f12 100644
--- a/app/helpers/admin/filter_helper.rb
+++ b/app/helpers/admin/filter_helper.rb
@@ -1,14 +1,15 @@
 # frozen_string_literal: true
 
 module Admin::FilterHelper
-  ACCOUNT_FILTERS      = %i(local remote by_domain active silenced suspended username display_name email ip staff).freeze
+  ACCOUNT_FILTERS      = %i(local remote by_domain active pending silenced suspended username display_name email ip staff).freeze
   REPORT_FILTERS       = %i(resolved account_id target_account_id).freeze
   INVITE_FILTER        = %i(available expired).freeze
   CUSTOM_EMOJI_FILTERS = %i(local remote by_domain shortcode).freeze
   TAGS_FILTERS         = %i(hidden).freeze
-  INSTANCES_FILTERS    = %i(limited).freeze
+  INSTANCES_FILTERS    = %i(limited by_domain).freeze
+  FOLLOWERS_FILTERS    = %i(relationship status by_domain activity order).freeze
 
-  FILTERS = ACCOUNT_FILTERS + REPORT_FILTERS + INVITE_FILTER + CUSTOM_EMOJI_FILTERS + TAGS_FILTERS + INSTANCES_FILTERS
+  FILTERS = ACCOUNT_FILTERS + REPORT_FILTERS + INVITE_FILTER + CUSTOM_EMOJI_FILTERS + TAGS_FILTERS + INSTANCES_FILTERS + FOLLOWERS_FILTERS
 
   def filter_link_to(text, link_to_params, link_class_params = link_to_params)
     new_url = filtered_url_for(link_to_params)
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 5097a0953e84bf1a5d966ccb08ec96d7293588f1..9d113263dfda1f4bb5a1ac84384c620fe5adde24 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -20,7 +20,23 @@ module ApplicationHelper
   end
 
   def open_registrations?
-    Setting.open_registrations
+    Setting.registrations_mode == 'open'
+  end
+
+  def approved_registrations?
+    Setting.registrations_mode == 'approved'
+  end
+
+  def closed_registrations?
+    Setting.registrations_mode == 'none'
+  end
+
+  def available_sign_up_path
+    if closed_registrations?
+      'https://joinmastodon.org/#getting-started'
+    else
+      new_user_registration_path
+    end
   end
 
   def open_deletion?
@@ -101,4 +117,9 @@ module ApplicationHelper
   def storage_host?
     ENV['S3_ALIAS_HOST'].present? || ENV['S3_CLOUDFRONT_HOST'].present?
   end
+
+  def quote_wrap(text, line_width: 80, break_sequence: "\n")
+    text = word_wrap(text, line_width: line_width - 2, break_sequence: break_sequence)
+    text.split("\n").map { |line| '> ' + line }.join("\n")
+  end
 end
diff --git a/app/helpers/home_helper.rb b/app/helpers/home_helper.rb
index 9b3f1380b149b99d702e92cb5755f366f453859d..df60b7dd7ac32e8c6dc373644d0556ee90d7a336 100644
--- a/app/helpers/home_helper.rb
+++ b/app/helpers/home_helper.rb
@@ -56,4 +56,22 @@ module HomeHelper
       'emojify'
     end
   end
+
+  def optional_link_to(condition, path, options = {}, &block)
+    if condition
+      link_to(path, options, &block)
+    else
+      content_tag(:div, &block)
+    end
+  end
+
+  def sign_up_message
+    if closed_registrations?
+      t('auth.registration_closed', instance: site_hostname)
+    elsif open_registrations?
+      t('auth.register')
+    elsif approved_registrations?
+      t('auth.apply_for_account')
+    end
+  end
 end
diff --git a/app/helpers/jsonld_helper.rb b/app/helpers/jsonld_helper.rb
index 5323972723ee324dd59f33a812235e6d7ce8c5c0..5b40112755a48aa8fb548621084b40967534483d 100644
--- a/app/helpers/jsonld_helper.rb
+++ b/app/helpers/jsonld_helper.rb
@@ -47,6 +47,15 @@ module JsonLdHelper
     !uri.start_with?('http://', 'https://')
   end
 
+  def invalid_origin?(url)
+    return true if unsupported_uri_scheme?(url)
+
+    needle   = Addressable::URI.parse(url).host
+    haystack = Addressable::URI.parse(@account.uri).host
+
+    !haystack.casecmp(needle).zero?
+  end
+
   def canonicalize(json)
     graph = RDF::Graph.new << JSON::LD::API.toRdf(json, documentLoader: method(:load_jsonld_context))
     graph.dump(:normalize)
@@ -63,12 +72,19 @@ module JsonLdHelper
     json.present? && json['id'] == uri ? json : nil
   end
 
-  def fetch_resource_without_id_validation(uri, on_behalf_of = nil)
+  def fetch_resource_without_id_validation(uri, on_behalf_of = nil, raise_on_temporary_error = false)
     build_request(uri, on_behalf_of).perform do |response|
+      unless response_successful?(response) || response_error_unsalvageable?(response) || !raise_on_temporary_error
+        raise Mastodon::UnexpectedResponseError, response
+      end
       return body_to_json(response.body_with_limit) if response.code == 200
     end
     # If request failed, retry without doing it on behalf of a user
+    return if on_behalf_of.nil?
     build_request(uri).perform do |response|
+      unless response_successful?(response) || response_error_unsalvageable?(response) || !raise_on_temporary_error
+        raise Mastodon::UnexpectedResponseError, response
+      end
       response.code == 200 ? body_to_json(response.body_with_limit) : nil
     end
   end
@@ -91,6 +107,14 @@ module JsonLdHelper
 
   private
 
+  def response_successful?(response)
+    (200...300).cover?(response.code)
+  end
+
+  def response_error_unsalvageable?(response)
+    (400...500).cover?(response.code) && response.code != 429
+  end
+
   def build_request(uri, on_behalf_of = nil)
     request = Request.new(:get, uri)
     request.on_behalf_of(on_behalf_of) if on_behalf_of
diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb
index 0e957e94655a4b3ef38490c75b80e8785e02fe6a..92bc222ea9dfd96c023bcd196a7afa83da55d7e8 100644
--- a/app/helpers/settings_helper.rb
+++ b/app/helpers/settings_helper.rb
@@ -4,8 +4,9 @@ module SettingsHelper
   HUMAN_LOCALES = {
     en: 'English',
     ar: 'العربية',
-    ast: 'l\'asturianu',
+    ast: 'Asturianu',
     bg: 'Български',
+    bn: 'বাংলা',
     ca: 'Català',
     co: 'Corsu',
     cs: 'Čeština',
@@ -19,8 +20,10 @@ module SettingsHelper
     fa: 'فارسی',
     fi: 'Suomi',
     fr: 'Français',
+    ga: 'Gaeilge',
     gl: 'Galego',
     he: 'עברית',
+    hi: 'हिन्दी',
     hr: 'Hrvatski',
     hu: 'Magyar',
     hy: 'Õ€Õ¡ÕµÕ¥Ö€Õ¥Õ¶',
@@ -29,24 +32,29 @@ module SettingsHelper
     it: 'Italiano',
     ja: '日本語',
     ka: 'ქართული',
+    kk: 'Қазақша',
     ko: '한국어',
+    lt: 'Lietuvių',
+    lv: 'Latviešu',
     ml: 'മലയാളം',
+    ms: 'Bahasa Melayu',
     nl: 'Nederlands',
     no: 'Norsk',
     oc: 'Occitan',
-    pl: 'Polszczyzna',
+    pl: 'Polski',
     pt: 'Português',
     'pt-BR': 'Português do Brasil',
-    ro: 'Limba română',
+    ro: 'Română',
     ru: 'Русский',
     sk: 'Slovenčina',
     sl: 'Slovenščina',
+    sq: 'Shqip',
     sr: 'Српски',
     'sr-Latn': 'Srpski (latinica)',
     sv: 'Svenska',
     ta: 'தமிழ்',
     te: 'తెలుగు',
-    th: 'ภาษาไทย',
+    th: 'ไทย',
     tr: 'Türkçe',
     uk: 'Українська',
     zh: '中文',
diff --git a/app/helpers/stream_entries_helper.rb b/app/helpers/stream_entries_helper.rb
index 033d435c49780920e2902d23ab06491bb61de2bd..02a860a74895399d509d9db05a8c093b5fce45bc 100644
--- a/app/helpers/stream_entries_helper.rb
+++ b/app/helpers/stream_entries_helper.rb
@@ -16,24 +16,32 @@ module StreamEntriesHelper
     if user_signed_in?
       if account.id == current_user.account_id
         link_to settings_profile_url, class: 'button logo-button' do
-          safe_join([render(file: Rails.root.join('app', 'javascript', 'images', 'logo.svg')), t('settings.edit_profile')])
+          safe_join([svg_logo, t('settings.edit_profile')])
         end
       elsif current_account.following?(account) || current_account.requested?(account)
         link_to account_unfollow_path(account), class: 'button logo-button button--destructive', data: { method: :post } do
-          safe_join([render(file: Rails.root.join('app', 'javascript', 'images', 'logo.svg')), t('accounts.unfollow')])
+          safe_join([svg_logo, t('accounts.unfollow')])
         end
       elsif !(account.memorial? || account.moved?)
-        link_to account_follow_path(account), class: 'button logo-button', data: { method: :post } do
-          safe_join([render(file: Rails.root.join('app', 'javascript', 'images', 'logo.svg')), t('accounts.follow')])
+        link_to account_follow_path(account), class: "button logo-button#{account.blocking?(current_account) ? ' disabled' : ''}", data: { method: :post } do
+          safe_join([svg_logo, t('accounts.follow')])
         end
       end
     elsif !(account.memorial? || account.moved?)
       link_to account_remote_follow_path(account), class: 'button logo-button modal-button', target: '_new' do
-        safe_join([render(file: Rails.root.join('app', 'javascript', 'images', 'logo.svg')), t('accounts.follow')])
+        safe_join([svg_logo, t('accounts.follow')])
       end
     end
   end
 
+  def svg_logo
+    content_tag(:svg, tag(:use, 'xlink:href' => '#mastodon-svg-logo'), 'viewBox' => '0 0 216.4144 232.00976')
+  end
+
+  def svg_logo_full
+    content_tag(:svg, tag(:use, 'xlink:href' => '#mastodon-svg-logo-full'), 'viewBox' => '0 0 713.35878 175.8678')
+  end
+
   def account_badge(account, all: false)
     if account.bot?
       content_tag(:div, content_tag(:div, t('accounts.roles.bot'), class: 'account-role bot'), class: 'roles')
@@ -104,9 +112,19 @@ module StreamEntriesHelper
     I18n.t('statuses.content_warning', warning: status.spoiler_text)
   end
 
+  def poll_summary(status)
+    return unless status.preloadable_poll
+    status.preloadable_poll.options.map { |o| "[ ] #{o}" }.join("\n")
+  end
+
   def status_description(status)
     components = [[media_summary(status), status_text_summary(status)].reject(&:blank?).join(' · ')]
-    components << status.text if status.spoiler_text.blank?
+
+    if status.spoiler_text.blank?
+      components << status.text
+      components << poll_summary(status)
+    end
+
     components.reject(&:blank?).join("\n\n")
   end
 
@@ -170,7 +188,7 @@ module StreamEntriesHelper
     when 'public'
       fa_icon 'globe fw'
     when 'unlisted'
-      fa_icon 'unlock-alt fw'
+      fa_icon 'unlock fw'
     when 'private'
       fa_icon 'lock fw'
     when 'direct'
diff --git a/app/javascript/images/logo_full.svg b/app/javascript/images/logo_full.svg
index c33883342d7d70063112cf744fd44d577862c32c..03bcf93e39d260706eeee4903abf1b09ed9908e6 100644
--- a/app/javascript/images/logo_full.svg
+++ b/app/javascript/images/logo_full.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 713.35878 175.8678"><path d="M160.55476 105.43125c-2.4125 12.40625-21.5975 25.9825-43.63375 28.61375-11.49125 1.3725-22.80375 2.63125-34.8675 2.07875-19.73-.90375-35.2975-4.71-35.2975-4.71 0 1.92125.11875 3.75.355 5.46 2.565 19.47 19.3075 20.6375 35.16625 21.18125 16.00625.5475 30.2575-3.9475 30.2575-3.9475l.65875 14.4725s-11.19625 6.01125-31.14 7.11625c-10.99875.605-24.65375-.27625-40.56-4.485C6.99851 162.08 1.06601 125.31.15851 88-.11899 76.9225.05226 66.47625.05226 57.74125c0-38.1525 24.99625-49.335 24.99625-49.335C37.65226 2.6175 59.27976.18375 81.76351 0h.5525c22.48375.18375 44.125 2.6175 56.72875 8.40625 0 0 24.99625 11.1825 24.99625 49.335 0 0 .3125 28.1475-3.48625 47.69" fill="#3088d4"/><path d="M34.65751 48.494c0-5.55375 4.5025-10.055 10.055-10.055 5.55375 0 10.055 4.50125 10.055 10.055 0 5.5525-4.50125 10.055-10.055 10.055-5.5525 0-10.055-4.5025-10.055-10.055M178.86476 60.69975v46.195h-18.30125v-44.8375c0-9.4525-3.9775-14.24875-11.9325-14.24875-8.79375 0-13.2025 5.69125-13.2025 16.94375V89.2935h-18.19375V64.75225c0-11.2525-4.40875-16.94375-13.2025-16.94375-7.955 0-11.9325 4.79625-11.9325 14.24875v44.8375H73.79851v-46.195c0-9.44125 2.40375-16.94375 7.2325-22.495 4.98-5.55 11.50125-8.395 19.595-8.395 9.36625 0 16.45875 3.59875 21.14625 10.79875l4.56 7.6425 4.55875-7.6425c4.68875-7.2 11.78-10.79875 21.1475-10.79875 8.09375 0 14.61375 2.845 19.59375 8.395 4.82875 5.55125 7.2325 13.05375 7.2325 22.495M241.91276 83.663625c3.77625-3.99 5.595-9.015 5.595-15.075 0-6.06-1.81875-11.085-5.595-14.9275-3.63625-3.99125-8.25375-5.91125-13.84875-5.91125-5.59625 0-10.2125 1.92-13.84875 5.91125-3.6375 3.8425-5.45625 8.8675-5.45625 14.9275 0 6.06 1.81875 11.085 5.45625 15.075 3.63625 3.8425 8.2525 5.76375 13.84875 5.76375 5.595 0 10.2125-1.92125 13.84875-5.76375m5.595-52.025h18.04625v73.9h-18.04625v-8.72125c-5.455 7.2425-13.01 10.79-22.80125 10.79-9.3725 0-17.34625-3.695-24.06125-11.23375-6.57375-7.5375-9.93125-16.84875-9.93125-27.785 0-10.78875 3.3575-20.10125 9.93125-27.63875 6.715-7.5375 14.68875-11.38 24.06125-11.38 9.79125 0 17.34625 3.5475 22.80125 10.78875v-8.72zM326.26951 67.258625c5.315 3.99 7.97375 9.60625 7.83375 16.7 0 7.53875-2.65875 13.45-8.11375 17.58875-5.45625 3.99125-12.03 6.06-20.00375 6.06-14.40875 0-24.20125-5.9125-29.3775-17.58875l15.66875-9.31c2.0975 6.35375 6.71375 9.60625 13.70875 9.60625 6.43375 0 9.6525-2.07 9.6525-6.35625 0-3.10375-4.1975-5.91125-12.73-8.1275-3.21875-.8875-5.87625-1.77375-7.97375-2.51375-2.9375-1.18125-5.455-2.5125-7.55375-4.1375-5.17625-3.99-7.83375-9.3125-7.83375-16.11 0-7.2425 2.5175-13.00625 7.55375-17.145 5.17625-4.28625 11.47-6.355 19.025-6.355 12.03 0 20.84375 5.1725 26.5775 15.66625l-15.38625 8.8675c-2.23875-5.02375-6.015-7.53625-11.19125-7.53625-5.45625 0-8.11375 2.06875-8.11375 6.05875 0 3.10375 4.19625 5.91125 12.73 8.12875 6.575 1.4775 11.75 3.695 15.5275 6.50375M383.626635 49.966125h-15.8075v30.7425c0 3.695 1.4 5.91125 4.0575 6.945 1.95875.74 5.875.8875 11.75.59125v17.29375c-12.16875 1.4775-20.9825.295-26.15875-3.69625-5.175-3.8425-7.69375-10.93625-7.69375-21.13375v-30.7425h-12.17v-18.3275h12.17v-14.9275l18.045-5.76375v20.69125h15.8075v18.3275zM441.124885 83.2205c3.6375-3.84375 5.455-8.72125 5.455-14.6325 0-5.91125-1.8175-10.78875-5.455-14.63125-3.6375-3.84375-8.11375-5.76375-13.57-5.76375-5.455 0-9.93125 1.92-13.56875 5.76375-3.4975 3.99-5.31625 8.8675-5.31625 14.63125 0 5.765 1.81875 10.6425 5.31625 14.6325 3.6375 3.8425 8.11375 5.76375 13.56875 5.76375 5.45625 0 9.9325-1.92125 13.57-5.76375m-39.86875 13.15375c-7.13375-7.5375-10.63125-16.70125-10.63125-27.78625 0-10.9375 3.4975-20.1 10.63125-27.6375 7.13375-7.5375 15.9475-11.38 26.29875-11.38 10.3525 0 19.165 3.8425 26.3 11.38 7.135 7.5375 10.77125 16.84875 10.77125 27.6375 0 10.9375-3.63625 20.24875-10.77125 27.78625-7.135 7.53875-15.8075 11.2325-26.3 11.2325-10.49125 0-19.165-3.69375-26.29875-11.2325M524.92126 83.663625c3.6375-3.99 5.455-9.015 5.455-15.075 0-6.06-1.8175-11.085-5.455-14.9275-3.63625-3.99125-8.25375-5.91125-13.84875-5.91125-5.59625 0-10.2125 1.92-13.98875 5.91125-3.63625 3.8425-5.45625 8.8675-5.45625 14.9275 0 6.06 1.82 11.085 5.45625 15.075 3.77625 3.8425 8.5325 5.76375 13.98875 5.76375 5.595 0 10.2125-1.92125 13.84875-5.76375m5.455-81.585h18.04625v103.46h-18.04625v-8.72125c-5.315 7.2425-12.87 10.79-22.66125 10.79-9.3725 0-17.485-3.695-24.2-11.23375-6.575-7.5375-9.9325-16.84875-9.9325-27.785 0-10.78875 3.3575-20.10125 9.9325-27.63875 6.715-7.5375 14.8275-11.38 24.2-11.38 9.79125 0 17.34625 3.5475 22.66125 10.78875v-38.28zM611.79626 83.2205c3.63625-3.84375 5.455-8.72125 5.455-14.6325 0-5.91125-1.81875-10.78875-5.455-14.63125-3.6375-3.84375-8.11375-5.76375-13.57-5.76375-5.455 0-9.9325 1.92-13.56875 5.76375-3.49875 3.99-5.31625 8.8675-5.31625 14.63125 0 5.765 1.8175 10.6425 5.31625 14.6325 3.63625 3.8425 8.11375 5.76375 13.56875 5.76375 5.45625 0 9.9325-1.92125 13.57-5.76375m-39.86875 13.15375c-7.135-7.5375-10.63125-16.70125-10.63125-27.78625 0-10.9375 3.49625-20.1 10.63125-27.6375 7.135-7.5375 15.9475-11.38 26.29875-11.38 10.3525 0 19.165 3.8425 26.3 11.38 7.135 7.5375 10.77125 16.84875 10.77125 27.6375 0 10.9375-3.63625 20.24875-10.77125 27.78625-7.135 7.53875-15.8075 11.2325-26.3 11.2325-10.49125 0-19.16375-3.69375-26.29875-11.2325M713.35876 60.163875v45.37375h-18.04625v-43.00875c0-4.8775-1.25875-8.5725-3.77625-11.38-2.37875-2.5125-5.73625-3.84375-10.0725-3.84375-10.2125 0-15.3875 6.06-15.3875 18.3275v39.905h-18.04625v-73.89875h18.04625v8.27625c4.33625-6.94625 11.19-10.345 20.84375-10.345 7.69375 0 13.98875 2.66 18.885 8.12875 5.035 5.46875 7.55375 12.85875 7.55375 22.465" fill="#fff"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg"><symbol id="mastodon-svg-logo-full" viewBox="0 0 713.35878 175.8678"><path d="M160.55476 105.43125c-2.4125 12.40625-21.5975 25.9825-43.63375 28.61375-11.49125 1.3725-22.80375 2.63125-34.8675 2.07875-19.73-.90375-35.2975-4.71-35.2975-4.71 0 1.92125.11875 3.75.355 5.46 2.565 19.47 19.3075 20.6375 35.16625 21.18125 16.00625.5475 30.2575-3.9475 30.2575-3.9475l.65875 14.4725s-11.19625 6.01125-31.14 7.11625c-10.99875.605-24.65375-.27625-40.56-4.485C6.99851 162.08 1.06601 125.31.15851 88-.11899 76.9225.05226 66.47625.05226 57.74125c0-38.1525 24.99625-49.335 24.99625-49.335C37.65226 2.6175 59.27976.18375 81.76351 0h.5525c22.48375.18375 44.125 2.6175 56.72875 8.40625 0 0 24.99625 11.1825 24.99625 49.335 0 0 .3125 28.1475-3.48625 47.69" fill="#3088d4"/><path d="M34.65751 48.494c0-5.55375 4.5025-10.055 10.055-10.055 5.55375 0 10.055 4.50125 10.055 10.055 0 5.5525-4.50125 10.055-10.055 10.055-5.5525 0-10.055-4.5025-10.055-10.055M178.86476 60.69975v46.195h-18.30125v-44.8375c0-9.4525-3.9775-14.24875-11.9325-14.24875-8.79375 0-13.2025 5.69125-13.2025 16.94375V89.2935h-18.19375V64.75225c0-11.2525-4.40875-16.94375-13.2025-16.94375-7.955 0-11.9325 4.79625-11.9325 14.24875v44.8375H73.79851v-46.195c0-9.44125 2.40375-16.94375 7.2325-22.495 4.98-5.55 11.50125-8.395 19.595-8.395 9.36625 0 16.45875 3.59875 21.14625 10.79875l4.56 7.6425 4.55875-7.6425c4.68875-7.2 11.78-10.79875 21.1475-10.79875 8.09375 0 14.61375 2.845 19.59375 8.395 4.82875 5.55125 7.2325 13.05375 7.2325 22.495M241.91276 83.663625c3.77625-3.99 5.595-9.015 5.595-15.075 0-6.06-1.81875-11.085-5.595-14.9275-3.63625-3.99125-8.25375-5.91125-13.84875-5.91125-5.59625 0-10.2125 1.92-13.84875 5.91125-3.6375 3.8425-5.45625 8.8675-5.45625 14.9275 0 6.06 1.81875 11.085 5.45625 15.075 3.63625 3.8425 8.2525 5.76375 13.84875 5.76375 5.595 0 10.2125-1.92125 13.84875-5.76375m5.595-52.025h18.04625v73.9h-18.04625v-8.72125c-5.455 7.2425-13.01 10.79-22.80125 10.79-9.3725 0-17.34625-3.695-24.06125-11.23375-6.57375-7.5375-9.93125-16.84875-9.93125-27.785 0-10.78875 3.3575-20.10125 9.93125-27.63875 6.715-7.5375 14.68875-11.38 24.06125-11.38 9.79125 0 17.34625 3.5475 22.80125 10.78875v-8.72zM326.26951 67.258625c5.315 3.99 7.97375 9.60625 7.83375 16.7 0 7.53875-2.65875 13.45-8.11375 17.58875-5.45625 3.99125-12.03 6.06-20.00375 6.06-14.40875 0-24.20125-5.9125-29.3775-17.58875l15.66875-9.31c2.0975 6.35375 6.71375 9.60625 13.70875 9.60625 6.43375 0 9.6525-2.07 9.6525-6.35625 0-3.10375-4.1975-5.91125-12.73-8.1275-3.21875-.8875-5.87625-1.77375-7.97375-2.51375-2.9375-1.18125-5.455-2.5125-7.55375-4.1375-5.17625-3.99-7.83375-9.3125-7.83375-16.11 0-7.2425 2.5175-13.00625 7.55375-17.145 5.17625-4.28625 11.47-6.355 19.025-6.355 12.03 0 20.84375 5.1725 26.5775 15.66625l-15.38625 8.8675c-2.23875-5.02375-6.015-7.53625-11.19125-7.53625-5.45625 0-8.11375 2.06875-8.11375 6.05875 0 3.10375 4.19625 5.91125 12.73 8.12875 6.575 1.4775 11.75 3.695 15.5275 6.50375M383.626635 49.966125h-15.8075v30.7425c0 3.695 1.4 5.91125 4.0575 6.945 1.95875.74 5.875.8875 11.75.59125v17.29375c-12.16875 1.4775-20.9825.295-26.15875-3.69625-5.175-3.8425-7.69375-10.93625-7.69375-21.13375v-30.7425h-12.17v-18.3275h12.17v-14.9275l18.045-5.76375v20.69125h15.8075v18.3275zM441.124885 83.2205c3.6375-3.84375 5.455-8.72125 5.455-14.6325 0-5.91125-1.8175-10.78875-5.455-14.63125-3.6375-3.84375-8.11375-5.76375-13.57-5.76375-5.455 0-9.93125 1.92-13.56875 5.76375-3.4975 3.99-5.31625 8.8675-5.31625 14.63125 0 5.765 1.81875 10.6425 5.31625 14.6325 3.6375 3.8425 8.11375 5.76375 13.56875 5.76375 5.45625 0 9.9325-1.92125 13.57-5.76375m-39.86875 13.15375c-7.13375-7.5375-10.63125-16.70125-10.63125-27.78625 0-10.9375 3.4975-20.1 10.63125-27.6375 7.13375-7.5375 15.9475-11.38 26.29875-11.38 10.3525 0 19.165 3.8425 26.3 11.38 7.135 7.5375 10.77125 16.84875 10.77125 27.6375 0 10.9375-3.63625 20.24875-10.77125 27.78625-7.135 7.53875-15.8075 11.2325-26.3 11.2325-10.49125 0-19.165-3.69375-26.29875-11.2325M524.92126 83.663625c3.6375-3.99 5.455-9.015 5.455-15.075 0-6.06-1.8175-11.085-5.455-14.9275-3.63625-3.99125-8.25375-5.91125-13.84875-5.91125-5.59625 0-10.2125 1.92-13.98875 5.91125-3.63625 3.8425-5.45625 8.8675-5.45625 14.9275 0 6.06 1.82 11.085 5.45625 15.075 3.77625 3.8425 8.5325 5.76375 13.98875 5.76375 5.595 0 10.2125-1.92125 13.84875-5.76375m5.455-81.585h18.04625v103.46h-18.04625v-8.72125c-5.315 7.2425-12.87 10.79-22.66125 10.79-9.3725 0-17.485-3.695-24.2-11.23375-6.575-7.5375-9.9325-16.84875-9.9325-27.785 0-10.78875 3.3575-20.10125 9.9325-27.63875 6.715-7.5375 14.8275-11.38 24.2-11.38 9.79125 0 17.34625 3.5475 22.66125 10.78875v-38.28zM611.79626 83.2205c3.63625-3.84375 5.455-8.72125 5.455-14.6325 0-5.91125-1.81875-10.78875-5.455-14.63125-3.6375-3.84375-8.11375-5.76375-13.57-5.76375-5.455 0-9.9325 1.92-13.56875 5.76375-3.49875 3.99-5.31625 8.8675-5.31625 14.63125 0 5.765 1.8175 10.6425 5.31625 14.6325 3.63625 3.8425 8.11375 5.76375 13.56875 5.76375 5.45625 0 9.9325-1.92125 13.57-5.76375m-39.86875 13.15375c-7.135-7.5375-10.63125-16.70125-10.63125-27.78625 0-10.9375 3.49625-20.1 10.63125-27.6375 7.135-7.5375 15.9475-11.38 26.29875-11.38 10.3525 0 19.165 3.8425 26.3 11.38 7.135 7.5375 10.77125 16.84875 10.77125 27.6375 0 10.9375-3.63625 20.24875-10.77125 27.78625-7.135 7.53875-15.8075 11.2325-26.3 11.2325-10.49125 0-19.16375-3.69375-26.29875-11.2325M713.35876 60.163875v45.37375h-18.04625v-43.00875c0-4.8775-1.25875-8.5725-3.77625-11.38-2.37875-2.5125-5.73625-3.84375-10.0725-3.84375-10.2125 0-15.3875 6.06-15.3875 18.3275v39.905h-18.04625v-73.89875h18.04625v8.27625c4.33625-6.94625 11.19-10.345 20.84375-10.345 7.69375 0 13.98875 2.66 18.885 8.12875 5.035 5.46875 7.55375 12.85875 7.55375 22.465"/></symbol></svg>
diff --git a/app/javascript/images/logo_transparent.svg b/app/javascript/images/logo_transparent.svg
index abd6d1f67d07e8ddcfa8c18185979708211c6572..a1e7b403e034c33cda85eb8af62f7a5e98d53e15 100644
--- a/app/javascript/images/logo_transparent.svg
+++ b/app/javascript/images/logo_transparent.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 216.4144 232.00976"><path d="M107.86523 0C78.203984.2425 49.672422 3.4535937 33.044922 11.089844c0 0-32.97656262 14.752031-32.97656262 65.082031 0 11.525-.224375 25.306175.140625 39.919925 1.19750002 49.22 9.02375002 97.72843 54.53124962 109.77343 20.9825 5.55375 38.99711 6.71547 53.505856 5.91797 26.31125-1.45875 41.08203-9.38867 41.08203-9.38867l-.86914-19.08984s-18.80171 5.92758-39.91796 5.20508c-20.921254-.7175-43.006879-2.25516-46.390629-27.94141-.3125-2.25625-.46875-4.66938-.46875-7.20313 0 0 20.536953 5.0204 46.564449 6.21289 15.915.73001 30.8393-.93343 45.99805-2.74218 29.07-3.47125 54.38125-21.3818 57.5625-37.74805 5.0125-25.78125 4.59961-62.916015 4.59961-62.916015 0-50.33-32.97461-65.082031-32.97461-65.082031C166.80539 3.4535938 138.255.2425 108.59375 0h-.72852zM74.296875 39.326172c12.355 0 21.710234 4.749297 27.896485 14.248047l6.01367 10.080078 6.01563-10.080078c6.185-9.49875 15.54023-14.248047 27.89648-14.248047 10.6775 0 19.28156 3.753672 25.85156 11.076172 6.36875 7.3225 9.53907 17.218828 9.53907 29.673828v60.941408h-24.14454V81.869141c0-12.46875-5.24453-18.798829-15.73828-18.798829-11.6025 0-17.41797 7.508516-17.41797 22.353516v32.375002H96.207031V85.423828c0-14.845-5.815468-22.353515-17.417969-22.353516-10.49375 0-15.740234 6.330079-15.740234 18.798829v59.148439H38.904297V80.076172c0-12.455 3.171016-22.351328 9.541015-29.673828 6.568751-7.3225 15.172813-11.076172 25.851563-11.076172z" fill="#fff"/></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg"><symbol id="mastodon-svg-logo" viewBox="0 0 216.4144 232.00976"><path d="M107.86523 0C78.203984.2425 49.672422 3.4535937 33.044922 11.089844c0 0-32.97656262 14.752031-32.97656262 65.082031 0 11.525-.224375 25.306175.140625 39.919925 1.19750002 49.22 9.02375002 97.72843 54.53124962 109.77343 20.9825 5.55375 38.99711 6.71547 53.505856 5.91797 26.31125-1.45875 41.08203-9.38867 41.08203-9.38867l-.86914-19.08984s-18.80171 5.92758-39.91796 5.20508c-20.921254-.7175-43.006879-2.25516-46.390629-27.94141-.3125-2.25625-.46875-4.66938-.46875-7.20313 0 0 20.536953 5.0204 46.564449 6.21289 15.915.73001 30.8393-.93343 45.99805-2.74218 29.07-3.47125 54.38125-21.3818 57.5625-37.74805 5.0125-25.78125 4.59961-62.916015 4.59961-62.916015 0-50.33-32.97461-65.082031-32.97461-65.082031C166.80539 3.4535938 138.255.2425 108.59375 0h-.72852zM74.296875 39.326172c12.355 0 21.710234 4.749297 27.896485 14.248047l6.01367 10.080078 6.01563-10.080078c6.185-9.49875 15.54023-14.248047 27.89648-14.248047 10.6775 0 19.28156 3.753672 25.85156 11.076172 6.36875 7.3225 9.53907 17.218828 9.53907 29.673828v60.941408h-24.14454V81.869141c0-12.46875-5.24453-18.798829-15.73828-18.798829-11.6025 0-17.41797 7.508516-17.41797 22.353516v32.375002H96.207031V85.423828c0-14.845-5.815468-22.353515-17.417969-22.353516-10.49375 0-15.740234 6.330079-15.740234 18.798829v59.148439H38.904297V80.076172c0-12.455 3.171016-22.351328 9.541015-29.673828 6.568751-7.3225 15.172813-11.076172 25.851563-11.076172z" /></symbol></svg>
diff --git a/app/javascript/images/logo_transparent_black.svg b/app/javascript/images/logo_transparent_black.svg
new file mode 100644
index 0000000000000000000000000000000000000000..e44bcf5e14b04302655ef9f6eea5ca73b092abb6
--- /dev/null
+++ b/app/javascript/images/logo_transparent_black.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 216.4144 232.00976"><path d="M107.86523 0C78.203984.2425 49.672422 3.4535937 33.044922 11.089844c0 0-32.97656262 14.752031-32.97656262 65.082031 0 11.525-.224375 25.306175.140625 39.919925 1.19750002 49.22 9.02375002 97.72843 54.53124962 109.77343 20.9825 5.55375 38.99711 6.71547 53.505856 5.91797 26.31125-1.45875 41.08203-9.38867 41.08203-9.38867l-.86914-19.08984s-18.80171 5.92758-39.91796 5.20508c-20.921254-.7175-43.006879-2.25516-46.390629-27.94141-.3125-2.25625-.46875-4.66938-.46875-7.20313 0 0 20.536953 5.0204 46.564449 6.21289 15.915.73001 30.8393-.93343 45.99805-2.74218 29.07-3.47125 54.38125-21.3818 57.5625-37.74805 5.0125-25.78125 4.59961-62.916015 4.59961-62.916015 0-50.33-32.97461-65.082031-32.97461-65.082031C166.80539 3.4535938 138.255.2425 108.59375 0h-.72852zM74.296875 39.326172c12.355 0 21.710234 4.749297 27.896485 14.248047l6.01367 10.080078 6.01563-10.080078c6.185-9.49875 15.54023-14.248047 27.89648-14.248047 10.6775 0 19.28156 3.753672 25.85156 11.076172 6.36875 7.3225 9.53907 17.218828 9.53907 29.673828v60.941408h-24.14454V81.869141c0-12.46875-5.24453-18.798829-15.73828-18.798829-11.6025 0-17.41797 7.508516-17.41797 22.353516v32.375002H96.207031V85.423828c0-14.845-5.815468-22.353515-17.417969-22.353516-10.49375 0-15.740234 6.330079-15.740234 18.798829v59.148439H38.904297V80.076172c0-12.455 3.171016-22.351328 9.541015-29.673828 6.568751-7.3225 15.172813-11.076172 25.851563-11.076172z" fill="#000"/></svg>
diff --git a/app/javascript/images/proof_providers/keybase.png b/app/javascript/images/proof_providers/keybase.png
new file mode 100644
index 0000000000000000000000000000000000000000..7e3ac657f419d3dab558f4454f85221b0932dcc5
Binary files /dev/null and b/app/javascript/images/proof_providers/keybase.png differ
diff --git a/app/javascript/mastodon/actions/alerts.js b/app/javascript/mastodon/actions/alerts.js
index 3f5d7ef46b198949838f880b14f84d94365bdf45..ef2500e7bdd84fb6a3cd353991a07ae1371f5bd7 100644
--- a/app/javascript/mastodon/actions/alerts.js
+++ b/app/javascript/mastodon/actions/alerts.js
@@ -8,6 +8,7 @@ const messages = defineMessages({
 export const ALERT_SHOW    = 'ALERT_SHOW';
 export const ALERT_DISMISS = 'ALERT_DISMISS';
 export const ALERT_CLEAR   = 'ALERT_CLEAR';
+export const ALERT_NOOP    = 'ALERT_NOOP';
 
 export function dismissAlert(alert) {
   return {
@@ -22,7 +23,7 @@ export function clearAlert() {
   };
 };
 
-export function showAlert(title, message) {
+export function showAlert(title = messages.unexpectedTitle, message = messages.unexpectedMessage) {
   return {
     type: ALERT_SHOW,
     title,
@@ -34,6 +35,11 @@ export function showAlertForError(error) {
   if (error.response) {
     const { data, status, statusText } = error.response;
 
+    if (status === 404 || status === 410) {
+      // Skip these errors as they are reflected in the UI
+      return { type: ALERT_NOOP };
+    }
+
     let message = statusText;
     let title   = `${status}`;
 
@@ -44,6 +50,6 @@ export function showAlertForError(error) {
     return showAlert(title, message);
   } else {
     console.error(error);
-    return showAlert(messages.unexpectedTitle, messages.unexpectedMessage);
+    return showAlert();
   }
 }
diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js
index a4352faaba63746cd28cf22faab7c1c6799cb5ed..fbf97d37475036232741bb3d2496aab2d04c715b 100644
--- a/app/javascript/mastodon/actions/compose.js
+++ b/app/javascript/mastodon/actions/compose.js
@@ -8,6 +8,8 @@ import resizeImage from '../utils/resize_image';
 import { importFetchedAccounts } from './importer';
 import { updateTimeline } from './timelines';
 import { showAlertForError } from './alerts';
+import { showAlert } from './alerts';
+import { defineMessages } from 'react-intl';
 
 let cancelFetchComposeSuggestionsAccounts;
 
@@ -49,6 +51,26 @@ export const COMPOSE_UPLOAD_CHANGE_REQUEST     = 'COMPOSE_UPLOAD_UPDATE_REQUEST'
 export const COMPOSE_UPLOAD_CHANGE_SUCCESS     = 'COMPOSE_UPLOAD_UPDATE_SUCCESS';
 export const COMPOSE_UPLOAD_CHANGE_FAIL        = 'COMPOSE_UPLOAD_UPDATE_FAIL';
 
+export const COMPOSE_POLL_ADD             = 'COMPOSE_POLL_ADD';
+export const COMPOSE_POLL_REMOVE          = 'COMPOSE_POLL_REMOVE';
+export const COMPOSE_POLL_OPTION_ADD      = 'COMPOSE_POLL_OPTION_ADD';
+export const COMPOSE_POLL_OPTION_CHANGE   = 'COMPOSE_POLL_OPTION_CHANGE';
+export const COMPOSE_POLL_OPTION_REMOVE   = 'COMPOSE_POLL_OPTION_REMOVE';
+export const COMPOSE_POLL_SETTINGS_CHANGE = 'COMPOSE_POLL_SETTINGS_CHANGE';
+
+const messages = defineMessages({
+  uploadErrorLimit: { id: 'upload_error.limit', defaultMessage: 'File upload limit exceeded.' },
+  uploadErrorPoll:  { id: 'upload_error.poll', defaultMessage: 'File upload not allowed with polls.' },
+});
+
+const COMPOSE_PANEL_BREAKPOINT = 600 + (285 * 1) + (10 * 1);
+
+export const ensureComposeIsVisible = (getState, routerHistory) => {
+  if (!getState().getIn(['compose', 'mounted']) && window.innerWidth < COMPOSE_PANEL_BREAKPOINT) {
+    routerHistory.push('/statuses/new');
+  }
+};
+
 export function changeCompose(text) {
   return {
     type: COMPOSE_CHANGE,
@@ -63,9 +85,7 @@ export function replyCompose(status, routerHistory) {
       status: status,
     });
 
-    if (!getState().getIn(['compose', 'mounted'])) {
-      routerHistory.push('/statuses/new');
-    }
+    ensureComposeIsVisible(getState, routerHistory);
   };
 };
 
@@ -88,9 +108,7 @@ export function mentionCompose(account, routerHistory) {
       account: account,
     });
 
-    if (!getState().getIn(['compose', 'mounted'])) {
-      routerHistory.push('/statuses/new');
-    }
+    ensureComposeIsVisible(getState, routerHistory);
   };
 };
 
@@ -101,9 +119,7 @@ export function directCompose(account, routerHistory) {
       account: account,
     });
 
-    if (!getState().getIn(['compose', 'mounted'])) {
-      routerHistory.push('/statuses/new');
-    }
+    ensureComposeIsVisible(getState, routerHistory);
   };
 };
 
@@ -123,8 +139,9 @@ export function submitCompose(routerHistory) {
       in_reply_to_id: getState().getIn(['compose', 'in_reply_to'], null),
       media_ids: media.map(item => item.get('id')),
       sensitive: getState().getIn(['compose', 'sensitive']),
-      spoiler_text: getState().getIn(['compose', 'spoiler_text'], ''),
+      spoiler_text: getState().getIn(['compose', 'spoiler']) ? getState().getIn(['compose', 'spoiler_text'], '') : '',
       visibility: getState().getIn(['compose', 'privacy']),
+      poll: getState().getIn(['compose', 'poll'], null),
     }, {
       headers: {
         'Idempotency-Key': getState().getIn(['compose', 'idempotencyKey']),
@@ -143,7 +160,9 @@ export function submitCompose(routerHistory) {
       // into the columns
 
       const insertIfOnline = timelineId => {
-        if (getState().getIn(['timelines', timelineId, 'items', 0]) !== null) {
+        const timeline = getState().getIn(['timelines', timelineId]);
+
+        if (timeline && timeline.get('items').size > 0 && timeline.getIn(['items', 0]) !== null && timeline.get('online')) {
           dispatch(updateTimeline(timelineId, { ...response.data }));
         }
       };
@@ -184,20 +203,40 @@ export function submitComposeFail(error) {
 
 export function uploadCompose(files) {
   return function (dispatch, getState) {
-    if (getState().getIn(['compose', 'media_attachments']).size > 3) {
+    const uploadLimit = 4;
+    const media  = getState().getIn(['compose', 'media_attachments']);
+    const progress = new Array(files.length).fill(0);
+    let total = Array.from(files).reduce((a, v) => a + v.size, 0);
+
+    if (files.length + media.size > uploadLimit) {
+      dispatch(showAlert(undefined, messages.uploadErrorLimit));
+      return;
+    }
+
+    if (getState().getIn(['compose', 'poll'])) {
+      dispatch(showAlert(undefined, messages.uploadErrorPoll));
       return;
     }
 
     dispatch(uploadComposeRequest());
 
-    resizeImage(files[0]).then(file => {
-      const data = new FormData();
-      data.append('file', file);
+    for (const [i, f] of Array.from(files).entries()) {
+      if (media.size + i > 3) break;
+
+      resizeImage(f).then(file => {
+        const data = new FormData();
+        data.append('file', file);
+        // Account for disparity in size of original image and resized data
+        total += file.size - f.size;
 
-      return api(getState).post('/api/v1/media', data, {
-        onUploadProgress: ({ loaded, total }) => dispatch(uploadComposeProgress(loaded, total)),
-      }).then(({ data }) => dispatch(uploadComposeSuccess(data)));
-    }).catch(error => dispatch(uploadComposeFail(error)));
+        return api(getState).post('/api/v1/media', data, {
+          onUploadProgress: function({ loaded }){
+            progress[i] = loaded;
+            dispatch(uploadComposeProgress(progress.reduce((a, v) => a + v, 0), total));
+          },
+        }).then(({ data }) => dispatch(uploadComposeSuccess(data)));
+      }).catch(error => dispatch(uploadComposeFail(error)));
+    };
   };
 };
 
@@ -346,7 +385,7 @@ export function readyComposeSuggestionsAccounts(token, accounts) {
   };
 };
 
-export function selectComposeSuggestion(position, token, suggestion) {
+export function selectComposeSuggestion(position, token, suggestion, path) {
   return (dispatch, getState) => {
     let completion, startPosition;
 
@@ -368,6 +407,7 @@ export function selectComposeSuggestion(position, token, suggestion) {
       position: startPosition,
       token,
       completion,
+      path,
     });
   };
 };
@@ -466,4 +506,46 @@ export function changeComposing(value) {
     type: COMPOSE_COMPOSING_CHANGE,
     value,
   };
-}
+};
+
+export function addPoll() {
+  return {
+    type: COMPOSE_POLL_ADD,
+  };
+};
+
+export function removePoll() {
+  return {
+    type: COMPOSE_POLL_REMOVE,
+  };
+};
+
+export function addPollOption(title) {
+  return {
+    type: COMPOSE_POLL_OPTION_ADD,
+    title,
+  };
+};
+
+export function changePollOption(index, title) {
+  return {
+    type: COMPOSE_POLL_OPTION_CHANGE,
+    index,
+    title,
+  };
+};
+
+export function removePollOption(index) {
+  return {
+    type: COMPOSE_POLL_OPTION_REMOVE,
+    index,
+  };
+};
+
+export function changePollSettings(expiresIn, isMultiple) {
+  return {
+    type: COMPOSE_POLL_SETTINGS_CHANGE,
+    expiresIn,
+    isMultiple,
+  };
+};
diff --git a/app/javascript/mastodon/actions/conversations.js b/app/javascript/mastodon/actions/conversations.js
index 3c2ea968060c8b32b097ce609ef5e04f670ff2e3..c6e062ef73b2e5129aa9ebce8254c77f5d7b59a9 100644
--- a/app/javascript/mastodon/actions/conversations.js
+++ b/app/javascript/mastodon/actions/conversations.js
@@ -41,13 +41,15 @@ export const expandConversations = ({ maxId } = {}) => (dispatch, getState) => {
     params.since_id = getState().getIn(['conversations', 'items', 0, 'last_status']);
   }
 
+  const isLoadingRecent = !!params.since_id;
+
   api(getState).get('/api/v1/conversations', { params })
     .then(response => {
       const next = getLinks(response).refs.find(link => link.rel === 'next');
 
       dispatch(importFetchedAccounts(response.data.reduce((aggr, item) => aggr.concat(item.accounts), [])));
       dispatch(importFetchedStatuses(response.data.map(item => item.last_status).filter(x => !!x)));
-      dispatch(expandConversationsSuccess(response.data, next ? next.uri : null));
+      dispatch(expandConversationsSuccess(response.data, next ? next.uri : null, isLoadingRecent));
     })
     .catch(err => dispatch(expandConversationsFail(err)));
 };
@@ -56,10 +58,11 @@ export const expandConversationsRequest = () => ({
   type: CONVERSATIONS_FETCH_REQUEST,
 });
 
-export const expandConversationsSuccess = (conversations, next) => ({
+export const expandConversationsSuccess = (conversations, next, isLoadingRecent) => ({
   type: CONVERSATIONS_FETCH_SUCCESS,
   conversations,
   next,
+  isLoadingRecent,
 });
 
 export const expandConversationsFail = error => ({
diff --git a/app/javascript/mastodon/actions/domain_blocks.js b/app/javascript/mastodon/actions/domain_blocks.js
index 0445a5e10c6f72753935cdf2fa4fbed3f4650fd7..34a33a65465ee2e058389ff0d006ccaa6a4ee727 100644
--- a/app/javascript/mastodon/actions/domain_blocks.js
+++ b/app/javascript/mastodon/actions/domain_blocks.js
@@ -23,6 +23,7 @@ export function blockDomain(domain) {
     api(getState).post('/api/v1/domain_blocks', { domain }).then(() => {
       const at_domain = '@' + domain;
       const accounts = getState().get('accounts').filter(item => item.get('acct').endsWith(at_domain)).valueSeq().map(item => item.get('id'));
+
       dispatch(blockDomainSuccess(domain, accounts));
     }).catch(err => {
       dispatch(blockDomainFail(domain, err));
diff --git a/app/javascript/mastodon/actions/identity_proofs.js b/app/javascript/mastodon/actions/identity_proofs.js
new file mode 100644
index 0000000000000000000000000000000000000000..449debf616fa5f50eb577763fb99727b53127399
--- /dev/null
+++ b/app/javascript/mastodon/actions/identity_proofs.js
@@ -0,0 +1,30 @@
+import api from '../api';
+
+export const IDENTITY_PROOFS_ACCOUNT_FETCH_REQUEST = 'IDENTITY_PROOFS_ACCOUNT_FETCH_REQUEST';
+export const IDENTITY_PROOFS_ACCOUNT_FETCH_SUCCESS = 'IDENTITY_PROOFS_ACCOUNT_FETCH_SUCCESS';
+export const IDENTITY_PROOFS_ACCOUNT_FETCH_FAIL    = 'IDENTITY_PROOFS_ACCOUNT_FETCH_FAIL';
+
+export const fetchAccountIdentityProofs = accountId => (dispatch, getState) => {
+  dispatch(fetchAccountIdentityProofsRequest(accountId));
+
+  api(getState).get(`/api/v1/accounts/${accountId}/identity_proofs`)
+    .then(({ data }) => dispatch(fetchAccountIdentityProofsSuccess(accountId, data)))
+    .catch(err => dispatch(fetchAccountIdentityProofsFail(accountId, err)));
+};
+
+export const fetchAccountIdentityProofsRequest = id => ({
+  type: IDENTITY_PROOFS_ACCOUNT_FETCH_REQUEST,
+  id,
+});
+
+export const fetchAccountIdentityProofsSuccess = (accountId, identity_proofs) => ({
+  type: IDENTITY_PROOFS_ACCOUNT_FETCH_SUCCESS,
+  accountId,
+  identity_proofs,
+});
+
+export const fetchAccountIdentityProofsFail = (accountId, err) => ({
+  type: IDENTITY_PROOFS_ACCOUNT_FETCH_FAIL,
+  accountId,
+  err,
+});
diff --git a/app/javascript/mastodon/actions/importer/index.js b/app/javascript/mastodon/actions/importer/index.js
index 931711f4b0563f985ed74ab9f4e55ac8f4b72ff3..f4372fb31d07833a11e3c856c293ef6036350e7c 100644
--- a/app/javascript/mastodon/actions/importer/index.js
+++ b/app/javascript/mastodon/actions/importer/index.js
@@ -1,11 +1,10 @@
-// import { autoPlayGif } from '../../initial_state';
-// import { putAccounts, putStatuses } from '../../storage/modifier';
-import { normalizeAccount, normalizeStatus } from './normalizer';
+import { normalizeAccount, normalizeStatus, normalizePoll } from './normalizer';
 
-export const ACCOUNT_IMPORT = 'ACCOUNT_IMPORT';
+export const ACCOUNT_IMPORT  = 'ACCOUNT_IMPORT';
 export const ACCOUNTS_IMPORT = 'ACCOUNTS_IMPORT';
-export const STATUS_IMPORT = 'STATUS_IMPORT';
+export const STATUS_IMPORT   = 'STATUS_IMPORT';
 export const STATUSES_IMPORT = 'STATUSES_IMPORT';
+export const POLLS_IMPORT    = 'POLLS_IMPORT';
 
 function pushUnique(array, object) {
   if (array.every(element => element.id !== object.id)) {
@@ -29,6 +28,10 @@ export function importStatuses(statuses) {
   return { type: STATUSES_IMPORT, statuses };
 }
 
+export function importPolls(polls) {
+  return { type: POLLS_IMPORT, polls };
+}
+
 export function importFetchedAccount(account) {
   return importFetchedAccounts([account]);
 }
@@ -45,7 +48,6 @@ export function importFetchedAccounts(accounts) {
   }
 
   accounts.forEach(processAccount);
-  //putAccounts(normalAccounts, !autoPlayGif);
 
   return importAccounts(normalAccounts);
 }
@@ -58,6 +60,7 @@ export function importFetchedStatuses(statuses) {
   return (dispatch, getState) => {
     const accounts = [];
     const normalStatuses = [];
+    const polls = [];
 
     function processStatus(status) {
       pushUnique(normalStatuses, normalizeStatus(status, getState().getIn(['statuses', status.id])));
@@ -66,12 +69,22 @@ export function importFetchedStatuses(statuses) {
       if (status.reblog && status.reblog.id) {
         processStatus(status.reblog);
       }
+
+      if (status.poll && status.poll.id) {
+        pushUnique(polls, normalizePoll(status.poll));
+      }
     }
 
     statuses.forEach(processStatus);
-    //putStatuses(normalStatuses);
 
+    dispatch(importPolls(polls));
     dispatch(importFetchedAccounts(accounts));
     dispatch(importStatuses(normalStatuses));
   };
 }
+
+export function importFetchedPoll(poll) {
+  return dispatch => {
+    dispatch(importPolls([normalizePoll(poll)]));
+  };
+}
diff --git a/app/javascript/mastodon/actions/importer/normalizer.js b/app/javascript/mastodon/actions/importer/normalizer.js
index 34a4150facb90c521a9e82f8142d20ebb2507a67..5e7e78e698484674d3b7814d6d820f4839b0ad6e 100644
--- a/app/javascript/mastodon/actions/importer/normalizer.js
+++ b/app/javascript/mastodon/actions/importer/normalizer.js
@@ -22,7 +22,7 @@ export function normalizeAccount(account) {
   if (account.fields) {
     account.fields = account.fields.map(pair => ({
       ...pair,
-      name_emojified: emojify(escapeTextContentForBrowser(pair.name)),
+      name_emojified: emojify(escapeTextContentForBrowser(pair.name), emojiMap),
       value_emojified: emojify(pair.value, emojiMap),
       value_plain: unescapeHTML(pair.value),
     }));
@@ -43,6 +43,10 @@ export function normalizeStatus(status, normalOldStatus) {
     normalStatus.reblog = status.reblog.id;
   }
 
+  if (status.poll && status.poll.id) {
+    normalStatus.poll = status.poll.id;
+  }
+
   // Only calculate these values when status first encountered
   // Otherwise keep the ones already in the reducer
   if (normalOldStatus) {
@@ -52,7 +56,7 @@ export function normalizeStatus(status, normalOldStatus) {
     normalStatus.hidden = normalOldStatus.get('hidden');
   } else {
     const spoilerText   = normalStatus.spoiler_text || '';
-    const searchContent = [spoilerText, status.content].join('\n\n').replace(/<br\s*\/?>/g, '\n').replace(/<\/p><p>/g, '\n\n');
+    const searchContent = ([spoilerText, status.content].concat((status.poll && status.poll.options) ? status.poll.options.map(option => option.title) : [])).join('\n\n').replace(/<br\s*\/?>/g, '\n').replace(/<\/p><p>/g, '\n\n');
     const emojiMap      = makeEmojiMap(normalStatus);
 
     normalStatus.search_index = domParser.parseFromString(searchContent, 'text/html').documentElement.textContent;
@@ -63,3 +67,16 @@ export function normalizeStatus(status, normalOldStatus) {
 
   return normalStatus;
 }
+
+export function normalizePoll(poll) {
+  const normalPoll = { ...poll };
+
+  const emojiMap = makeEmojiMap(normalPoll);
+
+  normalPoll.options = poll.options.map(option => ({
+    ...option,
+    title_emojified: emojify(escapeTextContentForBrowser(option.title), emojiMap),
+  }));
+
+  return normalPoll;
+}
diff --git a/app/javascript/mastodon/actions/modal.js b/app/javascript/mastodon/actions/modal.js
index 80e15c28ec17889413039375509900ffdfbddc50..3d0299db58af52132cede0f3ac219a1c6c298605 100644
--- a/app/javascript/mastodon/actions/modal.js
+++ b/app/javascript/mastodon/actions/modal.js
@@ -9,8 +9,9 @@ export function openModal(type, props) {
   };
 };
 
-export function closeModal() {
+export function closeModal(type) {
   return {
     type: MODAL_CLOSE,
+    modalType: type,
   };
 };
diff --git a/app/javascript/mastodon/actions/notifications.js b/app/javascript/mastodon/actions/notifications.js
index 4c145febc4fc1e9f2c32180588a923b6c4434d7f..56c952cb05866b3a0dbeaf97d4f06be7d4647842 100644
--- a/app/javascript/mastodon/actions/notifications.js
+++ b/app/javascript/mastodon/actions/notifications.js
@@ -7,10 +7,11 @@ import {
   importFetchedStatus,
   importFetchedStatuses,
 } from './importer';
+import { saveSettings } from './settings';
 import { defineMessages } from 'react-intl';
 import { List as ImmutableList } from 'immutable';
 import { unescapeHTML } from '../utils/html';
-import { getFilters, regexFromFilters } from '../selectors';
+import { getFiltersRegex } from '../selectors';
 
 export const NOTIFICATIONS_UPDATE      = 'NOTIFICATIONS_UPDATE';
 export const NOTIFICATIONS_UPDATE_NOOP = 'NOTIFICATIONS_UPDATE_NOOP';
@@ -42,14 +43,19 @@ export function updateNotifications(notification, intlMessages, intlLocale) {
     const showInColumn = getState().getIn(['settings', 'notifications', 'shows', notification.type], true);
     const showAlert    = getState().getIn(['settings', 'notifications', 'alerts', notification.type], true);
     const playSound    = getState().getIn(['settings', 'notifications', 'sounds', notification.type], true);
-    const filters      = getFilters(getState(), { contextType: 'notifications' });
+    const filters      = getFiltersRegex(getState(), { contextType: 'notifications' });
 
     let filtered = false;
 
     if (notification.type === 'mention') {
-      const regex       = regexFromFilters(filters);
+      const dropRegex   = filters[0];
+      const regex       = filters[1];
       const searchIndex = notification.status.spoiler_text + '\n' + unescapeHTML(notification.status.content);
 
+      if (dropRegex && dropRegex.test(searchIndex)) {
+        return;
+      }
+
       filtered = regex && regex.test(searchIndex);
     }
 
@@ -92,7 +98,7 @@ export function updateNotifications(notification, intlMessages, intlLocale) {
 const excludeTypesFromSettings = state => state.getIn(['settings', 'notifications', 'shows']).filter(enabled => !enabled).keySeq().toJS();
 
 const excludeTypesFromFilter = filter => {
-  const allTypes = ImmutableList(['follow', 'favourite', 'reblog', 'mention']);
+  const allTypes = ImmutableList(['follow', 'favourite', 'reblog', 'mention', 'poll']);
   return allTypes.filterNot(item => item === filter).toJS();
 };
 
@@ -187,5 +193,6 @@ export function setFilter (filterType) {
       value: filterType,
     });
     dispatch(expandNotifications());
+    dispatch(saveSettings());
   };
 };
diff --git a/app/javascript/mastodon/actions/polls.js b/app/javascript/mastodon/actions/polls.js
new file mode 100644
index 0000000000000000000000000000000000000000..8e8b82df5d0eed2a52cb9487f919f2aae4db4454
--- /dev/null
+++ b/app/javascript/mastodon/actions/polls.js
@@ -0,0 +1,60 @@
+import api from '../api';
+import { importFetchedPoll } from './importer';
+
+export const POLL_VOTE_REQUEST = 'POLL_VOTE_REQUEST';
+export const POLL_VOTE_SUCCESS = 'POLL_VOTE_SUCCESS';
+export const POLL_VOTE_FAIL    = 'POLL_VOTE_FAIL';
+
+export const POLL_FETCH_REQUEST = 'POLL_FETCH_REQUEST';
+export const POLL_FETCH_SUCCESS = 'POLL_FETCH_SUCCESS';
+export const POLL_FETCH_FAIL    = 'POLL_FETCH_FAIL';
+
+export const vote = (pollId, choices) => (dispatch, getState) => {
+  dispatch(voteRequest());
+
+  api(getState).post(`/api/v1/polls/${pollId}/votes`, { choices })
+    .then(({ data }) => {
+      dispatch(importFetchedPoll(data));
+      dispatch(voteSuccess(data));
+    })
+    .catch(err => dispatch(voteFail(err)));
+};
+
+export const fetchPoll = pollId => (dispatch, getState) => {
+  dispatch(fetchPollRequest());
+
+  api(getState).get(`/api/v1/polls/${pollId}`)
+    .then(({ data }) => {
+      dispatch(importFetchedPoll(data));
+      dispatch(fetchPollSuccess(data));
+    })
+    .catch(err => dispatch(fetchPollFail(err)));
+};
+
+export const voteRequest = () => ({
+  type: POLL_VOTE_REQUEST,
+});
+
+export const voteSuccess = poll => ({
+  type: POLL_VOTE_SUCCESS,
+  poll,
+});
+
+export const voteFail = error => ({
+  type: POLL_VOTE_FAIL,
+  error,
+});
+
+export const fetchPollRequest = () => ({
+  type: POLL_FETCH_REQUEST,
+});
+
+export const fetchPollSuccess = poll => ({
+  type: POLL_FETCH_SUCCESS,
+  poll,
+});
+
+export const fetchPollFail = error => ({
+  type: POLL_FETCH_FAIL,
+  error,
+});
diff --git a/app/javascript/mastodon/actions/search.js b/app/javascript/mastodon/actions/search.js
index b670d25c3c50728a291ec318f3247a1a94e18595..0974fdd15e6a5de30e318bade3ccbe4a73b58da4 100644
--- a/app/javascript/mastodon/actions/search.js
+++ b/app/javascript/mastodon/actions/search.js
@@ -37,6 +37,7 @@ export function submitSearch() {
       params: {
         q: value,
         resolve: true,
+        limit: 5,
       },
     }).then(response => {
       if (response.data.accounts) {
@@ -47,7 +48,7 @@ export function submitSearch() {
         dispatch(importFetchedStatuses(response.data.statuses));
       }
 
-      dispatch(fetchSearchSuccess(response.data));
+      dispatch(fetchSearchSuccess(response.data, value));
       dispatch(fetchRelationships(response.data.accounts.map(item => item.id)));
     }).catch(error => {
       dispatch(fetchSearchFail(error));
@@ -61,10 +62,11 @@ export function fetchSearchRequest() {
   };
 };
 
-export function fetchSearchSuccess(results) {
+export function fetchSearchSuccess(results, searchTerm) {
   return {
     type: SEARCH_FETCH_SUCCESS,
     results,
+    searchTerm,
   };
 };
 
diff --git a/app/javascript/mastodon/actions/statuses.js b/app/javascript/mastodon/actions/statuses.js
index e7c89b4ba8a4c49fc44e9ad0264ccd1d82cdd329..06a19afc3ad4b8b7a7bc38233e83a0f0e63d1b70 100644
--- a/app/javascript/mastodon/actions/statuses.js
+++ b/app/javascript/mastodon/actions/statuses.js
@@ -4,6 +4,7 @@ import { evictStatus } from '../storage/modifier';
 
 import { deleteFromTimelines } from './timelines';
 import { importFetchedStatus, importFetchedStatuses, importAccount, importStatus } from './importer';
+import { ensureComposeIsVisible } from './compose';
 
 export const STATUS_FETCH_REQUEST = 'STATUS_FETCH_REQUEST';
 export const STATUS_FETCH_SUCCESS = 'STATUS_FETCH_SUCCESS';
@@ -131,30 +132,32 @@ export function fetchStatusFail(id, error, skipLoading) {
   };
 };
 
-export function redraft(status) {
+export function redraft(status, raw_text) {
   return {
     type: REDRAFT,
     status,
+    raw_text,
   };
 };
 
-export function deleteStatus(id, router, withRedraft = false) {
+export function deleteStatus(id, routerHistory, withRedraft = false) {
   return (dispatch, getState) => {
-    const status = getState().getIn(['statuses', id]);
+    let status = getState().getIn(['statuses', id]);
+
+    if (status.get('poll')) {
+      status = status.set('poll', getState().getIn(['polls', status.get('poll')]));
+    }
 
     dispatch(deleteStatusRequest(id));
 
-    api(getState).delete(`/api/v1/statuses/${id}`).then(() => {
+    api(getState).delete(`/api/v1/statuses/${id}`).then(response => {
       evictStatus(id);
       dispatch(deleteStatusSuccess(id));
       dispatch(deleteFromTimelines(id));
 
       if (withRedraft) {
-        dispatch(redraft(status));
-
-        if (!getState().getIn(['compose', 'mounted'])) {
-          router.push('/statuses/new');
-        }
+        dispatch(redraft(status, response.data.text));
+        ensureComposeIsVisible(getState, routerHistory);
       }
     }).catch(error => {
       dispatch(deleteStatusFail(id, error));
diff --git a/app/javascript/mastodon/actions/streaming.js b/app/javascript/mastodon/actions/streaming.js
index cd319709d82b602d8008a67332fdfe724b306ff1..c678e9393205961a98a99c35071521e6c1f42d3a 100644
--- a/app/javascript/mastodon/actions/streaming.js
+++ b/app/javascript/mastodon/actions/streaming.js
@@ -3,6 +3,7 @@ import {
   updateTimeline,
   deleteFromTimelines,
   expandHomeTimeline,
+  connectTimeline,
   disconnectTimeline,
 } from './timelines';
 import { updateNotifications, expandNotifications } from './notifications';
@@ -16,7 +17,12 @@ export function connectTimelineStream (timelineId, path, pollingRefresh = null,
 
   return connectStream (path, pollingRefresh, (dispatch, getState) => {
     const locale = getState().getIn(['meta', 'locale']);
+
     return {
+      onConnect() {
+        dispatch(connectTimeline(timelineId));
+      },
+
       onDisconnect() {
         dispatch(disconnectTimeline(timelineId));
       },
diff --git a/app/javascript/mastodon/actions/timelines.js b/app/javascript/mastodon/actions/timelines.js
index 6e7bd027cb782d1037b6b11be719fdf487fbf1fa..06c21b96b7f95e016bab3961a5a9dc3ec579ffc2 100644
--- a/app/javascript/mastodon/actions/timelines.js
+++ b/app/javascript/mastodon/actions/timelines.js
@@ -12,6 +12,7 @@ export const TIMELINE_EXPAND_FAIL    = 'TIMELINE_EXPAND_FAIL';
 
 export const TIMELINE_SCROLL_TOP = 'TIMELINE_SCROLL_TOP';
 
+export const TIMELINE_CONNECT    = 'TIMELINE_CONNECT';
 export const TIMELINE_DISCONNECT = 'TIMELINE_DISCONNECT';
 
 export function updateTimeline(timeline, status, accept) {
@@ -95,7 +96,7 @@ export const expandPublicTimeline          = ({ maxId, onlyMedia } = {}, done =
 export const expandCommunityTimeline       = ({ maxId, onlyMedia } = {}, done = noOp) => expandTimeline(`community${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { local: true, max_id: maxId, only_media: !!onlyMedia }, done);
 export const expandAccountTimeline         = (accountId, { maxId, withReplies } = {}) => expandTimeline(`account:${accountId}${withReplies ? ':with_replies' : ''}`, `/api/v1/accounts/${accountId}/statuses`, { exclude_replies: !withReplies, max_id: maxId });
 export const expandAccountFeaturedTimeline = accountId => expandTimeline(`account:${accountId}:pinned`, `/api/v1/accounts/${accountId}/statuses`, { pinned: true });
-export const expandAccountMediaTimeline    = (accountId, { maxId } = {}) => expandTimeline(`account:${accountId}:media`, `/api/v1/accounts/${accountId}/statuses`, { max_id: maxId, only_media: true });
+export const expandAccountMediaTimeline    = (accountId, { maxId } = {}) => expandTimeline(`account:${accountId}:media`, `/api/v1/accounts/${accountId}/statuses`, { max_id: maxId, only_media: true, limit: 40 });
 export const expandListTimeline            = (id, { maxId } = {}, done = noOp) => expandTimeline(`list:${id}`, `/api/v1/timelines/list/${id}`, { max_id: maxId }, done);
 export const expandHashtagTimeline         = (hashtag, { maxId, tags } = {}, done = noOp) => {
   return expandTimeline(`hashtag:${hashtag}`, `/api/v1/timelines/tag/${hashtag}`, {
@@ -143,6 +144,13 @@ export function scrollTopTimeline(timeline, top) {
   };
 };
 
+export function connectTimeline(timeline) {
+  return {
+    type: TIMELINE_CONNECT,
+    timeline,
+  };
+};
+
 export function disconnectTimeline(timeline) {
   return {
     type: TIMELINE_DISCONNECT,
diff --git a/app/javascript/mastodon/api.js b/app/javascript/mastodon/api.js
index 4be3eadb022e5b0d512135b662566bc1e043cc3d..98d59de433f4bfc78feb7d2b37c3871fb2301a25 100644
--- a/app/javascript/mastodon/api.js
+++ b/app/javascript/mastodon/api.js
@@ -13,10 +13,14 @@ export const getLinks = response => {
 };
 
 let csrfHeader = {};
+
 function setCSRFHeader() {
-  const csrfToken = document.querySelector('meta[name=csrf-token]').content;
-  csrfHeader['X-CSRF-Token'] = csrfToken;
+  const csrfToken = document.querySelector('meta[name=csrf-token]');
+  if (csrfToken) {
+    csrfHeader['X-CSRF-Token'] = csrfToken.content;
+  }
 }
+
 ready(setCSRFHeader);
 
 export default getState => axios.create({
diff --git a/app/javascript/mastodon/components/account.js b/app/javascript/mastodon/components/account.js
index 206030c006bb34d48e2e9da2ec1dd1559c374f23..2705a6001341bff0ad06bbfd060fe0c42f5248ca 100644
--- a/app/javascript/mastodon/components/account.js
+++ b/app/javascript/mastodon/components/account.js
@@ -88,7 +88,7 @@ class Account extends ImmutablePureComponent {
       if (requested) {
         buttons = <IconButton disabled icon='hourglass' title={intl.formatMessage(messages.requested)} />;
       } else if (blocking) {
-        buttons = <IconButton active icon='unlock-alt' title={intl.formatMessage(messages.unblock, { name: account.get('username') })} onClick={this.handleBlock} />;
+        buttons = <IconButton active icon='unlock' title={intl.formatMessage(messages.unblock, { name: account.get('username') })} onClick={this.handleBlock} />;
       } else if (muting) {
         let hidingNotificationsButton;
         if (account.getIn(['relationship', 'muting_notifications'])) {
diff --git a/app/javascript/mastodon/components/attachment_list.js b/app/javascript/mastodon/components/attachment_list.js
index 8e5bb0e0be85b1aff44f172c68d7f73e4d92b549..5dfa1464c4fab474d589ccc6093ea6423874f7f2 100644
--- a/app/javascript/mastodon/components/attachment_list.js
+++ b/app/javascript/mastodon/components/attachment_list.js
@@ -2,6 +2,7 @@ import React from 'react';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import PropTypes from 'prop-types';
 import ImmutablePureComponent from 'react-immutable-pure-component';
+import Icon from 'mastodon/components/icon';
 
 const filename = url => url.split('/').pop().split('#')[0].split('?')[0];
 
@@ -24,7 +25,7 @@ export default class AttachmentList extends ImmutablePureComponent {
 
               return (
                 <li key={attachment.get('id')}>
-                  <a href={displayUrl} target='_blank' rel='noopener'><i className='fa fa-link' /> {filename(displayUrl)}</a>
+                  <a href={displayUrl} target='_blank' rel='noopener'><Icon id='link' /> {filename(displayUrl)}</a>
                 </li>
               );
             })}
@@ -36,7 +37,7 @@ export default class AttachmentList extends ImmutablePureComponent {
     return (
       <div className='attachment-list'>
         <div className='attachment-list__icon'>
-          <i className='fa fa-link' />
+          <Icon id='link' />
         </div>
 
         <ul className='attachment-list__list'>
diff --git a/app/javascript/mastodon/components/autosuggest_input.js b/app/javascript/mastodon/components/autosuggest_input.js
new file mode 100644
index 0000000000000000000000000000000000000000..c7d965b53ac5e284662512054f59ef57fbca7b8c
--- /dev/null
+++ b/app/javascript/mastodon/components/autosuggest_input.js
@@ -0,0 +1,229 @@
+import React from 'react';
+import AutosuggestAccountContainer from '../features/compose/containers/autosuggest_account_container';
+import AutosuggestEmoji from './autosuggest_emoji';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import PropTypes from 'prop-types';
+import { isRtl } from '../rtl';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+import classNames from 'classnames';
+import { List as ImmutableList } from 'immutable';
+
+const textAtCursorMatchesToken = (str, caretPosition, searchTokens) => {
+  let word;
+
+  let left  = str.slice(0, caretPosition).search(/\S+$/);
+  let right = str.slice(caretPosition).search(/\s/);
+
+  if (right < 0) {
+    word = str.slice(left);
+  } else {
+    word = str.slice(left, right + caretPosition);
+  }
+
+  if (!word || word.trim().length < 3 || searchTokens.indexOf(word[0]) === -1) {
+    return [null, null];
+  }
+
+  word = word.trim().toLowerCase();
+
+  if (word.length > 0) {
+    return [left + 1, word];
+  } else {
+    return [null, null];
+  }
+};
+
+export default class AutosuggestInput extends ImmutablePureComponent {
+
+  static propTypes = {
+    value: PropTypes.string,
+    suggestions: ImmutablePropTypes.list,
+    disabled: PropTypes.bool,
+    placeholder: PropTypes.string,
+    onSuggestionSelected: PropTypes.func.isRequired,
+    onSuggestionsClearRequested: PropTypes.func.isRequired,
+    onSuggestionsFetchRequested: PropTypes.func.isRequired,
+    onChange: PropTypes.func.isRequired,
+    onKeyUp: PropTypes.func,
+    onKeyDown: PropTypes.func,
+    autoFocus: PropTypes.bool,
+    className: PropTypes.string,
+    id: PropTypes.string,
+    searchTokens: PropTypes.arrayOf(PropTypes.string),
+    maxLength: PropTypes.number,
+  };
+
+  static defaultProps = {
+    autoFocus: true,
+    searchTokens: ImmutableList(['@', ':', '#']),
+  };
+
+  state = {
+    suggestionsHidden: true,
+    focused: false,
+    selectedSuggestion: 0,
+    lastToken: null,
+    tokenStart: 0,
+  };
+
+  onChange = (e) => {
+    const [ tokenStart, token ] = textAtCursorMatchesToken(e.target.value, e.target.selectionStart, this.props.searchTokens);
+
+    if (token !== null && this.state.lastToken !== token) {
+      this.setState({ lastToken: token, selectedSuggestion: 0, tokenStart });
+      this.props.onSuggestionsFetchRequested(token);
+    } else if (token === null) {
+      this.setState({ lastToken: null });
+      this.props.onSuggestionsClearRequested();
+    }
+
+    this.props.onChange(e);
+  }
+
+  onKeyDown = (e) => {
+    const { suggestions, disabled } = this.props;
+    const { selectedSuggestion, suggestionsHidden } = this.state;
+
+    if (disabled) {
+      e.preventDefault();
+      return;
+    }
+
+    if (e.which === 229 || e.isComposing) {
+      // Ignore key events during text composition
+      // e.key may be a name of the physical key even in this case (e.x. Safari / Chrome on Mac)
+      return;
+    }
+
+    switch(e.key) {
+    case 'Escape':
+      if (suggestions.size === 0 || suggestionsHidden) {
+        document.querySelector('.ui').parentElement.focus();
+      } else {
+        e.preventDefault();
+        this.setState({ suggestionsHidden: true });
+      }
+
+      break;
+    case 'ArrowDown':
+      if (suggestions.size > 0 && !suggestionsHidden) {
+        e.preventDefault();
+        this.setState({ selectedSuggestion: Math.min(selectedSuggestion + 1, suggestions.size - 1) });
+      }
+
+      break;
+    case 'ArrowUp':
+      if (suggestions.size > 0 && !suggestionsHidden) {
+        e.preventDefault();
+        this.setState({ selectedSuggestion: Math.max(selectedSuggestion - 1, 0) });
+      }
+
+      break;
+    case 'Enter':
+    case 'Tab':
+      // Select suggestion
+      if (this.state.lastToken !== null && suggestions.size > 0 && !suggestionsHidden) {
+        e.preventDefault();
+        e.stopPropagation();
+        this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestions.get(selectedSuggestion));
+      }
+
+      break;
+    }
+
+    if (e.defaultPrevented || !this.props.onKeyDown) {
+      return;
+    }
+
+    this.props.onKeyDown(e);
+  }
+
+  onBlur = () => {
+    this.setState({ suggestionsHidden: true, focused: false });
+  }
+
+  onFocus = () => {
+    this.setState({ focused: true });
+  }
+
+  onSuggestionClick = (e) => {
+    const suggestion = this.props.suggestions.get(e.currentTarget.getAttribute('data-index'));
+    e.preventDefault();
+    this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestion);
+    this.input.focus();
+  }
+
+  componentWillReceiveProps (nextProps) {
+    if (nextProps.suggestions !== this.props.suggestions && nextProps.suggestions.size > 0 && this.state.suggestionsHidden && this.state.focused) {
+      this.setState({ suggestionsHidden: false });
+    }
+  }
+
+  setInput = (c) => {
+    this.input = c;
+  }
+
+  renderSuggestion = (suggestion, i) => {
+    const { selectedSuggestion } = this.state;
+    let inner, key;
+
+    if (typeof suggestion === 'object') {
+      inner = <AutosuggestEmoji emoji={suggestion} />;
+      key   = suggestion.id;
+    } else if (suggestion[0] === '#') {
+      inner = suggestion;
+      key   = suggestion;
+    } else {
+      inner = <AutosuggestAccountContainer id={suggestion} />;
+      key   = suggestion;
+    }
+
+    return (
+      <div role='button' tabIndex='0' key={key} data-index={i} className={classNames('autosuggest-textarea__suggestions__item', { selected: i === selectedSuggestion })} onMouseDown={this.onSuggestionClick}>
+        {inner}
+      </div>
+    );
+  }
+
+  render () {
+    const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, className, id, maxLength } = this.props;
+    const { suggestionsHidden } = this.state;
+    const style = { direction: 'ltr' };
+
+    if (isRtl(value)) {
+      style.direction = 'rtl';
+    }
+
+    return (
+      <div className='autosuggest-input'>
+        <label>
+          <span style={{ display: 'none' }}>{placeholder}</span>
+
+          <input
+            type='text'
+            ref={this.setInput}
+            disabled={disabled}
+            placeholder={placeholder}
+            autoFocus={autoFocus}
+            value={value}
+            onChange={this.onChange}
+            onKeyDown={this.onKeyDown}
+            onKeyUp={onKeyUp}
+            onFocus={this.onFocus}
+            onBlur={this.onBlur}
+            style={style}
+            aria-autocomplete='list'
+            id={id}
+            className={className}
+            maxLength={maxLength}
+          />
+        </label>
+
+        <div className={`autosuggest-textarea__suggestions ${suggestionsHidden || suggestions.isEmpty() ? '' : 'autosuggest-textarea__suggestions--visible'}`}>
+          {suggestions.map(this.renderSuggestion)}
+        </div>
+      </div>
+    );
+  }
+
+}
diff --git a/app/javascript/mastodon/components/autosuggest_textarea.js b/app/javascript/mastodon/components/autosuggest_textarea.js
index a4f5cf50c65ae1a3b41d3d2294977e09a05abb69..b070fe3e5156d65353c46cce00cf8fb7f0509a3d 100644
--- a/app/javascript/mastodon/components/autosuggest_textarea.js
+++ b/app/javascript/mastodon/components/autosuggest_textarea.js
@@ -55,7 +55,8 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
   };
 
   state = {
-    suggestionsHidden: false,
+    suggestionsHidden: true,
+    focused: false,
     selectedSuggestion: 0,
     lastToken: null,
     tokenStart: 0,
@@ -134,7 +135,14 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
   }
 
   onBlur = () => {
-    this.setState({ suggestionsHidden: true });
+    this.setState({ suggestionsHidden: true, focused: false });
+  }
+
+  onFocus = (e) => {
+    this.setState({ focused: true });
+    if (this.props.onFocus) {
+      this.props.onFocus(e);
+    }
   }
 
   onSuggestionClick = (e) => {
@@ -145,7 +153,7 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
   }
 
   componentWillReceiveProps (nextProps) {
-    if (nextProps.suggestions !== this.props.suggestions && nextProps.suggestions.size > 0 && this.state.suggestionsHidden) {
+    if (nextProps.suggestions !== this.props.suggestions && nextProps.suggestions.size > 0 && this.state.suggestionsHidden && this.state.focused) {
       this.setState({ suggestionsHidden: false });
     }
   }
@@ -184,7 +192,7 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
   }
 
   render () {
-    const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus } = this.props;
+    const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, children } = this.props;
     const { suggestionsHidden } = this.state;
     const style = { direction: 'ltr' };
 
@@ -192,33 +200,39 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
       style.direction = 'rtl';
     }
 
-    return (
-      <div className='autosuggest-textarea'>
-        <label>
-          <span style={{ display: 'none' }}>{placeholder}</span>
-
-          <Textarea
-            inputRef={this.setTextarea}
-            className='autosuggest-textarea__textarea'
-            disabled={disabled}
-            placeholder={placeholder}
-            autoFocus={autoFocus}
-            value={value}
-            onChange={this.onChange}
-            onKeyDown={this.onKeyDown}
-            onKeyUp={onKeyUp}
-            onBlur={this.onBlur}
-            onPaste={this.onPaste}
-            style={style}
-            aria-autocomplete='list'
-          />
-        </label>
+    return [
+      <div className='compose-form__autosuggest-wrapper' key='autosuggest-wrapper'>
+        <div className='autosuggest-textarea'>
+          <label>
+            <span style={{ display: 'none' }}>{placeholder}</span>
+
+            <Textarea
+              inputRef={this.setTextarea}
+              className='autosuggest-textarea__textarea'
+              disabled={disabled}
+              placeholder={placeholder}
+              autoFocus={autoFocus}
+              value={value}
+              onChange={this.onChange}
+              onKeyDown={this.onKeyDown}
+              onKeyUp={onKeyUp}
+              onFocus={this.onFocus}
+              onBlur={this.onBlur}
+              onPaste={this.onPaste}
+              style={style}
+              aria-autocomplete='list'
+            />
+          </label>
+        </div>
+        {children}
+      </div>,
 
+      <div className='autosuggest-textarea__suggestions-wrapper' key='suggestions-wrapper'>
         <div className={`autosuggest-textarea__suggestions ${suggestionsHidden || suggestions.isEmpty() ? '' : 'autosuggest-textarea__suggestions--visible'}`}>
           {suggestions.map(this.renderSuggestion)}
         </div>
-      </div>
-    );
+      </div>,
+    ];
   }
 
 }
diff --git a/app/javascript/mastodon/components/button.js b/app/javascript/mastodon/components/button.js
index 51e2e6a7a80c83e5cfd0da880af2b863672890f0..eb8dd7dc8eb9c9501c0ce0be83e33f41d5c35c81 100644
--- a/app/javascript/mastodon/components/button.js
+++ b/app/javascript/mastodon/components/button.js
@@ -12,6 +12,7 @@ export default class Button extends React.PureComponent {
     secondary: PropTypes.bool,
     size: PropTypes.number,
     className: PropTypes.string,
+    title: PropTypes.string,
     style: PropTypes.object,
     children: PropTypes.node,
   };
@@ -54,6 +55,7 @@ export default class Button extends React.PureComponent {
         onClick={this.handleClick}
         ref={this.setRef}
         style={style}
+        title={this.props.title}
       >
         {this.props.text || this.props.children}
       </button>
diff --git a/app/javascript/mastodon/components/column_back_button.js b/app/javascript/mastodon/components/column_back_button.js
index 8a60c4192a968a4b86c623fce0314f49d4fd4e45..f41045787e47edbc70db7f9d4cafefb1b933b831 100644
--- a/app/javascript/mastodon/components/column_back_button.js
+++ b/app/javascript/mastodon/components/column_back_button.js
@@ -1,6 +1,7 @@
 import React from 'react';
 import { FormattedMessage } from 'react-intl';
 import PropTypes from 'prop-types';
+import Icon from 'mastodon/components/icon';
 
 export default class ColumnBackButton extends React.PureComponent {
 
@@ -19,7 +20,7 @@ export default class ColumnBackButton extends React.PureComponent {
   render () {
     return (
       <button onClick={this.handleClick} className='column-back-button'>
-        <i className='fa fa-fw fa-chevron-left column-back-button__icon' />
+        <Icon id='chevron-left' className='column-back-button__icon' fixedWidth />
         <FormattedMessage id='column_back_button.label' defaultMessage='Back' />
       </button>
     );
diff --git a/app/javascript/mastodon/components/column_back_button_slim.js b/app/javascript/mastodon/components/column_back_button_slim.js
index 964c100befe44676348cb8e28e8882fbcc7c0a0a..cc8bfb1515ba53b11bc4811d98663db737fede77 100644
--- a/app/javascript/mastodon/components/column_back_button_slim.js
+++ b/app/javascript/mastodon/components/column_back_button_slim.js
@@ -1,6 +1,7 @@
 import React from 'react';
 import { FormattedMessage } from 'react-intl';
 import ColumnBackButton from './column_back_button';
+import Icon from 'mastodon/components/icon';
 
 export default class ColumnBackButtonSlim extends ColumnBackButton {
 
@@ -8,7 +9,7 @@ export default class ColumnBackButtonSlim extends ColumnBackButton {
     return (
       <div className='column-back-button--slim'>
         <div role='button' tabIndex='0' onClick={this.handleClick} className='column-back-button column-back-button--slim-button'>
-          <i className='fa fa-fw fa-chevron-left column-back-button__icon' />
+          <Icon id='chevron-left' className='column-back-button__icon' fixedWidth />
           <FormattedMessage id='column_back_button.label' defaultMessage='Back' />
         </div>
       </div>
diff --git a/app/javascript/mastodon/components/column_header.js b/app/javascript/mastodon/components/column_header.js
index f68e4155ebbc83df779f2e764d96d52d5059a1a5..f33c689e7c6d1612767755a43201e62ed90906bc 100644
--- a/app/javascript/mastodon/components/column_header.js
+++ b/app/javascript/mastodon/components/column_header.js
@@ -2,6 +2,7 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import classNames from 'classnames';
 import { FormattedMessage, injectIntl, defineMessages } from 'react-intl';
+import Icon from 'mastodon/components/icon';
 
 const messages = defineMessages({
   show: { id: 'column_header.show_settings', defaultMessage: 'Show settings' },
@@ -109,22 +110,22 @@ class ColumnHeader extends React.PureComponent {
     }
 
     if (multiColumn && pinned) {
-      pinButton = <button key='pin-button' className='text-btn column-header__setting-btn' onClick={this.handlePin}><i className='fa fa fa-times' /> <FormattedMessage id='column_header.unpin' defaultMessage='Unpin' /></button>;
+      pinButton = <button key='pin-button' className='text-btn column-header__setting-btn' onClick={this.handlePin}><Icon id='times' /> <FormattedMessage id='column_header.unpin' defaultMessage='Unpin' /></button>;
 
       moveButtons = (
         <div key='move-buttons' className='column-header__setting-arrows'>
-          <button title={formatMessage(messages.moveLeft)} aria-label={formatMessage(messages.moveLeft)} className='text-btn column-header__setting-btn' onClick={this.handleMoveLeft}><i className='fa fa-chevron-left' /></button>
-          <button title={formatMessage(messages.moveRight)} aria-label={formatMessage(messages.moveRight)} className='text-btn column-header__setting-btn' onClick={this.handleMoveRight}><i className='fa fa-chevron-right' /></button>
+          <button title={formatMessage(messages.moveLeft)} aria-label={formatMessage(messages.moveLeft)} className='text-btn column-header__setting-btn' onClick={this.handleMoveLeft}><Icon id='chevron-left' /></button>
+          <button title={formatMessage(messages.moveRight)} aria-label={formatMessage(messages.moveRight)} className='text-btn column-header__setting-btn' onClick={this.handleMoveRight}><Icon id='chevron-right' /></button>
         </div>
       );
     } else if (multiColumn) {
-      pinButton = <button key='pin-button' className='text-btn column-header__setting-btn' onClick={this.handlePin}><i className='fa fa fa-plus' /> <FormattedMessage id='column_header.pin' defaultMessage='Pin' /></button>;
+      pinButton = <button key='pin-button' className='text-btn column-header__setting-btn' onClick={this.handlePin}><Icon id='plus' /> <FormattedMessage id='column_header.pin' defaultMessage='Pin' /></button>;
     }
 
     if (!pinned && (multiColumn || showBackButton)) {
       backButton = (
         <button onClick={this.handleBackClick} className='column-header__back-button'>
-          <i className='fa fa-fw fa-chevron-left column-back-button__icon' />
+          <Icon id='chevron-left' className='column-back-button__icon' fixedWidth />
           <FormattedMessage id='column_back_button.label' defaultMessage='Back' />
         </button>
       );
@@ -140,7 +141,7 @@ class ColumnHeader extends React.PureComponent {
     }
 
     if (children || multiColumn) {
-      collapseButton = <button className={collapsibleButtonClassName} title={formatMessage(collapsed ? messages.show : messages.hide)} aria-label={formatMessage(collapsed ? messages.show : messages.hide)} aria-pressed={collapsed ? 'false' : 'true'} onClick={this.handleToggleClick}><i className='fa fa-sliders' /></button>;
+      collapseButton = <button className={collapsibleButtonClassName} title={formatMessage(collapsed ? messages.show : messages.hide)} aria-label={formatMessage(collapsed ? messages.show : messages.hide)} aria-pressed={collapsed ? 'false' : 'true'} onClick={this.handleToggleClick}><Icon id='sliders' /></button>;
     }
 
     const hasTitle = icon && title;
@@ -150,7 +151,7 @@ class ColumnHeader extends React.PureComponent {
         <h1 className={buttonClassName}>
           {hasTitle && (
             <button onClick={this.handleTitleClick}>
-              <i className={`fa fa-fw fa-${icon} column-header__icon`} />
+              <Icon id={icon} fixedWidth className='column-header__icon' />
               {title}
             </button>
           )}
diff --git a/app/javascript/mastodon/components/display_name.js b/app/javascript/mastodon/components/display_name.js
index acddf77c54361806b5c695c1c2540940daf245a3..70ef82789e54c897123fc86bf9cc5da782d1adf4 100644
--- a/app/javascript/mastodon/components/display_name.js
+++ b/app/javascript/mastodon/components/display_name.js
@@ -1,6 +1,7 @@
 import React from 'react';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import PropTypes from 'prop-types';
+import { autoPlayGif } from 'mastodon/initial_state';
 
 export default class DisplayName extends React.PureComponent {
 
@@ -10,27 +11,78 @@ export default class DisplayName extends React.PureComponent {
     localDomain: PropTypes.string,
   };
 
+  _updateEmojis () {
+    const node = this.node;
+
+    if (!node || autoPlayGif) {
+      return;
+    }
+
+    const emojis = node.querySelectorAll('.custom-emoji');
+
+    for (var i = 0; i < emojis.length; i++) {
+      let emoji = emojis[i];
+      if (emoji.classList.contains('status-emoji')) {
+        continue;
+      }
+      emoji.classList.add('status-emoji');
+
+      emoji.addEventListener('mouseenter', this.handleEmojiMouseEnter, false);
+      emoji.addEventListener('mouseleave', this.handleEmojiMouseLeave, false);
+    }
+  }
+
+  componentDidMount () {
+    this._updateEmojis();
+  }
+
+  componentDidUpdate () {
+    this._updateEmojis();
+  }
+
+  handleEmojiMouseEnter = ({ target }) => {
+    target.src = target.getAttribute('data-original');
+  }
+
+  handleEmojiMouseLeave = ({ target }) => {
+    target.src = target.getAttribute('data-static');
+  }
+
+  setRef = (c) => {
+    this.node = c;
+  }
+
   render () {
-    const { account, others, localDomain } = this.props;
-    const displayNameHtml = { __html: account.get('display_name_html') };
+    const { others, localDomain } = this.props;
 
-    let suffix;
+    let displayName, suffix, account;
 
     if (others && others.size > 1) {
-      suffix = `+${others.size}`;
+      displayName = others.take(2).map(a => <bdi key={a.get('id')}><strong className='display-name__html' dangerouslySetInnerHTML={{ __html: a.get('display_name_html') }} /></bdi>).reduce((prev, cur) => [prev, ', ', cur]);
+
+      if (others.size - 2 > 0) {
+        suffix = `+${others.size - 2}`;
+      }
     } else {
+      if (others && others.size > 0) {
+        account = others.first();
+      } else {
+        account = this.props.account;
+      }
+
       let acct = account.get('acct');
 
       if (acct.indexOf('@') === -1 && localDomain) {
         acct = `${acct}@${localDomain}`;
       }
 
-      suffix = <span className='display-name__account'>@{acct}</span>;
+      displayName = <bdi><strong className='display-name__html' dangerouslySetInnerHTML={{ __html: account.get('display_name_html') }} /></bdi>;
+      suffix      = <span className='display-name__account'>@{acct}</span>;
     }
 
     return (
-      <span className='display-name'>
-        <bdi><strong className='display-name__html' dangerouslySetInnerHTML={displayNameHtml} /></bdi> {suffix}
+      <span className='display-name' ref={this.setRef}>
+        {displayName} {suffix}
       </span>
     );
   }
diff --git a/app/javascript/mastodon/components/domain.js b/app/javascript/mastodon/components/domain.js
index 24f80e7888a61ca38b9f3723bd530a85b4061312..85729ca9438ea26b5cd1dee40f9ef8b6a762044c 100644
--- a/app/javascript/mastodon/components/domain.js
+++ b/app/javascript/mastodon/components/domain.js
@@ -32,7 +32,7 @@ class Account extends ImmutablePureComponent {
           </span>
 
           <div className='domain__buttons'>
-            <IconButton active icon='unlock-alt' title={intl.formatMessage(messages.unblockDomain, { domain })} onClick={this.handleDomainUnblock} />
+            <IconButton active icon='unlock' title={intl.formatMessage(messages.unblockDomain, { domain })} onClick={this.handleDomainUnblock} />
           </div>
         </div>
       </div>
diff --git a/app/javascript/mastodon/components/dropdown_menu.js b/app/javascript/mastodon/components/dropdown_menu.js
index 91b65a02fb60da2e1c9f896bc01bd030504f2197..d423378c119f8ff1cd9c20accda0c8b15b22deb7 100644
--- a/app/javascript/mastodon/components/dropdown_menu.js
+++ b/app/javascript/mastodon/components/dropdown_menu.js
@@ -45,7 +45,9 @@ class DropdownMenu extends React.PureComponent {
     document.addEventListener('click', this.handleDocumentClick, false);
     document.addEventListener('keydown', this.handleKeyDown, false);
     document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
-    if (this.focusedItem && this.props.openedViaKeyboard) this.focusedItem.focus();
+    if (this.focusedItem && this.props.openedViaKeyboard) {
+      this.focusedItem.focus();
+    }
     this.setState({ mounted: true });
   }
 
@@ -81,6 +83,18 @@ class DropdownMenu extends React.PureComponent {
         element.focus();
       }
       break;
+    case 'Tab':
+      if (e.shiftKey) {
+        element = items[index-1] || items[items.length-1];
+      } else {
+        element = items[index+1] || items[0];
+      }
+      if (element) {
+        element.focus();
+        e.preventDefault();
+        e.stopPropagation();
+      }
+      break;
     case 'Home':
       element = items[0];
       if (element) {
@@ -93,11 +107,14 @@ class DropdownMenu extends React.PureComponent {
         element.focus();
       }
       break;
+    case 'Escape':
+      this.props.onClose();
+      break;
     }
   }
 
-  handleItemKeyDown = e => {
-    if (e.key === 'Enter') {
+  handleItemKeyPress = e => {
+    if (e.key === 'Enter' || e.key === ' ') {
       this.handleClick(e);
     }
   }
@@ -122,11 +139,11 @@ class DropdownMenu extends React.PureComponent {
       return <li key={`sep-${i}`} className='dropdown-menu__separator' />;
     }
 
-    const { text, href = '#' } = option;
+    const { text, href = '#', target = '_blank', method } = option;
 
     return (
       <li className='dropdown-menu__item' key={`${text}-${i}`}>
-        <a href={href} target='_blank' rel='noopener' role='button' tabIndex='0' ref={i === 0 ? this.setFocusRef : null} onClick={this.handleClick} onKeyDown={this.handleItemKeyDown} data-index={i}>
+        <a href={href} target={target} data-method={method} rel='noopener' role='button' tabIndex='0' ref={i === 0 ? this.setFocusRef : null} onClick={this.handleClick} onKeyPress={this.handleItemKeyPress} data-index={i}>
           {text}
         </a>
       </li>
@@ -193,25 +210,41 @@ export default class Dropdown extends React.PureComponent {
     } else {
       const { top } = target.getBoundingClientRect();
       const placement = top * 2 < innerHeight ? 'bottom' : 'top';
-
       this.props.onOpen(this.state.id, this.handleItemClick, placement, type !== 'click');
     }
   }
 
   handleClose = () => {
+    if (this.activeElement) {
+      this.activeElement.focus();
+      this.activeElement = null;
+    }
     this.props.onClose(this.state.id);
   }
 
-  handleKeyDown = e => {
+  handleMouseDown = () => {
+    if (!this.state.open) {
+      this.activeElement = document.activeElement;
+    }
+  }
+
+  handleButtonKeyDown = (e) => {
+    switch(e.key) {
+    case ' ':
+    case 'Enter':
+      this.handleMouseDown();
+      break;
+    }
+  }
+
+  handleKeyPress = (e) => {
     switch(e.key) {
     case ' ':
     case 'Enter':
       this.handleClick(e);
+      e.stopPropagation();
       e.preventDefault();
       break;
-    case 'Escape':
-      this.handleClose();
-      break;
     }
   }
 
@@ -249,7 +282,7 @@ export default class Dropdown extends React.PureComponent {
     const open = this.state.id === openDropdownId;
 
     return (
-      <div onKeyDown={this.handleKeyDown}>
+      <div>
         <IconButton
           icon={icon}
           title={title}
@@ -258,6 +291,9 @@ export default class Dropdown extends React.PureComponent {
           size={size}
           ref={this.setTargetRef}
           onClick={this.handleClick}
+          onMouseDown={this.handleMouseDown}
+          onKeyDown={this.handleButtonKeyDown}
+          onKeyPress={this.handleKeyPress}
         />
 
         <Overlay show={open} placement={dropdownPlacement} target={this.findTarget}>
diff --git a/app/javascript/mastodon/components/error_boundary.js b/app/javascript/mastodon/components/error_boundary.js
new file mode 100644
index 0000000000000000000000000000000000000000..d1ca5bf756a3513be65736fadaae74e8671b557e
--- /dev/null
+++ b/app/javascript/mastodon/components/error_boundary.js
@@ -0,0 +1,39 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import illustration from '../../images/elephant_ui_disappointed.svg';
+
+export default class ErrorBoundary extends React.PureComponent {
+
+  static propTypes = {
+    children: PropTypes.node,
+  };
+
+  state = {
+    hasError: false,
+    stackTrace: undefined,
+    componentStack: undefined,
+  }
+
+  componentDidCatch(error, info) {
+    this.setState({
+      hasError: true,
+      stackTrace: error.stack,
+      componentStack: info && info.componentStack,
+    });
+  }
+
+  render() {
+    const { hasError } = this.state;
+
+    if (!hasError) {
+      return this.props.children;
+    }
+
+    return (
+      <div>
+        <img src={illustration} alt='' />
+      </div>
+    );
+  }
+
+}
diff --git a/app/javascript/mastodon/components/icon.js b/app/javascript/mastodon/components/icon.js
new file mode 100644
index 0000000000000000000000000000000000000000..d8a17722fed2a7bbcaf4060d8587f71ebdd29524
--- /dev/null
+++ b/app/javascript/mastodon/components/icon.js
@@ -0,0 +1,21 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import classNames from 'classnames';
+
+export default class Icon extends React.PureComponent {
+
+  static propTypes = {
+    id: PropTypes.string.isRequired,
+    className: PropTypes.string,
+    fixedWidth: PropTypes.bool,
+  };
+
+  render () {
+    const { id, className, fixedWidth, ...other } = this.props;
+
+    return (
+      <i role='img' className={classNames('fa', `fa-${id}`, className, { 'fa-fw': fixedWidth })} {...other} />
+    );
+  }
+
+}
diff --git a/app/javascript/mastodon/components/icon_button.js b/app/javascript/mastodon/components/icon_button.js
index b96e48fd099373bf15fc019b43f8681859412e3c..40167505239b41a6c179d930a9a614ece8ad2c54 100644
--- a/app/javascript/mastodon/components/icon_button.js
+++ b/app/javascript/mastodon/components/icon_button.js
@@ -3,6 +3,7 @@ import Motion from '../features/ui/util/optional_motion';
 import spring from 'react-motion/lib/spring';
 import PropTypes from 'prop-types';
 import classNames from 'classnames';
+import Icon from 'mastodon/components/icon';
 
 export default class IconButton extends React.PureComponent {
 
@@ -11,6 +12,9 @@ export default class IconButton extends React.PureComponent {
     title: PropTypes.string.isRequired,
     icon: PropTypes.string.isRequired,
     onClick: PropTypes.func,
+    onMouseDown: PropTypes.func,
+    onKeyDown: PropTypes.func,
+    onKeyPress: PropTypes.func,
     size: PropTypes.number,
     active: PropTypes.bool,
     pressed: PropTypes.bool,
@@ -41,6 +45,24 @@ export default class IconButton extends React.PureComponent {
     }
   }
 
+  handleKeyPress = (e) => {
+    if (this.props.onKeyPress && !this.props.disabled) {
+      this.props.onKeyPress(e);
+    }
+  }
+
+  handleMouseDown = (e) => {
+    if (!this.props.disabled && this.props.onMouseDown) {
+      this.props.onMouseDown(e);
+    }
+  }
+
+  handleKeyDown = (e) => {
+    if (!this.props.disabled && this.props.onKeyDown) {
+      this.props.onKeyDown(e);
+    }
+  }
+
   render () {
     const style = {
       fontSize: `${this.props.size}px`,
@@ -83,10 +105,14 @@ export default class IconButton extends React.PureComponent {
           title={title}
           className={classes}
           onClick={this.handleClick}
+          onMouseDown={this.handleMouseDown}
+          onKeyDown={this.handleKeyDown}
+          onKeyPress={this.handleKeyPress}
           style={style}
           tabIndex={tabIndex}
+          disabled={disabled}
         >
-          <i className={`fa fa-fw fa-${icon}`} aria-hidden='true' />
+          <Icon id={icon} fixedWidth aria-hidden='true' />
         </button>
       );
     }
@@ -101,10 +127,14 @@ export default class IconButton extends React.PureComponent {
             title={title}
             className={classes}
             onClick={this.handleClick}
+            onMouseDown={this.handleMouseDown}
+            onKeyDown={this.handleKeyDown}
+            onKeyPress={this.handleKeyPress}
             style={style}
             tabIndex={tabIndex}
+            disabled={disabled}
           >
-            <i style={{ transform: `rotate(${rotate}deg)` }} className={`fa fa-fw fa-${icon}`} aria-hidden='true' />
+            <Icon id={icon} style={{ transform: `rotate(${rotate}deg)` }} fixedWidth aria-hidden='true' />
           </button>
         )}
       </Motion>
diff --git a/app/javascript/mastodon/components/icon_with_badge.js b/app/javascript/mastodon/components/icon_with_badge.js
new file mode 100644
index 0000000000000000000000000000000000000000..7851eb4be99704f66379ef6084668e17ee5b0d8c
--- /dev/null
+++ b/app/javascript/mastodon/components/icon_with_badge.js
@@ -0,0 +1,20 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import Icon from 'mastodon/components/icon';
+
+const formatNumber = num => num > 40 ? '40+' : num;
+
+const IconWithBadge = ({ id, count, className }) => (
+  <i className='icon-with-badge'>
+    <Icon id={id} fixedWidth className={className} />
+    {count > 0 && <i className='icon-with-badge__badge'>{formatNumber(count)}</i>}
+  </i>
+);
+
+IconWithBadge.propTypes = {
+  id: PropTypes.string.isRequired,
+  count: PropTypes.number.isRequired,
+  className: PropTypes.string,
+};
+
+export default IconWithBadge;
diff --git a/app/javascript/mastodon/components/intersection_observer_article.js b/app/javascript/mastodon/components/intersection_observer_article.js
index de2203a4bc4c6975bf5f29d4ad5a8ecb118c3e4a..e453730ba4fccd4ac4034e6c4addc9171736d929 100644
--- a/app/javascript/mastodon/components/intersection_observer_article.js
+++ b/app/javascript/mastodon/components/intersection_observer_article.js
@@ -65,7 +65,7 @@ export default class IntersectionObserverArticle extends React.Component {
   }
 
   updateStateAfterIntersection = (prevState) => {
-    if (prevState.isIntersecting && !this.entry.isIntersecting) {
+    if (prevState.isIntersecting !== false && !this.entry.isIntersecting) {
       scheduleIdleTask(this.hideIfNotIntersecting);
     }
     return {
diff --git a/app/javascript/mastodon/components/load_gap.js b/app/javascript/mastodon/components/load_gap.js
index ed4d445d0d3edc398d4563fa879818ddad35231b..a44d55d09354131b37d557310fb03dbb8f300027 100644
--- a/app/javascript/mastodon/components/load_gap.js
+++ b/app/javascript/mastodon/components/load_gap.js
@@ -1,6 +1,7 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import { injectIntl, defineMessages } from 'react-intl';
+import Icon from 'mastodon/components/icon';
 
 const messages = defineMessages({
   load_more: { id: 'status.load_more', defaultMessage: 'Load more' },
@@ -25,7 +26,7 @@ class LoadGap extends React.PureComponent {
 
     return (
       <button className='load-more load-gap' disabled={disabled} onClick={this.handleClick} aria-label={intl.formatMessage(messages.load_more)}>
-        <i className='fa fa-ellipsis-h' />
+        <Icon id='ellipsis-h' />
       </button>
     );
   }
diff --git a/app/javascript/mastodon/components/media_gallery.js b/app/javascript/mastodon/components/media_gallery.js
index c507920d0ee34aeeebdb0079c76990279dae234c..77bac61eec9e2a20b3ff71a710af2618c8b26626 100644
--- a/app/javascript/mastodon/components/media_gallery.js
+++ b/app/javascript/mastodon/components/media_gallery.js
@@ -7,6 +7,7 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import { isIOS } from '../is_mobile';
 import classNames from 'classnames';
 import { autoPlayGif, displayMedia } from '../initial_state';
+import { decode } from 'blurhash';
 
 const messages = defineMessages({
   toggle_visible: { id: 'media_gallery.toggle_visible', defaultMessage: 'Toggle visibility' },
@@ -21,6 +22,7 @@ class Item extends React.PureComponent {
     size: PropTypes.number.isRequired,
     onClick: PropTypes.func.isRequired,
     displayWidth: PropTypes.number,
+    visible: PropTypes.bool.isRequired,
   };
 
   static defaultProps = {
@@ -29,6 +31,10 @@ class Item extends React.PureComponent {
     size: 1,
   };
 
+  state = {
+    loaded: false,
+  };
+
   handleMouseEnter = (e) => {
     if (this.hoverToPlay()) {
       e.target.play();
@@ -62,8 +68,40 @@ class Item extends React.PureComponent {
     e.stopPropagation();
   }
 
+  componentDidMount () {
+    if (this.props.attachment.get('blurhash')) {
+      this._decode();
+    }
+  }
+
+  componentDidUpdate (prevProps) {
+    if (prevProps.attachment.get('blurhash') !== this.props.attachment.get('blurhash') && this.props.attachment.get('blurhash')) {
+      this._decode();
+    }
+  }
+
+  _decode () {
+    const hash   = this.props.attachment.get('blurhash');
+    const pixels = decode(hash, 32, 32);
+
+    if (pixels) {
+      const ctx       = this.canvas.getContext('2d');
+      const imageData = new ImageData(pixels, 32, 32);
+
+      ctx.putImageData(imageData, 0, 0);
+    }
+  }
+
+  setCanvasRef = c => {
+    this.canvas = c;
+  }
+
+  handleImageLoad = () => {
+    this.setState({ loaded: true });
+  }
+
   render () {
-    const { attachment, index, size, standalone, displayWidth } = this.props;
+    const { attachment, index, size, standalone, displayWidth, visible } = this.props;
 
     let width  = 50;
     let height = 100;
@@ -116,12 +154,20 @@ class Item extends React.PureComponent {
 
     let thumbnail = '';
 
-    if (attachment.get('type') === 'image') {
+    if (attachment.get('type') === 'unknown') {
+      return (
+        <div className={classNames('media-gallery__item', { standalone })} key={attachment.get('id')} style={{ left: left, top: top, right: right, bottom: bottom, width: `${width}%`, height: `${height}%` }}>
+          <a className='media-gallery__item-thumbnail' href={attachment.get('remote_url')} target='_blank' style={{ cursor: 'pointer' }} title={attachment.get('description')}>
+            <canvas width={32} height={32} ref={this.setCanvasRef} className='media-gallery__preview' />
+          </a>
+        </div>
+      );
+    } else if (attachment.get('type') === 'image') {
       const previewUrl   = attachment.get('preview_url');
       const previewWidth = attachment.getIn(['meta', 'small', 'width']);
 
-      const originalUrl    = attachment.get('url');
-      const originalWidth  = attachment.getIn(['meta', 'original', 'width']);
+      const originalUrl   = attachment.get('url');
+      const originalWidth = attachment.getIn(['meta', 'original', 'width']);
 
       const hasSize = typeof originalWidth === 'number' && typeof previewWidth === 'number';
 
@@ -147,6 +193,7 @@ class Item extends React.PureComponent {
             alt={attachment.get('description')}
             title={attachment.get('description')}
             style={{ objectPosition: `${x}% ${y}%` }}
+            onLoad={this.handleImageLoad}
           />
         </a>
       );
@@ -176,7 +223,8 @@ class Item extends React.PureComponent {
 
     return (
       <div className={classNames('media-gallery__item', { standalone })} key={attachment.get('id')} style={{ left: left, top: top, right: right, bottom: bottom, width: `${width}%`, height: `${height}%` }}>
-        {thumbnail}
+        <canvas width={32} height={32} ref={this.setCanvasRef} className={classNames('media-gallery__preview', { 'media-gallery__preview--hidden': visible && this.state.loaded })} />
+        {visible && thumbnail}
       </div>
     );
   }
@@ -194,6 +242,10 @@ class MediaGallery extends React.PureComponent {
     height: PropTypes.number.isRequired,
     onOpenMedia: PropTypes.func.isRequired,
     intl: PropTypes.object.isRequired,
+    defaultWidth: PropTypes.number,
+    cacheWidth: PropTypes.func,
+    visible: PropTypes.bool,
+    onToggleVisibility: PropTypes.func,
   };
 
   static defaultProps = {
@@ -201,17 +253,24 @@ class MediaGallery extends React.PureComponent {
   };
 
   state = {
-    visible: displayMedia !== 'hide_all' && !this.props.sensitive || displayMedia === 'show_all',
+    visible: this.props.visible !== undefined ? this.props.visible : (displayMedia !== 'hide_all' && !this.props.sensitive || displayMedia === 'show_all'),
+    width: this.props.defaultWidth,
   };
 
   componentWillReceiveProps (nextProps) {
-    if (!is(nextProps.media, this.props.media)) {
-      this.setState({ visible: !nextProps.sensitive });
+    if (!is(nextProps.media, this.props.media) && nextProps.visible === undefined) {
+      this.setState({ visible: displayMedia !== 'hide_all' && !nextProps.sensitive || displayMedia === 'show_all' });
+    } else if (!is(nextProps.visible, this.props.visible) && nextProps.visible !== undefined) {
+      this.setState({ visible: nextProps.visible });
     }
   }
 
   handleOpen = () => {
-    this.setState({ visible: !this.state.visible });
+    if (this.props.onToggleVisibility) {
+      this.props.onToggleVisibility();
+    } else {
+      this.setState({ visible: !this.state.visible });
+    }
   }
 
   handleClick = (index) => {
@@ -221,6 +280,8 @@ class MediaGallery extends React.PureComponent {
   handleRef = (node) => {
     if (node /*&& this.isStandaloneEligible()*/) {
       // offsetWidth triggers a layout, so only calculate when we need to
+      if (this.props.cacheWidth) this.props.cacheWidth(node.offsetWidth);
+
       this.setState({
         width: node.offsetWidth,
       });
@@ -233,10 +294,12 @@ class MediaGallery extends React.PureComponent {
   }
 
   render () {
-    const { media, intl, sensitive, height } = this.props;
-    const { width, visible } = this.state;
+    const { media, intl, sensitive, height, defaultWidth } = this.props;
+    const { visible } = this.state;
+
+    const width = this.state.width || defaultWidth;
 
-    let children;
+    let children, spoilerButton;
 
     const style = {};
 
@@ -250,35 +313,28 @@ class MediaGallery extends React.PureComponent {
       style.height = height;
     }
 
-    if (!visible) {
-      let warning;
+    const size = media.take(4).size;
 
-      if (sensitive) {
-        warning = <FormattedMessage id='status.sensitive_warning' defaultMessage='Sensitive content' />;
-      } else {
-        warning = <FormattedMessage id='status.media_hidden' defaultMessage='Media hidden' />;
-      }
+    if (this.isStandaloneEligible()) {
+      children = <Item standalone onClick={this.handleClick} attachment={media.get(0)} displayWidth={width} visible={visible} />;
+    } else {
+      children = media.take(4).map((attachment, i) => <Item key={attachment.get('id')} onClick={this.handleClick} attachment={attachment} index={i} size={size} displayWidth={width} visible={visible} />);
+    }
 
-      children = (
-        <button type='button' className='media-spoiler' onClick={this.handleOpen} style={style} ref={this.handleRef}>
-          <span className='media-spoiler__warning'>{warning}</span>
-          <span className='media-spoiler__trigger'><FormattedMessage id='status.sensitive_toggle' defaultMessage='Click to view' /></span>
+    if (visible) {
+      spoilerButton = <IconButton title={intl.formatMessage(messages.toggle_visible)} icon='eye-slash' overlay onClick={this.handleOpen} />;
+    } else {
+      spoilerButton = (
+        <button type='button' onClick={this.handleOpen} className='spoiler-button__overlay'>
+          <span className='spoiler-button__overlay__label'>{sensitive ? <FormattedMessage id='status.sensitive_warning' defaultMessage='Sensitive content' /> : <FormattedMessage id='status.media_hidden' defaultMessage='Media hidden' />}</span>
         </button>
       );
-    } else {
-      const size = media.take(4).size;
-
-      if (this.isStandaloneEligible()) {
-        children = <Item standalone onClick={this.handleClick} attachment={media.get(0)} displayWidth={width} />;
-      } else {
-        children = media.take(4).map((attachment, i) => <Item key={attachment.get('id')} onClick={this.handleClick} attachment={attachment} index={i} size={size} displayWidth={width} />);
-      }
     }
 
     return (
       <div className='media-gallery' style={style} ref={this.handleRef}>
-        <div className={classNames('spoiler-button', { 'spoiler-button--visible': visible })}>
-          <IconButton title={intl.formatMessage(messages.toggle_visible)} icon={visible ? 'eye' : 'eye-slash'} overlay onClick={this.handleOpen} />
+        <div className={classNames('spoiler-button', { 'spoiler-button--minified': visible })}>
+          {spoilerButton}
         </div>
 
         {children}
diff --git a/app/javascript/mastodon/components/modal_root.js b/app/javascript/mastodon/components/modal_root.js
index ef1156571f149fe38235fe9711b1cf7776b413a4..5d4f4bbe138ecc907e98716e9f7fb181155e69ee 100644
--- a/app/javascript/mastodon/components/modal_root.js
+++ b/app/javascript/mastodon/components/modal_root.js
@@ -21,8 +21,30 @@ export default class ModalRoot extends React.PureComponent {
     }
   }
 
+  handleKeyDown = (e) => {
+    if (e.key === 'Tab') {
+      const focusable = Array.from(this.node.querySelectorAll('button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])')).filter((x) => window.getComputedStyle(x).display !== 'none');
+      const index = focusable.indexOf(e.target);
+
+      let element;
+
+      if (e.shiftKey) {
+        element = focusable[index - 1] || focusable[focusable.length - 1];
+      } else {
+        element = focusable[index + 1] || focusable[0];
+      }
+
+      if (element) {
+        element.focus();
+        e.stopPropagation();
+        e.preventDefault();
+      }
+    }
+  }
+
   componentDidMount () {
     window.addEventListener('keyup', this.handleKeyUp, false);
+    window.addEventListener('keydown', this.handleKeyDown, false);
   }
 
   componentWillReceiveProps (nextProps) {
@@ -52,6 +74,7 @@ export default class ModalRoot extends React.PureComponent {
 
   componentWillUnmount () {
     window.removeEventListener('keyup', this.handleKeyUp);
+    window.removeEventListener('keydown', this.handleKeyDown);
   }
 
   getSiblings = () => {
diff --git a/app/javascript/mastodon/components/poll.js b/app/javascript/mastodon/components/poll.js
new file mode 100644
index 0000000000000000000000000000000000000000..690f9ae5a076da1169b18314d9315adeb024357f
--- /dev/null
+++ b/app/javascript/mastodon/components/poll.js
@@ -0,0 +1,140 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
+import classNames from 'classnames';
+import { vote, fetchPoll } from 'mastodon/actions/polls';
+import Motion from 'mastodon/features/ui/util/optional_motion';
+import spring from 'react-motion/lib/spring';
+import escapeTextContentForBrowser from 'escape-html';
+import emojify from 'mastodon/features/emoji/emoji';
+import RelativeTimestamp from './relative_timestamp';
+
+const messages = defineMessages({
+  closed: { id: 'poll.closed', defaultMessage: 'Closed' },
+});
+
+const makeEmojiMap = record => record.get('emojis').reduce((obj, emoji) => {
+  obj[`:${emoji.get('shortcode')}:`] = emoji.toJS();
+  return obj;
+}, {});
+
+export default @injectIntl
+class Poll extends ImmutablePureComponent {
+
+  static propTypes = {
+    poll: ImmutablePropTypes.map,
+    intl: PropTypes.object.isRequired,
+    dispatch: PropTypes.func,
+    disabled: PropTypes.bool,
+  };
+
+  state = {
+    selected: {},
+  };
+
+  handleOptionChange = e => {
+    const { target: { value } } = e;
+
+    if (this.props.poll.get('multiple')) {
+      const tmp = { ...this.state.selected };
+      if (tmp[value]) {
+        delete tmp[value];
+      } else {
+        tmp[value] = true;
+      }
+      this.setState({ selected: tmp });
+    } else {
+      const tmp = {};
+      tmp[value] = true;
+      this.setState({ selected: tmp });
+    }
+  };
+
+  handleVote = () => {
+    if (this.props.disabled) {
+      return;
+    }
+
+    this.props.dispatch(vote(this.props.poll.get('id'), Object.keys(this.state.selected)));
+  };
+
+  handleRefresh = () => {
+    if (this.props.disabled) {
+      return;
+    }
+
+    this.props.dispatch(fetchPoll(this.props.poll.get('id')));
+  };
+
+  renderOption (option, optionIndex) {
+    const { poll, disabled } = this.props;
+    const percent            = poll.get('votes_count') === 0 ? 0 : (option.get('votes_count') / poll.get('votes_count')) * 100;
+    const leading            = poll.get('options').filterNot(other => other.get('title') === option.get('title')).every(other => option.get('votes_count') > other.get('votes_count'));
+    const active             = !!this.state.selected[`${optionIndex}`];
+    const showResults        = poll.get('voted') || poll.get('expired');
+
+    let titleEmojified = option.get('title_emojified');
+    if (!titleEmojified) {
+      const emojiMap = makeEmojiMap(poll);
+      titleEmojified = emojify(escapeTextContentForBrowser(option.get('title')), emojiMap);
+    }
+
+    return (
+      <li key={option.get('title')}>
+        {showResults && (
+          <Motion defaultStyle={{ width: 0 }} style={{ width: spring(percent, { stiffness: 180, damping: 12 }) }}>
+            {({ width }) =>
+              <span className={classNames('poll__chart', { leading })} style={{ width: `${width}%` }} />
+            }
+          </Motion>
+        )}
+
+        <label className={classNames('poll__text', { selectable: !showResults })}>
+          <input
+            name='vote-options'
+            type={poll.get('multiple') ? 'checkbox' : 'radio'}
+            value={optionIndex}
+            checked={active}
+            onChange={this.handleOptionChange}
+            disabled={disabled}
+          />
+
+          {!showResults && <span className={classNames('poll__input', { checkbox: poll.get('multiple'), active })} />}
+          {showResults && <span className='poll__number'>{Math.round(percent)}%</span>}
+
+          <span dangerouslySetInnerHTML={{ __html: titleEmojified }} />
+        </label>
+      </li>
+    );
+  }
+
+  render () {
+    const { poll, intl } = this.props;
+
+    if (!poll) {
+      return null;
+    }
+
+    const timeRemaining = poll.get('expired') ? intl.formatMessage(messages.closed) : <RelativeTimestamp timestamp={poll.get('expires_at')} futureDate />;
+    const showResults   = poll.get('voted') || poll.get('expired');
+    const disabled      = this.props.disabled || Object.entries(this.state.selected).every(item => !item);
+
+    return (
+      <div className='poll'>
+        <ul>
+          {poll.get('options').map((option, i) => this.renderOption(option, i))}
+        </ul>
+
+        <div className='poll__footer'>
+          {!showResults && <button className='button button-secondary' disabled={disabled} onClick={this.handleVote}><FormattedMessage id='poll.vote' defaultMessage='Vote' /></button>}
+          {showResults && !this.props.disabled && <span><button className='poll__link' onClick={this.handleRefresh}><FormattedMessage id='poll.refresh' defaultMessage='Refresh' /></button> · </span>}
+          <FormattedMessage id='poll.total_votes' defaultMessage='{count, plural, one {# vote} other {# votes}}' values={{ count: poll.get('votes_count') }} />
+          {poll.get('expires_at') && <span> · {timeRemaining}</span>}
+        </div>
+      </div>
+    );
+  }
+
+}
diff --git a/app/javascript/mastodon/components/relative_timestamp.js b/app/javascript/mastodon/components/relative_timestamp.js
index 57d99dd199d75db223ac4acdfacd6cf6fa4cf8d1..aa4b73cfe6a7daa4bd87e5192bf9f7ee2f89e10d 100644
--- a/app/javascript/mastodon/components/relative_timestamp.js
+++ b/app/javascript/mastodon/components/relative_timestamp.js
@@ -8,6 +8,11 @@ const messages = defineMessages({
   minutes: { id: 'relative_time.minutes', defaultMessage: '{number}m' },
   hours: { id: 'relative_time.hours', defaultMessage: '{number}h' },
   days: { id: 'relative_time.days', defaultMessage: '{number}d' },
+  moments_remaining: { id: 'time_remaining.moments', defaultMessage: 'Moments remaining' },
+  seconds_remaining: { id: 'time_remaining.seconds', defaultMessage: '{number, plural, one {# second} other {# seconds}} left' },
+  minutes_remaining: { id: 'time_remaining.minutes', defaultMessage: '{number, plural, one {# minute} other {# minutes}} left' },
+  hours_remaining: { id: 'time_remaining.hours', defaultMessage: '{number, plural, one {# hour} other {# hours}} left' },
+  days_remaining: { id: 'time_remaining.days', defaultMessage: '{number, plural, one {# day} other {# days}} left' },
 });
 
 const dateFormatOptions = {
@@ -86,6 +91,26 @@ export const timeAgoString = (intl, date, now, year) => {
   return relativeTime;
 };
 
+const timeRemainingString = (intl, date, now) => {
+  const delta = date.getTime() - now;
+
+  let relativeTime;
+
+  if (delta < 10 * SECOND) {
+    relativeTime = intl.formatMessage(messages.moments_remaining);
+  } else if (delta < MINUTE) {
+    relativeTime = intl.formatMessage(messages.seconds_remaining, { number: Math.floor(delta / SECOND) });
+  } else if (delta < HOUR) {
+    relativeTime = intl.formatMessage(messages.minutes_remaining, { number: Math.floor(delta / MINUTE) });
+  } else if (delta < DAY) {
+    relativeTime = intl.formatMessage(messages.hours_remaining, { number: Math.floor(delta / HOUR) });
+  } else {
+    relativeTime = intl.formatMessage(messages.days_remaining, { number: Math.floor(delta / DAY) });
+  }
+
+  return relativeTime;
+};
+
 export default @injectIntl
 class RelativeTimestamp extends React.Component {
 
@@ -93,6 +118,7 @@ class RelativeTimestamp extends React.Component {
     intl: PropTypes.object.isRequired,
     timestamp: PropTypes.string.isRequired,
     year: PropTypes.number.isRequired,
+    futureDate: PropTypes.bool,
   };
 
   state = {
@@ -145,10 +171,10 @@ class RelativeTimestamp extends React.Component {
   }
 
   render () {
-    const { timestamp, intl, year } = this.props;
+    const { timestamp, intl, year, futureDate } = this.props;
 
     const date         = new Date(timestamp);
-    const relativeTime = timeAgoString(intl, date, this.state.now, year);
+    const relativeTime = futureDate ? timeRemainingString(intl, date, this.state.now) : timeAgoString(intl, date, this.state.now, year);
 
     return (
       <time dateTime={timestamp} title={intl.formatDate(date, dateFormatOptions)}>
diff --git a/app/javascript/mastodon/components/scrollable_list.js b/app/javascript/mastodon/components/scrollable_list.js
index fec06e26373357cd6002176c4860af2a693a69fc..0376cf85accef9390512dc9d67baf71623d255a0 100644
--- a/app/javascript/mastodon/components/scrollable_list.js
+++ b/app/javascript/mastodon/components/scrollable_list.js
@@ -40,6 +40,7 @@ export default class ScrollableList extends PureComponent {
 
   state = {
     fullscreen: null,
+    cachedMediaWidth: 250, // Default media/card width using default Mastodon theme
   };
 
   intersectionObserverWrapper = new IntersectionObserverWrapper();
@@ -130,6 +131,20 @@ export default class ScrollableList extends PureComponent {
     this.handleScroll();
   }
 
+  getScrollPosition = () => {
+    if (this.node && (this.node.scrollTop > 0 || this.mouseMovedRecently)) {
+      return { height: this.node.scrollHeight, top: this.node.scrollTop };
+    } else {
+      return null;
+    }
+  }
+
+  updateScrollBottom = (snapshot) => {
+    const newScrollTop = this.node.scrollHeight - snapshot;
+
+    this.setScrollTop(newScrollTop);
+  }
+
   getSnapshotBeforeUpdate (prevProps) {
     const someItemInserted = React.Children.count(prevProps.children) > 0 &&
       React.Children.count(prevProps.children) < React.Children.count(this.props.children) &&
@@ -150,6 +165,12 @@ export default class ScrollableList extends PureComponent {
     }
   }
 
+  cacheMediaWidth = (width) => {
+    if (width && this.state.cachedMediaWidth !== width) {
+      this.setState({ cachedMediaWidth: width });
+    }
+  }
+
   componentWillUnmount () {
     this.clearMouseIdleTimer();
     this.detachScrollListener();
@@ -239,7 +260,12 @@ export default class ScrollableList extends PureComponent {
                 intersectionObserverWrapper={this.intersectionObserverWrapper}
                 saveHeightKey={trackScroll ? `${this.context.router.route.location.key}:${scrollKey}` : null}
               >
-                {child}
+                {React.cloneElement(child, {
+                  getScrollPosition: this.getScrollPosition,
+                  updateScrollBottom: this.updateScrollBottom,
+                  cachedMediaWidth: this.state.cachedMediaWidth,
+                  cacheMediaWidth: this.cacheMediaWidth,
+                })}
               </IntersectionObserverArticleContainer>
             ))}
 
diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js
index 20d838500967f3c2d2e75c117ab2b46141b5510b..9b1035649d8b4ed6d0c8d6f7fb0f688933539cf7 100644
--- a/app/javascript/mastodon/components/status.js
+++ b/app/javascript/mastodon/components/status.js
@@ -15,6 +15,8 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
 import { MediaGallery, Video } from '../features/ui/util/async-components';
 import { HotKeys } from 'react-hotkeys';
 import classNames from 'classnames';
+import Icon from 'mastodon/components/icon';
+import { displayMedia } from '../initial_state';
 
 // We use the component (and not the container) since we do not want
 // to use the progress bar to show download progress
@@ -37,6 +39,18 @@ export const textForScreenReader = (intl, status, rebloggedByText = false) => {
   return values.join(', ');
 };
 
+export const defaultMediaVisibility = (status) => {
+  if (!status) {
+    return undefined;
+  }
+
+  if (status.get('reblog', null) !== null && typeof status.get('reblog') === 'object') {
+    status = status.get('reblog');
+  }
+
+  return (displayMedia !== 'hide_all' && !status.get('sensitive') || displayMedia === 'show_all');
+};
+
 export default @injectIntl
 class Status extends ImmutablePureComponent {
 
@@ -68,6 +82,10 @@ class Status extends ImmutablePureComponent {
     onMoveUp: PropTypes.func,
     onMoveDown: PropTypes.func,
     showThread: PropTypes.bool,
+    getScrollPosition: PropTypes.func,
+    updateScrollBottom: PropTypes.func,
+    cacheMediaWidth: PropTypes.func,
+    cachedMediaWidth: PropTypes.number,
   };
 
   // Avoid checking props that are functions (and whose equality will always
@@ -79,6 +97,65 @@ class Status extends ImmutablePureComponent {
     'hidden',
   ];
 
+  state = {
+    showMedia: defaultMediaVisibility(this.props.status),
+    statusId: undefined,
+  };
+
+  // Track height changes we know about to compensate scrolling
+  componentDidMount () {
+    this.didShowCard = !this.props.muted && !this.props.hidden && this.props.status && this.props.status.get('card');
+  }
+
+  getSnapshotBeforeUpdate () {
+    if (this.props.getScrollPosition) {
+      return this.props.getScrollPosition();
+    } else {
+      return null;
+    }
+  }
+
+  static getDerivedStateFromProps(nextProps, prevState) {
+    if (nextProps.status && nextProps.status.get('id') !== prevState.statusId) {
+      return {
+        showMedia: defaultMediaVisibility(nextProps.status),
+        statusId: nextProps.status.get('id'),
+      };
+    } else {
+      return null;
+    }
+  }
+
+  // Compensate height changes
+  componentDidUpdate (prevProps, prevState, snapshot) {
+    const doShowCard  = !this.props.muted && !this.props.hidden && this.props.status && this.props.status.get('card');
+
+    if (doShowCard && !this.didShowCard) {
+      this.didShowCard = true;
+
+      if (snapshot !== null && this.props.updateScrollBottom) {
+        if (this.node && this.node.offsetTop < snapshot.top) {
+          this.props.updateScrollBottom(snapshot.height - snapshot.top);
+        }
+      }
+    }
+  }
+
+  componentWillUnmount() {
+    if (this.node && this.props.getScrollPosition) {
+      const position = this.props.getScrollPosition();
+      if (position !== null && this.node.offsetTop < position.top) {
+        requestAnimationFrame(() => {
+          this.props.updateScrollBottom(position.height - position.top);
+        });
+      }
+    }
+  }
+
+  handleToggleMediaVisibility = () => {
+    this.setState({ showMedia: !this.state.showMedia });
+  }
+
   handleClick = () => {
     if (this.props.onClick) {
       this.props.onClick();
@@ -93,6 +170,22 @@ class Status extends ImmutablePureComponent {
     this.context.router.history.push(`/statuses/${status.getIn(['reblog', 'id'], status.get('id'))}`);
   }
 
+  handleExpandClick = (e) => {
+    if (this.props.onClick) {
+      this.props.onClick();
+      return;
+    }
+
+    if (e.button === 0) {
+      if (!this.context.router) {
+        return;
+      }
+
+      const { status } = this.props;
+      this.context.router.history.push(`/statuses/${status.getIn(['reblog', 'id'], status.get('id'))}`);
+    }
+  }
+
   handleAccountClick = (e) => {
     if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
       const id = e.currentTarget.getAttribute('data-id');
@@ -155,6 +248,10 @@ class Status extends ImmutablePureComponent {
     this.props.onToggleHidden(this._properStatus());
   }
 
+  handleHotkeyToggleSensitive = () => {
+    this.handleToggleMediaVisibility();
+  }
+
   _properStatus () {
     const { status } = this.props;
 
@@ -165,6 +262,10 @@ class Status extends ImmutablePureComponent {
     }
   }
 
+  handleRef = c => {
+    this.node = c;
+  }
+
   render () {
     let media = null;
     let statusAvatar, prepend, rebloggedByText;
@@ -179,7 +280,7 @@ class Status extends ImmutablePureComponent {
 
     if (hidden) {
       return (
-        <div>
+        <div ref={this.handleRef}>
           {status.getIn(['account', 'display_name']) || status.getIn(['account', 'username'])}
           {status.get('content')}
         </div>
@@ -194,7 +295,7 @@ class Status extends ImmutablePureComponent {
 
       return (
         <HotKeys handlers={minHandlers}>
-          <div className='status__wrapper status__wrapper--filtered focusable' tabIndex='0'>
+          <div className='status__wrapper status__wrapper--filtered focusable' tabIndex='0' ref={this.handleRef}>
             <FormattedMessage id='status.filtered' defaultMessage='Filtered' />
           </div>
         </HotKeys>
@@ -204,7 +305,7 @@ class Status extends ImmutablePureComponent {
     if (featured) {
       prepend = (
         <div className='status__prepend'>
-          <div className='status__prepend-icon-wrapper'><i className='fa fa-fw fa-thumb-tack status__prepend-icon' /></div>
+          <div className='status__prepend-icon-wrapper'><Icon id='thumb-tack' className='status__prepend-icon' fixedWidth /></div>
           <FormattedMessage id='status.pinned' defaultMessage='Pinned toot' />
         </div>
       );
@@ -213,7 +314,7 @@ class Status extends ImmutablePureComponent {
 
       prepend = (
         <div className='status__prepend'>
-          <div className='status__prepend-icon-wrapper'><i className='fa fa-fw fa-retweet status__prepend-icon' /></div>
+          <div className='status__prepend-icon-wrapper'><Icon id='retweet' className='status__prepend-icon' fixedWidth /></div>
           <FormattedMessage id='status.reblogged_by' defaultMessage='{name} boosted' values={{ name: <a onClick={this.handleAccountClick} data-id={status.getIn(['account', 'id'])} href={status.getIn(['account', 'url'])} className='status__display-name muted'><bdi><strong dangerouslySetInnerHTML={display_name_html} /></bdi></a> }} />
         </div>
       );
@@ -225,28 +326,32 @@ class Status extends ImmutablePureComponent {
     }
 
     if (status.get('media_attachments').size > 0) {
-      if (this.props.muted || status.get('media_attachments').some(item => item.get('type') === 'unknown')) {
+      if (this.props.muted) {
         media = (
           <AttachmentList
             compact
             media={status.get('media_attachments')}
           />
         );
-      } else if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
-        const video = status.getIn(['media_attachments', 0]);
+      } else if (['video', 'audio'].includes(status.getIn(['media_attachments', 0, 'type']))) {
+        const attachment = status.getIn(['media_attachments', 0]);
 
         media = (
           <Bundle fetchComponent={Video} loading={this.renderLoadingVideoPlayer} >
             {Component => (
               <Component
-                preview={video.get('preview_url')}
-                src={video.get('url')}
-                alt={video.get('description')}
-                width={239}
+                preview={attachment.get('preview_url')}
+                blurhash={attachment.get('blurhash')}
+                src={attachment.get('url')}
+                alt={attachment.get('description')}
+                width={this.props.cachedMediaWidth}
                 height={110}
                 inline
                 sensitive={status.get('sensitive')}
                 onOpenVideo={this.handleOpenVideo}
+                cacheWidth={this.props.cacheMediaWidth}
+                visible={this.state.showMedia}
+                onToggleVisibility={this.handleToggleMediaVisibility}
               />
             )}
           </Bundle>
@@ -254,7 +359,18 @@ class Status extends ImmutablePureComponent {
       } else {
         media = (
           <Bundle fetchComponent={MediaGallery} loading={this.renderLoadingMediaGallery}>
-            {Component => <Component media={status.get('media_attachments')} sensitive={status.get('sensitive')} height={110} onOpenMedia={this.props.onOpenMedia} />}
+            {Component => (
+              <Component
+                media={status.get('media_attachments')}
+                sensitive={status.get('sensitive')}
+                height={110}
+                onOpenMedia={this.props.onOpenMedia}
+                cacheWidth={this.props.cacheMediaWidth}
+                defaultWidth={this.props.cachedMediaWidth}
+                visible={this.state.showMedia}
+                onToggleVisibility={this.handleToggleMediaVisibility}
+              />
+            )}
           </Bundle>
         );
       }
@@ -264,11 +380,13 @@ class Status extends ImmutablePureComponent {
           onOpenMedia={this.props.onOpenMedia}
           card={status.get('card')}
           compact
+          cacheWidth={this.props.cacheMediaWidth}
+          defaultWidth={this.props.cachedMediaWidth}
         />
       );
     }
 
-    if (otherAccounts) {
+    if (otherAccounts && otherAccounts.size > 0) {
       statusAvatar = <AvatarComposite accounts={otherAccounts} size={48} />;
     } else if (account === undefined || account === null) {
       statusAvatar = <Avatar account={status.get('account')} size={48} />;
@@ -286,14 +404,16 @@ class Status extends ImmutablePureComponent {
       moveUp: this.handleHotkeyMoveUp,
       moveDown: this.handleHotkeyMoveDown,
       toggleHidden: this.handleHotkeyToggleHidden,
+      toggleSensitive: this.handleHotkeyToggleSensitive,
     };
 
     return (
       <HotKeys handlers={handlers}>
-        <div className={classNames('status__wrapper', `status__wrapper-${status.get('visibility')}`, { 'status__wrapper-reply': !!status.get('in_reply_to_id'), read: unread === false, focusable: !this.props.muted })} tabIndex={this.props.muted ? null : 0} data-featured={featured ? 'true' : null} aria-label={textForScreenReader(intl, status, rebloggedByText, !status.get('hidden'))}>
+        <div className={classNames('status__wrapper', `status__wrapper-${status.get('visibility')}`, { 'status__wrapper-reply': !!status.get('in_reply_to_id'), read: unread === false, focusable: !this.props.muted })} tabIndex={this.props.muted ? null : 0} data-featured={featured ? 'true' : null} aria-label={textForScreenReader(intl, status, rebloggedByText)} ref={this.handleRef}>
           {prepend}
 
           <div className={classNames('status', `status-${status.get('visibility')}`, { 'status-reply': !!status.get('in_reply_to_id'), muted: this.props.muted, read: unread === false })} data-id={status.get('id')}>
+            <div className='status__expand' onClick={this.handleExpandClick} role='presentation' />
             <div className='status__info'>
               <a href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener'><RelativeTimestamp timestamp={status.get('created_at')} /></a>
 
diff --git a/app/javascript/mastodon/components/status_action_bar.js b/app/javascript/mastodon/components/status_action_bar.js
index 0995a14904c29ccd76a186738a98ecd07f929d47..0bfbd887945dabdf9b9e5001c4d17121b087420c 100644
--- a/app/javascript/mastodon/components/status_action_bar.js
+++ b/app/javascript/mastodon/components/status_action_bar.js
@@ -32,6 +32,7 @@ const messages = defineMessages({
   embed: { id: 'status.embed', defaultMessage: 'Embed' },
   admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
   admin_status: { id: 'status.admin_status', defaultMessage: 'Open this status in the moderation interface' },
+  copy: { id: 'status.copy', defaultMessage: 'Copy link to status' },
 });
 
 const obfuscatedCount = count => {
@@ -77,7 +78,11 @@ class StatusActionBar extends ImmutablePureComponent {
   ]
 
   handleReplyClick = () => {
-    this.props.onReply(this.props.status, this.context.router.history);
+    if (me) {
+      this.props.onReply(this.props.status, this.context.router.history);
+    } else {
+      this._openInteractionDialog('reply');
+    }
   }
 
   handleShareClick = () => {
@@ -90,11 +95,23 @@ class StatusActionBar extends ImmutablePureComponent {
   }
 
   handleFavouriteClick = () => {
-    this.props.onFavourite(this.props.status);
+    if (me) {
+      this.props.onFavourite(this.props.status);
+    } else {
+      this._openInteractionDialog('favourite');
+    }
+  }
+
+  handleReblogClick = e => {
+    if (me) {
+      this.props.onReblog(this.props.status, e);
+    } else {
+      this._openInteractionDialog('reblog');
+    }
   }
 
-  handleReblogClick = (e) => {
-    this.props.onReblog(this.props.status, e);
+  _openInteractionDialog = type => {
+    window.open(`/interact/${this.props.status.get('id')}?type=${type}`, 'mastodon-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes');
   }
 
   handleDeleteClick = () => {
@@ -122,7 +139,7 @@ class StatusActionBar extends ImmutablePureComponent {
   }
 
   handleBlockClick = () => {
-    this.props.onBlock(this.props.status.get('account'));
+    this.props.onBlock(this.props.status);
   }
 
   handleOpen = () => {
@@ -141,6 +158,25 @@ class StatusActionBar extends ImmutablePureComponent {
     this.props.onMuteConversation(this.props.status);
   }
 
+  handleCopy = () => {
+    const url      = this.props.status.get('url');
+    const textarea = document.createElement('textarea');
+
+    textarea.textContent    = url;
+    textarea.style.position = 'fixed';
+
+    document.body.appendChild(textarea);
+
+    try {
+      textarea.select();
+      document.execCommand('copy');
+    } catch (e) {
+
+    } finally {
+      document.body.removeChild(textarea);
+    }
+  }
+
   render () {
     const { status, intl, withDismiss } = this.props;
 
@@ -156,6 +192,7 @@ class StatusActionBar extends ImmutablePureComponent {
     menu.push({ text: intl.formatMessage(messages.open), action: this.handleOpen });
 
     if (publicStatus) {
+      menu.push({ text: intl.formatMessage(messages.copy), action: this.handleCopy });
       menu.push({ text: intl.formatMessage(messages.embed), action: this.handleEmbed });
     }
 
@@ -184,6 +221,7 @@ class StatusActionBar extends ImmutablePureComponent {
       menu.push({ text: intl.formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }), action: this.handleMuteClick });
       menu.push({ text: intl.formatMessage(messages.block, { name: status.getIn(['account', 'username']) }), action: this.handleBlockClick });
       menu.push({ text: intl.formatMessage(messages.report, { name: status.getIn(['account', 'username']) }), action: this.handleReport });
+
       if (isStaff) {
         menu.push(null);
         menu.push({ text: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` });
@@ -211,9 +249,9 @@ class StatusActionBar extends ImmutablePureComponent {
 
     return (
       <div className='status__action-bar'>
-        <div className='status__action-bar__counter'><IconButton className='status__action-bar-button' disabled={anonymousAccess} title={replyTitle} icon={status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) ? 'reply' : replyIcon} onClick={this.handleReplyClick} /><span className='status__action-bar__counter__label' >{obfuscatedCount(status.get('replies_count'))}</span></div>
-        <IconButton className='status__action-bar-button' disabled={anonymousAccess || !publicStatus} active={status.get('reblogged')} pressed={status.get('reblogged')} title={!publicStatus ? intl.formatMessage(messages.cannot_reblog) : intl.formatMessage(messages.reblog)} icon={reblogIcon} onClick={this.handleReblogClick} />
-        <IconButton className='status__action-bar-button star-icon' disabled={anonymousAccess} animate active={status.get('favourited')} pressed={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} />
+        <div className='status__action-bar__counter'><IconButton className='status__action-bar-button' title={replyTitle} icon={status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) ? 'reply' : replyIcon} onClick={this.handleReplyClick} /><span className='status__action-bar__counter__label' >{obfuscatedCount(status.get('replies_count'))}</span></div>
+        <IconButton className='status__action-bar-button' disabled={!publicStatus} active={status.get('reblogged')} pressed={status.get('reblogged')} title={!publicStatus ? intl.formatMessage(messages.cannot_reblog) : intl.formatMessage(messages.reblog)} icon={reblogIcon} onClick={this.handleReblogClick} />
+        <IconButton className='status__action-bar-button star-icon' animate active={status.get('favourited')} pressed={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} />
         {shareButton}
 
         <div className='status__action-bar-dropdown'>
diff --git a/app/javascript/mastodon/components/status_content.js b/app/javascript/mastodon/components/status_content.js
index d8f18bd027c10c8cd445644e80f7c6d6d0220f14..179534e4074e302d89fa0d82c84a2ffe60fe660f 100644
--- a/app/javascript/mastodon/components/status_content.js
+++ b/app/javascript/mastodon/components/status_content.js
@@ -5,6 +5,9 @@ import { isRtl } from '../rtl';
 import { FormattedMessage } from 'react-intl';
 import Permalink from './permalink';
 import classnames from 'classnames';
+import PollContainer from 'mastodon/containers/poll_container';
+import Icon from 'mastodon/components/icon';
+import { autoPlayGif } from 'mastodon/initial_state';
 
 const MAX_HEIGHT = 642; // 20px * 32 (+ 2px padding at the top)
 
@@ -71,12 +74,35 @@ export default class StatusContent extends React.PureComponent {
     }
   }
 
+  _updateStatusEmojis () {
+    const node = this.node;
+
+    if (!node || autoPlayGif) {
+      return;
+    }
+
+    const emojis = node.querySelectorAll('.custom-emoji');
+
+    for (var i = 0; i < emojis.length; i++) {
+      let emoji = emojis[i];
+      if (emoji.classList.contains('status-emoji')) {
+        continue;
+      }
+      emoji.classList.add('status-emoji');
+
+      emoji.addEventListener('mouseenter', this.handleEmojiMouseEnter, false);
+      emoji.addEventListener('mouseleave', this.handleEmojiMouseLeave, false);
+    }
+  }
+
   componentDidMount () {
     this._updateStatusLinks();
+    this._updateStatusEmojis();
   }
 
   componentDidUpdate () {
     this._updateStatusLinks();
+    this._updateStatusEmojis();
   }
 
   onMentionClick = (mention, e) => {
@@ -95,6 +121,14 @@ export default class StatusContent extends React.PureComponent {
     }
   }
 
+  handleEmojiMouseEnter = ({ target }) => {
+    target.src = target.getAttribute('data-original');
+  }
+
+  handleEmojiMouseLeave = ({ target }) => {
+    target.src = target.getAttribute('data-static');
+  }
+
   handleMouseDown = (e) => {
     this.startXY = [e.clientX, e.clientY];
   }
@@ -107,8 +141,12 @@ export default class StatusContent extends React.PureComponent {
     const [ startX, startY ] = this.startXY;
     const [ deltaX, deltaY ] = [Math.abs(e.clientX - startX), Math.abs(e.clientY - startY)];
 
-    if (e.target.localName === 'button' || e.target.localName === 'a' || (e.target.parentNode && (e.target.parentNode.localName === 'button' || e.target.parentNode.localName === 'a'))) {
-      return;
+    let element = e.target;
+    while (element) {
+      if (element.localName === 'button' || element.localName === 'a' || element.localName === 'label') {
+        return;
+      }
+      element = element.parentNode;
     }
 
     if (deltaX + deltaY < 5 && e.button === 0 && this.props.onClick) {
@@ -129,11 +167,6 @@ export default class StatusContent extends React.PureComponent {
     }
   }
 
-  handleCollapsedClick = (e) => {
-    e.preventDefault();
-    this.setState({ collapsed: !this.state.collapsed });
-  }
-
   setRef = (c) => {
     this.node = c;
   }
@@ -162,7 +195,7 @@ export default class StatusContent extends React.PureComponent {
 
     const readMoreButton = (
       <button className='status__content__read-more-button' onClick={this.props.onClick} key='read-more'>
-        <FormattedMessage id='status.read_more' defaultMessage='Read more' /><i className='fa fa-fw fa-angle-right' />
+        <FormattedMessage id='status.read_more' defaultMessage='Read more' /><Icon id='angle-right' fixedWidth />
       </button>
     );
 
@@ -184,28 +217,25 @@ export default class StatusContent extends React.PureComponent {
       return (
         <div className={classNames} ref={this.setRef} tabIndex='0' style={directionStyle} onMouseDown={this.handleMouseDown} onMouseUp={this.handleMouseUp}>
           <p style={{ marginBottom: hidden && status.get('mentions').isEmpty() ? '0px' : null }}>
-            <span dangerouslySetInnerHTML={spoilerContent} />
+            <span dangerouslySetInnerHTML={spoilerContent} lang={status.get('language')} />
             {' '}
             <button tabIndex='0' className={`status__content__spoiler-link ${hidden ? 'status__content__spoiler-link--show-more' : 'status__content__spoiler-link--show-less'}`} onClick={this.handleSpoilerClick}>{toggleText}</button>
           </p>
 
           {mentionsPlaceholder}
 
-          <div tabIndex={!hidden ? 0 : null} className={`status__content__text ${!hidden ? 'status__content__text--visible' : ''}`} style={directionStyle} dangerouslySetInnerHTML={content} />
+          <div tabIndex={!hidden ? 0 : null} className={`status__content__text ${!hidden ? 'status__content__text--visible' : ''}`} style={directionStyle} dangerouslySetInnerHTML={content} lang={status.get('language')} />
+
+          {!hidden && !!status.get('poll') && <PollContainer pollId={status.get('poll')} />}
         </div>
       );
     } else if (this.props.onClick) {
       const output = [
-        <div
-          ref={this.setRef}
-          tabIndex='0'
-          key='content'
-          className={classNames}
-          style={directionStyle}
-          dangerouslySetInnerHTML={content}
-          onMouseDown={this.handleMouseDown}
-          onMouseUp={this.handleMouseUp}
-        />,
+        <div className={classNames} ref={this.setRef} tabIndex='0' style={directionStyle} onMouseDown={this.handleMouseDown} onMouseUp={this.handleMouseUp}>
+          <div className='status__content__text status__content__text--visible' style={directionStyle} dangerouslySetInnerHTML={content} lang={status.get('language')} />
+
+          {!!status.get('poll') && <PollContainer pollId={status.get('poll')} />}
+        </div>,
       ];
 
       if (this.state.collapsed) {
@@ -215,13 +245,11 @@ export default class StatusContent extends React.PureComponent {
       return output;
     } else {
       return (
-        <div
-          tabIndex='0'
-          ref={this.setRef}
-          className='status__content'
-          style={directionStyle}
-          dangerouslySetInnerHTML={content}
-        />
+        <div className={classNames} ref={this.setRef} tabIndex='0' style={directionStyle}>
+          <div className='status__content__text status__content__text--visible' style={directionStyle} dangerouslySetInnerHTML={content} lang={status.get('language')} />
+
+          {!!status.get('poll') && <PollContainer pollId={status.get('poll')} />}
+        </div>
       );
     }
   }
diff --git a/app/javascript/mastodon/components/status_list.js b/app/javascript/mastodon/components/status_list.js
index e417f9a2b96a170b9ce2e400d4873883a38be218..745e6422d3d86893a3dc5b92365f87b312f21a1b 100644
--- a/app/javascript/mastodon/components/status_list.js
+++ b/app/javascript/mastodon/components/status_list.js
@@ -46,22 +46,28 @@ export default class StatusList extends ImmutablePureComponent {
 
   handleMoveUp = (id, featured) => {
     const elementIndex = this.getCurrentStatusIndex(id, featured) - 1;
-    this._selectChild(elementIndex);
+    this._selectChild(elementIndex, true);
   }
 
   handleMoveDown = (id, featured) => {
     const elementIndex = this.getCurrentStatusIndex(id, featured) + 1;
-    this._selectChild(elementIndex);
+    this._selectChild(elementIndex, false);
   }
 
   handleLoadOlder = debounce(() => {
     this.props.onLoadMore(this.props.statusIds.size > 0 ? this.props.statusIds.last() : undefined);
   }, 300, { leading: true })
 
-  _selectChild (index) {
-    const element = this.node.node.querySelector(`article:nth-of-type(${index + 1}) .focusable`);
+  _selectChild (index, align_top) {
+    const container = this.node.node;
+    const element = container.querySelector(`article:nth-of-type(${index + 1}) .focusable`);
 
     if (element) {
+      if (align_top && container.scrollTop > element.offsetTop) {
+        element.scrollIntoView(true);
+      } else if (!align_top && container.scrollTop + container.clientHeight < element.offsetTop + element.offsetHeight) {
+        element.scrollIntoView(false);
+      }
       element.focus();
     }
   }
diff --git a/app/javascript/mastodon/containers/compose_container.js b/app/javascript/mastodon/containers/compose_container.js
index 5ee1d2f141ff6ffcfe30163f50b4fc0f3c0a2f0b..7bc7bbaa4dc29d97fec3bd9e124c2ea312221a2f 100644
--- a/app/javascript/mastodon/containers/compose_container.js
+++ b/app/javascript/mastodon/containers/compose_container.js
@@ -7,6 +7,7 @@ import { IntlProvider, addLocaleData } from 'react-intl';
 import { getLocale } from '../locales';
 import Compose from '../features/standalone/compose';
 import initialState from '../initial_state';
+import { fetchCustomEmojis } from '../actions/custom_emojis';
 
 const { localeData, messages } = getLocale();
 addLocaleData(localeData);
@@ -17,6 +18,8 @@ if (initialState) {
   store.dispatch(hydrateStore(initialState));
 }
 
+store.dispatch(fetchCustomEmojis());
+
 export default class TimelineContainer extends React.PureComponent {
 
   static propTypes = {
diff --git a/app/javascript/mastodon/containers/dropdown_menu_container.js b/app/javascript/mastodon/containers/dropdown_menu_container.js
index 73c8a1e530e7b0b8e285b2e7d3cca9c91c3659c4..f79b192029e5de0d666c1682a81ce8d604e8f35d 100644
--- a/app/javascript/mastodon/containers/dropdown_menu_container.js
+++ b/app/javascript/mastodon/containers/dropdown_menu_container.js
@@ -20,7 +20,7 @@ const mapDispatchToProps = (dispatch, { status, items }) => ({
     }) : openDropdownMenu(id, dropdownPlacement, keyboard));
   },
   onClose(id) {
-    dispatch(closeModal());
+    dispatch(closeModal('ACTIONS'));
     dispatch(closeDropdownMenu(id));
   },
 });
diff --git a/app/javascript/mastodon/containers/mastodon.js b/app/javascript/mastodon/containers/mastodon.js
index 2912540a00f189e6c68238d0b9c5ffb7af90a932..542b682821ee5cf9b2c9ec8ce177b34c63cca6c9 100644
--- a/app/javascript/mastodon/containers/mastodon.js
+++ b/app/javascript/mastodon/containers/mastodon.js
@@ -13,6 +13,7 @@ import { connectUserStream } from '../actions/streaming';
 import { IntlProvider, addLocaleData } from 'react-intl';
 import { getLocale } from '../locales';
 import initialState from '../initial_state';
+import ErrorBoundary from '../components/error_boundary';
 
 const { localeData, messages } = getLocale();
 addLocaleData(localeData);
@@ -75,7 +76,9 @@ export default class Mastodon extends React.PureComponent {
     return (
       <IntlProvider locale={locale} messages={messages}>
         <Provider store={store}>
-          <MastodonMount />
+          <ErrorBoundary>
+            <MastodonMount />
+          </ErrorBoundary>
         </Provider>
       </IntlProvider>
     );
diff --git a/app/javascript/mastodon/containers/media_container.js b/app/javascript/mastodon/containers/media_container.js
index 43bb394035c57d66cdfef81d52ca2e8d6d9d7121..51d4f0fed7a2522bd6a3c38d4d98d9b91ed4b35d 100644
--- a/app/javascript/mastodon/containers/media_container.js
+++ b/app/javascript/mastodon/containers/media_container.js
@@ -6,6 +6,7 @@ import { getLocale } from '../locales';
 import MediaGallery from '../components/media_gallery';
 import Video from '../features/video';
 import Card from '../features/status/components/card';
+import Poll from 'mastodon/components/poll';
 import ModalRoot from '../components/modal_root';
 import MediaModal from '../features/ui/components/media_modal';
 import { List as ImmutableList, fromJS } from 'immutable';
@@ -13,7 +14,7 @@ import { List as ImmutableList, fromJS } from 'immutable';
 const { localeData, messages } = getLocale();
 addLocaleData(localeData);
 
-const MEDIA_COMPONENTS = { MediaGallery, Video, Card };
+const MEDIA_COMPONENTS = { MediaGallery, Video, Card, Poll };
 
 export default class MediaContainer extends PureComponent {
 
@@ -54,11 +55,12 @@ export default class MediaContainer extends PureComponent {
           {[].map.call(components, (component, i) => {
             const componentName = component.getAttribute('data-component');
             const Component = MEDIA_COMPONENTS[componentName];
-            const { media, card, ...props } = JSON.parse(component.getAttribute('data-props'));
+            const { media, card, poll, ...props } = JSON.parse(component.getAttribute('data-props'));
 
             Object.assign(props, {
               ...(media ? { media: fromJS(media) } : {}),
               ...(card  ? { card:  fromJS(card)  } : {}),
+              ...(poll  ? { poll:  fromJS(poll)  } : {}),
 
               ...(componentName === 'Video' ? {
                 onOpenVideo: this.handleOpenVideo,
diff --git a/app/javascript/mastodon/containers/poll_container.js b/app/javascript/mastodon/containers/poll_container.js
new file mode 100644
index 0000000000000000000000000000000000000000..cd7216de7a579d3eb95058a3785863380510dcea
--- /dev/null
+++ b/app/javascript/mastodon/containers/poll_container.js
@@ -0,0 +1,8 @@
+import { connect } from 'react-redux';
+import Poll from 'mastodon/components/poll';
+
+const mapStateToProps = (state, { pollId }) => ({
+  poll: state.getIn(['polls', pollId]),
+});
+
+export default connect(mapStateToProps)(Poll);
diff --git a/app/javascript/mastodon/containers/status_container.js b/app/javascript/mastodon/containers/status_container.js
index b3555c76e550977cc3ae45bfa35789159bf09078..86324b846811df4cd8a4b6b1a32deebbf301c552 100644
--- a/app/javascript/mastodon/containers/status_container.js
+++ b/app/javascript/mastodon/containers/status_container.js
@@ -38,6 +38,7 @@ const messages = defineMessages({
   blockConfirm: { id: 'confirmations.block.confirm', defaultMessage: 'Block' },
   replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
   replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
+  blockAndReport: { id: 'confirmations.block.block_and_report', defaultMessage: 'Block & Report' },
 });
 
 const makeMapStateToProps = () => {
@@ -68,18 +69,18 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
   },
 
   onModalReblog (status) {
-    dispatch(reblog(status));
+    if (status.get('reblogged')) {
+      dispatch(unreblog(status));
+    } else {
+      dispatch(reblog(status));
+    }
   },
 
   onReblog (status, e) {
-    if (status.get('reblogged')) {
-      dispatch(unreblog(status));
+    if (e.shiftKey || !boostModal) {
+      this.onModalReblog(status);
     } else {
-      if (e.shiftKey || !boostModal) {
-        this.onModalReblog(status);
-      } else {
-        dispatch(openModal('BOOST', { status, onReblog: this.onModalReblog }));
-      }
+      dispatch(openModal('BOOST', { status, onReblog: this.onModalReblog }));
     }
   },
 
@@ -134,11 +135,17 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
     dispatch(openModal('VIDEO', { media, time }));
   },
 
-  onBlock (account) {
+  onBlock (status) {
+    const account = status.get('account');
     dispatch(openModal('CONFIRM', {
       message: <FormattedMessage id='confirmations.block.message' defaultMessage='Are you sure you want to block {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
       confirm: intl.formatMessage(messages.blockConfirm),
       onConfirm: () => dispatch(blockAccount(account.get('id'))),
+      secondary: intl.formatMessage(messages.blockAndReport),
+      onSecondary: () => {
+        dispatch(blockAccount(account.get('id')));
+        dispatch(initReport(account, status));
+      },
     }));
   },
 
diff --git a/app/javascript/mastodon/containers/timeline_container.js b/app/javascript/mastodon/containers/timeline_container.js
index a1a4bd024bce363dcbee32d5ab49640db4761c3a..54f8eb310817c01eeb833a95992651c8fc9cefd2 100644
--- a/app/javascript/mastodon/containers/timeline_container.js
+++ b/app/javascript/mastodon/containers/timeline_container.js
@@ -7,7 +7,6 @@ import { hydrateStore } from '../actions/store';
 import { IntlProvider, addLocaleData } from 'react-intl';
 import { getLocale } from '../locales';
 import PublicTimeline from '../features/standalone/public_timeline';
-import CommunityTimeline from '../features/standalone/community_timeline';
 import HashtagTimeline from '../features/standalone/hashtag_timeline';
 import ModalContainer from '../features/ui/containers/modal_container';
 import initialState from '../initial_state';
@@ -26,24 +25,22 @@ export default class TimelineContainer extends React.PureComponent {
   static propTypes = {
     locale: PropTypes.string.isRequired,
     hashtag: PropTypes.string,
-    showPublicTimeline: PropTypes.bool.isRequired,
+    local: PropTypes.bool,
   };
 
   static defaultProps = {
-    showPublicTimeline: initialState.settings.known_fediverse,
+    local: !initialState.settings.known_fediverse,
   };
 
   render () {
-    const { locale, hashtag, showPublicTimeline } = this.props;
+    const { locale, hashtag, local } = this.props;
 
     let timeline;
 
     if (hashtag) {
       timeline = <HashtagTimeline hashtag={hashtag} />;
-    } else if (showPublicTimeline) {
-      timeline = <PublicTimeline />;
     } else {
-      timeline = <CommunityTimeline />;
+      timeline = <PublicTimeline local={local} />;
     }
 
     return (
@@ -51,6 +48,7 @@ export default class TimelineContainer extends React.PureComponent {
         <Provider store={store}>
           <Fragment>
             {timeline}
+
             {ReactDOM.createPortal(
               <ModalContainer />,
               document.getElementById('modal-container'),
diff --git a/app/javascript/mastodon/features/account/components/action_bar.js b/app/javascript/mastodon/features/account/components/action_bar.js
deleted file mode 100644
index 8ed4c917ab1510810a5936fefddc744b40f8e67e..0000000000000000000000000000000000000000
--- a/app/javascript/mastodon/features/account/components/action_bar.js
+++ /dev/null
@@ -1,190 +0,0 @@
-import React from 'react';
-import ImmutablePropTypes from 'react-immutable-proptypes';
-import PropTypes from 'prop-types';
-import DropdownMenuContainer from '../../../containers/dropdown_menu_container';
-import { NavLink } from 'react-router-dom';
-import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
-import { me, isStaff  } from '../../../initial_state';
-import { shortNumberFormat } from '../../../utils/numbers';
-
-const messages = defineMessages({
-  mention: { id: 'account.mention', defaultMessage: 'Mention @{name}' },
-  direct: { id: 'account.direct', defaultMessage: 'Direct message @{name}' },
-  edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' },
-  unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' },
-  unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' },
-  unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' },
-  block: { id: 'account.block', defaultMessage: 'Block @{name}' },
-  mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' },
-  follow: { id: 'account.follow', defaultMessage: 'Follow' },
-  report: { id: 'account.report', defaultMessage: 'Report @{name}' },
-  share: { id: 'account.share', defaultMessage: 'Share @{name}\'s profile' },
-  media: { id: 'account.media', defaultMessage: 'Media' },
-  blockDomain: { id: 'account.block_domain', defaultMessage: 'Hide everything from {domain}' },
-  unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' },
-  hideReblogs: { id: 'account.hide_reblogs', defaultMessage: 'Hide boosts from @{name}' },
-  showReblogs: { id: 'account.show_reblogs', defaultMessage: 'Show boosts from @{name}' },
-  pins: { id: 'navigation_bar.pins', defaultMessage: 'Pinned toots' },
-  preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
-  follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' },
-  favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' },
-  lists: { id: 'navigation_bar.lists', defaultMessage: 'Lists' },
-  blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
-  domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Hidden domains' },
-  mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
-  endorse: { id: 'account.endorse', defaultMessage: 'Feature on profile' },
-  unendorse: { id: 'account.unendorse', defaultMessage: 'Don\'t feature on profile' },
-  add_or_remove_from_list: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists' },
-  admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
-});
-
-export default @injectIntl
-class ActionBar extends React.PureComponent {
-
-  static propTypes = {
-    account: ImmutablePropTypes.map.isRequired,
-    onFollow: PropTypes.func,
-    onBlock: PropTypes.func.isRequired,
-    onMention: PropTypes.func.isRequired,
-    onDirect: PropTypes.func.isRequired,
-    onReblogToggle: PropTypes.func.isRequired,
-    onReport: PropTypes.func.isRequired,
-    onMute: PropTypes.func.isRequired,
-    onBlockDomain: PropTypes.func.isRequired,
-    onUnblockDomain: PropTypes.func.isRequired,
-    onEndorseToggle: PropTypes.func.isRequired,
-    onAddToList: PropTypes.func.isRequired,
-    intl: PropTypes.object.isRequired,
-  };
-
-  handleShare = () => {
-    navigator.share({
-      url: this.props.account.get('url'),
-    });
-  }
-
-  isStatusesPageActive = (match, location) => {
-    if (!match) {
-      return false;
-    }
-    return !location.pathname.match(/\/(followers|following)\/?$/);
-  }
-
-  render () {
-    const { account, intl } = this.props;
-
-    let menu = [];
-    let extraInfo = '';
-
-    if (account.get('id') !== me) {
-      menu.push({ text: intl.formatMessage(messages.mention, { name: account.get('username') }), action: this.props.onMention });
-      menu.push({ text: intl.formatMessage(messages.direct, { name: account.get('username') }), action: this.props.onDirect });
-      menu.push(null);
-    }
-
-    if ('share' in navigator) {
-      menu.push({ text: intl.formatMessage(messages.share, { name: account.get('username') }), action: this.handleShare });
-      menu.push(null);
-    }
-
-    if (account.get('id') === me) {
-      menu.push({ text: intl.formatMessage(messages.edit_profile), href: '/settings/profile' });
-      menu.push({ text: intl.formatMessage(messages.preferences), href: '/settings/preferences' });
-      menu.push({ text: intl.formatMessage(messages.pins), to: '/pinned' });
-      menu.push(null);
-      menu.push({ text: intl.formatMessage(messages.follow_requests), to: '/follow_requests' });
-      menu.push({ text: intl.formatMessage(messages.favourites), to: '/favourites' });
-      menu.push({ text: intl.formatMessage(messages.lists), to: '/lists' });
-      menu.push(null);
-      menu.push({ text: intl.formatMessage(messages.mutes), to: '/mutes' });
-      menu.push({ text: intl.formatMessage(messages.blocks), to: '/blocks' });
-      menu.push({ text: intl.formatMessage(messages.domain_blocks), to: '/domain_blocks' });
-    } else {
-      if (account.getIn(['relationship', 'following'])) {
-        if (account.getIn(['relationship', 'showing_reblogs'])) {
-          menu.push({ text: intl.formatMessage(messages.hideReblogs, { name: account.get('username') }), action: this.props.onReblogToggle });
-        } else {
-          menu.push({ text: intl.formatMessage(messages.showReblogs, { name: account.get('username') }), action: this.props.onReblogToggle });
-        }
-
-        menu.push({ text: intl.formatMessage(account.getIn(['relationship', 'endorsed']) ? messages.unendorse : messages.endorse), action: this.props.onEndorseToggle });
-        menu.push({ text: intl.formatMessage(messages.add_or_remove_from_list), action: this.props.onAddToList });
-        menu.push(null);
-      }
-
-      if (account.getIn(['relationship', 'muting'])) {
-        menu.push({ text: intl.formatMessage(messages.unmute, { name: account.get('username') }), action: this.props.onMute });
-      } else {
-        menu.push({ text: intl.formatMessage(messages.mute, { name: account.get('username') }), action: this.props.onMute });
-      }
-
-      if (account.getIn(['relationship', 'blocking'])) {
-        menu.push({ text: intl.formatMessage(messages.unblock, { name: account.get('username') }), action: this.props.onBlock });
-      } else {
-        menu.push({ text: intl.formatMessage(messages.block, { name: account.get('username') }), action: this.props.onBlock });
-      }
-
-      menu.push({ text: intl.formatMessage(messages.report, { name: account.get('username') }), action: this.props.onReport });
-    }
-
-    if (account.get('acct') !== account.get('username')) {
-      const domain = account.get('acct').split('@')[1];
-
-      extraInfo = (
-        <div className='account__disclaimer'>
-          <FormattedMessage
-            id='account.disclaimer_full'
-            defaultMessage="Information below may reflect the user's profile incompletely."
-          />
-          {' '}
-          <a target='_blank' rel='noopener' href={account.get('url')}>
-            <FormattedMessage id='account.view_full_profile' defaultMessage='View full profile' />
-          </a>
-        </div>
-      );
-
-      menu.push(null);
-
-      if (account.getIn(['relationship', 'domain_blocking'])) {
-        menu.push({ text: intl.formatMessage(messages.unblockDomain, { domain }), action: this.props.onUnblockDomain });
-      } else {
-        menu.push({ text: intl.formatMessage(messages.blockDomain, { domain }), action: this.props.onBlockDomain });
-      }
-    }
-
-    if (account.get('id') !== me && isStaff) {
-      menu.push(null);
-      menu.push({ text: intl.formatMessage(messages.admin_account, { name: account.get('username') }), href: `/admin/accounts/${account.get('id')}` });
-    }
-
-    return (
-      <div>
-        {extraInfo}
-
-        <div className='account__action-bar'>
-          <div className='account__action-bar-links'>
-            <NavLink isActive={this.isStatusesPageActive} activeClassName='active' className='account__action-bar__tab' to={`/accounts/${account.get('id')}`} title={intl.formatNumber(account.get('statuses_count'))}>
-              <FormattedMessage id='account.posts' defaultMessage='Toots' />
-              <strong>{shortNumberFormat(account.get('statuses_count'))}</strong>
-            </NavLink>
-
-            <NavLink exact activeClassName='active' className='account__action-bar__tab' to={`/accounts/${account.get('id')}/following`} title={intl.formatNumber(account.get('following_count'))}>
-              <FormattedMessage id='account.follows' defaultMessage='Follows' />
-              <strong>{shortNumberFormat(account.get('following_count'))}</strong>
-            </NavLink>
-
-            <NavLink exact activeClassName='active' className='account__action-bar__tab' to={`/accounts/${account.get('id')}/followers`} title={intl.formatNumber(account.get('followers_count'))}>
-              <FormattedMessage id='account.followers' defaultMessage='Followers' />
-              <strong>{shortNumberFormat(account.get('followers_count'))}</strong>
-            </NavLink>
-          </div>
-
-          <div className='account__action-bar-dropdown'>
-            <DropdownMenuContainer items={menu} icon='ellipsis-v' size={24} direction='right' />
-          </div>
-        </div>
-      </div>
-    );
-  }
-
-}
diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js
index 2ab25cde44777cdd3096d37a973f7b02530369be..ac97bad7126cd9e2c8379a90620b933aff58a990 100644
--- a/app/javascript/mastodon/features/account/components/header.js
+++ b/app/javascript/mastodon/features/account/components/header.js
@@ -2,21 +2,49 @@ import React from 'react';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import PropTypes from 'prop-types';
 import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
-import IconButton from '../../../components/icon_button';
-import Motion from '../../ui/util/optional_motion';
-import spring from 'react-motion/lib/spring';
+import Button from 'mastodon/components/button';
 import ImmutablePureComponent from 'react-immutable-pure-component';
-import { autoPlayGif, me } from '../../../initial_state';
+import { autoPlayGif, me, isStaff } from 'mastodon/initial_state';
 import classNames from 'classnames';
+import Icon from 'mastodon/components/icon';
+import Avatar from 'mastodon/components/avatar';
+import { shortNumberFormat } from 'mastodon/utils/numbers';
+import { NavLink } from 'react-router-dom';
+import DropdownMenuContainer from 'mastodon/containers/dropdown_menu_container';
 
 const messages = defineMessages({
   unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' },
   follow: { id: 'account.follow', defaultMessage: 'Follow' },
+  cancel_follow_request: { id: 'account.cancel_follow_request', defaultMessage: 'Cancel follow request' },
   requested: { id: 'account.requested', defaultMessage: 'Awaiting approval. Click to cancel follow request' },
   unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' },
   edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' },
   linkVerifiedOn: { id: 'account.link_verified_on', defaultMessage: 'Ownership of this link was checked on {date}' },
   account_locked: { id: 'account.locked_info', defaultMessage: 'This account privacy status is set to locked. The owner manually reviews who can follow them.' },
+  mention: { id: 'account.mention', defaultMessage: 'Mention @{name}' },
+  direct: { id: 'account.direct', defaultMessage: 'Direct message @{name}' },
+  unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' },
+  block: { id: 'account.block', defaultMessage: 'Block @{name}' },
+  mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' },
+  report: { id: 'account.report', defaultMessage: 'Report @{name}' },
+  share: { id: 'account.share', defaultMessage: 'Share @{name}\'s profile' },
+  media: { id: 'account.media', defaultMessage: 'Media' },
+  blockDomain: { id: 'account.block_domain', defaultMessage: 'Hide everything from {domain}' },
+  unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' },
+  hideReblogs: { id: 'account.hide_reblogs', defaultMessage: 'Hide boosts from @{name}' },
+  showReblogs: { id: 'account.show_reblogs', defaultMessage: 'Show boosts from @{name}' },
+  pins: { id: 'navigation_bar.pins', defaultMessage: 'Pinned toots' },
+  preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
+  follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' },
+  favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' },
+  lists: { id: 'navigation_bar.lists', defaultMessage: 'Lists' },
+  blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
+  domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Hidden domains' },
+  mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
+  endorse: { id: 'account.endorse', defaultMessage: 'Feature on profile' },
+  unendorse: { id: 'account.unendorse', defaultMessage: 'Don\'t feature on profile' },
+  add_or_remove_from_list: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists' },
+  admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
 });
 
 const dateFormatOptions = {
@@ -28,120 +56,107 @@ const dateFormatOptions = {
   minute: '2-digit',
 };
 
-class Avatar extends ImmutablePureComponent {
+export default @injectIntl
+class Header extends ImmutablePureComponent {
 
   static propTypes = {
-    account: ImmutablePropTypes.map.isRequired,
-  };
-
-  state = {
-    isHovered: false,
+    account: ImmutablePropTypes.map,
+    identity_props: ImmutablePropTypes.list,
+    onFollow: PropTypes.func.isRequired,
+    onBlock: PropTypes.func.isRequired,
+    intl: PropTypes.object.isRequired,
+    domain: PropTypes.string.isRequired,
   };
 
-  handleMouseOver = () => {
-    if (this.state.isHovered) return;
-    this.setState({ isHovered: true });
+  openEditProfile = () => {
+    window.open('/settings/profile', '_blank');
   }
 
-  handleMouseOut = () => {
-    if (!this.state.isHovered) return;
-    this.setState({ isHovered: false });
+  isStatusesPageActive = (match, location) => {
+    if (!match) {
+      return false;
+    }
+
+    return !location.pathname.match(/\/(followers|following)\/?$/);
   }
 
-  render () {
-    const { account }   = this.props;
-    const { isHovered } = this.state;
+  _updateEmojis () {
+    const node = this.node;
 
-    return (
-      <Motion defaultStyle={{ radius: 90 }} style={{ radius: spring(isHovered ? 30 : 90, { stiffness: 180, damping: 12 }) }}>
-        {({ radius }) => (
-          <a
-            href={account.get('url')}
-            className='account__header__avatar'
-            role='presentation'
-            target='_blank'
-            rel='noopener'
-            style={{ borderRadius: `${radius}px`, backgroundImage: `url(${autoPlayGif || isHovered ? account.get('avatar') : account.get('avatar_static')})` }}
-            onMouseOver={this.handleMouseOver}
-            onMouseOut={this.handleMouseOut}
-            onFocus={this.handleMouseOver}
-            onBlur={this.handleMouseOut}
-          >
-            <span style={{ display: 'none' }}>{account.get('acct')}</span>
-          </a>
-        )}
-      </Motion>
-    );
+    if (!node || autoPlayGif) {
+      return;
+    }
+
+    const emojis = node.querySelectorAll('.custom-emoji');
+
+    for (var i = 0; i < emojis.length; i++) {
+      let emoji = emojis[i];
+      if (emoji.classList.contains('status-emoji')) {
+        continue;
+      }
+      emoji.classList.add('status-emoji');
+
+      emoji.addEventListener('mouseenter', this.handleEmojiMouseEnter, false);
+      emoji.addEventListener('mouseleave', this.handleEmojiMouseLeave, false);
+    }
   }
 
-}
+  componentDidMount () {
+    this._updateEmojis();
+  }
 
-export default @injectIntl
-class Header extends ImmutablePureComponent {
+  componentDidUpdate () {
+    this._updateEmojis();
+  }
 
-  static propTypes = {
-    account: ImmutablePropTypes.map,
-    onFollow: PropTypes.func.isRequired,
-    onBlock: PropTypes.func.isRequired,
-    intl: PropTypes.object.isRequired,
-  };
+  handleEmojiMouseEnter = ({ target }) => {
+    target.src = target.getAttribute('data-original');
+  }
 
-  openEditProfile = () => {
-    window.open('/settings/profile', '_blank');
+  handleEmojiMouseLeave = ({ target }) => {
+    target.src = target.getAttribute('data-static');
+  }
+
+  setRef = (c) => {
+    this.node = c;
   }
 
   render () {
-    const { account, intl } = this.props;
+    const { account, intl, domain, identity_proofs } = this.props;
 
     if (!account) {
       return null;
     }
 
-    let info        = '';
-    let mutingInfo  = '';
+    let info        = [];
     let actionBtn   = '';
     let lockedIcon  = '';
+    let menu        = [];
 
     if (me !== account.get('id') && account.getIn(['relationship', 'followed_by'])) {
-      info = <span className='account--follows-info'><FormattedMessage id='account.follows_you' defaultMessage='Follows you' /></span>;
+      info.push(<span key='followed_by' className='relationship-tag'><FormattedMessage id='account.follows_you' defaultMessage='Follows you' /></span>);
     } else if (me !== account.get('id') && account.getIn(['relationship', 'blocking'])) {
-      info = <span className='account--follows-info'><FormattedMessage id='account.blocked' defaultMessage='Blocked' /></span>;
+      info.push(<span key='blocked' className='relationship-tag'><FormattedMessage id='account.blocked' defaultMessage='Blocked' /></span>);
     }
 
     if (me !== account.get('id') && account.getIn(['relationship', 'muting'])) {
-      mutingInfo = <span className='account--muting-info'><FormattedMessage id='account.muted' defaultMessage='Muted' /></span>;
+      info.push(<span key='muted' className='relationship-tag'><FormattedMessage id='account.muted' defaultMessage='Muted' /></span>);
     } else if (me !== account.get('id') && account.getIn(['relationship', 'domain_blocking'])) {
-      mutingInfo = <span className='account--muting-info'><FormattedMessage id='account.domain_blocked' defaultMessage='Domain hidden' /></span>;
+      info.push(<span key='domain_blocked' className='relationship-tag'><FormattedMessage id='account.domain_blocked' defaultMessage='Domain hidden' /></span>);
     }
 
     if (me !== account.get('id')) {
       if (!account.get('relationship')) { // Wait until the relationship is loaded
         actionBtn = '';
       } else if (account.getIn(['relationship', 'requested'])) {
-        actionBtn = (
-          <div className='account--action-button'>
-            <IconButton size={26} active icon='hourglass' title={intl.formatMessage(messages.requested)} onClick={this.props.onFollow} />
-          </div>
-        );
+        actionBtn = <Button className='logo-button' text={intl.formatMessage(messages.cancel_follow_request)} title={intl.formatMessage(messages.requested)} onClick={this.props.onFollow} />;
       } else if (!account.getIn(['relationship', 'blocking'])) {
-        actionBtn = (
-          <div className='account--action-button'>
-            <IconButton size={26} icon={account.getIn(['relationship', 'following']) ? 'user-times' : 'user-plus'} active={account.getIn(['relationship', 'following'])} title={intl.formatMessage(account.getIn(['relationship', 'following']) ? messages.unfollow : messages.follow)} onClick={this.props.onFollow} />
-          </div>
-        );
+        actionBtn = <Button disabled={account.getIn(['relationship', 'blocked_by'])} className={classNames('logo-button', { 'button--destructive': account.getIn(['relationship', 'following']) })} text={intl.formatMessage(account.getIn(['relationship', 'following']) ? messages.unfollow : messages.follow)} onClick={this.props.onFollow} />;
       } else if (account.getIn(['relationship', 'blocking'])) {
-        actionBtn = (
-          <div className='account--action-button'>
-            <IconButton size={26} icon='unlock-alt' title={intl.formatMessage(messages.unblock, { name: account.get('username') })} onClick={this.props.onBlock} />
-          </div>
-        );
+        actionBtn = <Button className='logo-button' text={intl.formatMessage(messages.unblock, { name: account.get('username') })} onClick={this.props.onBlock} />;
       }
     } else {
-      actionBtn = (
-        <div className='account--action-button'>
-          <IconButton size={26} icon='pencil' title={intl.formatMessage(messages.edit_profile)} onClick={this.openEditProfile} />
-        </div>
-      );
+      actionBtn = <Button className='logo-button' text={intl.formatMessage(messages.edit_profile)} onClick={this.openEditProfile} />;
     }
 
     if (account.get('moved') && !account.getIn(['relationship', 'following'])) {
@@ -149,43 +164,160 @@ class Header extends ImmutablePureComponent {
     }
 
     if (account.get('locked')) {
-      lockedIcon = <i className='fa fa-lock' title={intl.formatMessage(messages.account_locked)} />;
+      lockedIcon = <Icon id='lock' title={intl.formatMessage(messages.account_locked)} />;
+    }
+
+    if (account.get('id') !== me) {
+      menu.push({ text: intl.formatMessage(messages.mention, { name: account.get('username') }), action: this.props.onMention });
+      menu.push({ text: intl.formatMessage(messages.direct, { name: account.get('username') }), action: this.props.onDirect });
+      menu.push(null);
+    }
+
+    if ('share' in navigator) {
+      menu.push({ text: intl.formatMessage(messages.share, { name: account.get('username') }), action: this.handleShare });
+      menu.push(null);
+    }
+
+    if (account.get('id') === me) {
+      menu.push({ text: intl.formatMessage(messages.edit_profile), href: '/settings/profile' });
+      menu.push({ text: intl.formatMessage(messages.preferences), href: '/settings/preferences' });
+      menu.push({ text: intl.formatMessage(messages.pins), to: '/pinned' });
+      menu.push(null);
+      menu.push({ text: intl.formatMessage(messages.follow_requests), to: '/follow_requests' });
+      menu.push({ text: intl.formatMessage(messages.favourites), to: '/favourites' });
+      menu.push({ text: intl.formatMessage(messages.lists), to: '/lists' });
+      menu.push(null);
+      menu.push({ text: intl.formatMessage(messages.mutes), to: '/mutes' });
+      menu.push({ text: intl.formatMessage(messages.blocks), to: '/blocks' });
+      menu.push({ text: intl.formatMessage(messages.domain_blocks), to: '/domain_blocks' });
+    } else {
+      if (account.getIn(['relationship', 'following'])) {
+        if (account.getIn(['relationship', 'showing_reblogs'])) {
+          menu.push({ text: intl.formatMessage(messages.hideReblogs, { name: account.get('username') }), action: this.props.onReblogToggle });
+        } else {
+          menu.push({ text: intl.formatMessage(messages.showReblogs, { name: account.get('username') }), action: this.props.onReblogToggle });
+        }
+
+        menu.push({ text: intl.formatMessage(account.getIn(['relationship', 'endorsed']) ? messages.unendorse : messages.endorse), action: this.props.onEndorseToggle });
+        menu.push({ text: intl.formatMessage(messages.add_or_remove_from_list), action: this.props.onAddToList });
+        menu.push(null);
+      }
+
+      if (account.getIn(['relationship', 'muting'])) {
+        menu.push({ text: intl.formatMessage(messages.unmute, { name: account.get('username') }), action: this.props.onMute });
+      } else {
+        menu.push({ text: intl.formatMessage(messages.mute, { name: account.get('username') }), action: this.props.onMute });
+      }
+
+      if (account.getIn(['relationship', 'blocking'])) {
+        menu.push({ text: intl.formatMessage(messages.unblock, { name: account.get('username') }), action: this.props.onBlock });
+      } else {
+        menu.push({ text: intl.formatMessage(messages.block, { name: account.get('username') }), action: this.props.onBlock });
+      }
+
+      menu.push({ text: intl.formatMessage(messages.report, { name: account.get('username') }), action: this.props.onReport });
+    }
+
+    if (account.get('acct') !== account.get('username')) {
+      const domain = account.get('acct').split('@')[1];
+
+      menu.push(null);
+
+      if (account.getIn(['relationship', 'domain_blocking'])) {
+        menu.push({ text: intl.formatMessage(messages.unblockDomain, { domain }), action: this.props.onUnblockDomain });
+      } else {
+        menu.push({ text: intl.formatMessage(messages.blockDomain, { domain }), action: this.props.onBlockDomain });
+      }
+    }
+
+    if (account.get('id') !== me && isStaff) {
+      menu.push(null);
+      menu.push({ text: intl.formatMessage(messages.admin_account, { name: account.get('username') }), href: `/admin/accounts/${account.get('id')}` });
     }
 
     const content         = { __html: account.get('note_emojified') };
     const displayNameHtml = { __html: account.get('display_name_html') };
     const fields          = account.get('fields');
-    const badge           = account.get('bot') ? (<div className='roles'><div className='account-role bot'><FormattedMessage id='account.badges.bot' defaultMessage='Bot' /></div></div>) : null;
+    const badge           = account.get('bot') ? (<div className='account-role bot'><FormattedMessage id='account.badges.bot' defaultMessage='Bot' /></div>) : null;
+    const acct            = account.get('acct').indexOf('@') === -1 && domain ? `${account.get('acct')}@${domain}` : account.get('acct');
 
     return (
-      <div className={classNames('account__header', { inactive: !!account.get('moved') })} style={{ backgroundImage: `url(${autoPlayGif ? account.get('header') : account.get('header_static')})` }}>
-        <div>
-          <Avatar account={account} />
+      <div className={classNames('account__header', { inactive: !!account.get('moved') })} ref={this.setRef}>
+        <div className='account__header__image'>
+          <div className='account__header__info'>
+            {info}
+          </div>
 
-          <span className='account__header__display-name' dangerouslySetInnerHTML={displayNameHtml} />
-          <span className='account__header__username'>@{account.get('acct')} {lockedIcon}</span>
+          <img src={autoPlayGif ? account.get('header') : account.get('header_static')} alt='' className='parallax' />
+        </div>
 
-          {badge}
+        <div className='account__header__bar'>
+          <div className='account__header__tabs'>
+            <a className='avatar' href={account.get('url')} rel='noopener' target='_blank'>
+              <Avatar account={account} size={90} />
+            </a>
 
-          <div className='account__header__content' dangerouslySetInnerHTML={content} />
+            <div className='spacer' />
 
-          {fields.size > 0 && (
-            <div className='account__header__fields'>
-              {fields.map((pair, i) => (
-                <dl key={i}>
-                  <dt dangerouslySetInnerHTML={{ __html: pair.get('name_emojified') }} title={pair.get('name')} />
+            <div className='account__header__tabs__buttons'>
+              {actionBtn}
 
-                  <dd className={pair.get('verified_at') && 'verified'} title={pair.get('value_plain')}>
-                    {pair.get('verified_at') && <span title={intl.formatMessage(messages.linkVerifiedOn, { date: intl.formatDate(pair.get('verified_at'), dateFormatOptions) })}><i className='fa fa-check verified__mark' /></span>} <span dangerouslySetInnerHTML={{ __html: pair.get('value_emojified') }} />
-                  </dd>
-                </dl>
-              ))}
+              <DropdownMenuContainer items={menu} icon='ellipsis-v' size={24} direction='right' />
             </div>
-          )}
+          </div>
+
+          <div className='account__header__tabs__name'>
+            <h1>
+              <span dangerouslySetInnerHTML={displayNameHtml} /> {badge}
+              <small>@{acct} {lockedIcon}</small>
+            </h1>
+          </div>
 
-          {info}
-          {mutingInfo}
-          {actionBtn}
+          <div className='account__header__extra'>
+            <div className='account__header__bio'>
+              { (fields.size > 0 || identity_proofs.size > 0) && (
+                <div className='account__header__fields'>
+                  {identity_proofs.map((proof, i) => (
+                    <dl key={i}>
+                      <dt dangerouslySetInnerHTML={{ __html: proof.get('provider') }} />
+
+                      <dd className='verified'>
+                        <a href={proof.get('proof_url')} target='_blank' rel='noopener'><span title={intl.formatMessage(messages.linkVerifiedOn, { date: intl.formatDate(proof.get('updated_at'), dateFormatOptions) })}>
+                          <Icon id='check' className='verified__mark' />
+                        </span></a>
+                        <a href={proof.get('profile_url')} target='_blank' rel='noopener'><span dangerouslySetInnerHTML={{ __html: ' '+proof.get('provider_username') }} /></a>
+                      </dd>
+                    </dl>
+                  ))}
+                  {fields.map((pair, i) => (
+                    <dl key={i}>
+                      <dt dangerouslySetInnerHTML={{ __html: pair.get('name_emojified') }} title={pair.get('name')} />
+
+                      <dd className={pair.get('verified_at') && 'verified'} title={pair.get('value_plain')}>
+                        {pair.get('verified_at') && <span title={intl.formatMessage(messages.linkVerifiedOn, { date: intl.formatDate(pair.get('verified_at'), dateFormatOptions) })}><Icon id='check' className='verified__mark' /></span>} <span dangerouslySetInnerHTML={{ __html: pair.get('value_emojified') }} />
+                      </dd>
+                    </dl>
+                  ))}
+                </div>
+              )}
+
+              {account.get('note').length > 0 && account.get('note') !== '<p></p>' && <div className='account__header__content' dangerouslySetInnerHTML={content} />}
+            </div>
+
+            <div className='account__header__extra__links'>
+              <NavLink isActive={this.isStatusesPageActive} activeClassName='active' to={`/accounts/${account.get('id')}`} title={intl.formatNumber(account.get('statuses_count'))}>
+                <strong>{shortNumberFormat(account.get('statuses_count'))}</strong> <FormattedMessage id='account.posts' defaultMessage='Toots' />
+              </NavLink>
+
+              <NavLink exact activeClassName='active' to={`/accounts/${account.get('id')}/following`} title={intl.formatNumber(account.get('following_count'))}>
+                <strong>{shortNumberFormat(account.get('following_count'))}</strong> <FormattedMessage id='account.follows' defaultMessage='Follows' />
+              </NavLink>
+
+              <NavLink exact activeClassName='active' to={`/accounts/${account.get('id')}/followers`} title={intl.formatNumber(account.get('followers_count'))}>
+                <strong>{shortNumberFormat(account.get('followers_count'))}</strong> <FormattedMessage id='account.followers' defaultMessage='Followers' />
+              </NavLink>
+            </div>
+          </div>
         </div>
       </div>
     );
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 7c330c4303b6f150656c50fb542c95e3f7ed8826..2609b96ffca1b362b6741e6acea73073e57ef7b8 100644
--- a/app/javascript/mastodon/features/account_gallery/components/media_item.js
+++ b/app/javascript/mastodon/features/account_gallery/components/media_item.js
@@ -1,61 +1,154 @@
 import React from 'react';
+import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import ImmutablePureComponent from 'react-immutable-pure-component';
-import Permalink from '../../../components/permalink';
-import { displayMedia } from '../../../initial_state';
+import Icon from 'mastodon/components/icon';
+import { autoPlayGif, displayMedia } from 'mastodon/initial_state';
+import classNames from 'classnames';
+import { decode } from 'blurhash';
+import { isIOS } from 'mastodon/is_mobile';
 
 export default class MediaItem extends ImmutablePureComponent {
 
   static propTypes = {
-    media: ImmutablePropTypes.map.isRequired,
+    attachment: ImmutablePropTypes.map.isRequired,
+    displayWidth: PropTypes.number.isRequired,
+    onOpenMedia: PropTypes.func.isRequired,
   };
 
   state = {
-    visible: displayMedia !== 'hide_all' && !this.props.media.getIn(['status', 'sensitive']) || displayMedia === 'show_all',
+    visible: displayMedia !== 'hide_all' && !this.props.attachment.getIn(['status', 'sensitive']) || displayMedia === 'show_all',
+    loaded: false,
   };
 
-  handleClick = () => {
-    if (!this.state.visible) {
-      this.setState({ visible: true });
-      return true;
+  componentDidMount () {
+    if (this.props.attachment.get('blurhash')) {
+      this._decode();
     }
+  }
+
+  componentDidUpdate (prevProps) {
+    if (prevProps.attachment.get('blurhash') !== this.props.attachment.get('blurhash') && this.props.attachment.get('blurhash')) {
+      this._decode();
+    }
+  }
 
-    return false;
+  _decode () {
+    const hash   = this.props.attachment.get('blurhash');
+    const pixels = decode(hash, 32, 32);
+
+    if (pixels) {
+      const ctx       = this.canvas.getContext('2d');
+      const imageData = new ImageData(pixels, 32, 32);
+
+      ctx.putImageData(imageData, 0, 0);
+    }
+  }
+
+  setCanvasRef = c => {
+    this.canvas = c;
+  }
+
+  handleImageLoad = () => {
+    this.setState({ loaded: true });
+  }
+
+  handleMouseEnter = e => {
+    if (this.hoverToPlay()) {
+      e.target.play();
+    }
+  }
+
+  handleMouseLeave = e => {
+    if (this.hoverToPlay()) {
+      e.target.pause();
+      e.target.currentTime = 0;
+    }
+  }
+
+  hoverToPlay () {
+    return !autoPlayGif && ['gifv', 'video'].indexOf(this.props.attachment.get('type')) !== -1;
+  }
+
+  handleClick = e => {
+    if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
+      e.preventDefault();
+
+      if (this.state.visible) {
+        this.props.onOpenMedia(this.props.attachment);
+      } else {
+        this.setState({ visible: true });
+      }
+    }
   }
 
   render () {
-    const { media } = this.props;
-    const { visible } = this.state;
-    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 = {};
+    const { attachment, displayWidth } = this.props;
+    const { visible, loaded } = this.state;
+
+    const width  = `${Math.floor((displayWidth - 4) / 3) - 4}px`;
+    const height = width;
+    const status = attachment.get('status');
+    const title = status.get('spoiler_text') || attachment.get('description');
 
-    let label, icon;
+    let thumbnail = '';
+    let icon;
 
-    if (media.get('type') === 'gifv') {
-      label = <span className='media-gallery__gifv__label'>GIF</span>;
+    if (attachment.get('type') === 'unknown') {
+      // Skip
+    } else if (attachment.get('type') === 'image') {
+      const focusX = attachment.getIn(['meta', 'focus', 'x']) || 0;
+      const focusY = attachment.getIn(['meta', 'focus', 'y']) || 0;
+      const x      = ((focusX /  2) + .5) * 100;
+      const y      = ((focusY / -2) + .5) * 100;
+
+      thumbnail = (
+        <img
+          src={attachment.get('preview_url')}
+          alt={attachment.get('description')}
+          title={attachment.get('description')}
+          style={{ objectPosition: `${x}% ${y}%` }}
+          onLoad={this.handleImageLoad}
+        />
+      );
+    } else if (['gifv', 'video'].indexOf(attachment.get('type')) !== -1) {
+      const autoPlay = !isIOS() && autoPlayGif;
+
+      thumbnail = (
+        <div className={classNames('media-gallery__gifv', { autoplay: autoPlay })}>
+          <video
+            className='media-gallery__item-gifv-thumbnail'
+            aria-label={attachment.get('description')}
+            title={attachment.get('description')}
+            role='application'
+            src={attachment.get('url')}
+            onMouseEnter={this.handleMouseEnter}
+            onMouseLeave={this.handleMouseLeave}
+            autoPlay={autoPlay}
+            loop
+            muted
+          />
+
+          <span className='media-gallery__gifv__label'>GIF</span>
+        </div>
+      );
     }
 
-    if (visible) {
-      style.backgroundImage    = `url(${media.get('preview_url')})`;
-      style.backgroundPosition = `${x}% ${y}%`;
-    } else {
+    if (!visible) {
       icon = (
         <span className='account-gallery__item__icons'>
-          <i className='fa fa-eye-slash' />
+          <Icon id='eye-slash' />
         </span>
       );
     }
 
     return (
-      <div className='account-gallery__item'>
-        <Permalink to={`/statuses/${status.get('id')}`} href={status.get('url')} style={style} onInterceptClick={this.handleClick}>
-          {icon}
-          {label}
-        </Permalink>
+      <div className='account-gallery__item' style={{ width, height }}>
+        <a className='media-gallery__item-thumbnail' href={status.get('url')} target='_blank' onClick={this.handleClick} title={title}>
+          <canvas width={32} height={32} ref={this.setCanvasRef} className={classNames('media-gallery__preview', { 'media-gallery__preview--hidden': visible && loaded })} />
+          {visible && thumbnail}
+          {!visible && icon}
+        </a>
       </div>
     );
   }
diff --git a/app/javascript/mastodon/features/account_gallery/index.js b/app/javascript/mastodon/features/account_gallery/index.js
index 96051818b89665cb45873e728913b97dd38f7629..5d6a53e18eb9b6f39bfc5b41ef506ca6e5c458d4 100644
--- a/app/javascript/mastodon/features/account_gallery/index.js
+++ b/app/javascript/mastodon/features/account_gallery/index.js
@@ -2,22 +2,25 @@ import React from 'react';
 import { connect } from 'react-redux';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import PropTypes from 'prop-types';
-import { fetchAccount } from '../../actions/accounts';
+import { fetchAccount } from 'mastodon/actions/accounts';
 import { expandAccountMediaTimeline } from '../../actions/timelines';
-import LoadingIndicator from '../../components/loading_indicator';
+import LoadingIndicator from 'mastodon/components/loading_indicator';
 import Column from '../ui/components/column';
-import ColumnBackButton from '../../components/column_back_button';
+import ColumnBackButton from 'mastodon/components/column_back_button';
 import ImmutablePureComponent from 'react-immutable-pure-component';
-import { getAccountGallery } from '../../selectors';
+import { getAccountGallery } from 'mastodon/selectors';
 import MediaItem from './components/media_item';
 import HeaderContainer from '../account_timeline/containers/header_container';
 import { ScrollContainer } from 'react-router-scroll-4';
-import LoadMore from '../../components/load_more';
+import LoadMore from 'mastodon/components/load_more';
+import MissingIndicator from 'mastodon/components/missing_indicator';
+import { openModal } from 'mastodon/actions/modal';
 
 const mapStateToProps = (state, props) => ({
-  medias: getAccountGallery(state, props.params.accountId),
+  isAccount: !!state.getIn(['accounts', props.params.accountId]),
+  attachments: getAccountGallery(state, props.params.accountId),
   isLoading: state.getIn(['timelines', `account:${props.params.accountId}:media`, 'isLoading']),
-  hasMore:   state.getIn(['timelines', `account:${props.params.accountId}:media`, 'hasMore']),
+  hasMore: state.getIn(['timelines', `account:${props.params.accountId}:media`, 'hasMore']),
 });
 
 class LoadMoreMedia extends ImmutablePureComponent {
@@ -49,9 +52,14 @@ class AccountGallery extends ImmutablePureComponent {
   static propTypes = {
     params: PropTypes.object.isRequired,
     dispatch: PropTypes.func.isRequired,
-    medias: ImmutablePropTypes.list.isRequired,
+    attachments: ImmutablePropTypes.list.isRequired,
     isLoading: PropTypes.bool,
     hasMore: PropTypes.bool,
+    isAccount: PropTypes.bool,
+  };
+
+  state = {
+    width: 323,
   };
 
   componentDidMount () {
@@ -68,11 +76,11 @@ class AccountGallery extends ImmutablePureComponent {
 
   handleScrollToBottom = () => {
     if (this.props.hasMore) {
-      this.handleLoadMore(this.props.medias.size > 0 ? this.props.medias.last().getIn(['status', 'id']) : undefined);
+      this.handleLoadMore(this.props.attachments.size > 0 ? this.props.attachments.last().getIn(['status', 'id']) : undefined);
     }
   }
 
-  handleScroll = (e) => {
+  handleScroll = e => {
     const { scrollTop, scrollHeight, clientHeight } = e.target;
     const offset = scrollHeight - scrollTop - clientHeight;
 
@@ -85,17 +93,41 @@ class AccountGallery extends ImmutablePureComponent {
     this.props.dispatch(expandAccountMediaTimeline(this.props.params.accountId, { maxId }));
   };
 
-  handleLoadOlder = (e) => {
+  handleLoadOlder = e => {
     e.preventDefault();
     this.handleScrollToBottom();
   }
 
+  handleOpenMedia = attachment => {
+    if (attachment.get('type') === 'video') {
+      this.props.dispatch(openModal('VIDEO', { media: attachment, status: attachment.get('status') }));
+    } else {
+      const media = attachment.getIn(['status', 'media_attachments']);
+      const index = media.findIndex(x => x.get('id') === attachment.get('id'));
+
+      this.props.dispatch(openModal('MEDIA', { media, index, status: attachment.get('status') }));
+    }
+  }
+
+  handleRef = c => {
+    if (c) {
+      this.setState({ width: c.offsetWidth });
+    }
+  }
+
   render () {
-    const { medias, shouldUpdateScroll, isLoading, hasMore } = this.props;
+    const { attachments, shouldUpdateScroll, isLoading, hasMore, isAccount } = this.props;
+    const { width } = this.state;
 
-    let loadOlder = null;
+    if (!isAccount) {
+      return (
+        <Column>
+          <MissingIndicator />
+        </Column>
+      );
+    }
 
-    if (!medias && isLoading) {
+    if (!attachments && isLoading) {
       return (
         <Column>
           <LoadingIndicator />
@@ -103,7 +135,9 @@ class AccountGallery extends ImmutablePureComponent {
       );
     }
 
-    if (hasMore && !(isLoading && medias.size === 0)) {
+    let loadOlder = null;
+
+    if (hasMore && !(isLoading && attachments.size === 0)) {
       loadOlder = <LoadMore visible={!isLoading} onClick={this.handleLoadOlder} />;
     }
 
@@ -115,23 +149,17 @@ class AccountGallery extends ImmutablePureComponent {
           <div className='scrollable scrollable--flex' onScroll={this.handleScroll}>
             <HeaderContainer accountId={this.props.params.accountId} />
 
-            <div role='feed' className='account-gallery__container'>
-              {medias.map((media, index) => media === null ? (
-                <LoadMoreMedia
-                  key={'more:' + medias.getIn(index + 1, 'id')}
-                  maxId={index > 0 ? medias.getIn(index - 1, 'id') : null}
-                  onLoadMore={this.handleLoadMore}
-                />
+            <div role='feed' className='account-gallery__container' ref={this.handleRef}>
+              {attachments.map((attachment, index) => attachment === null ? (
+                <LoadMoreMedia key={'more:' + attachments.getIn(index + 1, 'id')} maxId={index > 0 ? attachments.getIn(index - 1, 'id') : null} onLoadMore={this.handleLoadMore} />
               ) : (
-                <MediaItem
-                  key={media.get('id')}
-                  media={media}
-                />
+                <MediaItem key={attachment.get('id')} attachment={attachment} displayWidth={width} onOpenMedia={this.handleOpenMedia} />
               ))}
+
               {loadOlder}
             </div>
 
-            {isLoading && medias.size === 0 && (
+            {isLoading && attachments.size === 0 && (
               <div className='scrollable__append'>
                 <LoadingIndicator />
               </div>
diff --git a/app/javascript/mastodon/features/account_timeline/components/header.js b/app/javascript/mastodon/features/account_timeline/components/header.js
index 779e116e04d79b50b7fbdcdc2e84d49632398c78..844b8a236a89e555072786163da4c9f9e2010f1b 100644
--- a/app/javascript/mastodon/features/account_timeline/components/header.js
+++ b/app/javascript/mastodon/features/account_timeline/components/header.js
@@ -2,8 +2,6 @@ import React from 'react';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import PropTypes from 'prop-types';
 import InnerHeader from '../../account/components/header';
-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';
@@ -13,6 +11,7 @@ export default class Header extends ImmutablePureComponent {
 
   static propTypes = {
     account: ImmutablePropTypes.map,
+    identity_proofs: ImmutablePropTypes.list,
     onFollow: PropTypes.func.isRequired,
     onBlock: PropTypes.func.isRequired,
     onMention: PropTypes.func.isRequired,
@@ -25,6 +24,7 @@ export default class Header extends ImmutablePureComponent {
     onEndorseToggle: PropTypes.func.isRequired,
     onAddToList: PropTypes.func.isRequired,
     hideTabs: PropTypes.bool,
+    domain: PropTypes.string.isRequired,
   };
 
   static contextTypes = {
@@ -84,10 +84,10 @@ export default class Header extends ImmutablePureComponent {
   }
 
   render () {
-    const { account, hideTabs } = this.props;
+    const { account, hideTabs, identity_proofs } = this.props;
 
     if (account === null) {
-      return <MissingIndicator />;
+      return null;
     }
 
     return (
@@ -96,13 +96,9 @@ export default class Header extends ImmutablePureComponent {
 
         <InnerHeader
           account={account}
+          identity_proofs={identity_proofs}
           onFollow={this.handleFollow}
           onBlock={this.handleBlock}
-        />
-
-        <ActionBar
-          account={account}
-          onBlock={this.handleBlock}
           onMention={this.handleMention}
           onDirect={this.handleDirect}
           onReblogToggle={this.handleReblogToggle}
@@ -112,6 +108,7 @@ export default class Header extends ImmutablePureComponent {
           onUnblockDomain={this.handleUnblockDomain}
           onEndorseToggle={this.handleEndorseToggle}
           onAddToList={this.handleAddToList}
+          domain={this.props.domain}
         />
 
         {!hideTabs && (
diff --git a/app/javascript/mastodon/features/account_timeline/components/moved_note.js b/app/javascript/mastodon/features/account_timeline/components/moved_note.js
index 280389bba903fea6ef73acd06870079e9e80f80c..3e090bb5f2b53ecf5cec7c8cd9b013126c07bb86 100644
--- a/app/javascript/mastodon/features/account_timeline/components/moved_note.js
+++ b/app/javascript/mastodon/features/account_timeline/components/moved_note.js
@@ -5,6 +5,7 @@ import { FormattedMessage } from 'react-intl';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import AvatarOverlay from '../../../components/avatar_overlay';
 import DisplayName from '../../../components/display_name';
+import Icon from 'mastodon/components/icon';
 
 export default class MovedNote extends ImmutablePureComponent {
 
@@ -33,7 +34,7 @@ export default class MovedNote extends ImmutablePureComponent {
     return (
       <div className='account__moved-note'>
         <div className='account__moved-note__message'>
-          <div className='account__moved-note__icon-wrapper'><i className='fa fa-fw fa-suitcase account__moved-note__icon' /></div>
+          <div className='account__moved-note__icon-wrapper'><Icon id='suitcase' className='account__moved-note__icon' fixedWidth /></div>
           <FormattedMessage id='account.moved_to' defaultMessage='{name} has moved to:' values={{ name: <bdi><strong dangerouslySetInnerHTML={displayNameHtml} /></bdi> }} />
         </div>
 
diff --git a/app/javascript/mastodon/features/account_timeline/containers/header_container.js b/app/javascript/mastodon/features/account_timeline/containers/header_container.js
index 0fd79d036879d7641f257c16601a094fda6f520e..4d4ae6e8243e1024c41cba8375bc4ef3f4f8fb51 100644
--- a/app/javascript/mastodon/features/account_timeline/containers/header_container.js
+++ b/app/javascript/mastodon/features/account_timeline/containers/header_container.js
@@ -21,11 +21,13 @@ import { openModal } from '../../../actions/modal';
 import { blockDomain, unblockDomain } from '../../../actions/domain_blocks';
 import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import { unfollowModal } from '../../../initial_state';
+import { List as ImmutableList } from 'immutable';
 
 const messages = defineMessages({
   unfollowConfirm: { id: 'confirmations.unfollow.confirm', defaultMessage: 'Unfollow' },
   blockConfirm: { id: 'confirmations.block.confirm', defaultMessage: 'Block' },
   blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Hide entire domain' },
+  blockAndReport: { id: 'confirmations.block.block_and_report', defaultMessage: 'Block & Report' },
 });
 
 const makeMapStateToProps = () => {
@@ -33,6 +35,8 @@ const makeMapStateToProps = () => {
 
   const mapStateToProps = (state, { accountId }) => ({
     account: getAccount(state, accountId),
+    domain: state.getIn(['meta', 'domain']),
+    identity_proofs: state.getIn(['identity_proofs', accountId], ImmutableList()),
   });
 
   return mapStateToProps;
@@ -64,6 +68,11 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
         message: <FormattedMessage id='confirmations.block.message' defaultMessage='Are you sure you want to block {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
         confirm: intl.formatMessage(messages.blockConfirm),
         onConfirm: () => dispatch(blockAccount(account.get('id'))),
+        secondary: intl.formatMessage(messages.blockAndReport),
+        onSecondary: () => {
+          dispatch(blockAccount(account.get('id')));
+          dispatch(initReport(account));
+        },
       }));
     }
   },
diff --git a/app/javascript/mastodon/features/account_timeline/index.js b/app/javascript/mastodon/features/account_timeline/index.js
index afc484c607b9e9c663a884a0cd7a331273f95c97..27581bfdc887a3aa3fc63ff69c390568b1e1434a 100644
--- a/app/javascript/mastodon/features/account_timeline/index.js
+++ b/app/javascript/mastodon/features/account_timeline/index.js
@@ -12,15 +12,21 @@ import ColumnBackButton from '../../components/column_back_button';
 import { List as ImmutableList } from 'immutable';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import { FormattedMessage } from 'react-intl';
+import { fetchAccountIdentityProofs } from '../../actions/identity_proofs';
+import MissingIndicator from 'mastodon/components/missing_indicator';
+
+const emptyList = ImmutableList();
 
 const mapStateToProps = (state, { params: { accountId }, withReplies = false }) => {
   const path = withReplies ? `${accountId}:with_replies` : accountId;
 
   return {
-    statusIds: state.getIn(['timelines', `account:${path}`, 'items'], ImmutableList()),
-    featuredStatusIds: withReplies ? ImmutableList() : state.getIn(['timelines', `account:${accountId}:pinned`, 'items'], ImmutableList()),
+    isAccount: !!state.getIn(['accounts', accountId]),
+    statusIds: state.getIn(['timelines', `account:${path}`, 'items'], emptyList),
+    featuredStatusIds: withReplies ? ImmutableList() : state.getIn(['timelines', `account:${accountId}:pinned`, 'items'], emptyList),
     isLoading: state.getIn(['timelines', `account:${path}`, 'isLoading']),
-    hasMore:   state.getIn(['timelines', `account:${path}`, 'hasMore']),
+    hasMore: state.getIn(['timelines', `account:${path}`, 'hasMore']),
+    blockedBy: state.getIn(['relationships', accountId, 'blocked_by'], false),
   };
 };
 
@@ -36,24 +42,32 @@ class AccountTimeline extends ImmutablePureComponent {
     isLoading: PropTypes.bool,
     hasMore: PropTypes.bool,
     withReplies: PropTypes.bool,
+    blockedBy: PropTypes.bool,
+    isAccount: PropTypes.bool,
   };
 
   componentWillMount () {
     const { params: { accountId }, withReplies } = this.props;
 
     this.props.dispatch(fetchAccount(accountId));
+    this.props.dispatch(fetchAccountIdentityProofs(accountId));
+
     if (!withReplies) {
       this.props.dispatch(expandAccountFeaturedTimeline(accountId));
     }
+
     this.props.dispatch(expandAccountTimeline(accountId, { withReplies }));
   }
 
   componentWillReceiveProps (nextProps) {
     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(fetchAccountIdentityProofs(nextProps.params.accountId));
+
       if (!nextProps.withReplies) {
         this.props.dispatch(expandAccountFeaturedTimeline(nextProps.params.accountId));
       }
+
       this.props.dispatch(expandAccountTimeline(nextProps.params.accountId, { withReplies: nextProps.params.withReplies }));
     }
   }
@@ -63,7 +77,15 @@ class AccountTimeline extends ImmutablePureComponent {
   }
 
   render () {
-    const { shouldUpdateScroll, statusIds, featuredStatusIds, isLoading, hasMore } = this.props;
+    const { shouldUpdateScroll, statusIds, featuredStatusIds, isLoading, hasMore, blockedBy, isAccount } = this.props;
+
+    if (!isAccount) {
+      return (
+        <Column>
+          <MissingIndicator />
+        </Column>
+      );
+    }
 
     if (!statusIds && isLoading) {
       return (
@@ -73,6 +95,8 @@ class AccountTimeline extends ImmutablePureComponent {
       );
     }
 
+    const emptyMessage = blockedBy ? <FormattedMessage id='empty_column.account_unavailable' defaultMessage='Profile unavailable' /> : <FormattedMessage id='empty_column.account_timeline' defaultMessage='No toots here!' />;
+
     return (
       <Column>
         <ColumnBackButton />
@@ -81,13 +105,13 @@ class AccountTimeline extends ImmutablePureComponent {
           prepend={<HeaderContainer accountId={this.props.params.accountId} />}
           alwaysPrepend
           scrollKey='account_timeline'
-          statusIds={statusIds}
+          statusIds={blockedBy ? emptyList : statusIds}
           featuredStatusIds={featuredStatusIds}
           isLoading={isLoading}
           hasMore={hasMore}
           onLoadMore={this.handleLoadMore}
           shouldUpdateScroll={shouldUpdateScroll}
-          emptyMessage={<FormattedMessage id='empty_column.account_timeline' defaultMessage='No toots here!' />}
+          emptyMessage={emptyMessage}
         />
       </Column>
     );
diff --git a/app/javascript/mastodon/features/blocks/index.js b/app/javascript/mastodon/features/blocks/index.js
index ca7ce6f8ea395dc8829a5a3e3e11f1fffbcf4c9a..96a219c94720b2d34f635c1305e807aa7c2976eb 100644
--- a/app/javascript/mastodon/features/blocks/index.js
+++ b/app/javascript/mastodon/features/blocks/index.js
@@ -18,6 +18,7 @@ const messages = defineMessages({
 
 const mapStateToProps = state => ({
   accountIds: state.getIn(['user_lists', 'blocks', 'items']),
+  hasMore: !!state.getIn(['user_lists', 'blocks', 'next']),
 });
 
 export default @connect(mapStateToProps)
@@ -29,6 +30,7 @@ class Blocks extends ImmutablePureComponent {
     dispatch: PropTypes.func.isRequired,
     shouldUpdateScroll: PropTypes.func,
     accountIds: ImmutablePropTypes.list,
+    hasMore: PropTypes.bool,
     intl: PropTypes.object.isRequired,
   };
 
@@ -41,7 +43,7 @@ class Blocks extends ImmutablePureComponent {
   }, 300, { leading: true });
 
   render () {
-    const { intl, accountIds, shouldUpdateScroll } = this.props;
+    const { intl, accountIds, shouldUpdateScroll, hasMore } = this.props;
 
     if (!accountIds) {
       return (
@@ -59,6 +61,7 @@ class Blocks extends ImmutablePureComponent {
         <ScrollableList
           scrollKey='blocks'
           onLoadMore={this.handleLoadMore}
+          hasMore={hasMore}
           shouldUpdateScroll={shouldUpdateScroll}
           emptyMessage={emptyMessage}
         >
diff --git a/app/javascript/mastodon/features/compose/components/action_bar.js b/app/javascript/mastodon/features/compose/components/action_bar.js
index 95d6eeb06d03a657e2721ed5666838e960aacd74..d0303dbfbbf9007d0985bcdb16e7931fe19da9f1 100644
--- a/app/javascript/mastodon/features/compose/components/action_bar.js
+++ b/app/javascript/mastodon/features/compose/components/action_bar.js
@@ -15,6 +15,7 @@ const messages = defineMessages({
   domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Hidden domains' },
   mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
   filters: { id: 'navigation_bar.filters', defaultMessage: 'Muted words' },
+  logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
 });
 
 export default @injectIntl
@@ -42,11 +43,13 @@ class ActionBar extends React.PureComponent {
     menu.push({ text: intl.formatMessage(messages.blocks), to: '/blocks' });
     menu.push({ text: intl.formatMessage(messages.domain_blocks), to: '/domain_blocks' });
     menu.push({ text: intl.formatMessage(messages.filters), href: '/filters' });
+    menu.push(null);
+    menu.push({ text: intl.formatMessage(messages.logout), href: '/auth/sign_out', target: null, method: 'delete' });
 
     return (
       <div className='compose__action-bar'>
         <div className='compose__action-bar-dropdown'>
-          <DropdownMenuContainer items={menu} icon='ellipsis-v' size={24} direction='right' />
+          <DropdownMenuContainer items={menu} icon='chevron-down' size={16} direction='right' />
         </div>
       </div>
     );
diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js
index 16ed044024dba0136eb82a789f536d8b73af32b4..672f93cf45cc41cb29d1ffdb96226735432090b8 100644
--- a/app/javascript/mastodon/features/compose/components/compose_form.js
+++ b/app/javascript/mastodon/features/compose/components/compose_form.js
@@ -5,18 +5,21 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
 import PropTypes from 'prop-types';
 import ReplyIndicatorContainer from '../containers/reply_indicator_container';
 import AutosuggestTextarea from '../../../components/autosuggest_textarea';
+import AutosuggestInput from '../../../components/autosuggest_input';
+import PollButtonContainer from '../containers/poll_button_container';
 import UploadButtonContainer from '../containers/upload_button_container';
 import { defineMessages, injectIntl } from 'react-intl';
 import SpoilerButtonContainer from '../containers/spoiler_button_container';
 import PrivacyDropdownContainer from '../containers/privacy_dropdown_container';
-import SensitiveButtonContainer from '../containers/sensitive_button_container';
 import EmojiPickerDropdown from '../containers/emoji_picker_dropdown_container';
+import PollFormContainer from '../containers/poll_form_container';
 import UploadFormContainer from '../containers/upload_form_container';
 import WarningContainer from '../containers/warning_container';
 import { isMobile } from '../../../is_mobile';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import { length } from 'stringz';
 import { countableText } from '../util/counter';
+import Icon from 'mastodon/components/icon';
 
 const allowedAroundShortCode = '><\u0085\u0020\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\u0009\u000a\u000b\u000c\u000d';
 
@@ -37,17 +40,16 @@ class ComposeForm extends ImmutablePureComponent {
   static propTypes = {
     intl: PropTypes.object.isRequired,
     text: PropTypes.string.isRequired,
-    suggestion_token: PropTypes.string,
     suggestions: ImmutablePropTypes.list,
     spoiler: PropTypes.bool,
     privacy: PropTypes.string,
-    spoiler_text: PropTypes.string,
+    spoilerText: PropTypes.string,
     focusDate: PropTypes.instanceOf(Date),
     caretPosition: PropTypes.number,
     preselectDate: PropTypes.instanceOf(Date),
-    is_submitting: PropTypes.bool,
-    is_changing_upload: PropTypes.bool,
-    is_uploading: PropTypes.bool,
+    isSubmitting: PropTypes.bool,
+    isChangingUpload: PropTypes.bool,
+    isUploading: PropTypes.bool,
     onChange: PropTypes.func.isRequired,
     onSubmit: PropTypes.func.isRequired,
     onClearSuggestions: PropTypes.func.isRequired,
@@ -58,6 +60,7 @@ class ComposeForm extends ImmutablePureComponent {
     onPickEmoji: PropTypes.func.isRequired,
     showSearch: PropTypes.bool,
     anyMedia: PropTypes.bool,
+    singleColumn: PropTypes.bool,
   };
 
   static defaultProps = {
@@ -82,10 +85,10 @@ class ComposeForm extends ImmutablePureComponent {
     }
 
     // Submit disabled:
-    const { is_submitting, is_changing_upload, is_uploading, anyMedia } = this.props;
-    const fulltext = [this.props.spoiler_text, countableText(this.props.text)].join('');
+    const { isSubmitting, isChangingUpload, isUploading, anyMedia } = this.props;
+    const fulltext = [this.props.spoilerText, countableText(this.props.text)].join('');
 
-    if (is_submitting || is_uploading || is_changing_upload || length(fulltext) > 65535 || (fulltext.length !== 0 && fulltext.trim().length === 0 && !anyMedia)) {
+    if (isSubmitting || isUploading || isChangingUpload || length(fulltext) > 65535 || (fulltext.length !== 0 && fulltext.trim().length === 0 && !anyMedia)) {
       return;
     }
 
@@ -101,13 +104,26 @@ class ComposeForm extends ImmutablePureComponent {
   }
 
   onSuggestionSelected = (tokenStart, token, value) => {
-    this.props.onSuggestionSelected(tokenStart, token, value);
+    this.props.onSuggestionSelected(tokenStart, token, value, ['text']);
+  }
+
+  onSpoilerSuggestionSelected = (tokenStart, token, value) => {
+    this.props.onSuggestionSelected(tokenStart, token, value, ['spoiler_text']);
   }
 
   handleChangeSpoilerText = (e) => {
     this.props.onChangeSpoilerText(e.target.value);
   }
 
+  handleFocus = () => {
+    if (this.composeForm && !this.props.singleColumn) {
+      const { left, right } = this.composeForm.getBoundingClientRect();
+      if (left < 0 || right > (window.innerWidth || document.documentElement.clientWidth)) {
+        this.composeForm.scrollIntoView();
+      }
+    }
+  }
+
   componentDidUpdate (prevProps) {
     // This statement does several things:
     // - If we're beginning a reply, and,
@@ -130,11 +146,11 @@ class ComposeForm extends ImmutablePureComponent {
 
       this.autosuggestTextarea.textarea.setSelectionRange(selectionStart, selectionEnd);
       this.autosuggestTextarea.textarea.focus();
-    } else if(prevProps.is_submitting && !this.props.is_submitting) {
+    } else if(prevProps.isSubmitting && !this.props.isSubmitting) {
       this.autosuggestTextarea.textarea.focus();
     } else if (this.props.spoiler !== prevProps.spoiler) {
       if (this.props.spoiler) {
-        this.spoilerText.focus();
+        this.spoilerText.input.focus();
       } else {
         this.autosuggestTextarea.textarea.focus();
       }
@@ -149,6 +165,10 @@ class ComposeForm extends ImmutablePureComponent {
     this.spoilerText = c;
   }
 
+  setRef = c => {
+    this.composeForm = c;
+  };
+
   handleEmojiPick = (data) => {
     const { text }     = this.props;
     const position     = this.autosuggestTextarea.textarea.selectionStart;
@@ -159,13 +179,13 @@ class ComposeForm extends ImmutablePureComponent {
 
   render () {
     const { intl, onPaste, showSearch, anyMedia } = this.props;
-    const disabled = this.props.is_submitting;
-    const text     = [this.props.spoiler_text, countableText(this.props.text)].join('');
-    const disabledButton = disabled || this.props.is_uploading || this.props.is_changing_upload || length(text) > 65535 || (text.length !== 0 && text.trim().length === 0 && !anyMedia);
+    const disabled = this.props.isSubmitting;
+    const text     = [this.props.spoilerText, countableText(this.props.text)].join('');
+    const disabledButton = disabled || this.props.isUploading || this.props.isChangingUpload || length(text) > 65535 || (text.length !== 0 && text.trim().length === 0 && !anyMedia);
     let publishText = '';
 
     if (this.props.privacy === 'private' || this.props.privacy === 'direct') {
-      publishText = <span className='compose-form__publish-private'><i className='fa fa-lock' /> {intl.formatMessage(messages.publish)}</span>;
+      publishText = <span className='compose-form__publish-private'><Icon id='lock' /> {intl.formatMessage(messages.publish)}</span>;
     } else {
       publishText = this.props.privacy !== 'unlisted' ? intl.formatMessage(messages.publishLoud, { publish: intl.formatMessage(messages.publish) }) : intl.formatMessage(messages.publish);
     }
@@ -176,41 +196,51 @@ class ComposeForm extends ImmutablePureComponent {
 
         <ReplyIndicatorContainer />
 
-        <div className={`spoiler-input ${this.props.spoiler ? 'spoiler-input--visible' : ''}`}>
-          <label>
-            <span style={{ display: 'none' }}>{intl.formatMessage(messages.spoiler_placeholder)}</span>
-            <input placeholder={intl.formatMessage(messages.spoiler_placeholder)} value={this.props.spoiler_text} onChange={this.handleChangeSpoilerText} onKeyDown={this.handleKeyDown} type='text' className='spoiler-input__input'  id='cw-spoiler-input' ref={this.setSpoilerText} />
-          </label>
-        </div>
-
-        <div className='compose-form__autosuggest-wrapper'>
-          <AutosuggestTextarea
-            ref={this.setAutosuggestTextarea}
-            placeholder={intl.formatMessage(messages.placeholder)}
-            disabled={disabled}
-            value={this.props.text}
-            onChange={this.handleChange}
-            suggestions={this.props.suggestions}
+        <div className={`spoiler-input ${this.props.spoiler ? 'spoiler-input--visible' : ''}`} ref={this.setRef}>
+          <AutosuggestInput
+            placeholder={intl.formatMessage(messages.spoiler_placeholder)}
+            value={this.props.spoilerText}
+            onChange={this.handleChangeSpoilerText}
             onKeyDown={this.handleKeyDown}
+            disabled={!this.props.spoiler}
+            ref={this.setSpoilerText}
+            suggestions={this.props.suggestions}
             onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
             onSuggestionsClearRequested={this.onSuggestionsClearRequested}
-            onSuggestionSelected={this.onSuggestionSelected}
-            onPaste={onPaste}
-            autoFocus={!showSearch && !isMobile(window.innerWidth)}
+            onSuggestionSelected={this.onSpoilerSuggestionSelected}
+            searchTokens={[':']}
+            id='cw-spoiler-input'
+            className='spoiler-input__input'
           />
-
-          <EmojiPickerDropdown onPickEmoji={this.handleEmojiPick} />
         </div>
 
-        <div className='compose-form__modifiers'>
-          <UploadFormContainer />
-        </div>
+        <AutosuggestTextarea
+          ref={this.setAutosuggestTextarea}
+          placeholder={intl.formatMessage(messages.placeholder)}
+          disabled={disabled}
+          value={this.props.text}
+          onChange={this.handleChange}
+          suggestions={this.props.suggestions}
+          onFocus={this.handleFocus}
+          onKeyDown={this.handleKeyDown}
+          onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
+          onSuggestionsClearRequested={this.onSuggestionsClearRequested}
+          onSuggestionSelected={this.onSuggestionSelected}
+          onPaste={onPaste}
+          autoFocus={!showSearch && !isMobile(window.innerWidth)}
+        >
+          <EmojiPickerDropdown onPickEmoji={this.handleEmojiPick} />
+          <div className='compose-form__modifiers'>
+            <UploadFormContainer />
+            <PollFormContainer />
+          </div>
+        </AutosuggestTextarea>
 
         <div className='compose-form__buttons-wrapper'>
           <div className='compose-form__buttons'>
             <UploadButtonContainer />
+            <PollButtonContainer />
             <PrivacyDropdownContainer />
-            <SensitiveButtonContainer />
             <SpoilerButtonContainer />
           </div>
           <div className='character-counter__wrapper'><CharacterCounter max={65535} text={text} /></div>
diff --git a/app/javascript/mastodon/features/compose/components/navigation_bar.js b/app/javascript/mastodon/features/compose/components/navigation_bar.js
index 9910eb4f9fd07aa5c76b2590515cc543ec93cc13..d8d49cb95cd5391409374d165f43b8f73abe1972 100644
--- a/app/javascript/mastodon/features/compose/components/navigation_bar.js
+++ b/app/javascript/mastodon/features/compose/components/navigation_bar.js
@@ -20,7 +20,7 @@ export default class NavigationBar extends ImmutablePureComponent {
       <div className='navigation-bar'>
         <Permalink href={this.props.account.get('url')} to={`/accounts/${this.props.account.get('id')}`}>
           <span style={{ display: 'none' }}>{this.props.account.get('acct')}</span>
-          <Avatar account={this.props.account} size={40} />
+          <Avatar account={this.props.account} size={48} />
         </Permalink>
 
         <div className='navigation-bar__profile'>
diff --git a/app/javascript/mastodon/features/compose/components/poll_button.js b/app/javascript/mastodon/features/compose/components/poll_button.js
new file mode 100644
index 0000000000000000000000000000000000000000..76f96bfa41ef0e3dae4e990c24e78f01ac9529b3
--- /dev/null
+++ b/app/javascript/mastodon/features/compose/components/poll_button.js
@@ -0,0 +1,55 @@
+import React from 'react';
+import IconButton from '../../../components/icon_button';
+import PropTypes from 'prop-types';
+import { defineMessages, injectIntl } from 'react-intl';
+
+const messages = defineMessages({
+  add_poll: { id: 'poll_button.add_poll', defaultMessage: 'Add a poll' },
+  remove_poll: { id: 'poll_button.remove_poll', defaultMessage: 'Remove poll' },
+});
+
+const iconStyle = {
+  height: null,
+  lineHeight: '27px',
+};
+
+export default
+@injectIntl
+class PollButton extends React.PureComponent {
+
+  static propTypes = {
+    disabled: PropTypes.bool,
+    unavailable: PropTypes.bool,
+    active: PropTypes.bool,
+    onClick: PropTypes.func.isRequired,
+    intl: PropTypes.object.isRequired,
+  };
+
+  handleClick = () => {
+    this.props.onClick();
+  }
+
+  render () {
+    const { intl, active, unavailable, disabled } = this.props;
+
+    if (unavailable) {
+      return null;
+    }
+
+    return (
+      <div className='compose-form__poll-button'>
+        <IconButton
+          icon='tasks'
+          title={intl.formatMessage(active ? messages.remove_poll : messages.add_poll)}
+          disabled={disabled}
+          onClick={this.handleClick}
+          className={`compose-form__poll-button-icon ${active ? 'active' : ''}`}
+          size={18}
+          inverted
+          style={iconStyle}
+        />
+      </div>
+    );
+  }
+
+}
diff --git a/app/javascript/mastodon/features/compose/components/poll_form.js b/app/javascript/mastodon/features/compose/components/poll_form.js
new file mode 100644
index 0000000000000000000000000000000000000000..211601d520602fb02a6d1c357138120ed991167e
--- /dev/null
+++ b/app/javascript/mastodon/features/compose/components/poll_form.js
@@ -0,0 +1,163 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
+import IconButton from 'mastodon/components/icon_button';
+import Icon from 'mastodon/components/icon';
+import AutosuggestInput from 'mastodon/components/autosuggest_input';
+import classNames from 'classnames';
+
+const messages = defineMessages({
+  option_placeholder: { id: 'compose_form.poll.option_placeholder', defaultMessage: 'Choice {number}' },
+  add_option: { id: 'compose_form.poll.add_option', defaultMessage: 'Add a choice' },
+  remove_option: { id: 'compose_form.poll.remove_option', defaultMessage: 'Remove this choice' },
+  poll_duration: { id: 'compose_form.poll.duration', defaultMessage: 'Poll duration' },
+  minutes: { id: 'intervals.full.minutes', defaultMessage: '{number, plural, one {# minute} other {# minutes}}' },
+  hours: { id: 'intervals.full.hours', defaultMessage: '{number, plural, one {# hour} other {# hours}}' },
+  days: { id: 'intervals.full.days', defaultMessage: '{number, plural, one {# day} other {# days}}' },
+});
+
+@injectIntl
+class Option extends React.PureComponent {
+
+  static propTypes = {
+    title: PropTypes.string.isRequired,
+    index: PropTypes.number.isRequired,
+    isPollMultiple: PropTypes.bool,
+    onChange: PropTypes.func.isRequired,
+    onRemove: PropTypes.func.isRequired,
+    onToggleMultiple: PropTypes.func.isRequired,
+    suggestions: ImmutablePropTypes.list,
+    onClearSuggestions: PropTypes.func.isRequired,
+    onFetchSuggestions: PropTypes.func.isRequired,
+    onSuggestionSelected: PropTypes.func.isRequired,
+    intl: PropTypes.object.isRequired,
+  };
+
+  handleOptionTitleChange = e => {
+    this.props.onChange(this.props.index, e.target.value);
+  };
+
+  handleOptionRemove = () => {
+    this.props.onRemove(this.props.index);
+  };
+
+
+  handleToggleMultiple = e => {
+    this.props.onToggleMultiple();
+    e.preventDefault();
+    e.stopPropagation();
+  };
+
+  onSuggestionsClearRequested = () => {
+    this.props.onClearSuggestions();
+  }
+
+  onSuggestionsFetchRequested = (token) => {
+    this.props.onFetchSuggestions(token);
+  }
+
+  onSuggestionSelected = (tokenStart, token, value) => {
+    this.props.onSuggestionSelected(tokenStart, token, value, ['poll', 'options', this.props.index]);
+  }
+
+  render () {
+    const { isPollMultiple, title, index, intl } = this.props;
+
+    return (
+      <li>
+        <label className='poll__text editable'>
+          <span
+            className={classNames('poll__input', { checkbox: isPollMultiple })}
+            onClick={this.handleToggleMultiple}
+            role='button'
+            tabIndex='0'
+          />
+
+          <AutosuggestInput
+            placeholder={intl.formatMessage(messages.option_placeholder, { number: index + 1 })}
+            maxLength={25}
+            value={title}
+            onChange={this.handleOptionTitleChange}
+            suggestions={this.props.suggestions}
+            onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
+            onSuggestionsClearRequested={this.onSuggestionsClearRequested}
+            onSuggestionSelected={this.onSuggestionSelected}
+            searchTokens={[':']}
+          />
+        </label>
+
+        <div className='poll__cancel'>
+          <IconButton disabled={index <= 1} title={intl.formatMessage(messages.remove_option)} icon='times' onClick={this.handleOptionRemove} />
+        </div>
+      </li>
+    );
+  }
+
+}
+
+export default
+@injectIntl
+class PollForm extends ImmutablePureComponent {
+
+  static propTypes = {
+    options: ImmutablePropTypes.list,
+    expiresIn: PropTypes.number,
+    isMultiple: PropTypes.bool,
+    onChangeOption: PropTypes.func.isRequired,
+    onAddOption: PropTypes.func.isRequired,
+    onRemoveOption: PropTypes.func.isRequired,
+    onChangeSettings: PropTypes.func.isRequired,
+    suggestions: ImmutablePropTypes.list,
+    onClearSuggestions: PropTypes.func.isRequired,
+    onFetchSuggestions: PropTypes.func.isRequired,
+    onSuggestionSelected: PropTypes.func.isRequired,
+    intl: PropTypes.object.isRequired,
+  };
+
+  handleAddOption = () => {
+    this.props.onAddOption('');
+  };
+
+  handleSelectDuration = e => {
+    this.props.onChangeSettings(e.target.value, this.props.isMultiple);
+  };
+
+  handleToggleMultiple = () => {
+    this.props.onChangeSettings(this.props.expiresIn, !this.props.isMultiple);
+  };
+
+  render () {
+    const { options, expiresIn, isMultiple, onChangeOption, onRemoveOption, intl, ...other } = this.props;
+
+    if (!options) {
+      return null;
+    }
+
+    return (
+      <div className='compose-form__poll-wrapper'>
+        <ul>
+          {options.map((title, i) => <Option title={title} key={i} index={i} onChange={onChangeOption} onRemove={onRemoveOption} isPollMultiple={isMultiple} onToggleMultiple={this.handleToggleMultiple} {...other} />)}
+        </ul>
+
+        <div className='poll__footer'>
+          {options.size < 4 && (
+            <button className='button button-secondary' onClick={this.handleAddOption}><Icon id='plus' /> <FormattedMessage {...messages.add_option} /></button>
+          )}
+
+          <select value={expiresIn} onChange={this.handleSelectDuration}>
+            <option value={300}>{intl.formatMessage(messages.minutes, { number: 5 })}</option>
+            <option value={1800}>{intl.formatMessage(messages.minutes, { number: 30 })}</option>
+            <option value={3600}>{intl.formatMessage(messages.hours, { number: 1 })}</option>
+            <option value={21600}>{intl.formatMessage(messages.hours, { number: 6 })}</option>
+            <option value={86400}>{intl.formatMessage(messages.days, { number: 1 })}</option>
+            <option value={259200}>{intl.formatMessage(messages.days, { number: 3 })}</option>
+            <option value={604800}>{intl.formatMessage(messages.days, { number: 7 })}</option>
+          </select>
+        </div>
+      </div>
+    );
+  }
+
+}
diff --git a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js b/app/javascript/mastodon/features/compose/components/privacy_dropdown.js
index 5698765d94f2b55e54ac9f328f2df6f08235c3dd..7cbfe463add1e278d77522cec57efdef766727d4 100644
--- a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js
+++ b/app/javascript/mastodon/features/compose/components/privacy_dropdown.js
@@ -7,6 +7,7 @@ import Motion from '../../ui/util/optional_motion';
 import spring from 'react-motion/lib/spring';
 import detectPassiveEvents from 'detect-passive-events';
 import classNames from 'classnames';
+import Icon from 'mastodon/components/icon';
 
 const messages = defineMessages({
   public_short: { id: 'privacy.public.short', defaultMessage: 'Public' },
@@ -72,6 +73,19 @@ class PrivacyDropdownMenu extends React.PureComponent {
         this.props.onChange(element.getAttribute('data-index'));
       }
       break;
+    case 'Tab':
+      if (e.shiftKey) {
+        element = this.node.childNodes[index - 1] || this.node.lastChild;
+      } else {
+        element = this.node.childNodes[index + 1] || this.node.firstChild;
+      }
+      if (element) {
+        element.focus();
+        this.props.onChange(element.getAttribute('data-index'));
+        e.preventDefault();
+        e.stopPropagation();
+      }
+      break;
     case 'Home':
       element = this.node.firstChild;
       if (element) {
@@ -128,11 +142,11 @@ class PrivacyDropdownMenu extends React.PureComponent {
           // It should not be transformed when mounting because the resulting
           // size will be used to determine the coordinate of the menu by
           // react-overlays
-          <div className={`privacy-dropdown__dropdown ${placement}`} style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null }} role='listbox' ref={this.setRef}>
+          <div className={`privacy-dropdown__dropdown ${placement}`} style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null, zIndex: 2 }} role='listbox' ref={this.setRef}>
             {items.map(item => (
               <div role='option' tabIndex='0' key={item.value} data-index={item.value} onKeyDown={this.handleKeyDown} onClick={this.handleClick} className={classNames('privacy-dropdown__option', { active: item.value === value })} aria-selected={item.value === value} ref={item.value === value ? this.setFocusRef : null}>
                 <div className='privacy-dropdown__option__icon'>
-                  <i className={`fa fa-fw fa-${item.icon}`} />
+                  <Icon id={item.icon} fixedWidth />
                 </div>
 
                 <div className='privacy-dropdown__option__content'>
@@ -179,6 +193,9 @@ class PrivacyDropdown extends React.PureComponent {
       }
     } else {
       const { top } = target.getBoundingClientRect();
+      if (this.state.open && this.activeElement) {
+        this.activeElement.focus();
+      }
       this.setState({ placement: top * 2 < innerHeight ? 'bottom' : 'top' });
       this.setState({ open: !this.state.open });
     }
@@ -201,7 +218,25 @@ class PrivacyDropdown extends React.PureComponent {
     }
   }
 
+  handleMouseDown = () => {
+    if (!this.state.open) {
+      this.activeElement = document.activeElement;
+    }
+  }
+
+  handleButtonKeyDown = (e) => {
+    switch(e.key) {
+    case ' ':
+    case 'Enter':
+      this.handleMouseDown();
+      break;
+    }
+  }
+
   handleClose = () => {
+    if (this.state.open && this.activeElement) {
+      this.activeElement.focus();
+    }
     this.setState({ open: false });
   }
 
@@ -214,7 +249,7 @@ class PrivacyDropdown extends React.PureComponent {
 
     this.options = [
       { icon: 'globe', value: 'public', text: formatMessage(messages.public_short), meta: formatMessage(messages.public_long) },
-      { icon: 'unlock-alt', value: 'unlisted', text: formatMessage(messages.unlisted_short), meta: formatMessage(messages.unlisted_long) },
+      { icon: 'unlock', value: 'unlisted', text: formatMessage(messages.unlisted_short), meta: formatMessage(messages.unlisted_long) },
       { icon: 'lock', value: 'private', text: formatMessage(messages.private_short), meta: formatMessage(messages.private_long) },
       { icon: 'envelope', value: 'direct', text: formatMessage(messages.direct_short), meta: formatMessage(messages.direct_long) },
     ];
@@ -228,7 +263,7 @@ class PrivacyDropdown extends React.PureComponent {
 
     return (
       <div className={classNames('privacy-dropdown', placement, { active: open })} onKeyDown={this.handleKeyDown}>
-        <div className={classNames('privacy-dropdown__value', { active: this.options.indexOf(valueOption) === 0 })}>
+        <div className={classNames('privacy-dropdown__value', { active: this.options.indexOf(valueOption) === (placement === 'bottom' ? 0 : (this.options.length - 1)) })}>
           <IconButton
             className='privacy-dropdown__value-icon'
             icon={valueOption.icon}
@@ -238,6 +273,8 @@ class PrivacyDropdown extends React.PureComponent {
             active={open}
             inverted
             onClick={this.handleToggle}
+            onMouseDown={this.handleMouseDown}
+            onKeyDown={this.handleButtonKeyDown}
             style={{ height: null, lineHeight: '27px' }}
           />
         </div>
diff --git a/app/javascript/mastodon/features/compose/components/reply_indicator.js b/app/javascript/mastodon/features/compose/components/reply_indicator.js
index 142223f3d8a223d3d6f29dc76038d858d16706b4..66dc8574216de32ff3c5b3a6061a1f24fff0b513 100644
--- a/app/javascript/mastodon/features/compose/components/reply_indicator.js
+++ b/app/javascript/mastodon/features/compose/components/reply_indicator.js
@@ -7,6 +7,7 @@ import DisplayName from '../../../components/display_name';
 import { defineMessages, injectIntl } from 'react-intl';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import { isRtl } from '../../../rtl';
+import AttachmentList from 'mastodon/components/attachment_list';
 
 const messages = defineMessages({
   cancel: { id: 'reply_indicator.cancel', defaultMessage: 'Cancel' },
@@ -60,6 +61,13 @@ class ReplyIndicator extends ImmutablePureComponent {
         </div>
 
         <div className='reply-indicator__content' style={style} dangerouslySetInnerHTML={content} />
+
+        {status.get('media_attachments').size > 0 && (
+          <AttachmentList
+            compact
+            media={status.get('media_attachments')}
+          />
+        )}
       </div>
     );
   }
diff --git a/app/javascript/mastodon/features/compose/components/search.js b/app/javascript/mastodon/features/compose/components/search.js
index d203d87800930e908d54d97df0dffd7f0cfb56bd..7f9edfeee30e75c2b1ad1fb49f390460c1900325 100644
--- a/app/javascript/mastodon/features/compose/components/search.js
+++ b/app/javascript/mastodon/features/compose/components/search.js
@@ -5,6 +5,7 @@ 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';
+import Icon from 'mastodon/components/icon';
 
 const messages = defineMessages({
   placeholder: { id: 'search.placeholder', defaultMessage: 'Search' },
@@ -20,7 +21,7 @@ class SearchPopout extends React.PureComponent {
     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 }}>
+      <div style={{ ...style, position: 'absolute', width: 285, zIndex: 2 }}>
         <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 }) }}>
           {({ opacity, scaleX, scaleY }) => (
             <div className='search-popout' style={{ opacity: opacity, transform: `scale(${scaleX}, ${scaleY})` }}>
@@ -46,6 +47,10 @@ class SearchPopout extends React.PureComponent {
 export default @injectIntl
 class Search extends React.PureComponent {
 
+  static contextTypes = {
+    router: PropTypes.object.isRequired,
+  };
+
   static propTypes = {
     value: PropTypes.string.isRequired,
     submitted: PropTypes.bool,
@@ -53,6 +58,7 @@ class Search extends React.PureComponent {
     onSubmit: PropTypes.func.isRequired,
     onClear: PropTypes.func.isRequired,
     onShow: PropTypes.func.isRequired,
+    openInRoute: PropTypes.bool,
     intl: PropTypes.object.isRequired,
   };
 
@@ -72,19 +78,20 @@ class Search extends React.PureComponent {
     }
   }
 
-  handleKeyDown = (e) => {
+  handleKeyUp = (e) => {
     if (e.key === 'Enter') {
       e.preventDefault();
+
       this.props.onSubmit();
+
+      if (this.props.openInRoute) {
+        this.context.router.history.push('/search');
+      }
     } else if (e.key === 'Escape') {
       document.querySelector('.ui').parentElement.focus();
     }
   }
 
-  noop () {
-
-  }
-
   handleFocus = () => {
     this.setState({ expanded: true });
     this.props.onShow();
@@ -109,15 +116,15 @@ class Search extends React.PureComponent {
             placeholder={intl.formatMessage(messages.placeholder)}
             value={value}
             onChange={this.handleChange}
-            onKeyUp={this.handleKeyDown}
+            onKeyUp={this.handleKeyUp}
             onFocus={this.handleFocus}
             onBlur={this.handleBlur}
           />
         </label>
 
         <div role='button' tabIndex='0' className='search__icon' onClick={this.handleClear}>
-          <i className={`fa fa-search ${hasValue ? '' : 'active'}`} />
-          <i aria-label={intl.formatMessage(messages.placeholder)} className={`fa fa-times-circle ${hasValue ? 'active' : ''}`} />
+          <Icon id='search' className={hasValue ? '' : 'active'} />
+          <Icon id='times-circle' className={hasValue ? 'active' : ''} aria-label={intl.formatMessage(messages.placeholder)} />
         </div>
 
         <Overlay show={expanded && !hasValue} placement='bottom' target={this}>
diff --git a/app/javascript/mastodon/features/compose/components/search_results.js b/app/javascript/mastodon/features/compose/components/search_results.js
index f0ddf6d7144bf9b35f7ff2a2e3012520a26472fd..2f338dd2469a49856d8c66b96e55e4591e46d7d6 100644
--- a/app/javascript/mastodon/features/compose/components/search_results.js
+++ b/app/javascript/mastodon/features/compose/components/search_results.js
@@ -6,6 +6,8 @@ import AccountContainer from '../../../containers/account_container';
 import StatusContainer from '../../../containers/status_container';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import Hashtag from '../../../components/hashtag';
+import Icon from 'mastodon/components/icon';
+import { searchEnabled } from '../../../initial_state';
 
 const messages = defineMessages({
   dismissSuggestion: { id: 'suggestions.dismiss', defaultMessage: 'Dismiss suggestion' },
@@ -19,6 +21,7 @@ class SearchResults extends ImmutablePureComponent {
     suggestions: ImmutablePropTypes.list.isRequired,
     fetchSuggestions: PropTypes.func.isRequired,
     dismissSuggestion: PropTypes.func.isRequired,
+    searchTerm: PropTypes.string,
     intl: PropTypes.object.isRequired,
   };
 
@@ -27,14 +30,14 @@ class SearchResults extends ImmutablePureComponent {
   }
 
   render () {
-    const { intl, results, suggestions, dismissSuggestion } = this.props;
+    const { intl, results, suggestions, dismissSuggestion, searchTerm } = this.props;
 
     if (results.isEmpty() && !suggestions.isEmpty()) {
       return (
         <div className='search-results'>
           <div className='trends'>
             <div className='trends__header'>
-              <i className='fa fa-user-plus fa-fw' />
+              <Icon id='user-plus' fixedWidth />
               <FormattedMessage id='suggestions.header' defaultMessage='You might be interested in…' />
             </div>
 
@@ -59,7 +62,7 @@ class SearchResults extends ImmutablePureComponent {
       count   += results.get('accounts').size;
       accounts = (
         <div className='search-results__section'>
-          <h5><i className='fa fa-fw fa-users' /><FormattedMessage id='search_results.accounts' defaultMessage='People' /></h5>
+          <h5><Icon id='users' fixedWidth /><FormattedMessage id='search_results.accounts' defaultMessage='People' /></h5>
 
           {results.get('accounts').map(accountId => <AccountContainer key={accountId} id={accountId} />)}
         </div>
@@ -70,18 +73,28 @@ class SearchResults extends ImmutablePureComponent {
       count   += results.get('statuses').size;
       statuses = (
         <div className='search-results__section'>
-          <h5><i className='fa fa-fw fa-quote-right' /><FormattedMessage id='search_results.statuses' defaultMessage='Toots' /></h5>
+          <h5><Icon id='quote-right' fixedWidth /><FormattedMessage id='search_results.statuses' defaultMessage='Toots' /></h5>
 
           {results.get('statuses').map(statusId => <StatusContainer key={statusId} id={statusId} />)}
         </div>
       );
+    } else if(results.get('statuses') && results.get('statuses').size === 0 && !searchEnabled && !(searchTerm.startsWith('@') || searchTerm.startsWith('#') || searchTerm.includes(' '))) {
+      statuses = (
+        <div className='search-results__section'>
+          <h5><Icon id='quote-right' fixedWidth /><FormattedMessage id='search_results.statuses' defaultMessage='Toots' /></h5>
+
+          <div className='search-results__info'>
+            <FormattedMessage id='search_results.statuses_fts_disabled' defaultMessage='Searching toots by their content is not enabled on this Mastodon server.' />
+          </div>
+        </div>
+      );
     }
 
     if (results.get('hashtags') && results.get('hashtags').size > 0) {
       count += results.get('hashtags').size;
       hashtags = (
         <div className='search-results__section'>
-          <h5><i className='fa fa-fw fa-hashtag' /><FormattedMessage id='search_results.hashtags' defaultMessage='Hashtags' /></h5>
+          <h5><Icon id='hashtag' fixedWidth /><FormattedMessage id='search_results.hashtags' defaultMessage='Hashtags' /></h5>
 
           {results.get('hashtags').map(hashtag => <Hashtag key={hashtag.get('name')} hashtag={hashtag} />)}
         </div>
@@ -91,7 +104,7 @@ class SearchResults extends ImmutablePureComponent {
     return (
       <div className='search-results'>
         <div className='search-results__header'>
-          <i className='fa fa-search fa-fw' />
+          <Icon id='search' fixedWidth />
           <FormattedMessage id='search_results.total' defaultMessage='{count, number} {count, plural, one {result} other {results}}' values={{ count }} />
         </div>
 
diff --git a/app/javascript/mastodon/features/compose/components/upload.js b/app/javascript/mastodon/features/compose/components/upload.js
index a1e99dcbbdbca3346ec4e90d428fb7590d7ae0c7..629cbc36ac34cff657ac860c4db18007ea611219 100644
--- a/app/javascript/mastodon/features/compose/components/upload.js
+++ b/app/javascript/mastodon/features/compose/components/upload.js
@@ -6,6 +6,7 @@ import spring from 'react-motion/lib/spring';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import classNames from 'classnames';
+import Icon from 'mastodon/components/icon';
 
 const messages = defineMessages({
   description: { id: 'upload_form.description', defaultMessage: 'Describe for the visually impaired' },
@@ -99,17 +100,16 @@ class Upload extends ImmutablePureComponent {
           {({ scale }) => (
             <div className='compose-form__upload-thumbnail' style={{ transform: `scale(${scale})`, backgroundImage: `url(${media.get('preview_url')})`, backgroundPosition: `${x}% ${y}%` }}>
               <div className={classNames('compose-form__upload__actions', { active })}>
-                <button className='icon-button' onClick={this.handleUndoClick}><i className='fa fa-times' /> <FormattedMessage id='upload_form.undo' defaultMessage='Delete' /></button>
-                {media.get('type') === 'image' && <button className='icon-button' onClick={this.handleFocalPointClick}><i className='fa fa-crosshairs' /> <FormattedMessage id='upload_form.focus' defaultMessage='Crop' /></button>}
+                <button className='icon-button' onClick={this.handleUndoClick}><Icon id='times' /> <FormattedMessage id='upload_form.undo' defaultMessage='Delete' /></button>
+                {media.get('type') === 'image' && <button className='icon-button' onClick={this.handleFocalPointClick}><Icon id='crosshairs' /> <FormattedMessage id='upload_form.focus' defaultMessage='Crop' /></button>}
               </div>
 
               <div className={classNames('compose-form__upload-description', { active })}>
                 <label>
                   <span style={{ display: 'none' }}>{intl.formatMessage(messages.description)}</span>
 
-                  <input
+                  <textarea
                     placeholder={intl.formatMessage(messages.description)}
-                    type='text'
                     value={description}
                     maxLength={420}
                     onFocus={this.handleInputFocus}
diff --git a/app/javascript/mastodon/features/compose/components/upload_button.js b/app/javascript/mastodon/features/compose/components/upload_button.js
index b6fe770eada75e214e62980d4026aa7e37aaa45e..d550019f41841ba3039fab9bd16fbcd76d2f5487 100644
--- a/app/javascript/mastodon/features/compose/components/upload_button.js
+++ b/app/javascript/mastodon/features/compose/components/upload_button.js
@@ -7,9 +7,11 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 
 const messages = defineMessages({
-  upload: { id: 'upload_button.label', defaultMessage: 'Add media (JPEG, PNG, GIF, WebM, MP4, MOV)' },
+  upload: { id: 'upload_button.label', defaultMessage: 'Add media ({formats})' },
 });
 
+const SUPPORTED_FORMATS = 'JPEG, PNG, GIF, WebM, MP4, MOV, OGG, WAV, MP3, FLAC';
+
 const makeMapStateToProps = () => {
   const mapStateToProps = state => ({
     acceptContentTypes: state.getIn(['media_attachments', 'accept_content_types']),
@@ -29,6 +31,7 @@ class UploadButton extends ImmutablePureComponent {
 
   static propTypes = {
     disabled: PropTypes.bool,
+    unavailable: PropTypes.bool,
     onSelectFile: PropTypes.func.isRequired,
     style: PropTypes.object,
     resetFileKey: PropTypes.number,
@@ -51,19 +54,22 @@ class UploadButton extends ImmutablePureComponent {
   }
 
   render () {
+    const { intl, resetFileKey, unavailable, disabled, acceptContentTypes } = this.props;
 
-    const { intl, resetFileKey, disabled, acceptContentTypes } = this.props;
+    if (unavailable) {
+      return null;
+    }
 
     return (
       <div className='compose-form__upload-button'>
-        <IconButton icon='camera' title={intl.formatMessage(messages.upload)} disabled={disabled} onClick={this.handleClick} className='compose-form__upload-button-icon' size={18} inverted style={iconStyle} />
+        <IconButton icon='paperclip' title={intl.formatMessage(messages.upload, { formats: SUPPORTED_FORMATS })} disabled={disabled} onClick={this.handleClick} className='compose-form__upload-button-icon' size={18} inverted style={iconStyle} />
         <label>
-          <span style={{ display: 'none' }}>{intl.formatMessage(messages.upload)}</span>
+          <span style={{ display: 'none' }}>{intl.formatMessage(messages.upload, { formats: SUPPORTED_FORMATS })}</span>
           <input
             key={resetFileKey}
             ref={this.setRef}
             type='file'
-            multiple={false}
+            multiple
             accept={acceptContentTypes.toArray().join(',')}
             onChange={this.handleChange}
             disabled={disabled}
diff --git a/app/javascript/mastodon/features/compose/components/upload_form.js b/app/javascript/mastodon/features/compose/components/upload_form.js
index b7f11220530fb1a5f7b67653828baeedd4ba4dd4..9ff2aa0fa631fdbcd64dfd3038d12e0166b08282 100644
--- a/app/javascript/mastodon/features/compose/components/upload_form.js
+++ b/app/javascript/mastodon/features/compose/components/upload_form.js
@@ -3,6 +3,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
 import UploadProgressContainer from '../containers/upload_progress_container';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import UploadContainer from '../containers/upload_container';
+import SensitiveButtonContainer from '../containers/sensitive_button_container';
 
 export default class UploadForm extends ImmutablePureComponent {
 
@@ -22,6 +23,8 @@ export default class UploadForm extends ImmutablePureComponent {
             <UploadContainer id={id} key={id} />
           ))}
         </div>
+
+        {!mediaIds.isEmpty() && <SensitiveButtonContainer />}
       </div>
     );
   }
diff --git a/app/javascript/mastodon/features/compose/components/upload_progress.js b/app/javascript/mastodon/features/compose/components/upload_progress.js
index d5e6f19cda78e2eaa051c925a66ecbca9fcc3e40..cbe58f573926954c42db1193e6b3b442a31a2d7e 100644
--- a/app/javascript/mastodon/features/compose/components/upload_progress.js
+++ b/app/javascript/mastodon/features/compose/components/upload_progress.js
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
 import Motion from '../../ui/util/optional_motion';
 import spring from 'react-motion/lib/spring';
 import { FormattedMessage } from 'react-intl';
+import Icon from 'mastodon/components/icon';
 
 export default class UploadProgress extends React.PureComponent {
 
@@ -21,7 +22,7 @@ export default class UploadProgress extends React.PureComponent {
     return (
       <div className='upload-progress'>
         <div className='upload-progress__icon'>
-          <i className='fa fa-upload' />
+          <Icon id='upload' />
         </div>
 
         <div className='upload-progress__message'>
diff --git a/app/javascript/mastodon/features/compose/containers/compose_form_container.js b/app/javascript/mastodon/features/compose/containers/compose_form_container.js
index b4a1c4b44462e4a37dcd7f8dfb7cdf206ddaf4f6..37a0e8845b4f1b1d2f523a40ad932407b6b2c1fd 100644
--- a/app/javascript/mastodon/features/compose/containers/compose_form_container.js
+++ b/app/javascript/mastodon/features/compose/containers/compose_form_container.js
@@ -1,6 +1,5 @@
 import { connect } from 'react-redux';
 import ComposeForm from '../components/compose_form';
-import { uploadCompose } from '../../../actions/compose';
 import {
   changeCompose,
   submitCompose,
@@ -9,21 +8,21 @@ import {
   selectComposeSuggestion,
   changeComposeSpoilerText,
   insertEmojiCompose,
+  uploadCompose,
 } from '../../../actions/compose';
 
 const mapStateToProps = state => ({
   text: state.getIn(['compose', 'text']),
-  suggestion_token: state.getIn(['compose', 'suggestion_token']),
   suggestions: state.getIn(['compose', 'suggestions']),
   spoiler: state.getIn(['compose', 'spoiler']),
-  spoiler_text: state.getIn(['compose', 'spoiler_text']),
+  spoilerText: state.getIn(['compose', 'spoiler_text']),
   privacy: state.getIn(['compose', 'privacy']),
   focusDate: state.getIn(['compose', 'focusDate']),
   caretPosition: state.getIn(['compose', 'caretPosition']),
   preselectDate: state.getIn(['compose', 'preselectDate']),
-  is_submitting: state.getIn(['compose', 'is_submitting']),
-  is_changing_upload: state.getIn(['compose', 'is_changing_upload']),
-  is_uploading: state.getIn(['compose', 'is_uploading']),
+  isSubmitting: state.getIn(['compose', 'is_submitting']),
+  isChangingUpload: state.getIn(['compose', 'is_changing_upload']),
+  isUploading: state.getIn(['compose', 'is_uploading']),
   showSearch: state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']),
   anyMedia: state.getIn(['compose', 'media_attachments']).size > 0,
 });
@@ -46,8 +45,8 @@ const mapDispatchToProps = (dispatch) => ({
     dispatch(fetchComposeSuggestions(token));
   },
 
-  onSuggestionSelected (position, token, accountId) {
-    dispatch(selectComposeSuggestion(position, token, accountId));
+  onSuggestionSelected (position, token, suggestion, path) {
+    dispatch(selectComposeSuggestion(position, token, suggestion, path));
   },
 
   onChangeSpoilerText (checked) {
diff --git a/app/javascript/mastodon/features/compose/containers/poll_button_container.js b/app/javascript/mastodon/features/compose/containers/poll_button_container.js
new file mode 100644
index 0000000000000000000000000000000000000000..8f1cb7c10a53464a4adac5544172fff03d720a8f
--- /dev/null
+++ b/app/javascript/mastodon/features/compose/containers/poll_button_container.js
@@ -0,0 +1,24 @@
+import { connect } from 'react-redux';
+import PollButton from '../components/poll_button';
+import { addPoll, removePoll } from '../../../actions/compose';
+
+const mapStateToProps = state => ({
+  unavailable: state.getIn(['compose', 'is_uploading']) || (state.getIn(['compose', 'media_attachments']).size > 0),
+  active: state.getIn(['compose', 'poll']) !== null,
+});
+
+const mapDispatchToProps = dispatch => ({
+
+  onClick () {
+    dispatch((_, getState) => {
+      if (getState().getIn(['compose', 'poll'])) {
+        dispatch(removePoll());
+      } else {
+        dispatch(addPoll());
+      }
+    });
+  },
+
+});
+
+export default connect(mapStateToProps, mapDispatchToProps)(PollButton);
diff --git a/app/javascript/mastodon/features/compose/containers/poll_form_container.js b/app/javascript/mastodon/features/compose/containers/poll_form_container.js
new file mode 100644
index 0000000000000000000000000000000000000000..1401371d0f073d47bb443ff59968deb4954159eb
--- /dev/null
+++ b/app/javascript/mastodon/features/compose/containers/poll_form_container.js
@@ -0,0 +1,48 @@
+import { connect } from 'react-redux';
+import PollForm from '../components/poll_form';
+import { addPollOption, removePollOption, changePollOption, changePollSettings } from '../../../actions/compose';
+import {
+  clearComposeSuggestions,
+  fetchComposeSuggestions,
+  selectComposeSuggestion,
+} from '../../../actions/compose';
+
+const mapStateToProps = state => ({
+  suggestions: state.getIn(['compose', 'suggestions']),
+  options: state.getIn(['compose', 'poll', 'options']),
+  expiresIn: state.getIn(['compose', 'poll', 'expires_in']),
+  isMultiple: state.getIn(['compose', 'poll', 'multiple']),
+});
+
+const mapDispatchToProps = dispatch => ({
+  onAddOption(title) {
+    dispatch(addPollOption(title));
+  },
+
+  onRemoveOption(index) {
+    dispatch(removePollOption(index));
+  },
+
+  onChangeOption(index, title) {
+    dispatch(changePollOption(index, title));
+  },
+
+  onChangeSettings(expiresIn, isMultiple) {
+    dispatch(changePollSettings(expiresIn, isMultiple));
+  },
+
+  onClearSuggestions () {
+    dispatch(clearComposeSuggestions());
+  },
+
+  onFetchSuggestions (token) {
+    dispatch(fetchComposeSuggestions(token));
+  },
+
+  onSuggestionSelected (position, token, accountId, path) {
+    dispatch(selectComposeSuggestion(position, token, accountId, path));
+  },
+
+});
+
+export default connect(mapStateToProps, mapDispatchToProps)(PollForm);
diff --git a/app/javascript/mastodon/features/compose/containers/search_results_container.js b/app/javascript/mastodon/features/compose/containers/search_results_container.js
index f9637861ae7b437c632f10f0967590f0e98df3b3..e4d5f3420787c81184c529bc951e843243a46cfb 100644
--- a/app/javascript/mastodon/features/compose/containers/search_results_container.js
+++ b/app/javascript/mastodon/features/compose/containers/search_results_container.js
@@ -5,6 +5,7 @@ import { fetchSuggestions, dismissSuggestion } from '../../../actions/suggestion
 const mapStateToProps = state => ({
   results: state.getIn(['search', 'results']),
   suggestions: state.getIn(['suggestions', 'items']),
+  searchTerm: state.getIn(['search', 'searchTerm']),
 });
 
 const mapDispatchToProps = dispatch => ({
diff --git a/app/javascript/mastodon/features/compose/containers/sensitive_button_container.js b/app/javascript/mastodon/features/compose/containers/sensitive_button_container.js
index 43de8f213e1a73b415b991b57fe98818c650bc48..7073f76c2e8f81f81189f7003e22edc5f882594e 100644
--- a/app/javascript/mastodon/features/compose/containers/sensitive_button_container.js
+++ b/app/javascript/mastodon/features/compose/containers/sensitive_button_container.js
@@ -2,11 +2,8 @@ import React from 'react';
 import { connect } from 'react-redux';
 import PropTypes from 'prop-types';
 import classNames from 'classnames';
-import IconButton from '../../../components/icon_button';
-import { changeComposeSensitivity } from '../../../actions/compose';
-import Motion from '../../ui/util/optional_motion';
-import spring from 'react-motion/lib/spring';
-import { injectIntl, defineMessages } from 'react-intl';
+import { changeComposeSensitivity } from 'mastodon/actions/compose';
+import { injectIntl, defineMessages, FormattedMessage } from 'react-intl';
 
 const messages = defineMessages({
   marked: { id: 'compose_form.sensitive.marked', defaultMessage: 'Media is marked as sensitive' },
@@ -14,7 +11,6 @@ const messages = defineMessages({
 });
 
 const mapStateToProps = state => ({
-  visible: state.getIn(['compose', 'media_attachments']).size > 0,
   active: state.getIn(['compose', 'sensitive']),
   disabled: state.getIn(['compose', 'spoiler']),
 });
@@ -30,7 +26,6 @@ const mapDispatchToProps = dispatch => ({
 class SensitiveButton extends React.PureComponent {
 
   static propTypes = {
-    visible: PropTypes.bool,
     active: PropTypes.bool,
     disabled: PropTypes.bool,
     onClick: PropTypes.func.isRequired,
@@ -38,32 +33,24 @@ class SensitiveButton extends React.PureComponent {
   };
 
   render () {
-    const { visible, active, disabled, onClick, intl } = this.props;
+    const { active, disabled, onClick, intl } = this.props;
 
     return (
-      <Motion defaultStyle={{ scale: 0.87 }} style={{ scale: spring(visible ? 1 : 0.87, { stiffness: 200, damping: 3 }) }}>
-        {({ scale }) => {
-          const icon = active ? 'eye-slash' : 'eye';
-          const className = classNames('compose-form__sensitive-button', {
-            'compose-form__sensitive-button--visible': visible,
-          });
-          return (
-            <div className={className} style={{ transform: `scale(${scale})` }}>
-              <IconButton
-                className='compose-form__sensitive-button__icon'
-                title={intl.formatMessage(active ? messages.marked : messages.unmarked)}
-                icon={icon}
-                onClick={onClick}
-                size={18}
-                active={active}
-                disabled={disabled}
-                style={{ lineHeight: null, height: null }}
-                inverted
-              />
-            </div>
-          );
-        }}
-      </Motion>
+      <div className='compose-form__sensitive-button'>
+        <label className={classNames('icon-button', { active })} title={intl.formatMessage(active ? messages.marked : messages.unmarked)}>
+          <input
+            name='mark-sensitive'
+            type='checkbox'
+            checked={active}
+            onChange={onClick}
+            disabled={disabled}
+          />
+
+          <span className={classNames('checkbox', { active })} />
+
+          <FormattedMessage id='compose_form.sensitive.hide' defaultMessage='Mark media as sensitive' />
+        </label>
+      </div>
     );
   }
 
diff --git a/app/javascript/mastodon/features/compose/containers/upload_button_container.js b/app/javascript/mastodon/features/compose/containers/upload_button_container.js
index 1f1d915bc84598c8402cbec89fcc6319c124b1f7..1471e628b05e360fcb08820ef40fd5dce40c3968 100644
--- a/app/javascript/mastodon/features/compose/containers/upload_button_container.js
+++ b/app/javascript/mastodon/features/compose/containers/upload_button_container.js
@@ -3,7 +3,8 @@ import UploadButton from '../components/upload_button';
 import { uploadCompose } from '../../../actions/compose';
 
 const mapStateToProps = state => ({
-  disabled: state.getIn(['compose', 'is_uploading']) || (state.getIn(['compose', 'media_attachments']).size > 3 || state.getIn(['compose', 'media_attachments']).some(m => m.get('type') === 'video')),
+  disabled: state.getIn(['compose', 'is_uploading']) || (state.getIn(['compose', 'media_attachments']).size > 3 || state.getIn(['compose', 'media_attachments']).some(m => ['video', 'audio'].includes(m.get('type')))),
+  unavailable: state.getIn(['compose', 'poll']) !== null,
   resetFileKey: state.getIn(['compose', 'resetFileKey']),
 });
 
diff --git a/app/javascript/mastodon/features/compose/index.js b/app/javascript/mastodon/features/compose/index.js
index d76cd76e61be2bdd3816e2cdb81217a007fe7bdc..0731abcf4d5a8c3245de61a5c78fb5ebc80fea6e 100644
--- a/app/javascript/mastodon/features/compose/index.js
+++ b/app/javascript/mastodon/features/compose/index.js
@@ -14,6 +14,7 @@ import SearchResultsContainer from './containers/search_results_container';
 import { changeComposing } from '../../actions/compose';
 import elephantUIPlane from '../../../images/elephant_ui_plane.svg';
 import { mascot } from '../../initial_state';
+import Icon from 'mastodon/components/icon';
 
 const messages = defineMessages({
   start: { id: 'getting_started.heading', defaultMessage: 'Getting started' },
@@ -77,21 +78,21 @@ class Compose extends React.PureComponent {
       const { columns } = this.props;
       header = (
         <nav className='drawer__header'>
-          <Link to='/getting-started' className='drawer__tab' title={intl.formatMessage(messages.start)} aria-label={intl.formatMessage(messages.start)}><i role='img' className='fa fa-fw fa-bars' /></Link>
+          <Link to='/getting-started' className='drawer__tab' title={intl.formatMessage(messages.start)} aria-label={intl.formatMessage(messages.start)}><Icon id='bars' fixedWidth /></Link>
           {!columns.some(column => column.get('id') === 'HOME') && (
-            <Link to='/timelines/home' className='drawer__tab' title={intl.formatMessage(messages.home_timeline)} aria-label={intl.formatMessage(messages.home_timeline)}><i role='img' className='fa fa-fw fa-home' /></Link>
+            <Link to='/timelines/home' className='drawer__tab' title={intl.formatMessage(messages.home_timeline)} aria-label={intl.formatMessage(messages.home_timeline)}><Icon id='home' fixedWidth /></Link>
           )}
           {!columns.some(column => column.get('id') === 'NOTIFICATIONS') && (
-            <Link to='/notifications' className='drawer__tab' title={intl.formatMessage(messages.notifications)} aria-label={intl.formatMessage(messages.notifications)}><i role='img' className='fa fa-fw fa-bell' /></Link>
+            <Link to='/notifications' className='drawer__tab' title={intl.formatMessage(messages.notifications)} aria-label={intl.formatMessage(messages.notifications)}><Icon id='bell' fixedWidth /></Link>
           )}
           {!columns.some(column => column.get('id') === 'COMMUNITY') && (
-            <Link to='/timelines/public/local' className='drawer__tab' title={intl.formatMessage(messages.community)} aria-label={intl.formatMessage(messages.community)}><i role='img' className='fa fa-fw fa-users' /></Link>
+            <Link to='/timelines/public/local' className='drawer__tab' title={intl.formatMessage(messages.community)} aria-label={intl.formatMessage(messages.community)}><Icon id='users' fixedWidth /></Link>
           )}
           {!columns.some(column => column.get('id') === 'PUBLIC') && (
-            <Link to='/timelines/public' className='drawer__tab' title={intl.formatMessage(messages.public)} aria-label={intl.formatMessage(messages.public)}><i role='img' className='fa fa-fw fa-globe' /></Link>
+            <Link to='/timelines/public' className='drawer__tab' title={intl.formatMessage(messages.public)} aria-label={intl.formatMessage(messages.public)}><Icon id='globe' fixedWidth /></Link>
           )}
-          <a href='/settings/preferences' className='drawer__tab' title={intl.formatMessage(messages.preferences)} aria-label={intl.formatMessage(messages.preferences)}><i role='img' className='fa fa-fw fa-cog' /></a>
-          <a href='/auth/sign_out' className='drawer__tab' data-method='delete' title={intl.formatMessage(messages.logout)} aria-label={intl.formatMessage(messages.logout)}><i role='img' className='fa fa-fw fa-sign-out' /></a>
+          <a href='/settings/preferences' className='drawer__tab' title={intl.formatMessage(messages.preferences)} aria-label={intl.formatMessage(messages.preferences)}><Icon id='cog' fixedWidth /></a>
+          <a href='/auth/sign_out' className='drawer__tab' data-method='delete' title={intl.formatMessage(messages.logout)} aria-label={intl.formatMessage(messages.logout)}><Icon id='sign-out' fixedWidth /></a>
         </nav>
       );
     }
@@ -105,12 +106,12 @@ class Compose extends React.PureComponent {
         <div className='drawer__pager'>
           {!isSearchPage && <div className='drawer__inner' onFocus={this.onFocus}>
             <NavigationContainer onClose={this.onBlur} />
+
             <ComposeFormContainer />
-            {multiColumn && (
-              <div className='drawer__inner__mastodon'>
-                <img alt='' draggable='false' src={mascot || elephantUIPlane} />
-              </div>
-            )}
+
+            <div className='drawer__inner__mastodon'>
+              <img alt='' draggable='false' src={mascot || elephantUIPlane} />
+            </div>
           </div>}
 
           <Motion defaultStyle={{ x: isSearchPage ? 0 : -100 }} style={{ x: spring(showSearch || isSearchPage ? 0 : -100, { stiffness: 210, damping: 20 }) }}>
diff --git a/app/javascript/mastodon/features/direct_timeline/components/column_settings.js b/app/javascript/mastodon/features/direct_timeline/components/column_settings.js
deleted file mode 100644
index b629c128dd8ae898eaa774d60bf9b998b8eb828f..0000000000000000000000000000000000000000
--- a/app/javascript/mastodon/features/direct_timeline/components/column_settings.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import ImmutablePropTypes from 'react-immutable-proptypes';
-import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
-import SettingText from '../../../components/setting_text';
-
-const messages = defineMessages({
-  filter_regex: { id: 'home.column_settings.filter_regex', defaultMessage: 'Filter out by regular expressions' },
-  settings: { id: 'home.settings', defaultMessage: 'Column settings' },
-});
-
-export default @injectIntl
-class ColumnSettings extends React.PureComponent {
-
-  static propTypes = {
-    settings: ImmutablePropTypes.map.isRequired,
-    onChange: PropTypes.func.isRequired,
-    intl: PropTypes.object.isRequired,
-  };
-
-  render () {
-    const { settings, onChange, intl } = this.props;
-
-    return (
-      <div>
-        <span className='column-settings__section'><FormattedMessage id='home.column_settings.advanced' defaultMessage='Advanced' /></span>
-
-        <div className='column-settings__row'>
-          <SettingText settings={settings} settingKey={['regex', 'body']} onChange={onChange} label={intl.formatMessage(messages.filter_regex)} />
-        </div>
-      </div>
-    );
-  }
-
-}
diff --git a/app/javascript/mastodon/features/direct_timeline/components/conversations_list.js b/app/javascript/mastodon/features/direct_timeline/components/conversations_list.js
index 635c03c1d129c4d0e64eb74f06e0cf51bdd407bf..8867bbd7385aa00fc54a966d18dfdb20317dc75c 100644
--- a/app/javascript/mastodon/features/direct_timeline/components/conversations_list.js
+++ b/app/javascript/mastodon/features/direct_timeline/components/conversations_list.js
@@ -20,18 +20,24 @@ export default class ConversationsList extends ImmutablePureComponent {
 
   handleMoveUp = id => {
     const elementIndex = this.getCurrentIndex(id) - 1;
-    this._selectChild(elementIndex);
+    this._selectChild(elementIndex, true);
   }
 
   handleMoveDown = id => {
     const elementIndex = this.getCurrentIndex(id) + 1;
-    this._selectChild(elementIndex);
+    this._selectChild(elementIndex, false);
   }
 
-  _selectChild (index) {
-    const element = this.node.node.querySelector(`article:nth-of-type(${index + 1}) .focusable`);
+  _selectChild (index, align_top) {
+    const container = this.node.node;
+    const element = container.querySelector(`article:nth-of-type(${index + 1}) .focusable`);
 
     if (element) {
+      if (align_top && container.scrollTop > element.offsetTop) {
+        element.scrollIntoView(true);
+      } else if (!align_top && container.scrollTop + container.clientHeight < element.offsetTop + element.offsetHeight) {
+        element.scrollIntoView(false);
+      }
       element.focus();
     }
   }
diff --git a/app/javascript/mastodon/features/direct_timeline/containers/column_settings_container.js b/app/javascript/mastodon/features/direct_timeline/containers/column_settings_container.js
deleted file mode 100644
index 38054ce9eb24193aab14295567a73ad672bc693e..0000000000000000000000000000000000000000
--- a/app/javascript/mastodon/features/direct_timeline/containers/column_settings_container.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import { connect } from 'react-redux';
-import ColumnSettings from '../components/column_settings';
-import { changeSetting } from '../../../actions/settings';
-
-const mapStateToProps = state => ({
-  settings: state.getIn(['settings', 'direct']),
-});
-
-const mapDispatchToProps = dispatch => ({
-
-  onChange (key, checked) {
-    dispatch(changeSetting(['direct', ...key], checked));
-  },
-
-});
-
-export default connect(mapStateToProps, mapDispatchToProps)(ColumnSettings);
diff --git a/app/javascript/mastodon/features/domain_blocks/index.js b/app/javascript/mastodon/features/domain_blocks/index.js
index 5c1bd11610ca7a70c065322a73e483843a4df127..7c075f5a5c5109cb8a268126cc1b863dd06ae5ef 100644
--- a/app/javascript/mastodon/features/domain_blocks/index.js
+++ b/app/javascript/mastodon/features/domain_blocks/index.js
@@ -19,6 +19,7 @@ const messages = defineMessages({
 
 const mapStateToProps = state => ({
   domains: state.getIn(['domain_lists', 'blocks', 'items']),
+  hasMore: !!state.getIn(['domain_lists', 'blocks', 'next']),
 });
 
 export default @connect(mapStateToProps)
@@ -29,6 +30,7 @@ class Blocks extends ImmutablePureComponent {
     params: PropTypes.object.isRequired,
     dispatch: PropTypes.func.isRequired,
     shouldUpdateScroll: PropTypes.func,
+    hasMore: PropTypes.bool,
     domains: ImmutablePropTypes.orderedSet,
     intl: PropTypes.object.isRequired,
   };
@@ -42,7 +44,7 @@ class Blocks extends ImmutablePureComponent {
   }, 300, { leading: true });
 
   render () {
-    const { intl, domains, shouldUpdateScroll } = this.props;
+    const { intl, domains, shouldUpdateScroll, hasMore } = this.props;
 
     if (!domains) {
       return (
@@ -60,6 +62,7 @@ class Blocks extends ImmutablePureComponent {
         <ScrollableList
           scrollKey='domain_blocks'
           onLoadMore={this.handleLoadMore}
+          hasMore={hasMore}
           shouldUpdateScroll={shouldUpdateScroll}
           emptyMessage={emptyMessage}
         >
diff --git a/app/javascript/mastodon/features/emoji/emoji.js b/app/javascript/mastodon/features/emoji/emoji.js
index 988cea2530d1e6f7a9b799dc4c3141343eba3583..fa91b50149fadcd4204b1024026fda6271eef34b 100644
--- a/app/javascript/mastodon/features/emoji/emoji.js
+++ b/app/javascript/mastodon/features/emoji/emoji.js
@@ -29,7 +29,7 @@ const emojify = (str, customEmojis = {}) => {
         // if you want additional emoji handler, add statements below which set replacement and return true.
         if (shortname in customEmojis) {
           const filename = autoPlayGif ? customEmojis[shortname].url : customEmojis[shortname].static_url;
-          replacement = `<img draggable="false" class="emojione" alt="${shortname}" title="${shortname}" src="${filename}" />`;
+          replacement = `<img draggable="false" class="emojione custom-emoji" alt="${shortname}" title="${shortname}" src="${filename}" data-original="${customEmojis[shortname].url}" data-static="${customEmojis[shortname].static_url}" />`;
           return true;
         }
         return false;
diff --git a/app/javascript/mastodon/features/follow_requests/index.js b/app/javascript/mastodon/features/follow_requests/index.js
index 56ae8764b42dd6c7f56ae24a4136da505bc6f442..44624cb40665155a5330922c45b8c520962d5950 100644
--- a/app/javascript/mastodon/features/follow_requests/index.js
+++ b/app/javascript/mastodon/features/follow_requests/index.js
@@ -18,6 +18,7 @@ const messages = defineMessages({
 
 const mapStateToProps = state => ({
   accountIds: state.getIn(['user_lists', 'follow_requests', 'items']),
+  hasMore: !!state.getIn(['user_lists', 'follow_requests', 'next']),
 });
 
 export default @connect(mapStateToProps)
@@ -28,6 +29,7 @@ class FollowRequests extends ImmutablePureComponent {
     params: PropTypes.object.isRequired,
     dispatch: PropTypes.func.isRequired,
     shouldUpdateScroll: PropTypes.func,
+    hasMore: PropTypes.bool,
     accountIds: ImmutablePropTypes.list,
     intl: PropTypes.object.isRequired,
   };
@@ -41,7 +43,7 @@ class FollowRequests extends ImmutablePureComponent {
   }, 300, { leading: true });
 
   render () {
-    const { intl, shouldUpdateScroll, accountIds } = this.props;
+    const { intl, shouldUpdateScroll, accountIds, hasMore } = this.props;
 
     if (!accountIds) {
       return (
@@ -54,11 +56,12 @@ class FollowRequests extends ImmutablePureComponent {
     const emptyMessage = <FormattedMessage id='empty_column.follow_requests' defaultMessage="You don't have any follow requests yet. When you receive one, it will show up here." />;
 
     return (
-      <Column icon='users' heading={intl.formatMessage(messages.heading)}>
+      <Column icon='user-plus' heading={intl.formatMessage(messages.heading)}>
         <ColumnBackButtonSlim />
         <ScrollableList
           scrollKey='follow_requests'
           onLoadMore={this.handleLoadMore}
+          hasMore={hasMore}
           shouldUpdateScroll={shouldUpdateScroll}
           emptyMessage={emptyMessage}
         >
diff --git a/app/javascript/mastodon/features/followers/index.js b/app/javascript/mastodon/features/followers/index.js
index ce56f270ca361836efaf76bcb30120f6d835de06..e3387e1be8351241ae77caa383756b0821d1f623 100644
--- a/app/javascript/mastodon/features/followers/index.js
+++ b/app/javascript/mastodon/features/followers/index.js
@@ -16,10 +16,13 @@ import Column from '../ui/components/column';
 import HeaderContainer from '../account_timeline/containers/header_container';
 import ColumnBackButton from '../../components/column_back_button';
 import ScrollableList from '../../components/scrollable_list';
+import MissingIndicator from 'mastodon/components/missing_indicator';
 
 const mapStateToProps = (state, props) => ({
+  isAccount: !!state.getIn(['accounts', props.params.accountId]),
   accountIds: state.getIn(['user_lists', 'followers', props.params.accountId, 'items']),
   hasMore: !!state.getIn(['user_lists', 'followers', props.params.accountId, 'next']),
+  blockedBy: state.getIn(['relationships', props.params.accountId, 'blocked_by'], false),
 });
 
 export default @connect(mapStateToProps)
@@ -31,6 +34,8 @@ class Followers extends ImmutablePureComponent {
     shouldUpdateScroll: PropTypes.func,
     accountIds: ImmutablePropTypes.list,
     hasMore: PropTypes.bool,
+    blockedBy: PropTypes.bool,
+    isAccount: PropTypes.bool,
   };
 
   componentWillMount () {
@@ -50,7 +55,15 @@ class Followers extends ImmutablePureComponent {
   }, 300, { leading: true });
 
   render () {
-    const { shouldUpdateScroll, accountIds, hasMore } = this.props;
+    const { shouldUpdateScroll, accountIds, hasMore, blockedBy, isAccount } = this.props;
+
+    if (!isAccount) {
+      return (
+        <Column>
+          <MissingIndicator />
+        </Column>
+      );
+    }
 
     if (!accountIds) {
       return (
@@ -60,7 +73,7 @@ class Followers extends ImmutablePureComponent {
       );
     }
 
-    const emptyMessage = <FormattedMessage id='account.followers.empty' defaultMessage='No one follows this user yet.' />;
+    const emptyMessage = blockedBy ? <FormattedMessage id='empty_column.account_unavailable' defaultMessage='Profile unavailable' /> : <FormattedMessage id='account.followers.empty' defaultMessage='No one follows this user yet.' />;
 
     return (
       <Column>
@@ -75,7 +88,7 @@ class Followers extends ImmutablePureComponent {
           alwaysPrepend
           emptyMessage={emptyMessage}
         >
-          {accountIds.map(id =>
+          {blockedBy ? [] : accountIds.map(id =>
             <AccountContainer key={id} id={id} withNote={false} />
           )}
         </ScrollableList>
diff --git a/app/javascript/mastodon/features/following/index.js b/app/javascript/mastodon/features/following/index.js
index bda0438a0a582ac137329b6394ad2fa0d518498f..3bf89fb2bab7927f1f64e8c0644845c3cec9746f 100644
--- a/app/javascript/mastodon/features/following/index.js
+++ b/app/javascript/mastodon/features/following/index.js
@@ -16,10 +16,13 @@ import Column from '../ui/components/column';
 import HeaderContainer from '../account_timeline/containers/header_container';
 import ColumnBackButton from '../../components/column_back_button';
 import ScrollableList from '../../components/scrollable_list';
+import MissingIndicator from 'mastodon/components/missing_indicator';
 
 const mapStateToProps = (state, props) => ({
+  isAccount: !!state.getIn(['accounts', props.params.accountId]),
   accountIds: state.getIn(['user_lists', 'following', props.params.accountId, 'items']),
   hasMore: !!state.getIn(['user_lists', 'following', props.params.accountId, 'next']),
+  blockedBy: state.getIn(['relationships', props.params.accountId, 'blocked_by'], false),
 });
 
 export default @connect(mapStateToProps)
@@ -31,6 +34,8 @@ class Following extends ImmutablePureComponent {
     shouldUpdateScroll: PropTypes.func,
     accountIds: ImmutablePropTypes.list,
     hasMore: PropTypes.bool,
+    blockedBy: PropTypes.bool,
+    isAccount: PropTypes.bool,
   };
 
   componentWillMount () {
@@ -50,7 +55,15 @@ class Following extends ImmutablePureComponent {
   }, 300, { leading: true });
 
   render () {
-    const { shouldUpdateScroll, accountIds, hasMore } = this.props;
+    const { shouldUpdateScroll, accountIds, hasMore, blockedBy, isAccount } = this.props;
+
+    if (!isAccount) {
+      return (
+        <Column>
+          <MissingIndicator />
+        </Column>
+      );
+    }
 
     if (!accountIds) {
       return (
@@ -60,7 +73,7 @@ class Following extends ImmutablePureComponent {
       );
     }
 
-    const emptyMessage = <FormattedMessage id='account.follows.empty' defaultMessage="This user doesn't follow anyone yet." />;
+    const emptyMessage = blockedBy ? <FormattedMessage id='empty_column.account_unavailable' defaultMessage='Profile unavailable' /> : <FormattedMessage id='account.follows.empty' defaultMessage="This user doesn't follow anyone yet." />;
 
     return (
       <Column>
@@ -75,7 +88,7 @@ class Following extends ImmutablePureComponent {
           alwaysPrepend
           emptyMessage={emptyMessage}
         >
-          {accountIds.map(id =>
+          {blockedBy ? [] : accountIds.map(id =>
             <AccountContainer key={id} id={id} withNote={false} />
           )}
         </ScrollableList>
diff --git a/app/javascript/mastodon/features/getting_started/index.js b/app/javascript/mastodon/features/getting_started/index.js
index 709a3aa96dfd3a0ad6a0f32e4421b8fa69e8a604..fc7840ec190d1f635f0895d173ffd008367ca8f4 100644
--- a/app/javascript/mastodon/features/getting_started/index.js
+++ b/app/javascript/mastodon/features/getting_started/index.js
@@ -7,11 +7,12 @@ import { connect } from 'react-redux';
 import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import ImmutablePureComponent from 'react-immutable-pure-component';
-import { me, invitesEnabled, version, profile_directory } from '../../initial_state';
-import { fetchFollowRequests } from '../../actions/accounts';
+import { me, profile_directory } from '../../initial_state';
+import { fetchFollowRequests } from 'mastodon/actions/accounts';
 import { List as ImmutableList } from 'immutable';
-import { Link } from 'react-router-dom';
 import NavigationBar from '../compose/components/navigation_bar';
+import Icon from 'mastodon/components/icon';
+import LinkFooter from 'mastodon/features/ui/components/link_footer';
 
 const messages = defineMessages({
   home_timeline: { id: 'tabs_bar.home', defaultMessage: 'Home' },
@@ -54,10 +55,16 @@ const badgeDisplay = (number, limit) => {
   }
 };
 
+const NAVIGATION_PANEL_BREAKPOINT = 600 + (285 * 2) + (10 * 2);
+
 export default @connect(mapStateToProps, mapDispatchToProps)
 @injectIntl
 class GettingStarted extends ImmutablePureComponent {
 
+  static contextTypes = {
+    router: PropTypes.object.isRequired,
+  };
+
   static propTypes = {
     intl: PropTypes.object.isRequired,
     myAccount: ImmutablePropTypes.map.isRequired,
@@ -69,7 +76,12 @@ class GettingStarted extends ImmutablePureComponent {
   };
 
   componentDidMount () {
-    const { myAccount, fetchFollowRequests } = this.props;
+    const { myAccount, fetchFollowRequests, multiColumn } = this.props;
+
+    if (!multiColumn && window.innerWidth >= NAVIGATION_PANEL_BREAKPOINT) {
+      this.context.router.history.replace('/timelines/home');
+      return;
+    }
 
     if (myAccount.get('locked')) {
       fetchFollowRequests();
@@ -122,7 +134,7 @@ class GettingStarted extends ImmutablePureComponent {
     height += 48*3;
 
     if (myAccount.get('locked')) {
-      navItems.push(<ColumnLink key={i++} icon='users' text={intl.formatMessage(messages.follow_requests)} badge={badgeDisplay(unreadFollowRequests, 40)} to='/follow_requests' />);
+      navItems.push(<ColumnLink key={i++} icon='user-plus' text={intl.formatMessage(messages.follow_requests)} badge={badgeDisplay(unreadFollowRequests, 40)} to='/follow_requests' />);
       height += 48;
     }
 
@@ -140,7 +152,7 @@ class GettingStarted extends ImmutablePureComponent {
         {multiColumn && <div className='column-header__wrapper'>
           <h1 className='column-header'>
             <button>
-              <i className='fa fa-bars fa-fw column-header__icon' />
+              <Icon id='bars' className='column-header__icon' fixedWidth />
               <FormattedMessage id='getting_started.heading' defaultMessage='Getting started' />
             </button>
           </h1>
@@ -154,27 +166,7 @@ class GettingStarted extends ImmutablePureComponent {
 
           {!multiColumn && <div className='flex-spacer' />}
 
-          <div className='getting-started__footer'>
-            <ul>
-              {invitesEnabled && <li><a href='/invites' target='_blank'><FormattedMessage id='getting_started.invite' defaultMessage='Invite people' /></a> · </li>}
-              {multiColumn && <li><Link to='/keyboard-shortcuts'><FormattedMessage id='navigation_bar.keyboard_shortcuts' defaultMessage='Hotkeys' /></Link> · </li>}
-              <li><a href='/auth/edit'><FormattedMessage id='getting_started.security' defaultMessage='Security' /></a> · </li>
-              <li><a href='/about/more' target='_blank'><FormattedMessage id='navigation_bar.info' defaultMessage='About this instance' /></a> · </li>
-              <li><a href='https://joinmastodon.org/apps' target='_blank'><FormattedMessage id='navigation_bar.apps' defaultMessage='Mobile apps' /></a> · </li>
-              <li><a href='/terms' target='_blank'><FormattedMessage id='getting_started.terms' defaultMessage='Terms of service' /></a> · </li>
-              <li><a href='/settings/applications' target='_blank'><FormattedMessage id='getting_started.developers' defaultMessage='Developers' /></a> · </li>
-              <li><a href='https://docs.joinmastodon.org' target='_blank'><FormattedMessage id='getting_started.documentation' defaultMessage='Documentation' /></a> · </li>
-              <li><a href='/auth/sign_out' data-method='delete'><FormattedMessage id='navigation_bar.logout' defaultMessage='Logout' /></a></li>
-            </ul>
-
-            <p>
-              <FormattedMessage
-                id='getting_started.open_source_notice'
-                defaultMessage='Mastodon is open source software. You can contribute or report issues on GitHub at {github}.'
-                values={{ github: <span><a href='https://github.com/tootsuite/mastodon' rel='noopener' target='_blank'>tootsuite/mastodon</a> (v{version})</span> }}
-              />
-            </p>
-          </div>
+          <LinkFooter withHotkeys={multiColumn} />
         </div>
       </Column>
     );
diff --git a/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js b/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js
index 9c9f62d8211ebcbf0f2a31551e3b0335be732e97..cdc138c8bf3a440586c8f65b4793343978b089b0 100644
--- a/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js
+++ b/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js
@@ -1,10 +1,15 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
-import { injectIntl, FormattedMessage } from 'react-intl';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import Toggle from 'react-toggle';
 import AsyncSelect from 'react-select/lib/Async';
 
+const messages = defineMessages({
+  placeholder: { id: 'hashtag.column_settings.select.placeholder', defaultMessage: 'Enter hashtags…' },
+  noOptions: { id: 'hashtag.column_settings.select.no_options_message', defaultMessage: 'No suggestions found' },
+});
+
 export default @injectIntl
 class ColumnSettings extends React.PureComponent {
 
@@ -25,6 +30,7 @@ class ColumnSettings extends React.PureComponent {
 
   tags (mode) {
     let tags = this.props.settings.getIn(['tags', mode]) || [];
+
     if (tags.toJSON) {
       return tags.toJSON();
     } else {
@@ -32,33 +38,36 @@ class ColumnSettings extends React.PureComponent {
     }
   };
 
-  onSelect = (mode) => {
-    return (value) => {
-      this.props.onChange(['tags', mode], value);
-    };
-  };
+  onSelect = mode => value => this.props.onChange(['tags', mode], value);
 
   onToggle = () => {
     if (this.state.open && this.hasTags()) {
       this.props.onChange('tags', {});
     }
+
     this.setState({ open: !this.state.open });
   };
 
+  noOptionsMessage = () => this.props.intl.formatMessage(messages.noOptions);
+
   modeSelect (mode) {
     return (
-      <div className='column-settings__section'>
-        {this.modeLabel(mode)}
+      <div className='column-settings__row'>
+        <span className='column-settings__section'>
+          {this.modeLabel(mode)}
+        </span>
+
         <AsyncSelect
           isMulti
           autoFocus
           value={this.tags(mode)}
-          settings={this.props.settings}
-          settingPath={['tags', mode]}
           onChange={this.onSelect(mode)}
           loadOptions={this.props.onLoad}
-          classNamePrefix='column-settings__hashtag-select'
+          className='column-select__container'
+          classNamePrefix='column-select'
           name='tags'
+          placeholder={this.props.intl.formatMessage(messages.placeholder)}
+          noOptionsMessage={this.noOptionsMessage}
         />
       </div>
     );
@@ -66,11 +75,15 @@ class ColumnSettings extends React.PureComponent {
 
   modeLabel (mode) {
     switch(mode) {
-    case 'any':  return <FormattedMessage id='hashtag.column_settings.tag_mode.any' defaultMessage='Any of these' />;
-    case 'all':  return <FormattedMessage id='hashtag.column_settings.tag_mode.all' defaultMessage='All of these' />;
-    case 'none': return <FormattedMessage id='hashtag.column_settings.tag_mode.none' defaultMessage='None of these' />;
+    case 'any':
+      return <FormattedMessage id='hashtag.column_settings.tag_mode.any' defaultMessage='Any of these' />;
+    case 'all':
+      return <FormattedMessage id='hashtag.column_settings.tag_mode.all' defaultMessage='All of these' />;
+    case 'none':
+      return <FormattedMessage id='hashtag.column_settings.tag_mode.none' defaultMessage='None of these' />;
+    default:
+      return '';
     }
-    return '';
   };
 
   render () {
@@ -78,23 +91,21 @@ class ColumnSettings extends React.PureComponent {
       <div>
         <div className='column-settings__row'>
           <div className='setting-toggle'>
-            <Toggle
-              id='hashtag.column_settings.tag_toggle'
-              onChange={this.onToggle}
-              checked={this.state.open}
-            />
+            <Toggle id='hashtag.column_settings.tag_toggle' onChange={this.onToggle} checked={this.state.open} />
+
             <span className='setting-toggle__label'>
               <FormattedMessage id='hashtag.column_settings.tag_toggle' defaultMessage='Include additional tags in this column' />
             </span>
           </div>
         </div>
-        {this.state.open &&
+
+        {this.state.open && (
           <div className='column-settings__hashtags'>
             {this.modeSelect('any')}
             {this.modeSelect('all')}
             {this.modeSelect('none')}
           </div>
-        }
+        )}
       </div>
     );
   }
diff --git a/app/javascript/mastodon/features/hashtag_timeline/index.js b/app/javascript/mastodon/features/hashtag_timeline/index.js
index c2e026d13611d97dca0fcf7d0bf24abb7fa1526c..0d3c97a6489cc9d4caa56bb09e98ed0a71c3ef36 100644
--- a/app/javascript/mastodon/features/hashtag_timeline/index.js
+++ b/app/javascript/mastodon/features/hashtag_timeline/index.js
@@ -41,15 +41,19 @@ class HashtagTimeline extends React.PureComponent {
 
   title = () => {
     let title = [this.props.params.id];
+
     if (this.additionalFor('any')) {
-      title.push(' ', <FormattedMessage id='hashtag.column_header.tag_mode.any'  values={{ additional: this.additionalFor('any') }} defaultMessage='or {additional}' />);
+      title.push(' ', <FormattedMessage key='any' id='hashtag.column_header.tag_mode.any'  values={{ additional: this.additionalFor('any') }} defaultMessage='or {additional}' />);
     }
+
     if (this.additionalFor('all')) {
-      title.push(' ', <FormattedMessage id='hashtag.column_header.tag_mode.all'  values={{ additional: this.additionalFor('all') }} defaultMessage='and {additional}' />);
+      title.push(' ', <FormattedMessage key='all' id='hashtag.column_header.tag_mode.all'  values={{ additional: this.additionalFor('all') }} defaultMessage='and {additional}' />);
     }
+
     if (this.additionalFor('none')) {
-      title.push(' ', <FormattedMessage id='hashtag.column_header.tag_mode.none' values={{ additional: this.additionalFor('none') }} defaultMessage='without {additional}' />);
+      title.push(' ', <FormattedMessage key='none' id='hashtag.column_header.tag_mode.none' values={{ additional: this.additionalFor('none') }} defaultMessage='without {additional}' />);
     }
+
     return title;
   }
 
@@ -77,9 +81,10 @@ class HashtagTimeline extends React.PureComponent {
     let all  = (tags.all || []).map(tag => tag.value);
     let none = (tags.none || []).map(tag => tag.value);
 
-    [id, ...any].map((tag) => {
-      this.disconnects.push(dispatch(connectHashtagStream(id, tag, (status) => {
+    [id, ...any].map(tag => {
+      this.disconnects.push(dispatch(connectHashtagStream(id, tag, status => {
         let tags = status.tags.map(tag => tag.name);
+
         return all.filter(tag => tags.includes(tag)).length === all.length &&
                none.filter(tag => tags.includes(tag)).length === 0;
       })));
@@ -95,12 +100,14 @@ class HashtagTimeline extends React.PureComponent {
     const { dispatch } = this.props;
     const { id, tags } = this.props.params;
 
+    this._subscribe(dispatch, id, tags);
     dispatch(expandHashtagTimeline(id, { tags }));
   }
 
   componentWillReceiveProps (nextProps) {
     const { dispatch, params } = this.props;
     const { id, tags } = nextProps.params;
+
     if (id !== params.id || !isEqual(tags, params.tags)) {
       this._unsubscribe();
       this._subscribe(dispatch, id, tags);
diff --git a/app/javascript/mastodon/features/home_timeline/index.js b/app/javascript/mastodon/features/home_timeline/index.js
index 3ffa7a681526c40f7474d1dccda53d7f5f37faa0..097f91c16ca34472cd47c3fe91de9d627b915fdb 100644
--- a/app/javascript/mastodon/features/home_timeline/index.js
+++ b/app/javascript/mastodon/features/home_timeline/index.js
@@ -16,7 +16,7 @@ const messages = defineMessages({
 
 const mapStateToProps = state => ({
   hasUnread: state.getIn(['timelines', 'home', 'unread']) > 0,
-  isPartial: state.getIn(['timelines', 'home', 'items', 0], null) === null,
+  isPartial: state.getIn(['timelines', 'home', 'isPartial']),
 });
 
 export default @connect(mapStateToProps)
diff --git a/app/javascript/mastodon/features/introduction/index.js b/app/javascript/mastodon/features/introduction/index.js
index e712b2f7d4ea3b8c960274e688c96811a08e5517..754477bb992dfc56520a36d01dd4f08b19b4c8f3 100644
--- a/app/javascript/mastodon/features/introduction/index.js
+++ b/app/javascript/mastodon/features/introduction/index.js
@@ -89,7 +89,7 @@ const FrameInteractions = ({ onNext }) => (
     </div>
 
     <div className='introduction__action'>
-      <button className='button' onClick={onNext}><FormattedMessage id='introduction.interactions.action' defaultMessage='Finish tutorial!' /></button>
+      <button className='button' onClick={onNext}><FormattedMessage id='introduction.interactions.action' defaultMessage='Finish toot-orial!' /></button>
     </div>
   </div>
 );
diff --git a/app/javascript/mastodon/features/keyboard_shortcuts/index.js b/app/javascript/mastodon/features/keyboard_shortcuts/index.js
index ab1ac511e0397502290ffc9c5738da16de8de7d8..01b45652c5339aaf62dae187d3d54858fd9f71c1 100644
--- a/app/javascript/mastodon/features/keyboard_shortcuts/index.js
+++ b/app/javascript/mastodon/features/keyboard_shortcuts/index.js
@@ -60,6 +60,10 @@ class KeyboardShortcuts extends ImmutablePureComponent {
                 <td><kbd>x</kbd></td>
                 <td><FormattedMessage id='keyboard_shortcuts.toggle_hidden' defaultMessage='to show/hide text behind CW' /></td>
               </tr>
+              <tr>
+                <td><kbd>h</kbd></td>
+                <td><FormattedMessage id='keyboard_shortcuts.toggle_sensitivity' defaultMessage='to show/hide media' /></td>
+              </tr>
               <tr>
                 <td><kbd>up</kbd>, <kbd>k</kbd></td>
                 <td><FormattedMessage id='keyboard_shortcuts.up' defaultMessage='to move up in the list' /></td>
diff --git a/app/javascript/mastodon/features/list_adder/components/list.js b/app/javascript/mastodon/features/list_adder/components/list.js
index cb8eb7d7a91a85657fc1d91c27c6b9867832bce9..60c8958a73762981bf3c1271f213d455f7f65543 100644
--- a/app/javascript/mastodon/features/list_adder/components/list.js
+++ b/app/javascript/mastodon/features/list_adder/components/list.js
@@ -6,6 +6,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
 import IconButton from '../../../components/icon_button';
 import { defineMessages, injectIntl } from 'react-intl';
 import { removeFromListAdder, addToListAdder } from '../../../actions/lists';
+import Icon from 'mastodon/components/icon';
 
 const messages = defineMessages({
   remove: { id: 'lists.account.remove', defaultMessage: 'Remove from list' },
@@ -53,7 +54,7 @@ class List extends ImmutablePureComponent {
       <div className='list'>
         <div className='list__wrapper'>
           <div className='list__display-name'>
-            <i className='fa fa-fw fa-list-ul column-link__icon' />
+            <Icon id='list-ul' className='column-link__icon' fixedWidth />
             {list.get('title')}
           </div>
 
diff --git a/app/javascript/mastodon/features/list_editor/components/edit_list_form.js b/app/javascript/mastodon/features/list_editor/components/edit_list_form.js
new file mode 100644
index 0000000000000000000000000000000000000000..3ccab12a800c7891ffde4ceeb3ba1f12b2d2cb6c
--- /dev/null
+++ b/app/javascript/mastodon/features/list_editor/components/edit_list_form.js
@@ -0,0 +1,70 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import PropTypes from 'prop-types';
+import { changeListEditorTitle, submitListEditor } from '../../../actions/lists';
+import IconButton from '../../../components/icon_button';
+import { defineMessages, injectIntl } from 'react-intl';
+
+const messages = defineMessages({
+  title: { id: 'lists.edit.submit', defaultMessage: 'Change title' },
+});
+
+const mapStateToProps = state => ({
+  value: state.getIn(['listEditor', 'title']),
+  disabled: !state.getIn(['listEditor', 'isChanged']) || !state.getIn(['listEditor', 'title']),
+});
+
+const mapDispatchToProps = dispatch => ({
+  onChange: value => dispatch(changeListEditorTitle(value)),
+  onSubmit: () => dispatch(submitListEditor(false)),
+});
+
+export default @connect(mapStateToProps, mapDispatchToProps)
+@injectIntl
+class ListForm extends React.PureComponent {
+
+  static propTypes = {
+    value: PropTypes.string.isRequired,
+    disabled: PropTypes.bool,
+    intl: PropTypes.object.isRequired,
+    onChange: PropTypes.func.isRequired,
+    onSubmit: PropTypes.func.isRequired,
+  };
+
+  handleChange = e => {
+    this.props.onChange(e.target.value);
+  }
+
+  handleSubmit = e => {
+    e.preventDefault();
+    this.props.onSubmit();
+  }
+
+  handleClick = () => {
+    this.props.onSubmit();
+  }
+
+  render () {
+    const { value, disabled, intl } = this.props;
+
+    const title = intl.formatMessage(messages.title);
+
+    return (
+      <form className='column-inline-form' onSubmit={this.handleSubmit}>
+        <input
+          className='setting-text'
+          value={value}
+          onChange={this.handleChange}
+        />
+
+        <IconButton
+          disabled={disabled}
+          icon='check'
+          title={title}
+          onClick={this.handleClick}
+        />
+      </form>
+    );
+  }
+
+}
diff --git a/app/javascript/mastodon/features/list_editor/components/search.js b/app/javascript/mastodon/features/list_editor/components/search.js
index f7617fe5876a262e78b84365b04b0742287aa093..e3f069bb8072ba83ebccbe0378d473668a28bc0d 100644
--- a/app/javascript/mastodon/features/list_editor/components/search.js
+++ b/app/javascript/mastodon/features/list_editor/components/search.js
@@ -4,6 +4,7 @@ import { connect } from 'react-redux';
 import { defineMessages, injectIntl } from 'react-intl';
 import { fetchListSuggestions, clearListSuggestions, changeListSuggestions } from '../../../actions/lists';
 import classNames from 'classnames';
+import Icon from 'mastodon/components/icon';
 
 const messages = defineMessages({
   search: { id: 'lists.search', defaultMessage: 'Search among people you follow' },
@@ -65,8 +66,8 @@ class Search extends React.PureComponent {
         </label>
 
         <div role='button' tabIndex='0' className='search__icon' onClick={this.handleClear}>
-          <i className={classNames('fa fa-search', { active: !hasValue })} />
-          <i aria-label={intl.formatMessage(messages.search)} className={classNames('fa fa-times-circle', { active: hasValue })} />
+          <Icon id='search' className={classNames({ active: !hasValue })} />
+          <Icon id='times-circle' aria-label={intl.formatMessage(messages.search)} className={classNames({ active: hasValue })} />
         </div>
       </div>
     );
diff --git a/app/javascript/mastodon/features/list_editor/index.js b/app/javascript/mastodon/features/list_editor/index.js
index aab0cdd0c0cf3b49c8c1cfc283919a7d7d6e7059..48466604a7d2176e1649fdcc4a45726063826e99 100644
--- a/app/javascript/mastodon/features/list_editor/index.js
+++ b/app/javascript/mastodon/features/list_editor/index.js
@@ -7,11 +7,11 @@ import { injectIntl } from 'react-intl';
 import { setupListEditor, clearListSuggestions, resetListEditor } from '../../actions/lists';
 import Account from './components/account';
 import Search from './components/search';
+import EditListForm from './components/edit_list_form';
 import Motion from '../ui/util/optional_motion';
 import spring from 'react-motion/lib/spring';
 
 const mapStateToProps = state => ({
-  title: state.getIn(['listEditor', 'title']),
   accountIds: state.getIn(['listEditor', 'accounts', 'items']),
   searchAccountIds: state.getIn(['listEditor', 'suggestions', 'items']),
 });
@@ -33,7 +33,6 @@ class ListEditor extends ImmutablePureComponent {
     onInitialize: PropTypes.func.isRequired,
     onClear: PropTypes.func.isRequired,
     onReset: PropTypes.func.isRequired,
-    title: PropTypes.string.isRequired,
     accountIds: ImmutablePropTypes.list.isRequired,
     searchAccountIds: ImmutablePropTypes.list.isRequired,
   };
@@ -49,12 +48,12 @@ class ListEditor extends ImmutablePureComponent {
   }
 
   render () {
-    const { title, accountIds, searchAccountIds, onClear } = this.props;
+    const { accountIds, searchAccountIds, onClear } = this.props;
     const showSearch = searchAccountIds.size > 0;
 
     return (
       <div className='modal-root__modal list-editor'>
-        <h4>{title}</h4>
+        <EditListForm />
 
         <Search />
 
diff --git a/app/javascript/mastodon/features/list_timeline/index.js b/app/javascript/mastodon/features/list_timeline/index.js
index 5b047ace483fdcb52948efb31801272e50130100..0db6d2228299e56eefcdccd73db7a4d7d3bc4948 100644
--- a/app/javascript/mastodon/features/list_timeline/index.js
+++ b/app/javascript/mastodon/features/list_timeline/index.js
@@ -14,6 +14,7 @@ import { fetchList, deleteList } from '../../actions/lists';
 import { openModal } from '../../actions/modal';
 import MissingIndicator from '../../components/missing_indicator';
 import LoadingIndicator from '../../components/loading_indicator';
+import Icon from 'mastodon/components/icon';
 
 const messages = defineMessages({
   deleteMessage: { id: 'confirmations.delete_list.message', defaultMessage: 'Are you sure you want to permanently delete this list?' },
@@ -74,6 +75,23 @@ class ListTimeline extends React.PureComponent {
     this.disconnect = dispatch(connectListStream(id));
   }
 
+  componentWillReceiveProps (nextProps) {
+    const { dispatch } = this.props;
+    const { id } = nextProps.params;
+
+    if (id !== this.props.params.id) {
+      if (this.disconnect) {
+        this.disconnect();
+        this.disconnect = null;
+      }
+
+      dispatch(fetchList(id));
+      dispatch(expandListTimeline(id));
+
+      this.disconnect = dispatch(connectListStream(id));
+    }
+  }
+
   componentWillUnmount () {
     if (this.disconnect) {
       this.disconnect();
@@ -150,15 +168,13 @@ class ListTimeline extends React.PureComponent {
         >
           <div className='column-header__links'>
             <button className='text-btn column-header__setting-btn' tabIndex='0' onClick={this.handleEditClick}>
-              <i className='fa fa-pencil' /> <FormattedMessage id='lists.edit' defaultMessage='Edit list' />
+              <Icon id='pencil' /> <FormattedMessage id='lists.edit' defaultMessage='Edit list' />
             </button>
 
             <button className='text-btn column-header__setting-btn' tabIndex='0' onClick={this.handleDeleteClick}>
-              <i className='fa fa-trash' /> <FormattedMessage id='lists.delete' defaultMessage='Delete list' />
+              <Icon id='trash' /> <FormattedMessage id='lists.delete' defaultMessage='Delete list' />
             </button>
           </div>
-
-          <hr />
         </ColumnHeader>
 
         <StatusListContainer
diff --git a/app/javascript/mastodon/features/lists/components/new_list_form.js b/app/javascript/mastodon/features/lists/components/new_list_form.js
index 7392466401780ac0c80822d32cf9291cd54986f1..7faf50be81c4842f3458faad47b6f3391591fa1b 100644
--- a/app/javascript/mastodon/features/lists/components/new_list_form.js
+++ b/app/javascript/mastodon/features/lists/components/new_list_form.js
@@ -66,7 +66,7 @@ class NewListForm extends React.PureComponent {
         </label>
 
         <IconButton
-          disabled={disabled}
+          disabled={disabled || !value}
           icon='plus'
           title={title}
           onClick={this.handleClick}
diff --git a/app/javascript/mastodon/features/lists/index.js b/app/javascript/mastodon/features/lists/index.js
index 24f40c16b6d95153b9d2aae6d351615e675bc53e..015e21b6876ce5115cd47e4eb3c0799c3ae1b136 100644
--- a/app/javascript/mastodon/features/lists/index.js
+++ b/app/javascript/mastodon/features/lists/index.js
@@ -65,11 +65,11 @@ class Lists extends ImmutablePureComponent {
 
         <NewListForm />
 
-        <ColumnSubheading text={intl.formatMessage(messages.subheading)} />
         <ScrollableList
           scrollKey='lists'
           shouldUpdateScroll={shouldUpdateScroll}
           emptyMessage={emptyMessage}
+          prepend={<ColumnSubheading text={intl.formatMessage(messages.subheading)} />}
         >
           {lists.map(list =>
             <ColumnLink key={list.get('id')} to={`/timelines/list/${list.get('id')}`} icon='list-ul' text={list.get('title')} />
diff --git a/app/javascript/mastodon/features/mutes/index.js b/app/javascript/mastodon/features/mutes/index.js
index f979ef72f90fd519189b0a073df36e96e142cb52..4ed29a1ce6717907902022d515357c7c832cc03f 100644
--- a/app/javascript/mastodon/features/mutes/index.js
+++ b/app/javascript/mastodon/features/mutes/index.js
@@ -18,6 +18,7 @@ const messages = defineMessages({
 
 const mapStateToProps = state => ({
   accountIds: state.getIn(['user_lists', 'mutes', 'items']),
+  hasMore: !!state.getIn(['user_lists', 'mutes', 'next']),
 });
 
 export default @connect(mapStateToProps)
@@ -28,6 +29,7 @@ class Mutes extends ImmutablePureComponent {
     params: PropTypes.object.isRequired,
     dispatch: PropTypes.func.isRequired,
     shouldUpdateScroll: PropTypes.func,
+    hasMore: PropTypes.bool,
     accountIds: ImmutablePropTypes.list,
     intl: PropTypes.object.isRequired,
   };
@@ -41,7 +43,7 @@ class Mutes extends ImmutablePureComponent {
   }, 300, { leading: true });
 
   render () {
-    const { intl, shouldUpdateScroll, accountIds } = this.props;
+    const { intl, shouldUpdateScroll, hasMore, accountIds } = this.props;
 
     if (!accountIds) {
       return (
@@ -59,6 +61,7 @@ class Mutes extends ImmutablePureComponent {
         <ScrollableList
           scrollKey='mutes'
           onLoadMore={this.handleLoadMore}
+          hasMore={hasMore}
           shouldUpdateScroll={shouldUpdateScroll}
           emptyMessage={emptyMessage}
         >
diff --git a/app/javascript/mastodon/features/notifications/components/clear_column_button.js b/app/javascript/mastodon/features/notifications/components/clear_column_button.js
index e0bf4c82d5b2029762d64a3506211445d6a6981d..b82fd092f8ea076f0021d8bc3e284ffbf5f6cb99 100644
--- a/app/javascript/mastodon/features/notifications/components/clear_column_button.js
+++ b/app/javascript/mastodon/features/notifications/components/clear_column_button.js
@@ -1,6 +1,7 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import { FormattedMessage } from 'react-intl';
+import Icon from 'mastodon/components/icon';
 
 export default class ClearColumnButton extends React.PureComponent {
 
@@ -10,7 +11,7 @@ export default class ClearColumnButton extends React.PureComponent {
 
   render () {
     return (
-      <button className='text-btn column-header__setting-btn' tabIndex='0' onClick={this.props.onClick}><i className='fa fa-eraser' /> <FormattedMessage id='notifications.clear' defaultMessage='Clear notifications' /></button>
+      <button className='text-btn column-header__setting-btn' tabIndex='0' onClick={this.props.onClick}><Icon id='eraser' /> <FormattedMessage id='notifications.clear' defaultMessage='Clear notifications' /></button>
     );
   }
 
diff --git a/app/javascript/mastodon/features/notifications/components/column_settings.js b/app/javascript/mastodon/features/notifications/components/column_settings.js
index a334fd63cc8fa7bf4c2c947d29efcabce05cefce..60a86312a1e0d9bfa02ec304151b924e5394af90 100644
--- a/app/javascript/mastodon/features/notifications/components/column_settings.js
+++ b/app/javascript/mastodon/features/notifications/components/column_settings.js
@@ -89,6 +89,17 @@ export default class ColumnSettings extends React.PureComponent {
             <SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'reblog']} onChange={onChange} label={soundStr} />
           </div>
         </div>
+
+        <div role='group' aria-labelledby='notifications-poll'>
+          <span id='notifications-poll' className='column-settings__section'><FormattedMessage id='notifications.column_settings.poll' defaultMessage='Poll results:' /></span>
+
+          <div className='column-settings__row'>
+            <SettingToggle prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'poll']} onChange={onChange} label={alertStr} />
+            {showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingPath={['alerts', 'poll']} onChange={this.onPushChange} label={pushStr} />}
+            <SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'poll']} onChange={onChange} label={showStr} />
+            <SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'poll']} onChange={onChange} label={soundStr} />
+          </div>
+        </div>
       </div>
     );
   }
diff --git a/app/javascript/mastodon/features/notifications/components/filter_bar.js b/app/javascript/mastodon/features/notifications/components/filter_bar.js
index f95a2c9dea695ad2f8b8d053e194a87c7072ce88..3f3e6ab7d234dfde1db3d585220fc2617b83aa84 100644
--- a/app/javascript/mastodon/features/notifications/components/filter_bar.js
+++ b/app/javascript/mastodon/features/notifications/components/filter_bar.js
@@ -1,11 +1,13 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
+import Icon from 'mastodon/components/icon';
 
 const tooltips = defineMessages({
   mentions: { id: 'notifications.filter.mentions', defaultMessage: 'Mentions' },
   favourites: { id: 'notifications.filter.favourites', defaultMessage: 'Favourites' },
   boosts: { id: 'notifications.filter.boosts', defaultMessage: 'Boosts' },
+  polls: { id: 'notifications.filter.polls', defaultMessage: 'Poll results' },
   follows: { id: 'notifications.filter.follows', defaultMessage: 'Follows' },
 });
 
@@ -62,28 +64,35 @@ class FilterBar extends React.PureComponent {
           onClick={this.onClick('mention')}
           title={intl.formatMessage(tooltips.mentions)}
         >
-          <i className='fa fa-fw fa-at' />
+          <Icon id='at' fixedWidth />
         </button>
         <button
           className={selectedFilter === 'favourite' ? 'active' : ''}
           onClick={this.onClick('favourite')}
           title={intl.formatMessage(tooltips.favourites)}
         >
-          <i className='fa fa-fw fa-star' />
+          <Icon id='star' fixedWidth />
         </button>
         <button
           className={selectedFilter === 'reblog' ? 'active' : ''}
           onClick={this.onClick('reblog')}
           title={intl.formatMessage(tooltips.boosts)}
         >
-          <i className='fa fa-fw fa-retweet' />
+          <Icon id='retweet' fixedWidth />
+        </button>
+        <button
+          className={selectedFilter === 'poll' ? 'active' : ''}
+          onClick={this.onClick('poll')}
+          title={intl.formatMessage(tooltips.polls)}
+        >
+          <Icon id='tasks' fixedWidth />
         </button>
         <button
           className={selectedFilter === 'follow' ? 'active' : ''}
           onClick={this.onClick('follow')}
           title={intl.formatMessage(tooltips.follows)}
         >
-          <i className='fa fa-fw fa-user-plus' />
+          <Icon id='user-plus' fixedWidth />
         </button>
       </div>
     );
diff --git a/app/javascript/mastodon/features/notifications/components/notification.js b/app/javascript/mastodon/features/notifications/components/notification.js
index 44da423adcd6fdc63a30ddef653477e4abf930b7..41e9324e6f6065e49ae7db6ba1a6274321f7199d 100644
--- a/app/javascript/mastodon/features/notifications/components/notification.js
+++ b/app/javascript/mastodon/features/notifications/components/notification.js
@@ -7,6 +7,7 @@ import { injectIntl, FormattedMessage } from 'react-intl';
 import Permalink from '../../../components/permalink';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import { HotKeys } from 'react-hotkeys';
+import Icon from 'mastodon/components/icon';
 
 const notificationForScreenReader = (intl, message, timestamp) => {
   const output = [message];
@@ -29,7 +30,15 @@ class Notification extends ImmutablePureComponent {
     onMoveUp: PropTypes.func.isRequired,
     onMoveDown: PropTypes.func.isRequired,
     onMention: PropTypes.func.isRequired,
+    onFavourite: PropTypes.func.isRequired,
+    onReblog: PropTypes.func.isRequired,
+    onToggleHidden: PropTypes.func.isRequired,
+    status: ImmutablePropTypes.map,
     intl: PropTypes.object.isRequired,
+    getScrollPosition: PropTypes.func,
+    updateScrollBottom: PropTypes.func,
+    cacheMediaWidth: PropTypes.func,
+    cachedMediaWidth: PropTypes.number,
   };
 
   handleMoveUp = () => {
@@ -64,14 +73,32 @@ class Notification extends ImmutablePureComponent {
     onMention(notification.get('account'), this.context.router.history);
   }
 
+  handleHotkeyFavourite = () => {
+    const { status } = this.props;
+    if (status) this.props.onFavourite(status);
+  }
+
+  handleHotkeyBoost = e => {
+    const { status } = this.props;
+    if (status) this.props.onReblog(status, e);
+  }
+
+  handleHotkeyToggleHidden = () => {
+    const { status } = this.props;
+    if (status) this.props.onToggleHidden(status);
+  }
+
   getHandlers () {
     return {
-      moveUp: this.handleMoveUp,
-      moveDown: this.handleMoveDown,
+      reply: this.handleMention,
+      favourite: this.handleHotkeyFavourite,
+      boost: this.handleHotkeyBoost,
+      mention: this.handleMention,
       open: this.handleOpen,
       openProfile: this.handleOpenProfile,
-      mention: this.handleMention,
-      reply: this.handleMention,
+      moveUp: this.handleMoveUp,
+      moveDown: this.handleMoveDown,
+      toggleHidden: this.handleHotkeyToggleHidden,
     };
   }
 
@@ -83,7 +110,7 @@ class Notification extends ImmutablePureComponent {
         <div className='notification notification-follow focusable' tabIndex='0' aria-label={notificationForScreenReader(intl, intl.formatMessage({ id: 'notification.follow', defaultMessage: '{name} followed you' }, { name: account.get('acct') }), notification.get('created_at'))}>
           <div className='notification__message'>
             <div className='notification__favourite-icon-wrapper'>
-              <i className='fa fa-fw fa-user-plus' />
+              <Icon id='user-plus' fixedWidth />
             </div>
 
             <span title={notification.get('created_at')}>
@@ -106,6 +133,10 @@ class Notification extends ImmutablePureComponent {
         onMoveDown={this.handleMoveDown}
         onMoveUp={this.handleMoveUp}
         contextType='notifications'
+        getScrollPosition={this.props.getScrollPosition}
+        updateScrollBottom={this.props.updateScrollBottom}
+        cachedMediaWidth={this.props.cachedMediaWidth}
+        cacheMediaWidth={this.props.cacheMediaWidth}
       />
     );
   }
@@ -118,7 +149,7 @@ class Notification extends ImmutablePureComponent {
         <div className='notification notification-favourite focusable' tabIndex='0' aria-label={notificationForScreenReader(intl, intl.formatMessage({ id: 'notification.favourite', defaultMessage: '{name} favourited your status' }, { name: notification.getIn(['account', 'acct']) }), notification.get('created_at'))}>
           <div className='notification__message'>
             <div className='notification__favourite-icon-wrapper'>
-              <i className='fa fa-fw fa-star star-icon' />
+              <Icon id='star' className='star-icon' fixedWidth />
             </div>
 
             <span title={notification.get('created_at')}>
@@ -126,7 +157,17 @@ class Notification extends ImmutablePureComponent {
             </span>
           </div>
 
-          <StatusContainer id={notification.get('status')} account={notification.get('account')} muted withDismiss hidden={!!this.props.hidden} />
+          <StatusContainer
+            id={notification.get('status')}
+            account={notification.get('account')}
+            muted
+            withDismiss
+            hidden={!!this.props.hidden}
+            getScrollPosition={this.props.getScrollPosition}
+            updateScrollBottom={this.props.updateScrollBottom}
+            cachedMediaWidth={this.props.cachedMediaWidth}
+            cacheMediaWidth={this.props.cacheMediaWidth}
+          />
         </div>
       </HotKeys>
     );
@@ -140,7 +181,7 @@ class Notification extends ImmutablePureComponent {
         <div className='notification notification-reblog focusable' tabIndex='0' aria-label={notificationForScreenReader(intl, intl.formatMessage({ id: 'notification.reblog', defaultMessage: '{name} boosted your status' }, { name: notification.getIn(['account', 'acct']) }), notification.get('created_at'))}>
           <div className='notification__message'>
             <div className='notification__favourite-icon-wrapper'>
-              <i className='fa fa-fw fa-retweet' />
+              <Icon id='retweet' fixedWidth />
             </div>
 
             <span title={notification.get('created_at')}>
@@ -148,7 +189,49 @@ class Notification extends ImmutablePureComponent {
             </span>
           </div>
 
-          <StatusContainer id={notification.get('status')} account={notification.get('account')} muted withDismiss hidden={this.props.hidden} />
+          <StatusContainer
+            id={notification.get('status')}
+            account={notification.get('account')}
+            muted
+            withDismiss
+            hidden={this.props.hidden}
+            getScrollPosition={this.props.getScrollPosition}
+            updateScrollBottom={this.props.updateScrollBottom}
+            cachedMediaWidth={this.props.cachedMediaWidth}
+            cacheMediaWidth={this.props.cacheMediaWidth}
+          />
+        </div>
+      </HotKeys>
+    );
+  }
+
+  renderPoll (notification) {
+    const { intl } = this.props;
+
+    return (
+      <HotKeys handlers={this.getHandlers()}>
+        <div className='notification notification-poll focusable' tabIndex='0' aria-label={notificationForScreenReader(intl, intl.formatMessage({ id: 'notification.poll', defaultMessage: 'A poll you have voted in has ended' }), notification.get('created_at'))}>
+          <div className='notification__message'>
+            <div className='notification__favourite-icon-wrapper'>
+              <Icon id='tasks' fixedWidth />
+            </div>
+
+            <span title={notification.get('created_at')}>
+              <FormattedMessage id='notification.poll' defaultMessage='A poll you have voted in has ended' />
+            </span>
+          </div>
+
+          <StatusContainer
+            id={notification.get('status')}
+            account={notification.get('account')}
+            muted
+            withDismiss
+            hidden={this.props.hidden}
+            getScrollPosition={this.props.getScrollPosition}
+            updateScrollBottom={this.props.updateScrollBottom}
+            cachedMediaWidth={this.props.cachedMediaWidth}
+            cacheMediaWidth={this.props.cacheMediaWidth}
+          />
         </div>
       </HotKeys>
     );
@@ -169,6 +252,8 @@ class Notification extends ImmutablePureComponent {
       return this.renderFavourite(notification, link);
     case 'reblog':
       return this.renderReblog(notification, link);
+    case 'poll':
+      return this.renderPoll(notification);
     }
 
     return null;
diff --git a/app/javascript/mastodon/features/notifications/containers/notification_container.js b/app/javascript/mastodon/features/notifications/containers/notification_container.js
index 921aa460f522b0386402b4fefd2dd81bf4b6bc3e..78576c760cbe541a1838c7b799e7e69cdf124b71 100644
--- a/app/javascript/mastodon/features/notifications/containers/notification_container.js
+++ b/app/javascript/mastodon/features/notifications/containers/notification_container.js
@@ -1,14 +1,31 @@
 import { connect } from 'react-redux';
-import { makeGetNotification } from '../../../selectors';
+import { makeGetNotification, makeGetStatus } from '../../../selectors';
 import Notification from '../components/notification';
+import { openModal } from '../../../actions/modal';
 import { mentionCompose } from '../../../actions/compose';
+import {
+  reblog,
+  favourite,
+  unreblog,
+  unfavourite,
+} from '../../../actions/interactions';
+import {
+  hideStatus,
+  revealStatus,
+} from '../../../actions/statuses';
+import { boostModal } from '../../../initial_state';
 
 const makeMapStateToProps = () => {
   const getNotification = makeGetNotification();
+  const getStatus = makeGetStatus();
 
-  const mapStateToProps = (state, props) => ({
-    notification: getNotification(state, props.notification, props.accountId),
-  });
+  const mapStateToProps = (state, props) => {
+    const notification = getNotification(state, props.notification, props.accountId);
+    return {
+      notification: notification,
+      status: notification.get('status') ? getStatus(state, { id: notification.get('status') }) : null,
+    };
+  };
 
   return mapStateToProps;
 };
@@ -17,6 +34,38 @@ const mapDispatchToProps = dispatch => ({
   onMention: (account, router) => {
     dispatch(mentionCompose(account, router));
   },
+
+  onModalReblog (status) {
+    dispatch(reblog(status));
+  },
+
+  onReblog (status, e) {
+    if (status.get('reblogged')) {
+      dispatch(unreblog(status));
+    } else {
+      if (e.shiftKey || !boostModal) {
+        this.onModalReblog(status);
+      } else {
+        dispatch(openModal('BOOST', { status, onReblog: this.onModalReblog }));
+      }
+    }
+  },
+
+  onFavourite (status) {
+    if (status.get('favourited')) {
+      dispatch(unfavourite(status));
+    } else {
+      dispatch(favourite(status));
+    }
+  },
+
+  onToggleHidden (status) {
+    if (status.get('hidden')) {
+      dispatch(revealStatus(status.get('id')));
+    } else {
+      dispatch(hideStatus(status.get('id')));
+    }
+  },
 });
 
 export default connect(makeMapStateToProps, mapDispatchToProps)(Notification);
diff --git a/app/javascript/mastodon/features/notifications/index.js b/app/javascript/mastodon/features/notifications/index.js
index 9430b20505040a1d1023098b3c0c470d6d21f34e..006c4565750282b2fb8db24617edf5fddda9aab2 100644
--- a/app/javascript/mastodon/features/notifications/index.js
+++ b/app/javascript/mastodon/features/notifications/index.js
@@ -113,18 +113,24 @@ class Notifications extends React.PureComponent {
 
   handleMoveUp = id => {
     const elementIndex = this.props.notifications.findIndex(item => item !== null && item.get('id') === id) - 1;
-    this._selectChild(elementIndex);
+    this._selectChild(elementIndex, true);
   }
 
   handleMoveDown = id => {
     const elementIndex = this.props.notifications.findIndex(item => item !== null && item.get('id') === id) + 1;
-    this._selectChild(elementIndex);
+    this._selectChild(elementIndex, false);
   }
 
-  _selectChild (index) {
-    const element = this.column.node.querySelector(`article:nth-of-type(${index + 1}) .focusable`);
+  _selectChild (index, align_top) {
+    const container = this.column.node;
+    const element = container.querySelector(`article:nth-of-type(${index + 1}) .focusable`);
 
     if (element) {
+      if (align_top && container.scrollTop > element.offsetTop) {
+        element.scrollIntoView(true);
+      } else if (!align_top && container.scrollTop + container.clientHeight < element.offsetTop + element.offsetHeight) {
+        element.scrollIntoView(false);
+      }
       element.focus();
     }
   }
diff --git a/app/javascript/mastodon/features/public_timeline/index.js b/app/javascript/mastodon/features/public_timeline/index.js
index d640033ebb6f47b5b261e453ea457bb9cb0b00be..2b7d9c56f99519b08a92e751d05a1eccdc33c330 100644
--- a/app/javascript/mastodon/features/public_timeline/index.js
+++ b/app/javascript/mastodon/features/public_timeline/index.js
@@ -124,7 +124,7 @@ class PublicTimeline extends React.PureComponent {
           onLoadMore={this.handleLoadMore}
           trackScroll={!pinned}
           scrollKey={`public_timeline-${columnId}`}
-          emptyMessage={<FormattedMessage id='empty_column.public' defaultMessage='There is nothing here! Write something publicly, or manually follow users from other instances to fill it up' />}
+          emptyMessage={<FormattedMessage id='empty_column.public' defaultMessage='There is nothing here! Write something publicly, or manually follow users from other servers to fill it up' />}
           shouldUpdateScroll={shouldUpdateScroll}
         />
       </Column>
diff --git a/app/javascript/mastodon/features/report/components/status_check_box.js b/app/javascript/mastodon/features/report/components/status_check_box.js
index 2552d94d899c9c8d9f60d5aba4f829697b28dc16..c29e517da86e241d34ea78bc18c7284c1ddeca32 100644
--- a/app/javascript/mastodon/features/report/components/status_check_box.js
+++ b/app/javascript/mastodon/features/report/components/status_check_box.js
@@ -35,6 +35,7 @@ export default class StatusCheckBox extends React.PureComponent {
             {Component => (
               <Component
                 preview={video.get('preview_url')}
+                blurhash={video.get('blurhash')}
                 src={video.get('url')}
                 alt={video.get('description')}
                 width={239}
diff --git a/app/javascript/mastodon/features/search/index.js b/app/javascript/mastodon/features/search/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..76bf70d4bd2360347caf4252c1ccd2f509e5ee8f
--- /dev/null
+++ b/app/javascript/mastodon/features/search/index.js
@@ -0,0 +1,17 @@
+import React from 'react';
+import SearchContainer from 'mastodon/features/compose/containers/search_container';
+import SearchResultsContainer from 'mastodon/features/compose/containers/search_results_container';
+
+const Search = () => (
+  <div className='column search-page'>
+    <SearchContainer />
+
+    <div className='drawer__pager'>
+      <div className='drawer__inner darker'>
+        <SearchResultsContainer />
+      </div>
+    </div>
+  </div>
+);
+
+export default Search;
diff --git a/app/javascript/mastodon/features/standalone/community_timeline/index.js b/app/javascript/mastodon/features/standalone/community_timeline/index.js
deleted file mode 100644
index f917f41c974a2dbe6e4789783931ab22881c62f6..0000000000000000000000000000000000000000
--- a/app/javascript/mastodon/features/standalone/community_timeline/index.js
+++ /dev/null
@@ -1,71 +0,0 @@
-import React from 'react';
-import { connect } from 'react-redux';
-import PropTypes from 'prop-types';
-import StatusListContainer from '../../ui/containers/status_list_container';
-import { expandCommunityTimeline } from '../../../actions/timelines';
-import Column from '../../../components/column';
-import ColumnHeader from '../../../components/column_header';
-import { defineMessages, injectIntl } from 'react-intl';
-import { connectCommunityStream } from '../../../actions/streaming';
-
-const messages = defineMessages({
-  title: { id: 'standalone.public_title', defaultMessage: 'A look inside...' },
-});
-
-export default @connect()
-@injectIntl
-class CommunityTimeline extends React.PureComponent {
-
-  static propTypes = {
-    dispatch: PropTypes.func.isRequired,
-    intl: PropTypes.object.isRequired,
-  };
-
-  handleHeaderClick = () => {
-    this.column.scrollTop();
-  }
-
-  setRef = c => {
-    this.column = c;
-  }
-
-  componentDidMount () {
-    const { dispatch } = this.props;
-
-    dispatch(expandCommunityTimeline());
-    this.disconnect = dispatch(connectCommunityStream());
-  }
-
-  componentWillUnmount () {
-    if (this.disconnect) {
-      this.disconnect();
-      this.disconnect = null;
-    }
-  }
-
-  handleLoadMore = maxId => {
-    this.props.dispatch(expandCommunityTimeline({ maxId }));
-  }
-
-  render () {
-    const { intl } = this.props;
-
-    return (
-      <Column ref={this.setRef} label={intl.formatMessage(messages.title)}>
-        <ColumnHeader
-          icon='users'
-          title={intl.formatMessage(messages.title)}
-          onClick={this.handleHeaderClick}
-        />
-
-        <StatusListContainer
-          timelineId='community'
-          onLoadMore={this.handleLoadMore}
-          scrollKey='standalone_public_timeline'
-          trackScroll={false}
-        />
-      </Column>
-    );
-  }
-
-}
diff --git a/app/javascript/mastodon/features/standalone/hashtag_timeline/index.js b/app/javascript/mastodon/features/standalone/hashtag_timeline/index.js
index 333726f94225d91c946a10b1eb41243f5f161a9d..73919c39dd429259d579edaf0ffa5615dc81c206 100644
--- a/app/javascript/mastodon/features/standalone/hashtag_timeline/index.js
+++ b/app/javascript/mastodon/features/standalone/hashtag_timeline/index.js
@@ -2,13 +2,12 @@ import React from 'react';
 import { connect } from 'react-redux';
 import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
-import { expandHashtagTimeline } from '../../../actions/timelines';
-import { connectHashtagStream } from '../../../actions/streaming';
+import { expandHashtagTimeline } from 'mastodon/actions/timelines';
 import Masonry from 'react-masonry-infinite';
 import { List as ImmutableList } from 'immutable';
-import DetailedStatusContainer from '../../status/containers/detailed_status_container';
+import DetailedStatusContainer from 'mastodon/features/status/containers/detailed_status_container';
 import { debounce } from 'lodash';
-import LoadingIndicator from '../../../components/loading_indicator';
+import LoadingIndicator from 'mastodon/components/loading_indicator';
 
 const mapStateToProps = (state, { hashtag }) => ({
   statusIds: state.getIn(['timelines', `hashtag:${hashtag}`, 'items'], ImmutableList()),
@@ -31,14 +30,6 @@ class HashtagTimeline extends React.PureComponent {
     const { dispatch, hashtag } = this.props;
 
     dispatch(expandHashtagTimeline(hashtag));
-    this.disconnect = dispatch(connectHashtagStream(hashtag, hashtag));
-  }
-
-  componentWillUnmount () {
-    if (this.disconnect) {
-      this.disconnect();
-      this.disconnect = null;
-    }
   }
 
   handleLoadMore = () => {
diff --git a/app/javascript/mastodon/features/standalone/public_timeline/index.js b/app/javascript/mastodon/features/standalone/public_timeline/index.js
index 618696eb167f5412874b51fe8769e7cc996d782d..19b0b14be6a35d2decfb9f4f89825672b397f222 100644
--- a/app/javascript/mastodon/features/standalone/public_timeline/index.js
+++ b/app/javascript/mastodon/features/standalone/public_timeline/index.js
@@ -1,70 +1,98 @@
 import React from 'react';
 import { connect } from 'react-redux';
 import PropTypes from 'prop-types';
-import StatusListContainer from '../../ui/containers/status_list_container';
-import { expandPublicTimeline } from '../../../actions/timelines';
-import Column from '../../../components/column';
-import ColumnHeader from '../../../components/column_header';
-import { defineMessages, injectIntl } from 'react-intl';
-import { connectPublicStream } from '../../../actions/streaming';
-
-const messages = defineMessages({
-  title: { id: 'standalone.public_title', defaultMessage: 'A look inside...' },
-});
-
-export default @connect()
-@injectIntl
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import { expandPublicTimeline, expandCommunityTimeline } from 'mastodon/actions/timelines';
+import Masonry from 'react-masonry-infinite';
+import { List as ImmutableList, Map as ImmutableMap } from 'immutable';
+import DetailedStatusContainer from 'mastodon/features/status/containers/detailed_status_container';
+import { debounce } from 'lodash';
+import LoadingIndicator from 'mastodon/components/loading_indicator';
+
+const mapStateToProps = (state, { local }) => {
+  const timeline = state.getIn(['timelines', local ? 'community' : 'public'], ImmutableMap());
+
+  return {
+    statusIds: timeline.get('items', ImmutableList()),
+    isLoading: timeline.get('isLoading', false),
+    hasMore: timeline.get('hasMore', false),
+  };
+};
+
+export default @connect(mapStateToProps)
 class PublicTimeline extends React.PureComponent {
 
   static propTypes = {
     dispatch: PropTypes.func.isRequired,
-    intl: PropTypes.object.isRequired,
+    statusIds: ImmutablePropTypes.list.isRequired,
+    isLoading: PropTypes.bool.isRequired,
+    hasMore: PropTypes.bool.isRequired,
+    local: PropTypes.bool,
   };
 
-  handleHeaderClick = () => {
-    this.column.scrollTop();
+  componentDidMount () {
+    this._connect();
   }
 
-  setRef = c => {
-    this.column = c;
+  componentDidUpdate (prevProps) {
+    if (prevProps.local !== this.props.local) {
+      this._connect();
+    }
   }
 
-  componentDidMount () {
-    const { dispatch } = this.props;
+  _connect () {
+    const { dispatch, local } = this.props;
 
-    dispatch(expandPublicTimeline());
-    this.disconnect = dispatch(connectPublicStream());
+    dispatch(local ? expandCommunityTimeline() : expandPublicTimeline());
   }
 
-  componentWillUnmount () {
-    if (this.disconnect) {
-      this.disconnect();
-      this.disconnect = null;
+  handleLoadMore = () => {
+    const { dispatch, statusIds, local } = this.props;
+    const maxId = statusIds.last();
+
+    if (maxId) {
+      dispatch(local ? expandCommunityTimeline({ maxId }) : expandPublicTimeline({ maxId }));
     }
   }
 
-  handleLoadMore = maxId => {
-    this.props.dispatch(expandPublicTimeline({ maxId }));
+  setRef = c => {
+    this.masonry = c;
   }
 
+  handleHeightChange = debounce(() => {
+    if (!this.masonry) {
+      return;
+    }
+
+    this.masonry.forcePack();
+  }, 50)
+
   render () {
-    const { intl } = this.props;
+    const { statusIds, hasMore, isLoading } = this.props;
+
+    const sizes = [
+      { columns: 1, gutter: 0 },
+      { mq: '415px', columns: 1, gutter: 10 },
+      { mq: '640px', columns: 2, gutter: 10 },
+      { mq: '960px', columns: 3, gutter: 10 },
+      { mq: '1255px', columns: 3, gutter: 10 },
+    ];
+
+    const loader = (isLoading && statusIds.isEmpty()) ? <LoadingIndicator key={0} /> : undefined;
 
     return (
-      <Column ref={this.setRef} label={intl.formatMessage(messages.title)}>
-        <ColumnHeader
-          icon='globe'
-          title={intl.formatMessage(messages.title)}
-          onClick={this.handleHeaderClick}
-        />
-
-        <StatusListContainer
-          timelineId='public'
-          onLoadMore={this.handleLoadMore}
-          scrollKey='standalone_public_timeline'
-          trackScroll={false}
-        />
-      </Column>
+      <Masonry ref={this.setRef} className='statuses-grid' hasMore={hasMore} loadMore={this.handleLoadMore} sizes={sizes} loader={loader}>
+        {statusIds.map(statusId => (
+          <div className='statuses-grid__item' key={statusId}>
+            <DetailedStatusContainer
+              id={statusId}
+              compact
+              measureHeight
+              onHeightChange={this.handleHeightChange}
+            />
+          </div>
+        )).toArray()}
+      </Masonry>
     );
   }
 
diff --git a/app/javascript/mastodon/features/status/components/action_bar.js b/app/javascript/mastodon/features/status/components/action_bar.js
index d3b725283ad74d0178ca375e38fde8b9dd4dfdd1..3e511b7a64fa109af768ace680ab776347c1048c 100644
--- a/app/javascript/mastodon/features/status/components/action_bar.js
+++ b/app/javascript/mastodon/features/status/components/action_bar.js
@@ -28,6 +28,7 @@ const messages = defineMessages({
   embed: { id: 'status.embed', defaultMessage: 'Embed' },
   admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
   admin_status: { id: 'status.admin_status', defaultMessage: 'Open this status in the moderation interface' },
+  copy: { id: 'status.copy', defaultMessage: 'Copy link to status' },
 });
 
 export default @injectIntl
@@ -91,7 +92,7 @@ class ActionBar extends React.PureComponent {
   }
 
   handleBlockClick = () => {
-    this.props.onBlock(this.props.status.get('account'));
+    this.props.onBlock(this.props.status);
   }
 
   handleReport = () => {
@@ -113,6 +114,25 @@ class ActionBar extends React.PureComponent {
     this.props.onEmbed(this.props.status);
   }
 
+  handleCopy = () => {
+    const url      = this.props.status.get('url');
+    const textarea = document.createElement('textarea');
+
+    textarea.textContent    = url;
+    textarea.style.position = 'fixed';
+
+    document.body.appendChild(textarea);
+
+    try {
+      textarea.select();
+      document.execCommand('copy');
+    } catch (e) {
+
+    } finally {
+      document.body.removeChild(textarea);
+    }
+  }
+
   render () {
     const { status, intl } = this.props;
 
@@ -122,6 +142,7 @@ class ActionBar extends React.PureComponent {
     let menu = [];
 
     if (publicStatus) {
+      menu.push({ text: intl.formatMessage(messages.copy), action: this.handleCopy });
       menu.push({ text: intl.formatMessage(messages.embed), action: this.handleEmbed });
       menu.push(null);
     }
diff --git a/app/javascript/mastodon/features/status/components/card.js b/app/javascript/mastodon/features/status/components/card.js
index 8491299ef49c68d1bf3128efa74f8e36a7d02c13..0eff544119f66b62a6022242fc6161d356b06fd9 100644
--- a/app/javascript/mastodon/features/status/components/card.js
+++ b/app/javascript/mastodon/features/status/components/card.js
@@ -4,6 +4,7 @@ import Immutable from 'immutable';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import punycode from 'punycode';
 import classnames from 'classnames';
+import Icon from 'mastodon/components/icon';
 
 const IDNA_PREFIX = 'xn--';
 
@@ -60,6 +61,8 @@ export default class Card extends React.PureComponent {
     maxDescription: PropTypes.number,
     onOpenMedia: PropTypes.func.isRequired,
     compact: PropTypes.bool,
+    defaultWidth: PropTypes.number,
+    cacheWidth: PropTypes.func,
   };
 
   static defaultProps = {
@@ -68,7 +71,7 @@ export default class Card extends React.PureComponent {
   };
 
   state = {
-    width: 280,
+    width: this.props.defaultWidth || 280,
     embedded: false,
   };
 
@@ -111,6 +114,7 @@ export default class Card extends React.PureComponent {
 
   setRef = c => {
     if (c) {
+      if (this.props.cacheWidth) this.props.cacheWidth(c.offsetWidth);
       this.setState({ width: c.offsetWidth });
     }
   }
@@ -175,8 +179,8 @@ export default class Card extends React.PureComponent {
 
             <div className='status-card__actions'>
               <div>
-                <button onClick={this.handleEmbedClick}><i className={`fa fa-${iconVariant}`} /></button>
-                {horizontal && <a href={card.get('url')} target='_blank' rel='noopener'><i className='fa fa-external-link' /></a>}
+                <button onClick={this.handleEmbedClick}><Icon id={iconVariant} /></button>
+                {horizontal && <a href={card.get('url')} target='_blank' rel='noopener'><Icon id='external-link' /></a>}
               </div>
             </div>
           </div>
@@ -198,7 +202,7 @@ export default class Card extends React.PureComponent {
     } else {
       embed = (
         <div className='status-card__image'>
-          <i className='fa fa-file-text' />
+          <Icon id='file-text' />
         </div>
       );
     }
diff --git a/app/javascript/mastodon/features/status/components/detailed_status.js b/app/javascript/mastodon/features/status/components/detailed_status.js
index 0630387d297745febbf454132ad1c4e1a6705a50..4af157af1347883deaf0a7820224a3f30d15625d 100644
--- a/app/javascript/mastodon/features/status/components/detailed_status.js
+++ b/app/javascript/mastodon/features/status/components/detailed_status.js
@@ -5,7 +5,6 @@ import Avatar from '../../../components/avatar';
 import DisplayName from '../../../components/display_name';
 import StatusContent from '../../../components/status_content';
 import MediaGallery from '../../../components/media_gallery';
-import AttachmentList from '../../../components/attachment_list';
 import { Link } from 'react-router-dom';
 import { FormattedDate, FormattedNumber } from 'react-intl';
 import Card from './card';
@@ -13,6 +12,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
 import Video from '../../video';
 import scheduleIdleTask from '../../ui/util/schedule_idle_task';
 import classNames from 'classnames';
+import Icon from 'mastodon/components/icon';
 
 export default class DetailedStatus extends ImmutablePureComponent {
 
@@ -21,7 +21,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
   };
 
   static propTypes = {
-    status: ImmutablePropTypes.map.isRequired,
+    status: ImmutablePropTypes.map,
     onOpenMedia: PropTypes.func.isRequired,
     onOpenVideo: PropTypes.func.isRequired,
     onToggleHidden: PropTypes.func.isRequired,
@@ -29,6 +29,8 @@ export default class DetailedStatus extends ImmutablePureComponent {
     onHeightChange: PropTypes.func,
     domain: PropTypes.string.isRequired,
     compact: PropTypes.bool,
+    showMedia: PropTypes.bool,
+    onToggleMediaVisibility: PropTypes.func,
   };
 
   state = {
@@ -86,7 +88,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
   }
 
   render () {
-    const status = this.props.status.get('reblog') ? this.props.status.get('reblog') : this.props.status;
+    const status = (this.props.status && this.props.status.get('reblog')) ? this.props.status.get('reblog') : this.props.status;
     const outerStyle = { boxSizing: 'border-box' };
     const { compact } = this.props;
 
@@ -105,21 +107,22 @@ export default class DetailedStatus extends ImmutablePureComponent {
     }
 
     if (status.get('media_attachments').size > 0) {
-      if (status.get('media_attachments').some(item => item.get('type') === 'unknown')) {
-        media = <AttachmentList media={status.get('media_attachments')} />;
-      } else if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
-        const video = status.getIn(['media_attachments', 0]);
+      if (['video', 'audio'].includes(status.getIn(['media_attachments', 0, 'type']))) {
+        const attachment = status.getIn(['media_attachments', 0]);
 
         media = (
           <Video
-            preview={video.get('preview_url')}
-            src={video.get('url')}
-            alt={video.get('description')}
+            preview={attachment.get('preview_url')}
+            blurhash={attachment.get('blurhash')}
+            src={attachment.get('url')}
+            alt={attachment.get('description')}
             width={300}
             height={150}
             inline
             onOpenVideo={this.handleOpenVideo}
             sensitive={status.get('sensitive')}
+            visible={this.props.showMedia}
+            onToggleVisibility={this.props.onToggleMediaVisibility}
           />
         );
       } else {
@@ -130,6 +133,8 @@ export default class DetailedStatus extends ImmutablePureComponent {
             media={status.get('media_attachments')}
             height={300}
             onOpenMedia={this.props.onOpenMedia}
+            visible={this.props.showMedia}
+            onToggleVisibility={this.props.onToggleMediaVisibility}
           />
         );
       }
@@ -148,11 +153,11 @@ export default class DetailedStatus extends ImmutablePureComponent {
     }
 
     if (status.get('visibility') === 'private') {
-      reblogLink = <i className={`fa fa-${reblogIcon}`} />;
+      reblogLink = <Icon id={reblogIcon} />;
     } else if (this.context.router) {
       reblogLink = (
         <Link to={`/statuses/${status.get('id')}/reblogs`} className='detailed-status__link'>
-          <i className={`fa fa-${reblogIcon}`} />
+          <Icon id={reblogIcon} />
           <span className='detailed-status__reblogs'>
             <FormattedNumber value={status.get('reblogs_count')} />
           </span>
@@ -161,7 +166,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
     } else {
       reblogLink = (
         <a href={`/interact/${status.get('id')}?type=reblog`} className='detailed-status__link' onClick={this.handleModalLink}>
-          <i className={`fa fa-${reblogIcon}`} />
+          <Icon id={reblogIcon} />
           <span className='detailed-status__reblogs'>
             <FormattedNumber value={status.get('reblogs_count')} />
           </span>
@@ -172,7 +177,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
     if (this.context.router) {
       favouriteLink = (
         <Link to={`/statuses/${status.get('id')}/favourites`} className='detailed-status__link'>
-          <i className='fa fa-star' />
+          <Icon id='star' />
           <span className='detailed-status__favorites'>
             <FormattedNumber value={status.get('favourites_count')} />
           </span>
@@ -181,7 +186,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
     } else {
       favouriteLink = (
         <a href={`/interact/${status.get('id')}?type=favourite`} className='detailed-status__link' onClick={this.handleModalLink}>
-          <i className='fa fa-star' />
+          <Icon id='star' />
           <span className='detailed-status__favorites'>
             <FormattedNumber value={status.get('favourites_count')} />
           </span>
diff --git a/app/javascript/mastodon/features/status/containers/detailed_status_container.js b/app/javascript/mastodon/features/status/containers/detailed_status_container.js
index 2c0db0a6b23e7d7835157c1b1307db8fc6f2be59..61e0c428a108c49443428f14d49b063dd655e08e 100644
--- a/app/javascript/mastodon/features/status/containers/detailed_status_container.js
+++ b/app/javascript/mastodon/features/status/containers/detailed_status_container.js
@@ -38,6 +38,7 @@ const messages = defineMessages({
   blockConfirm: { id: 'confirmations.block.confirm', defaultMessage: 'Block' },
   replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
   replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
+  blockAndReport: { id: 'confirmations.block.block_and_report', defaultMessage: 'Block & Report' },
 });
 
 const makeMapStateToProps = () => {
@@ -135,11 +136,17 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
     dispatch(openModal('VIDEO', { media, time }));
   },
 
-  onBlock (account) {
+  onBlock (status) {
+    const account = status.get('account');
     dispatch(openModal('CONFIRM', {
       message: <FormattedMessage id='confirmations.block.message' defaultMessage='Are you sure you want to block {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
       confirm: intl.formatMessage(messages.blockConfirm),
       onConfirm: () => dispatch(blockAccount(account.get('id'))),
+      secondary: intl.formatMessage(messages.blockAndReport),
+      onSecondary: () => {
+        dispatch(blockAccount(account.get('id')));
+        dispatch(initReport(account, status));
+      },
     }));
   },
 
diff --git a/app/javascript/mastodon/features/status/index.js b/app/javascript/mastodon/features/status/index.js
index d48b682ebbc22303bdeca152a177627bfdfc9523..0422111ae38e1a1e76a361e26f216dae888fa3b1 100644
--- a/app/javascript/mastodon/features/status/index.js
+++ b/app/javascript/mastodon/features/status/index.js
@@ -4,6 +4,7 @@ import { connect } from 'react-redux';
 import PropTypes from 'prop-types';
 import classNames from 'classnames';
 import ImmutablePropTypes from 'react-immutable-proptypes';
+import { createSelector } from 'reselect';
 import { fetchStatus } from '../../actions/statuses';
 import MissingIndicator from '../../components/missing_indicator';
 import DetailedStatus from './components/detailed_status';
@@ -43,7 +44,8 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
 import { HotKeys } from 'react-hotkeys';
 import { boostModal, deleteModal } from '../../initial_state';
 import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from '../ui/util/fullscreen';
-import { textForScreenReader } from '../../components/status';
+import { textForScreenReader, defaultMediaVisibility } from '../../components/status';
+import Icon from 'mastodon/components/icon';
 
 const messages = defineMessages({
   deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
@@ -56,44 +58,64 @@ const messages = defineMessages({
   detailedStatus: { id: 'status.detailed_status', defaultMessage: 'Detailed conversation view' },
   replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
   replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
+  blockAndReport: { id: 'confirmations.block.block_and_report', defaultMessage: 'Block & Report' },
 });
 
 const makeMapStateToProps = () => {
   const getStatus = makeGetStatus();
 
-  const mapStateToProps = (state, props) => {
-    const status = getStatus(state, { id: props.params.statusId });
+  const getAncestorsIds = createSelector([
+    (_, { id }) => id,
+    state => state.getIn(['contexts', 'inReplyTos']),
+  ], (statusId, inReplyTos) => {
     let ancestorsIds = Immutable.List();
+    ancestorsIds = ancestorsIds.withMutations(mutable => {
+      let id = statusId;
+
+      while (id) {
+        mutable.unshift(id);
+        id = inReplyTos.get(id);
+      }
+    });
+
+    return ancestorsIds;
+  });
+
+  const getDescendantsIds = createSelector([
+    (_, { id }) => id,
+    state => state.getIn(['contexts', 'replies']),
+  ], (statusId, contextReplies) => {
     let descendantsIds = Immutable.List();
+    descendantsIds = descendantsIds.withMutations(mutable => {
+      const ids = [statusId];
 
-    if (status) {
-      ancestorsIds = ancestorsIds.withMutations(mutable => {
-        let id = status.get('in_reply_to_id');
+      while (ids.length > 0) {
+        let id        = ids.shift();
+        const replies = contextReplies.get(id);
 
-        while (id) {
-          mutable.unshift(id);
-          id = state.getIn(['contexts', 'inReplyTos', id]);
+        if (statusId !== id) {
+          mutable.push(id);
         }
-      });
 
-      descendantsIds = descendantsIds.withMutations(mutable => {
-        const ids = [status.get('id')];
+        if (replies) {
+          replies.reverse().forEach(reply => {
+            ids.unshift(reply);
+          });
+        }
+      }
+    });
 
-        while (ids.length > 0) {
-          let id        = ids.shift();
-          const replies = state.getIn(['contexts', 'replies', id]);
+    return descendantsIds;
+  });
 
-          if (status.get('id') !== id) {
-            mutable.push(id);
-          }
+  const mapStateToProps = (state, props) => {
+    const status = getStatus(state, { id: props.params.statusId });
+    let ancestorsIds = Immutable.List();
+    let descendantsIds = Immutable.List();
 
-          if (replies) {
-            replies.reverse().forEach(reply => {
-              ids.unshift(reply);
-            });
-          }
-        }
-      });
+    if (status) {
+      ancestorsIds = getAncestorsIds(state, { id: status.get('in_reply_to_id') });
+      descendantsIds = getDescendantsIds(state, { id: status.get('id') });
     }
 
     return {
@@ -129,6 +151,8 @@ class Status extends ImmutablePureComponent {
 
   state = {
     fullscreen: false,
+    showMedia: defaultMediaVisibility(this.props.status),
+    loadedStatusId: undefined,
   };
 
   componentWillMount () {
@@ -144,6 +168,14 @@ class Status extends ImmutablePureComponent {
       this._scrolledIntoView = false;
       this.props.dispatch(fetchStatus(nextProps.params.statusId));
     }
+
+    if (nextProps.status && nextProps.status.get('id') !== this.state.loadedStatusId) {
+      this.setState({ showMedia: defaultMediaVisibility(nextProps.status), loadedStatusId: nextProps.status.get('id') });
+    }
+  }
+
+  handleToggleMediaVisibility = () => {
+    this.setState({ showMedia: !this.state.showMedia });
   }
 
   handleFavouriteClick = (status) => {
@@ -252,13 +284,19 @@ class Status extends ImmutablePureComponent {
     }
   }
 
-  handleBlockClick = (account) => {
+  handleBlockClick = (status) => {
     const { dispatch, intl } = this.props;
+    const account = status.get('account');
 
     dispatch(openModal('CONFIRM', {
       message: <FormattedMessage id='confirmations.block.message' defaultMessage='Are you sure you want to block {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
       confirm: intl.formatMessage(messages.blockConfirm),
       onConfirm: () => dispatch(blockAccount(account.get('id'))),
+      secondary: intl.formatMessage(messages.blockAndReport),
+      onSecondary: () => {
+        dispatch(blockAccount(account.get('id')));
+        dispatch(initReport(account, status));
+      },
     }));
   }
 
@@ -304,19 +342,23 @@ class Status extends ImmutablePureComponent {
     this.handleToggleHidden(this.props.status);
   }
 
+  handleHotkeyToggleSensitive = () => {
+    this.handleToggleMediaVisibility();
+  }
+
   handleMoveUp = id => {
     const { status, ancestorsIds, descendantsIds } = this.props;
 
     if (id === status.get('id')) {
-      this._selectChild(ancestorsIds.size - 1);
+      this._selectChild(ancestorsIds.size - 1, true);
     } else {
       let index = ancestorsIds.indexOf(id);
 
       if (index === -1) {
         index = descendantsIds.indexOf(id);
-        this._selectChild(ancestorsIds.size + index);
+        this._selectChild(ancestorsIds.size + index, true);
       } else {
-        this._selectChild(index - 1);
+        this._selectChild(index - 1, true);
       }
     }
   }
@@ -325,23 +367,29 @@ class Status extends ImmutablePureComponent {
     const { status, ancestorsIds, descendantsIds } = this.props;
 
     if (id === status.get('id')) {
-      this._selectChild(ancestorsIds.size + 1);
+      this._selectChild(ancestorsIds.size + 1, false);
     } else {
       let index = ancestorsIds.indexOf(id);
 
       if (index === -1) {
         index = descendantsIds.indexOf(id);
-        this._selectChild(ancestorsIds.size + index + 2);
+        this._selectChild(ancestorsIds.size + index + 2, false);
       } else {
-        this._selectChild(index + 1);
+        this._selectChild(index + 1, false);
       }
     }
   }
 
-  _selectChild (index) {
-    const element = this.node.querySelectorAll('.focusable')[index];
+  _selectChild (index, align_top) {
+    const container = this.node;
+    const element = container.querySelectorAll('.focusable')[index];
 
     if (element) {
+      if (align_top && container.scrollTop > element.offsetTop) {
+        element.scrollIntoView(true);
+      } else if (!align_top && container.scrollTop + container.clientHeight < element.offsetTop + element.offsetHeight) {
+        element.scrollIntoView(false);
+      }
       element.focus();
     }
   }
@@ -418,6 +466,7 @@ class Status extends ImmutablePureComponent {
       mention: this.handleHotkeyMention,
       openProfile: this.handleHotkeyOpenProfile,
       toggleHidden: this.handleHotkeyToggleHidden,
+      toggleSensitive: this.handleHotkeyToggleSensitive,
     };
 
     return (
@@ -425,7 +474,7 @@ class Status extends ImmutablePureComponent {
         <ColumnHeader
           showBackButton
           extraButton={(
-            <button className='column-header__button' title={intl.formatMessage(status.get('hidden') ? messages.revealAll : messages.hideAll)} aria-label={intl.formatMessage(status.get('hidden') ? messages.revealAll : messages.hideAll)} onClick={this.handleToggleAll} aria-pressed={status.get('hidden') ? 'false' : 'true'}><i className={`fa fa-${status.get('hidden') ? 'eye-slash' : 'eye'}`} /></button>
+            <button className='column-header__button' title={intl.formatMessage(status.get('hidden') ? messages.revealAll : messages.hideAll)} aria-label={intl.formatMessage(status.get('hidden') ? messages.revealAll : messages.hideAll)} onClick={this.handleToggleAll} aria-pressed={status.get('hidden') ? 'false' : 'true'}><Icon id={status.get('hidden') ? 'eye-slash' : 'eye'} /></button>
           )}
         />
 
@@ -434,13 +483,15 @@ class Status extends ImmutablePureComponent {
             {ancestors}
 
             <HotKeys handlers={handlers}>
-              <div className={classNames('focusable', 'detailed-status__wrapper')} tabIndex='0' aria-label={textForScreenReader(intl, status, false, !status.get('hidden'))}>
+              <div className={classNames('focusable', 'detailed-status__wrapper')} tabIndex='0' aria-label={textForScreenReader(intl, status, false)}>
                 <DetailedStatus
                   status={status}
                   onOpenVideo={this.handleOpenVideo}
                   onOpenMedia={this.handleOpenMedia}
                   onToggleHidden={this.handleToggleHidden}
                   domain={domain}
+                  showMedia={this.state.showMedia}
+                  onToggleMediaVisibility={this.handleToggleMediaVisibility}
                 />
 
                 <ActionBar
diff --git a/app/javascript/mastodon/features/ui/components/actions_modal.js b/app/javascript/mastodon/features/ui/components/actions_modal.js
index 9792eba5f70713bd51c8396ac5d3f82549ab9c73..00280f7a685352e27e0c250615755e39826ee615 100644
--- a/app/javascript/mastodon/features/ui/components/actions_modal.js
+++ b/app/javascript/mastodon/features/ui/components/actions_modal.js
@@ -64,7 +64,7 @@ export default class ActionsModal extends ImmutablePureComponent {
       <div className='modal-root__modal actions-modal'>
         {status}
 
-        <ul>
+        <ul className={classNames({ 'with-status': !!status })}>
           {this.props.actions.map(this.renderAction)}
         </ul>
       </div>
diff --git a/app/javascript/mastodon/features/ui/components/boost_modal.js b/app/javascript/mastodon/features/ui/components/boost_modal.js
index b128e67d23d02b0258000081ac06b44db8e9c7d3..70f4a1282e2a55239615147388a91177a9df8e64 100644
--- a/app/javascript/mastodon/features/ui/components/boost_modal.js
+++ b/app/javascript/mastodon/features/ui/components/boost_modal.js
@@ -8,8 +8,11 @@ import Avatar from '../../../components/avatar';
 import RelativeTimestamp from '../../../components/relative_timestamp';
 import DisplayName from '../../../components/display_name';
 import ImmutablePureComponent from 'react-immutable-pure-component';
+import Icon from 'mastodon/components/icon';
+import AttachmentList from 'mastodon/components/attachment_list';
 
 const messages = defineMessages({
+  cancel_reblog: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' },
   reblog: { id: 'status.reblog', defaultMessage: 'Boost' },
 });
 
@@ -50,6 +53,7 @@ class BoostModal extends ImmutablePureComponent {
 
   render () {
     const { status, intl } = this.props;
+    const buttonText = status.get('reblogged') ? messages.cancel_reblog : messages.reblog;
 
     return (
       <div className='modal-root__modal boost-modal'>
@@ -70,12 +74,19 @@ class BoostModal extends ImmutablePureComponent {
             </div>
 
             <StatusContent status={status} />
+
+            {status.get('media_attachments').size > 0 && (
+              <AttachmentList
+                compact
+                media={status.get('media_attachments')}
+              />
+            )}
           </div>
         </div>
 
         <div className='boost-modal__action-bar'>
-          <div><FormattedMessage id='boost_modal.combo' defaultMessage='You can press {combo} to skip this next time' values={{ combo: <span>Shift + <i className='fa fa-retweet' /></span> }} /></div>
-          <Button text={intl.formatMessage(messages.reblog)} onClick={this.handleReblog} ref={this.setRef} />
+          <div><FormattedMessage id='boost_modal.combo' defaultMessage='You can press {combo} to skip this next time' values={{ combo: <span>Shift + <Icon id='retweet' /></span> }} /></div>
+          <Button text={intl.formatMessage(buttonText)} onClick={this.handleReblog} ref={this.setRef} />
         </div>
       </div>
     );
diff --git a/app/javascript/mastodon/features/ui/components/bundle.js b/app/javascript/mastodon/features/ui/components/bundle.js
index e7d93525175c2653b90d9bd31d57b36a1813a042..a60ace35ba670ebc37efa82763e9f6c29b396980 100644
--- a/app/javascript/mastodon/features/ui/components/bundle.js
+++ b/app/javascript/mastodon/features/ui/components/bundle.js
@@ -53,6 +53,11 @@ class Bundle extends React.PureComponent {
     const { fetchComponent, onFetch, onFetchSuccess, onFetchFail, renderDelay } = props || this.props;
     const cachedMod = Bundle.cache.get(fetchComponent);
 
+    if (fetchComponent === undefined) {
+      this.setState({ mod: null });
+      return Promise.resolve();
+    }
+
     onFetch();
 
     if (cachedMod) {
diff --git a/app/javascript/mastodon/features/ui/components/column_header.js b/app/javascript/mastodon/features/ui/components/column_header.js
index e8bdd8054f47275687ec0068667b857e2cd41ea3..b1a36e173d70a520345aa0356962a1cbdc585e16 100644
--- a/app/javascript/mastodon/features/ui/components/column_header.js
+++ b/app/javascript/mastodon/features/ui/components/column_header.js
@@ -1,6 +1,7 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import classNames from 'classnames';
+import Icon from 'mastodon/components/icon';
 
 export default class ColumnHeader extends React.PureComponent {
 
@@ -21,7 +22,7 @@ export default class ColumnHeader extends React.PureComponent {
     let iconElement = '';
 
     if (icon) {
-      iconElement = <i className={`fa fa-fw fa-${icon} column-header__icon`} />;
+      iconElement = <Icon id={icon} fixedWidth className='column-header__icon' />;
     }
 
     return (
diff --git a/app/javascript/mastodon/features/ui/components/column_link.js b/app/javascript/mastodon/features/ui/components/column_link.js
index 25c2d1cf86027557ac65f845029cf08354fa83d5..0a25f1ea203d7b7a0ea12d8794a4608bc8d3d797 100644
--- a/app/javascript/mastodon/features/ui/components/column_link.js
+++ b/app/javascript/mastodon/features/ui/components/column_link.js
@@ -1,6 +1,7 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import { Link } from 'react-router-dom';
+import Icon from 'mastodon/components/icon';
 
 const ColumnLink = ({ icon, text, to, href, method, badge }) => {
   const badgeElement = typeof badge !== 'undefined' ? <span className='column-link__badge'>{badge}</span> : null;
@@ -8,7 +9,7 @@ const ColumnLink = ({ icon, text, to, href, method, badge }) => {
   if (href) {
     return (
       <a href={href} className='column-link' data-method={method}>
-        <i className={`fa fa-fw fa-${icon} column-link__icon`} />
+        <Icon id={icon} fixedWidth className='column-link__icon' />
         {text}
         {badgeElement}
       </a>
@@ -16,7 +17,7 @@ const ColumnLink = ({ icon, text, to, href, method, badge }) => {
   } else {
     return (
       <Link to={to} className='column-link'>
-        <i className={`fa fa-fw fa-${icon} column-link__icon`} />
+        <Icon id={icon} fixedWidth className='column-link__icon' />
         {text}
         {badgeElement}
       </Link>
diff --git a/app/javascript/mastodon/features/ui/components/columns_area.js b/app/javascript/mastodon/features/ui/components/columns_area.js
index b7e350cbce29175a8e4e578be958364a05574985..042e44e43e9f46cb42518941a7544a25b41688bb 100644
--- a/app/javascript/mastodon/features/ui/components/columns_area.js
+++ b/app/javascript/mastodon/features/ui/components/columns_area.js
@@ -5,7 +5,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 
 import ReactSwipeableViews from 'react-swipeable-views';
-import { links, getIndex, getLink } from './tabs_bar';
+import TabsBar, { links, getIndex, getLink } from './tabs_bar';
 import { Link } from 'react-router-dom';
 
 import BundleContainer from '../containers/bundle_container';
@@ -13,6 +13,9 @@ import ColumnLoading from './column_loading';
 import DrawerLoading from './drawer_loading';
 import BundleColumnError from './bundle_column_error';
 import { Compose, Notifications, HomeTimeline, CommunityTimeline, PublicTimeline, HashtagTimeline, DirectTimeline, FavouritedStatuses, ListTimeline } from '../../ui/util/async-components';
+import Icon from 'mastodon/components/icon';
+import ComposePanel from './compose_panel';
+import NavigationPanel from './navigation_panel';
 
 import detectPassiveEvents from 'detect-passive-events';
 import { scrollRight } from '../../../scroll';
@@ -107,6 +110,11 @@ class ColumnsArea extends ImmutablePureComponent {
     // React-router does this for us, but too late, feeling laggy.
     document.querySelector(currentLinkSelector).classList.remove('active');
     document.querySelector(nextLinkSelector).classList.add('active');
+
+    if (!this.state.shouldAnimate && typeof this.pendingIndex === 'number') {
+      this.context.router.history.push(getLink(this.pendingIndex));
+      this.pendingIndex = null;
+    }
   }
 
   handleAnimationEnd = () => {
@@ -138,7 +146,7 @@ class ColumnsArea extends ImmutablePureComponent {
       <ColumnLoading title={title} icon={icon} />;
 
     return (
-      <div className='columns-area' key={index}>
+      <div className='columns-area columns-area--mobile' key={index}>
         {view}
       </div>
     );
@@ -157,22 +165,40 @@ class ColumnsArea extends ImmutablePureComponent {
     const { shouldAnimate } = this.state;
 
     const columnIndex = getIndex(this.context.router.history.location.pathname);
-    this.pendingIndex = null;
 
     if (singleColumn) {
-      const floatingActionButton = shouldHideFAB(this.context.router.history.location.pathname) ? null : <Link key='floating-action-button' to='/statuses/new' className='floating-action-button' aria-label={intl.formatMessage(messages.publish)}><i className='fa fa-pencil' /></Link>;
+      const floatingActionButton = shouldHideFAB(this.context.router.history.location.pathname) ? null : <Link key='floating-action-button' to='/statuses/new' className='floating-action-button' aria-label={intl.formatMessage(messages.publish)}><Icon id='pencil' /></Link>;
 
-      return columnIndex !== -1 ? [
+      const content = 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>,
-
-        floatingActionButton,
-      ] : [
-        <div className='columns-area'>{children}</div>,
-
-        floatingActionButton,
-      ];
+        </ReactSwipeableViews>
+      ) : (
+        <div key='content' className='columns-area columns-area--mobile'>{children}</div>
+      );
+
+      return (
+        <div className='columns-area__panels'>
+          <div className='columns-area__panels__pane columns-area__panels__pane--compositional'>
+            <div className='columns-area__panels__pane__inner'>
+              <ComposePanel />
+            </div>
+          </div>
+
+          <div className='columns-area__panels__main'>
+            <TabsBar key='tabs' />
+            {content}
+          </div>
+
+          <div className='columns-area__panels__pane columns-area__panels__pane--start columns-area__panels__pane--navigational'>
+            <div className='columns-area__panels__pane__inner'>
+              <NavigationPanel />
+            </div>
+          </div>
+
+          {floatingActionButton}
+        </div>
+      );
     }
 
     return (
diff --git a/app/javascript/mastodon/features/ui/components/compose_panel.js b/app/javascript/mastodon/features/ui/components/compose_panel.js
new file mode 100644
index 0000000000000000000000000000000000000000..c7821f473a1a3a7afeb802a49bfb2f4d256b4d1a
--- /dev/null
+++ b/app/javascript/mastodon/features/ui/components/compose_panel.js
@@ -0,0 +1,16 @@
+import React from 'react';
+import SearchContainer from 'mastodon/features/compose/containers/search_container';
+import ComposeFormContainer from 'mastodon/features/compose/containers/compose_form_container';
+import NavigationContainer from 'mastodon/features/compose/containers/navigation_container';
+import LinkFooter from './link_footer';
+
+const ComposePanel = () => (
+  <div className='compose-panel'>
+    <SearchContainer openInRoute />
+    <NavigationContainer />
+    <ComposeFormContainer singleColumn />
+    <LinkFooter withHotkeys />
+  </div>
+);
+
+export default ComposePanel;
diff --git a/app/javascript/mastodon/features/ui/components/confirmation_modal.js b/app/javascript/mastodon/features/ui/components/confirmation_modal.js
index f0f3ad134d22e8f7b29e81b46ac362c6ee97fb7f..1227fa453e4f37b40dc1ea2add7345f3ccc38236 100644
--- a/app/javascript/mastodon/features/ui/components/confirmation_modal.js
+++ b/app/javascript/mastodon/features/ui/components/confirmation_modal.js
@@ -11,6 +11,8 @@ class ConfirmationModal extends React.PureComponent {
     confirm: PropTypes.string.isRequired,
     onClose: PropTypes.func.isRequired,
     onConfirm: PropTypes.func.isRequired,
+    secondary: PropTypes.string,
+    onSecondary: PropTypes.func,
     intl: PropTypes.object.isRequired,
   };
 
@@ -23,6 +25,11 @@ class ConfirmationModal extends React.PureComponent {
     this.props.onConfirm();
   }
 
+  handleSecondary = () => {
+    this.props.onClose();
+    this.props.onSecondary();
+  }
+
   handleCancel = () => {
     this.props.onClose();
   }
@@ -32,7 +39,7 @@ class ConfirmationModal extends React.PureComponent {
   }
 
   render () {
-    const { message, confirm } = this.props;
+    const { message, confirm, secondary } = this.props;
 
     return (
       <div className='modal-root__modal confirmation-modal'>
@@ -44,6 +51,9 @@ class ConfirmationModal extends React.PureComponent {
           <Button onClick={this.handleCancel} className='confirmation-modal__cancel-button'>
             <FormattedMessage id='confirmation_modal.cancel' defaultMessage='Cancel' />
           </Button>
+          {secondary !== undefined && (
+            <Button text={secondary} onClick={this.handleSecondary} className='confirmation-modal__secondary-button' />
+          )}
           <Button text={confirm} onClick={this.handleClick} ref={this.setRef} />
         </div>
       </div>
diff --git a/app/javascript/mastodon/features/ui/components/follow_requests_nav_link.js b/app/javascript/mastodon/features/ui/components/follow_requests_nav_link.js
new file mode 100644
index 0000000000000000000000000000000000000000..90c953893aded65914ed70d1c9f381d58e92e56c
--- /dev/null
+++ b/app/javascript/mastodon/features/ui/components/follow_requests_nav_link.js
@@ -0,0 +1,44 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { fetchFollowRequests } from 'mastodon/actions/accounts';
+import { connect } from 'react-redux';
+import { NavLink, withRouter } from 'react-router-dom';
+import IconWithBadge from 'mastodon/components/icon_with_badge';
+import { me } from 'mastodon/initial_state';
+import { List as ImmutableList } from 'immutable';
+import { FormattedMessage } from 'react-intl';
+
+const mapStateToProps = state => ({
+  locked: state.getIn(['accounts', me, 'locked']),
+  count: state.getIn(['user_lists', 'follow_requests', 'items'], ImmutableList()).size,
+});
+
+export default @withRouter
+@connect(mapStateToProps)
+class FollowRequestsNavLink extends React.Component {
+
+  static propTypes = {
+    dispatch: PropTypes.func.isRequired,
+    locked: PropTypes.bool,
+    count: PropTypes.number.isRequired,
+  };
+
+  componentDidMount () {
+    const { dispatch, locked } = this.props;
+
+    if (locked) {
+      dispatch(fetchFollowRequests());
+    }
+  }
+
+  render () {
+    const { locked, count } = this.props;
+
+    if (!locked || count === 0) {
+      return null;
+    }
+
+    return <NavLink className='column-link column-link--transparent' to='/follow_requests'><IconWithBadge className='column-link__icon' id='user-plus' count={count} /><FormattedMessage id='navigation_bar.follow_requests' defaultMessage='Follow requests' /></NavLink>;
+  }
+
+}
diff --git a/app/javascript/mastodon/features/ui/components/link_footer.js b/app/javascript/mastodon/features/ui/components/link_footer.js
new file mode 100644
index 0000000000000000000000000000000000000000..b481983dc88649fbb01580d9546ba979e4d41c17
--- /dev/null
+++ b/app/javascript/mastodon/features/ui/components/link_footer.js
@@ -0,0 +1,35 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { FormattedMessage } from 'react-intl';
+import { Link } from 'react-router-dom';
+import { invitesEnabled, version, repository, source_url } from 'mastodon/initial_state';
+
+const LinkFooter = ({ withHotkeys }) => (
+  <div className='getting-started__footer'>
+    <ul>
+      {invitesEnabled && <li><a href='/invites' target='_blank'><FormattedMessage id='getting_started.invite' defaultMessage='Invite people' /></a> · </li>}
+      {withHotkeys && <li><Link to='/keyboard-shortcuts'><FormattedMessage id='navigation_bar.keyboard_shortcuts' defaultMessage='Hotkeys' /></Link> · </li>}
+      <li><a href='/auth/edit'><FormattedMessage id='getting_started.security' defaultMessage='Security' /></a> · </li>
+      <li><a href='/about/more' target='_blank'><FormattedMessage id='navigation_bar.info' defaultMessage='About this server' /></a> · </li>
+      <li><a href='https://joinmastodon.org/apps' target='_blank'><FormattedMessage id='navigation_bar.apps' defaultMessage='Mobile apps' /></a> · </li>
+      <li><a href='/terms' target='_blank'><FormattedMessage id='getting_started.terms' defaultMessage='Terms of service' /></a> · </li>
+      <li><a href='/settings/applications' target='_blank'><FormattedMessage id='getting_started.developers' defaultMessage='Developers' /></a> · </li>
+      <li><a href='https://docs.joinmastodon.org' target='_blank'><FormattedMessage id='getting_started.documentation' defaultMessage='Documentation' /></a> · </li>
+      <li><a href='/auth/sign_out' data-method='delete'><FormattedMessage id='navigation_bar.logout' defaultMessage='Logout' /></a></li>
+    </ul>
+
+    <p>
+      <FormattedMessage
+        id='getting_started.open_source_notice'
+        defaultMessage='Mastodon is open source software. You can contribute or report issues on GitHub at {github}.'
+        values={{ github: <span><a href={source_url} rel='noopener' target='_blank'>{repository}</a> (v{version})</span> }}
+      />
+    </p>
+  </div>
+);
+
+LinkFooter.propTypes = {
+  withHotkeys: PropTypes.bool,
+};
+
+export default LinkFooter;
diff --git a/app/javascript/mastodon/features/ui/components/list_panel.js b/app/javascript/mastodon/features/ui/components/list_panel.js
new file mode 100644
index 0000000000000000000000000000000000000000..1f7ec683a7f00475e2be4073d95c08a06e4bba4a
--- /dev/null
+++ b/app/javascript/mastodon/features/ui/components/list_panel.js
@@ -0,0 +1,55 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+import { fetchLists } from 'mastodon/actions/lists';
+import { connect } from 'react-redux';
+import { createSelector } from 'reselect';
+import { NavLink, withRouter } from 'react-router-dom';
+import Icon from 'mastodon/components/icon';
+
+const getOrderedLists = createSelector([state => state.get('lists')], lists => {
+  if (!lists) {
+    return lists;
+  }
+
+  return lists.toList().filter(item => !!item).sort((a, b) => a.get('title').localeCompare(b.get('title'))).take(4);
+});
+
+const mapStateToProps = state => ({
+  lists: getOrderedLists(state),
+});
+
+export default @withRouter
+@connect(mapStateToProps)
+class ListPanel extends ImmutablePureComponent {
+
+  static propTypes = {
+    dispatch: PropTypes.func.isRequired,
+    lists: ImmutablePropTypes.list,
+  };
+
+  componentDidMount () {
+    const { dispatch } = this.props;
+    dispatch(fetchLists());
+  }
+
+  render () {
+    const { lists } = this.props;
+
+    if (!lists || lists.isEmpty()) {
+      return null;
+    }
+
+    return (
+      <div>
+        <hr />
+
+        {lists.map(list => (
+          <NavLink key={list.get('id')} className='column-link column-link--transparent' strict to={`/timelines/list/${list.get('id')}`}><Icon className='column-link__icon' id='list-ul' fixedWidth />{list.get('title')}</NavLink>
+        ))}
+      </div>
+    );
+  }
+
+}
diff --git a/app/javascript/mastodon/features/ui/components/media_modal.js b/app/javascript/mastodon/features/ui/components/media_modal.js
index d29a4a6a7d3a6a19319dd3bf102830216eb8f04c..da2ac5f26d5a4670bb0bd08f27e399af87b52463 100644
--- a/app/javascript/mastodon/features/ui/components/media_modal.js
+++ b/app/javascript/mastodon/features/ui/components/media_modal.js
@@ -2,13 +2,14 @@ import React from 'react';
 import ReactSwipeableViews from 'react-swipeable-views';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import PropTypes from 'prop-types';
-import Video from '../../video';
-import ExtendedVideoPlayer from '../../../components/extended_video_player';
+import Video from 'mastodon/features/video';
+import ExtendedVideoPlayer from 'mastodon/components/extended_video_player';
 import classNames from 'classnames';
-import { defineMessages, injectIntl } from 'react-intl';
-import IconButton from '../../../components/icon_button';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
+import IconButton from 'mastodon/components/icon_button';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import ImageLoader from './image_loader';
+import Icon from 'mastodon/components/icon';
 
 const messages = defineMessages({
   close: { id: 'lightbox.close', defaultMessage: 'Close' },
@@ -23,6 +24,7 @@ class MediaModal extends ImmutablePureComponent {
 
   static propTypes = {
     media: ImmutablePropTypes.list.isRequired,
+    status: ImmutablePropTypes.map,
     index: PropTypes.number.isRequired,
     onClose: PropTypes.func.isRequired,
     intl: PropTypes.object.isRequired,
@@ -71,9 +73,12 @@ class MediaModal extends ImmutablePureComponent {
 
   componentDidMount () {
     window.addEventListener('keydown', this.handleKeyDown, false);
+
     if (this.context.router) {
       const history = this.context.router.history;
+
       history.push(history.location.pathname, previewState);
+
       this.unlistenHistory = history.listen(() => {
         this.props.onClose();
       });
@@ -82,6 +87,7 @@ class MediaModal extends ImmutablePureComponent {
 
   componentWillUnmount () {
     window.removeEventListener('keydown', this.handleKeyDown);
+
     if (this.context.router) {
       this.unlistenHistory();
 
@@ -101,15 +107,22 @@ class MediaModal extends ImmutablePureComponent {
     }));
   };
 
+  handleStatusClick = e => {
+    if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
+      e.preventDefault();
+      this.context.router.history.push(`/statuses/${this.props.status.get('id')}`);
+    }
+  }
+
   render () {
-    const { media, intl, onClose } = this.props;
+    const { media, status, intl, onClose } = this.props;
     const { navigationHidden } = this.state;
 
     const index = this.getIndex();
     let pagination = [];
 
-    const leftNav  = media.size > 1 && <button tabIndex='0' className='media-modal__nav media-modal__nav--left' onClick={this.handlePrevClick} aria-label={intl.formatMessage(messages.previous)}><i className='fa fa-fw fa-chevron-left' /></button>;
-    const rightNav = media.size > 1 && <button tabIndex='0' className='media-modal__nav  media-modal__nav--right' onClick={this.handleNextClick} aria-label={intl.formatMessage(messages.next)}><i className='fa fa-fw fa-chevron-right' /></button>;
+    const leftNav  = media.size > 1 && <button tabIndex='0' className='media-modal__nav media-modal__nav--left' onClick={this.handlePrevClick} aria-label={intl.formatMessage(messages.previous)}><Icon id='chevron-left' fixedWidth /></button>;
+    const rightNav = media.size > 1 && <button tabIndex='0' className='media-modal__nav  media-modal__nav--right' onClick={this.handleNextClick} aria-label={intl.formatMessage(messages.next)}><Icon id='chevron-right' fixedWidth /></button>;
 
     if (media.size > 1) {
       pagination = media.map((item, i) => {
@@ -143,6 +156,7 @@ class MediaModal extends ImmutablePureComponent {
         return (
           <Video
             preview={image.get('preview_url')}
+            blurhash={image.get('blurhash')}
             src={image.get('url')}
             width={image.get('width')}
             height={image.get('height')}
@@ -205,10 +219,19 @@ class MediaModal extends ImmutablePureComponent {
             {content}
           </ReactSwipeableViews>
         </div>
+
         <div className={navigationClassName}>
           <IconButton className='media-modal__close' title={intl.formatMessage(messages.close)} icon='times' onClick={onClose} size={40} />
+
           {leftNav}
           {rightNav}
+
+          {status && (
+            <div className={classNames('media-modal__meta', { 'media-modal__meta--shifted': media.size > 1 })}>
+              <a href={status.get('url')} onClick={this.handleStatusClick}><FormattedMessage id='lightbox.view_context' defaultMessage='View context' /></a>
+            </div>
+          )}
+
           <ul className='media-modal__pagination'>
             {pagination}
           </ul>
diff --git a/app/javascript/mastodon/features/ui/components/navigation_panel.js b/app/javascript/mastodon/features/ui/components/navigation_panel.js
new file mode 100644
index 0000000000000000000000000000000000000000..ef3ad2e092f86e07936985041471a08906620e03
--- /dev/null
+++ b/app/javascript/mastodon/features/ui/components/navigation_panel.js
@@ -0,0 +1,31 @@
+import React from 'react';
+import { NavLink, withRouter } from 'react-router-dom';
+import { FormattedMessage } from 'react-intl';
+import Icon from 'mastodon/components/icon';
+import { profile_directory } from 'mastodon/initial_state';
+import NotificationsCounterIcon from './notifications_counter_icon';
+import FollowRequestsNavLink from './follow_requests_nav_link';
+import ListPanel from './list_panel';
+
+const NavigationPanel = () => (
+  <div className='navigation-panel'>
+    <NavLink className='column-link column-link--transparent' to='/timelines/home' data-preview-title-id='column.home' data-preview-icon='home' ><Icon className='column-link__icon' id='home' fixedWidth /><FormattedMessage id='tabs_bar.home' defaultMessage='Home' /></NavLink>
+    <NavLink className='column-link column-link--transparent' to='/notifications' data-preview-title-id='column.notifications' data-preview-icon='bell' ><NotificationsCounterIcon className='column-link__icon' /><FormattedMessage id='tabs_bar.notifications' defaultMessage='Notifications' /></NavLink>
+    <FollowRequestsNavLink />
+    <NavLink className='column-link column-link--transparent' to='/timelines/public/local' data-preview-title-id='column.community' data-preview-icon='users' ><Icon className='column-link__icon' id='users' fixedWidth /><FormattedMessage id='tabs_bar.local_timeline' defaultMessage='Local' /></NavLink>
+    <NavLink className='column-link column-link--transparent' exact to='/timelines/public' data-preview-title-id='column.public' data-preview-icon='globe' ><Icon className='column-link__icon' id='globe' fixedWidth /><FormattedMessage id='tabs_bar.federated_timeline' defaultMessage='Federated' /></NavLink>
+    <NavLink className='column-link column-link--transparent' to='/timelines/direct'><Icon className='column-link__icon' id='envelope' fixedWidth /><FormattedMessage id='navigation_bar.direct' defaultMessage='Direct messages' /></NavLink>
+    <NavLink className='column-link column-link--transparent' to='/favourites'><Icon className='column-link__icon' id='star' fixedWidth /><FormattedMessage id='navigation_bar.favourites' defaultMessage='Favourites' /></NavLink>
+    <NavLink className='column-link column-link--transparent' to='/lists'><Icon className='column-link__icon' id='list-ul' fixedWidth /><FormattedMessage id='navigation_bar.lists' defaultMessage='Lists' /></NavLink>
+
+    <ListPanel />
+
+    <hr />
+
+    <a className='column-link column-link--transparent' href='/settings/preferences'><Icon className='column-link__icon' id='cog' fixedWidth /><FormattedMessage id='navigation_bar.preferences' defaultMessage='Preferences' /></a>
+    <a className='column-link column-link--transparent' href='/relationships'><Icon className='column-link__icon' id='users' fixedWidth /><FormattedMessage id='navigation_bar.follows_and_followers' defaultMessage='Follows and followers' /></a>
+    {!!profile_directory && <a className='column-link column-link--transparent' href='/explore'><Icon className='column-link__icon' id='address-book-o' fixedWidth /><FormattedMessage id='navigation_bar.profile_directory' defaultMessage='Profile directory' /></a>}
+  </div>
+);
+
+export default withRouter(NavigationPanel);
diff --git a/app/javascript/mastodon/features/ui/components/notifications_counter_icon.js b/app/javascript/mastodon/features/ui/components/notifications_counter_icon.js
new file mode 100644
index 0000000000000000000000000000000000000000..da553cd9f0624b432b440d5e22d8b7f6888905dc
--- /dev/null
+++ b/app/javascript/mastodon/features/ui/components/notifications_counter_icon.js
@@ -0,0 +1,9 @@
+import { connect } from 'react-redux';
+import IconWithBadge from 'mastodon/components/icon_with_badge';
+
+const mapStateToProps = state => ({
+  count: state.getIn(['notifications', 'unread']),
+  id: 'bell',
+});
+
+export default connect(mapStateToProps)(IconWithBadge);
diff --git a/app/javascript/mastodon/features/ui/components/report_modal.js b/app/javascript/mastodon/features/ui/components/report_modal.js
index bc6b18664a97401baf319872bdced75cc3627b47..2e41f784dd17c0fd9d0c80631b07c1cbdaf31bb0 100644
--- a/app/javascript/mastodon/features/ui/components/report_modal.js
+++ b/app/javascript/mastodon/features/ui/components/report_modal.js
@@ -97,7 +97,7 @@ class ReportModal extends ImmutablePureComponent {
 
         <div className='report-modal__container'>
           <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>
+            <p><FormattedMessage id='report.hint' defaultMessage='The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:' /></p>
 
             <textarea
               className='setting-text light'
diff --git a/app/javascript/mastodon/features/ui/components/tabs_bar.js b/app/javascript/mastodon/features/ui/components/tabs_bar.js
index 16236ea51e5e2c6b4e95acb6e97ee328e51339ea..29583d3d798aaead2bde744233257f58f4c6aeed 100644
--- a/app/javascript/mastodon/features/ui/components/tabs_bar.js
+++ b/app/javascript/mastodon/features/ui/components/tabs_bar.js
@@ -4,16 +4,16 @@ import { NavLink, withRouter } from 'react-router-dom';
 import { FormattedMessage, injectIntl } from 'react-intl';
 import { debounce } from 'lodash';
 import { isUserTouching } from '../../../is_mobile';
+import Icon from 'mastodon/components/icon';
+import NotificationsCounterIcon from './notifications_counter_icon';
 
 export const links = [
-  <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' to='/search' data-preview-title-id='tabs_bar.search' data-preview-icon='bell' ><i className='fa fa-fw fa-search' /><FormattedMessage id='tabs_bar.search' defaultMessage='Search' /></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>,
+  <NavLink className='tabs-bar__link' to='/timelines/home' data-preview-title-id='column.home' data-preview-icon='home' ><Icon id='home' fixedWidth /><FormattedMessage id='tabs_bar.home' defaultMessage='Home' /></NavLink>,
+  <NavLink className='tabs-bar__link' to='/notifications' data-preview-title-id='column.notifications' data-preview-icon='bell' ><NotificationsCounterIcon /><FormattedMessage id='tabs_bar.notifications' defaultMessage='Notifications' /></NavLink>,
+  <NavLink className='tabs-bar__link' to='/timelines/public/local' data-preview-title-id='column.community' data-preview-icon='users' ><Icon id='users' fixedWidth /><FormattedMessage id='tabs_bar.local_timeline' defaultMessage='Local' /></NavLink>,
+  <NavLink className='tabs-bar__link' exact to='/timelines/public' data-preview-title-id='column.public' data-preview-icon='globe' ><Icon id='globe' fixedWidth /><FormattedMessage id='tabs_bar.federated_timeline' defaultMessage='Federated' /></NavLink>,
+  <NavLink className='tabs-bar__link optional' to='/search' data-preview-title-id='tabs_bar.search' data-preview-icon='bell' ><Icon id='search' fixedWidth /><FormattedMessage id='tabs_bar.search' defaultMessage='Search' /></NavLink>,
+  <NavLink className='tabs-bar__link' style={{ flexGrow: '0', flexBasis: '30px' }} to='/getting-started' data-preview-title-id='getting_started.heading' data-preview-icon='bars' ><Icon id='bars' fixedWidth /></NavLink>,
 ];
 
 export function getIndex (path) {
diff --git a/app/javascript/mastodon/features/ui/components/video_modal.js b/app/javascript/mastodon/features/ui/components/video_modal.js
index 7cf3eb4d458f6db79cd19a2e1020e09dce52b811..213d31316c81af9df6f6a33d799ef851036985b2 100644
--- a/app/javascript/mastodon/features/ui/components/video_modal.js
+++ b/app/javascript/mastodon/features/ui/components/video_modal.js
@@ -1,28 +1,69 @@
 import React from 'react';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import PropTypes from 'prop-types';
-import Video from '../../video';
+import Video from 'mastodon/features/video';
 import ImmutablePureComponent from 'react-immutable-pure-component';
+import { FormattedMessage } from 'react-intl';
+
+export const previewState = 'previewVideoModal';
 
 export default class VideoModal extends ImmutablePureComponent {
 
   static propTypes = {
     media: ImmutablePropTypes.map.isRequired,
+    status: ImmutablePropTypes.map,
     time: PropTypes.number,
     onClose: PropTypes.func.isRequired,
   };
 
+  static contextTypes = {
+    router: PropTypes.object,
+  };
+
+  componentDidMount () {
+    if (this.context.router) {
+      const history = this.context.router.history;
+
+      history.push(history.location.pathname, previewState);
+
+      this.unlistenHistory = history.listen(() => {
+        this.props.onClose();
+      });
+    }
+  }
+
+  componentWillUnmount () {
+    if (this.context.router) {
+      this.unlistenHistory();
+
+      if (this.context.router.history.location.state === previewState) {
+        this.context.router.history.goBack();
+      }
+    }
+  }
+
+  handleStatusClick = e => {
+    if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
+      e.preventDefault();
+      this.context.router.history.push(`/statuses/${this.props.status.get('id')}`);
+    }
+  }
+
   render () {
-    const { media, time, onClose } = this.props;
+    const { media, status, time, onClose } = this.props;
+
+    const link = status && <a href={status.get('url')} onClick={this.handleStatusClick}><FormattedMessage id='lightbox.view_context' defaultMessage='View context' /></a>;
 
     return (
       <div className='modal-root__modal video-modal'>
         <div>
           <Video
             preview={media.get('preview_url')}
+            blurhash={media.get('blurhash')}
             src={media.get('url')}
             startTime={time}
             onCloseVideo={onClose}
+            link={link}
             detailed
             alt={media.get('description')}
           />
diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js
index f01c2bf247861d4d3676303a238271f7d0c7aec0..791133afd32ed905705ca2cdd108c538acc82a45 100644
--- a/app/javascript/mastodon/features/ui/index.js
+++ b/app/javascript/mastodon/features/ui/index.js
@@ -7,7 +7,6 @@ import { Redirect, withRouter } from 'react-router-dom';
 import PropTypes from 'prop-types';
 import NotificationsContainer from './containers/notifications_container';
 import LoadingBarContainer from './containers/loading_bar_container';
-import TabsBar from './components/tabs_bar';
 import ModalContainer from './containers/modal_container';
 import { isMobile } from '../../is_mobile';
 import { debounce } from 'lodash';
@@ -45,9 +44,11 @@ import {
   Mutes,
   PinnedStatuses,
   Lists,
+  Search,
 } from './util/async-components';
-import { me } from '../../initial_state';
-import { previewState } from './components/media_modal';
+import { me, forceSingleColumn } from '../../initial_state';
+import { previewState as previewMediaState } from './components/media_modal';
+import { previewState as previewVideoState } from './components/video_modal';
 
 // Dummy import, to make sure that <Status /> ends up in the application bundle.
 // Without this it ends up in ~8 very commonly used bundles.
@@ -92,6 +93,7 @@ const keyMap = {
   goToMuted: 'g m',
   goToRequests: 'g r',
   toggleHidden: 'x',
+  toggleSensitive: 'h',
 };
 
 class SwitchingColumnsArea extends React.PureComponent {
@@ -121,7 +123,7 @@ class SwitchingColumnsArea extends React.PureComponent {
   }
 
   shouldUpdateScroll (_, { location }) {
-    return location.state !== previewState;
+    return location.state !== previewMediaState && location.state !== previewVideoState;
   }
 
   handleResize = debounce(() => {
@@ -140,10 +142,11 @@ class SwitchingColumnsArea extends React.PureComponent {
   render () {
     const { children } = this.props;
     const { mobile } = this.state;
-    const redirect = mobile ? <Redirect from='/' to='/timelines/home' exact /> : <Redirect from='/' to='/getting-started' exact />;
+    const singleColumn = forceSingleColumn || mobile;
+    const redirect = singleColumn ? <Redirect from='/' to='/timelines/home' exact /> : <Redirect from='/' to='/getting-started' exact />;
 
     return (
-      <ColumnsAreaContainer ref={this.setRef} singleColumn={mobile}>
+      <ColumnsAreaContainer ref={this.setRef} singleColumn={singleColumn}>
         <WrappedSwitch>
           {redirect}
           <WrappedRoute path='/getting-started' component={GettingStarted} content={children} />
@@ -159,7 +162,7 @@ class SwitchingColumnsArea extends React.PureComponent {
           <WrappedRoute path='/favourites' component={FavouritedStatuses} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
           <WrappedRoute path='/pinned' component={PinnedStatuses} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
 
-          <WrappedRoute path='/search' component={Compose} content={children} componentParams={{ isSearchPage: true }} />
+          <WrappedRoute path='/search' component={Search} content={children} />
 
           <WrappedRoute path='/statuses/new' component={Compose} content={children} />
           <WrappedRoute path='/statuses/:statusId' exact component={Status} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
@@ -263,7 +266,7 @@ class UI extends React.PureComponent {
     this.setState({ draggingOver: false });
     this.dragTargets = [];
 
-    if (e.dataTransfer && e.dataTransfer.files.length === 1) {
+    if (e.dataTransfer && e.dataTransfer.files.length >= 1) {
       this.props.dispatch(uploadCompose(e.dataTransfer.files));
     }
   }
@@ -367,11 +370,16 @@ class UI extends React.PureComponent {
   handleHotkeyFocusColumn = e => {
     const index  = (e.key * 1) + 1; // First child is drawer, skip that
     const column = this.node.querySelector(`.column:nth-child(${index})`);
+    if (!column) return;
+    const container = column.querySelector('.scrollable');
 
-    if (column) {
-      const status = column.querySelector('.focusable');
+    if (container) {
+      const status = container.querySelector('.focusable');
 
       if (status) {
+        if (container.scrollTop > status.offsetTop) {
+          status.scrollIntoView(true);
+        }
         status.focus();
       }
     }
@@ -473,8 +481,6 @@ class UI extends React.PureComponent {
     return (
       <HotKeys keyMap={keyMap} handlers={handlers} ref={this.setHotkeysRef} attach={window} focused>
         <div className={classNames('ui', { 'is-composing': isComposing })} ref={this.setRef} style={{ pointerEvents: dropdownMenuIsOpen ? 'none' : null }}>
-          <TabsBar />
-
           <SwitchingColumnsArea location={location} onLayoutChange={this.handleLayoutChange}>
             {children}
           </SwitchingColumnsArea>
diff --git a/app/javascript/mastodon/features/ui/util/async-components.js b/app/javascript/mastodon/features/ui/util/async-components.js
index 235fd2a073c2556571a3586358024344e2c57ecd..6e8ed163a539a5c2bddb5b5d43213b17faf7ea9d 100644
--- a/app/javascript/mastodon/features/ui/util/async-components.js
+++ b/app/javascript/mastodon/features/ui/util/async-components.js
@@ -129,3 +129,7 @@ export function ListEditor () {
 export function ListAdder () {
   return import(/*webpackChunkName: "features/list_adder" */'../../list_adder');
 }
+
+export function Search () {
+  return import(/*webpackChunkName: "features/search" */'../../search');
+}
diff --git a/app/javascript/mastodon/features/video/index.js b/app/javascript/mastodon/features/video/index.js
index 3650fddb630e6d2dbcffad22b48a16b42c1b5307..b0c4085277fc13fc572a953502edbab8406fc4e7 100644
--- a/app/javascript/mastodon/features/video/index.js
+++ b/app/javascript/mastodon/features/video/index.js
@@ -1,11 +1,13 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
-import { fromJS } from 'immutable';
+import { fromJS, is } from 'immutable';
 import { throttle } from 'lodash';
 import classNames from 'classnames';
 import { isFullscreen, requestFullscreen, exitFullscreen } from '../ui/util/fullscreen';
 import { displayMedia } from '../../initial_state';
+import Icon from 'mastodon/components/icon';
+import { decode } from 'blurhash';
 
 const messages = defineMessages({
   play: { id: 'video.play', defaultMessage: 'Play' },
@@ -99,7 +101,12 @@ class Video extends React.PureComponent {
     onCloseVideo: PropTypes.func,
     detailed: PropTypes.bool,
     inline: PropTypes.bool,
+    cacheWidth: PropTypes.func,
+    visible: PropTypes.bool,
+    onToggleVisibility: PropTypes.func,
     intl: PropTypes.object.isRequired,
+    blurhash: PropTypes.string,
+    link: PropTypes.node,
   };
 
   state = {
@@ -108,11 +115,11 @@ class Video extends React.PureComponent {
     volume: 0.5,
     paused: true,
     dragging: false,
-    containerWidth: false,
+    containerWidth: this.props.width,
     fullscreen: false,
     hovered: false,
     muted: false,
-    revealed: displayMedia !== 'hide_all' && !this.props.sensitive || displayMedia === 'show_all',
+    revealed: this.props.visible !== undefined ? this.props.visible : (displayMedia !== 'hide_all' && !this.props.sensitive || displayMedia === 'show_all'),
   };
 
   // hard coded in components.scss
@@ -128,6 +135,7 @@ class Video extends React.PureComponent {
     this.player = c;
 
     if (c) {
+      if (this.props.cacheWidth) this.props.cacheWidth(this.player.offsetWidth);
       this.setState({
         containerWidth: c.offsetWidth,
       });
@@ -136,6 +144,10 @@ class Video extends React.PureComponent {
 
   setVideoRef = c => {
     this.video = c;
+
+    if (this.video) {
+      this.setState({ volume: this.video.volume, muted: this.video.muted });
+    }
   }
 
   setSeekRef = c => {
@@ -146,6 +158,10 @@ class Video extends React.PureComponent {
     this.volume = c;
   }
 
+  setCanvasRef = c => {
+    this.canvas = c;
+  }
+
   handleClickRoot = e => e.stopPropagation();
 
   handlePlay = () => {
@@ -164,7 +180,6 @@ class Video extends React.PureComponent {
   }
 
   handleVolumeMouseDown = e => {
-
     document.addEventListener('mousemove', this.handleMouseVolSlide, true);
     document.addEventListener('mouseup', this.handleVolumeMouseUp, true);
     document.addEventListener('touchmove', this.handleMouseVolSlide, true);
@@ -184,7 +199,6 @@ class Video extends React.PureComponent {
   }
 
   handleMouseVolSlide = throttle(e => {
-
     const rect = this.volume.getBoundingClientRect();
     const x = (e.clientX - rect.left) / this.volWidth; //x position within the element.
 
@@ -255,6 +269,10 @@ class Video extends React.PureComponent {
     document.addEventListener('webkitfullscreenchange', this.handleFullscreenChange, true);
     document.addEventListener('mozfullscreenchange', this.handleFullscreenChange, true);
     document.addEventListener('MSFullscreenChange', this.handleFullscreenChange, true);
+
+    if (this.props.blurhash) {
+      this._decode();
+    }
   }
 
   componentWillUnmount () {
@@ -264,6 +282,33 @@ class Video extends React.PureComponent {
     document.removeEventListener('MSFullscreenChange', this.handleFullscreenChange, true);
   }
 
+  componentWillReceiveProps (nextProps) {
+    if (!is(nextProps.visible, this.props.visible) && nextProps.visible !== undefined) {
+      this.setState({ revealed: nextProps.visible });
+    }
+  }
+
+  componentDidUpdate (prevProps, prevState) {
+    if (prevState.revealed && !this.state.revealed && this.video) {
+      this.video.pause();
+    }
+    if (prevProps.blurhash !== this.props.blurhash && this.props.blurhash) {
+      this._decode();
+    }
+  }
+
+  _decode () {
+    const hash   = this.props.blurhash;
+    const pixels = decode(hash, 32, 32);
+
+    if (pixels) {
+      const ctx       = this.canvas.getContext('2d');
+      const imageData = new ImageData(pixels, 32, 32);
+
+      ctx.putImageData(imageData, 0, 0);
+    }
+  }
+
   handleFullscreenChange = () => {
     this.setState({ fullscreen: isFullscreen() });
   }
@@ -282,11 +327,11 @@ class Video extends React.PureComponent {
   }
 
   toggleReveal = () => {
-    if (this.state.revealed) {
-      this.video.pause();
+    if (this.props.onToggleVisibility) {
+      this.props.onToggleVisibility();
+    } else {
+      this.setState({ revealed: !this.state.revealed });
     }
-
-    this.setState({ revealed: !this.state.revealed });
   }
 
   handleLoadedData = () => {
@@ -302,8 +347,13 @@ class Video extends React.PureComponent {
     }
   }
 
+  handleVolumeChange = () => {
+    this.setState({ volume: this.video.volume, muted: this.video.muted });
+  }
+
   handleOpenVideo = () => {
     const { src, preview, width, height, alt } = this.props;
+
     const media = fromJS({
       type: 'video',
       url: src,
@@ -323,7 +373,7 @@ class Video extends React.PureComponent {
   }
 
   render () {
-    const { preview, src, inline, startTime, onOpenVideo, onCloseVideo, intl, alt, detailed, sensitive } = this.props;
+    const { preview, src, inline, startTime, onOpenVideo, onCloseVideo, intl, alt, detailed, sensitive, link } = this.props;
     const { containerWidth, currentTime, duration, volume, buffer, dragging, paused, fullscreen, hovered, muted, revealed } = this.state;
     const progress = (currentTime / duration) * 100;
 
@@ -337,11 +387,11 @@ class Video extends React.PureComponent {
       width  = containerWidth;
       height = containerWidth / (16/9);
 
-      playerStyle.width  = width;
       playerStyle.height = height;
     }
 
     let preload;
+
     if (startTime || fullscreen || dragging) {
       preload = 'auto';
     } else if (detailed) {
@@ -351,6 +401,7 @@ class Video extends React.PureComponent {
     }
 
     let warning;
+
     if (sensitive) {
       warning = <FormattedMessage id='status.sensitive_warning' defaultMessage='Sensitive content' />;
     } else {
@@ -368,7 +419,9 @@ class Video extends React.PureComponent {
         onClick={this.handleClickRoot}
         tabIndex={0}
       >
-        <video
+        <canvas width={32} height={32} ref={this.setCanvasRef} className={classNames('media-gallery__preview', { 'media-gallery__preview--hidden': revealed })} />
+
+        {revealed && <video
           ref={this.setVideoRef}
           src={src}
           poster={preview}
@@ -387,12 +440,14 @@ class Video extends React.PureComponent {
           onTimeUpdate={this.handleTimeUpdate}
           onLoadedData={this.handleLoadedData}
           onProgress={this.handleProgress}
-        />
+          onVolumeChange={this.handleVolumeChange}
+        />}
 
-        <button type='button' className={classNames('video-player__spoiler', { active: !revealed })} onClick={this.toggleReveal}>
-          <span className='video-player__spoiler__title'>{warning}</span>
-          <span className='video-player__spoiler__subtitle'><FormattedMessage id='status.sensitive_toggle' defaultMessage='Click to view' /></span>
-        </button>
+        <div className={classNames('spoiler-button', { 'spoiler-button--hidden': revealed })}>
+          <button type='button' className='spoiler-button__overlay' onClick={this.toggleReveal}>
+            <span className='spoiler-button__overlay__label'>{warning}</span>
+          </button>
+        </div>
 
         <div className={classNames('video-player__controls', { active: paused || hovered })}>
           <div className='video-player__seek' onMouseDown={this.handleMouseDown} ref={this.setSeekRef}>
@@ -408,8 +463,9 @@ class Video extends React.PureComponent {
 
           <div className='video-player__buttons-bar'>
             <div className='video-player__buttons left'>
-              <button type='button' aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} onClick={this.togglePlay}><i className={classNames('fa fa-fw', { 'fa-play': paused, 'fa-pause': !paused })} /></button>
-              <button type='button' aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} onMouseEnter={this.volumeSlider} onMouseLeave={this.volumeSlider} onClick={this.toggleMute}><i className={classNames('fa fa-fw', { 'fa-volume-off': muted, 'fa-volume-up': !muted })} /></button>
+              <button type='button' aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} onClick={this.togglePlay}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
+              <button type='button' aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} onClick={this.toggleMute}><Icon id={muted ? 'volume-off' : 'volume-up'} fixedWidth /></button>
+
               <div className='video-player__volume' onMouseDown={this.handleVolumeMouseDown} ref={this.setVolumeRef}>
                 <div className='video-player__volume__current' style={{ width: `${volumeWidth}px` }} />
                 <span
@@ -419,20 +475,22 @@ class Video extends React.PureComponent {
                 />
               </div>
 
-              {(detailed || fullscreen) &&
+              {(detailed || fullscreen) && (
                 <span>
                   <span className='video-player__time-current'>{formatTime(currentTime)}</span>
                   <span className='video-player__time-sep'>/</span>
                   <span className='video-player__time-total'>{formatTime(duration)}</span>
                 </span>
-              }
+              )}
+
+              {link && <span className='video-player__link'>{link}</span>}
             </div>
 
             <div className='video-player__buttons right'>
-              {!onCloseVideo && <button type='button' aria-label={intl.formatMessage(messages.hide)} onClick={this.toggleReveal}><i className='fa fa-fw fa-eye' /></button>}
-              {(!fullscreen && onOpenVideo) && <button type='button' aria-label={intl.formatMessage(messages.expand)} onClick={this.handleOpenVideo}><i className='fa fa-fw fa-expand' /></button>}
-              {onCloseVideo && <button type='button' aria-label={intl.formatMessage(messages.close)} onClick={this.handleCloseVideo}><i className='fa fa-fw fa-compress' /></button>}
-              <button type='button' aria-label={intl.formatMessage(fullscreen ? messages.exit_fullscreen : messages.fullscreen)} onClick={this.toggleFullscreen}><i className={classNames('fa fa-fw', { 'fa-arrows-alt': !fullscreen, 'fa-compress': fullscreen })} /></button>
+              {!onCloseVideo && <button type='button' aria-label={intl.formatMessage(messages.hide)} onClick={this.toggleReveal}><Icon id='eye-slash' fixedWidth /></button>}
+              {(!fullscreen && onOpenVideo) && <button type='button' aria-label={intl.formatMessage(messages.expand)} onClick={this.handleOpenVideo}><Icon id='expand' fixedWidth /></button>}
+              {onCloseVideo && <button type='button' aria-label={intl.formatMessage(messages.close)} onClick={this.handleCloseVideo}><Icon id='compress' fixedWidth /></button>}
+              <button type='button' aria-label={intl.formatMessage(fullscreen ? messages.exit_fullscreen : messages.fullscreen)} onClick={this.toggleFullscreen}><Icon id={fullscreen ? 'compress' : 'arrows-alt'} fixedWidth /></button>
             </div>
           </div>
         </div>
diff --git a/app/javascript/mastodon/initial_state.js b/app/javascript/mastodon/initial_state.js
index 8c2e9d2de49d9b87428b873196c1aaff74b5e7c5..125508c2345cad89188c36e552113b228837a897 100644
--- a/app/javascript/mastodon/initial_state.js
+++ b/app/javascript/mastodon/initial_state.js
@@ -13,9 +13,12 @@ export const deleteModal = getMeta('delete_modal');
 export const me = getMeta('me');
 export const searchEnabled = getMeta('search_enabled');
 export const invitesEnabled = getMeta('invites_enabled');
+export const repository = getMeta('repository');
+export const source_url = getMeta('source_url');
 export const version = getMeta('version');
 export const mascot = getMeta('mascot');
 export const profile_directory = getMeta('profile_directory');
 export const isStaff = getMeta('is_staff');
+export const forceSingleColumn = !getMeta('advanced_layout');
 
 export default initialState;
diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json
index 1486272e2264482e438ca409ffea96491a6d3459..d05c61f9860820e4347d5e8edf3cec68cf7b983d 100644
--- a/app/javascript/mastodon/locales/ar.json
+++ b/app/javascript/mastodon/locales/ar.json
@@ -1,45 +1,43 @@
 {
-  "account.add_or_remove_from_list": "اضافو أو حذف مِن القوائم",
+  "account.add_or_remove_from_list": "أضفه أو أزله من القائمة",
   "account.badges.bot": "روبوت",
   "account.block": "حظر @{name}",
-  "account.block_domain": "إخفاء كل شيئ قادم من إسم النطاق {domain}",
+  "account.block_domain": "إخفاء كل شيئ قادم من اسم النطاق {domain}",
   "account.blocked": "محظور",
   "account.direct": "رسالة خاصة إلى @{name}",
-  "account.disclaimer_full": "قد لا تعكس المعلومات أدناه الملف الشخصي الكامل للمستخدم.",
   "account.domain_blocked": "النطاق مخفي",
   "account.edit_profile": "تعديل الملف الشخصي",
-  "account.endorse": "إبرازه على الملف الشخصي",
+  "account.endorse": "خاصّية على الملف الشخصي",
   "account.follow": "تابِع",
-  "account.followers": "المتابعون",
+  "account.followers": "متابعون",
   "account.followers.empty": "لا أحد يتبع هذا الحساب بعد.",
   "account.follows": "يتبع",
-  "account.follows.empty": "هذا المستخدِم لا يتبع أحدًا بعد.",
+  "account.follows.empty": "هذا الحساب لا يتبع أحدًا بعد.",
   "account.follows_you": "يتابعك",
   "account.hide_reblogs": "إخفاء ترقيات @{name}",
-  "account.link_verified_on": "تم التحقق مِن مالك هذا الرابط بتاريخ {date}",
-  "account.locked_info": "تم تأمين خصوصية هذا الحساب عبر قُفل. فصاحب الحساب يُراجِع يدويا طلبات المتابَعة و الاشتراك بحسابه.",
+  "account.link_verified_on": "تم التحقق مِن مِلْكية هذا الرابط بتاريخ {date}",
+  "account.locked_info": "تم تأمين خصوصية هذا الحساب عبر قفل. صاحب الحساب يُراجِع يدويا طلبات المتابَعة و الاشتراك بحسابه.",
   "account.media": "وسائط",
-  "account.mention": "أُذكُر @{name}",
-  "account.moved_to": "{name} إنتقل إلى :",
-  "account.mute": "أكتم @{name}",
-  "account.mute_notifications": "كتم إخطارات @{name}",
+  "account.mention": "أُذكُر/ي @{name}",
+  "account.moved_to": "{name} انتقل إلى:",
+  "account.mute": "كتم @{name}",
+  "account.mute_notifications": "كتم الإخطارات من @{name}",
   "account.muted": "مكتوم",
   "account.posts": "التبويقات",
   "account.posts_with_replies": "التبويقات و الردود",
-  "account.report": "أبلغ عن @{name}",
-  "account.requested": "في انتظار الموافقة",
-  "account.share": "مشاركة @{name}'s profile",
+  "account.report": "أبلغ/ي عن @{name}",
+  "account.requested": "في انتظار الموافقة. اضْغَطْ/ي لإلغاء طلب المتابعة",
+  "account.share": "مشاركة حساب @{name}",
   "account.show_reblogs": "عرض ترقيات @{name}",
   "account.unblock": "إلغاء الحظر عن @{name}",
-  "account.unblock_domain": "فك حظر {domain}",
+  "account.unblock_domain": "فك الخْفى عن {domain}",
   "account.unendorse": "إزالة ترويجه مِن الملف الشخصي",
   "account.unfollow": "إلغاء المتابعة",
   "account.unmute": "إلغاء الكتم عن @{name}",
   "account.unmute_notifications": "إلغاء كتم إخطارات @{name}",
-  "account.view_full_profile": "عرض الملف الشخصي كاملا",
   "alert.unexpected.message": "لقد طرأ هناك خطأ غير متوقّع.",
-  "alert.unexpected.title": "المعذرة !",
-  "boost_modal.combo": "يمكنك ضغط {combo} لتخطّي هذه في المرّة القادمة",
+  "alert.unexpected.title": "المعذرة!",
+  "boost_modal.combo": "يمكنك/ي ضغط {combo} لتخطّي هذه في المرّة القادمة",
   "bundle_column_error.body": "لقد وقع هناك خطأ أثناء عملية تحميل هذا العنصر.",
   "bundle_column_error.retry": "إعادة المحاولة",
   "bundle_column_error.title": "خطأ في الشبكة",
@@ -68,27 +66,33 @@
   "column_subheading.settings": "الإعدادات",
   "community.column_settings.media_only": "الوسائط فقط",
   "compose_form.direct_message_warning": "لن يَظهر هذا التبويق إلا للمستخدمين المذكورين.",
-  "compose_form.direct_message_warning_learn_more": "إقرأ المزيد",
+  "compose_form.direct_message_warning_learn_more": "اقرأ المزيد",
   "compose_form.hashtag_warning": "هذا التبويق لن يُدرَج تحت أي وسم كان بما أنه غير مُدرَج. لا يُسمح بالبحث إلّا عن التبويقات العمومية عن طريق الوسوم.",
   "compose_form.lock_disclaimer": "حسابك ليس {locked}. يمكن لأي شخص متابعتك و عرض المنشورات.",
   "compose_form.lock_disclaimer.lock": "مقفل",
   "compose_form.placeholder": "فيمَ تفكّر؟",
+  "compose_form.poll.add_option": "إضافة خيار",
+  "compose_form.poll.duration": "مدة استطلاع الرأي",
+  "compose_form.poll.option_placeholder": "الخيار {number}",
+  "compose_form.poll.remove_option": "إزالة هذا الخيار",
   "compose_form.publish": "بوّق",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "تحديد الوسائط كحساسة",
   "compose_form.sensitive.marked": "لقد تم تحديد هذه الصورة كحساسة",
   "compose_form.sensitive.unmarked": "لم يتم تحديد الصورة كحساسة",
   "compose_form.spoiler.marked": "إنّ النص مخفي وراء تحذير",
   "compose_form.spoiler.unmarked": "النص غير مخفي",
   "compose_form.spoiler_placeholder": "تنبيه عن المحتوى",
   "confirmation_modal.cancel": "إلغاء",
+  "confirmations.block.block_and_report": "احجبه وابلغ عنه",
   "confirmations.block.confirm": "حجب",
   "confirmations.block.message": "هل أنت متأكد أنك تريد حجب {name} ؟",
   "confirmations.delete.confirm": "حذف",
   "confirmations.delete.message": "هل أنت متأكد أنك تريد حذف هذا المنشور ؟",
-  "confirmations.delete_list.confirm": "Delete",
+  "confirmations.delete_list.confirm": "احذف",
   "confirmations.delete_list.message": "هل تود حقا حذف هذه القائمة ؟",
-  "confirmations.domain_block.confirm": "إخفاء إسم النطاق كاملا",
-  "confirmations.domain_block.message": "متأكد من أنك تود حظر إسم النطاق {domain} بالكامل ؟ في غالب الأحيان يُستَحسَن كتم أو حظر بعض الحسابات بدلا من حظر نطاق بالكامل.\nلن تتمكن مِن رؤية محتوى هذا النطاق لا على خيوطك العمومية و لا في إشعاراتك. سوف يتم كذلك إزالة كافة متابعيك المنتمين إلى هذا النطاق.",
+  "confirmations.domain_block.confirm": "إخفاء اسم النطاق كاملا",
+  "confirmations.domain_block.message": "متأكد من أنك تود حظر اسم النطاق {domain} بالكامل ؟ في غالب الأحيان يُستَحسَن كتم أو حظر بعض الحسابات بدلا من حظر نطاق بالكامل.\nلن تتمكن مِن رؤية محتوى هذا النطاق لا على خيوطك العمومية و لا في إشعاراتك. سوف يتم كذلك إزالة كافة متابعيك المنتمين إلى هذا النطاق.",
   "confirmations.mute.confirm": "أكتم",
   "confirmations.mute.message": "هل أنت متأكد أنك تريد كتم {name} ؟",
   "confirmations.redraft.confirm": "إزالة و إعادة الصياغة",
@@ -98,24 +102,25 @@
   "confirmations.unfollow.confirm": "إلغاء المتابعة",
   "confirmations.unfollow.message": "متأكد من أنك تريد إلغاء متابعة {name} ؟",
   "embed.instructions": "يمكنكم إدماج هذا المنشور على موقعكم الإلكتروني عن طريق نسخ الشفرة أدناه.",
-  "embed.preview": "هكذا ما سوف يبدو عليه :",
+  "embed.preview": "هكذا ما سوف يبدو عليه:",
   "emoji_button.activity": "الأنشطة",
   "emoji_button.custom": "مخصص",
   "emoji_button.flags": "الأعلام",
   "emoji_button.food": "الطعام والشراب",
   "emoji_button.label": "أدرج إيموجي",
   "emoji_button.nature": "الطبيعة",
-  "emoji_button.not_found": "لا إيموجو !! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.not_found": "لا إيموجو!! (╯°□°)╯︵ ┻━┻",
   "emoji_button.objects": "أشياء",
   "emoji_button.people": "الناس",
-  "emoji_button.recent": "الشائعة الإستخدام",
+  "emoji_button.recent": "الشائعة الاستخدام",
   "emoji_button.search": "ابحث...",
   "emoji_button.search_results": "نتائج البحث",
   "emoji_button.symbols": "رموز",
   "emoji_button.travel": "أماكن و أسفار",
   "empty_column.account_timeline": "ليس هناك تبويقات!",
+  "empty_column.account_unavailable": "الملف الشخصي غير متوفر",
   "empty_column.blocks": "لم تقم بحظر أي مستخدِم بعد.",
-  "empty_column.community": "الخط الزمني المحلي فارغ. أكتب شيئا ما للعامة كبداية !",
+  "empty_column.community": "الخط العام المحلي فارغ. أكتب شيئا ما للعامة كبداية!",
   "empty_column.direct": "لم تتلق أية رسالة خاصة مباشِرة بعد. سوف يتم عرض الرسائل المباشرة هنا إن قمت بإرسال واحدة أو تلقيت البعض منها.",
   "empty_column.domain_blocks": "ليس هناك نطاقات مخفية بعد.",
   "empty_column.favourited_statuses": "ليس لديك أية تبويقات مفضلة بعد. عندما ستقوم بالإعجاب بواحد، سيظهر هنا.",
@@ -128,13 +133,13 @@
   "empty_column.lists": "ليس عندك أية قائمة بعد. سوف تظهر قائمتك هنا إن قمت بإنشاء واحدة.",
   "empty_column.mutes": "لم تقم بكتم أي مستخدم بعد.",
   "empty_column.notifications": "لم تتلق أي إشعار بعدُ. تفاعل مع المستخدمين الآخرين لإنشاء محادثة.",
-  "empty_column.public": "لا يوجد أي شيء هنا ! قم بنشر شيء ما للعامة، أو إتبع مستخدمين آخرين في الخوادم المثيلة الأخرى لملء خيط المحادثات العام",
+  "empty_column.public": "لا يوجد أي شيء هنا! قم بنشر شيء ما للعامة، أو اتبع المستخدمين الآخرين المتواجدين على الخوادم الأخرى لملء خيط المحادثات",
   "follow_request.authorize": "ترخيص",
   "follow_request.reject": "رفض",
   "getting_started.developers": "المُطوِّرون",
   "getting_started.directory": "دليل المستخدِمين والمستخدِمات",
   "getting_started.documentation": "الدليل",
-  "getting_started.heading": "إستعدّ للبدء",
+  "getting_started.heading": "استعدّ للبدء",
   "getting_started.invite": "دعوة أشخاص",
   "getting_started.open_source_notice": "ماستدون برنامج مفتوح المصدر. يمكنك المساهمة، أو الإبلاغ عن تقارير الأخطاء، على جيت هب {github}.",
   "getting_started.security": "الأمان",
@@ -142,20 +147,25 @@
   "hashtag.column_header.tag_mode.all": "Ùˆ {additional}",
   "hashtag.column_header.tag_mode.any": "أو {additional}",
   "hashtag.column_header.tag_mode.none": "بدون {additional}",
+  "hashtag.column_settings.select.no_options_message": "لم يُعثَر على أي اقتراح",
+  "hashtag.column_settings.select.placeholder": "قم بإدخال وسوم…",
   "hashtag.column_settings.tag_mode.all": "كلها",
   "hashtag.column_settings.tag_mode.any": "أي كان مِن هذه",
   "hashtag.column_settings.tag_mode.none": "لا شيء مِن هذه",
-  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "hashtag.column_settings.tag_toggle": "إدراج الوسوم الإضافية لهذا العمود",
   "home.column_settings.basic": "أساسية",
   "home.column_settings.show_reblogs": "عرض الترقيات",
   "home.column_settings.show_replies": "عرض الردود",
+  "intervals.full.days": "{number, plural, one {# يوم} other {# أيام}}",
+  "intervals.full.hours": "{number, plural, one {# ساعة} other {# ساعات}}",
+  "intervals.full.minutes": "{number, plural, one {# دقيقة} other {# دقائق}}",
   "introduction.federation.action": "التالي",
-  "introduction.federation.federated.headline": "Federated",
+  "introduction.federation.federated.headline": "الفديرالي",
   "introduction.federation.federated.text": "كافة المنشورات التي نُشِرت إلى العامة على الخوادم الأخرى للفديفرس سوف يتم عرضها على الخيط المُوحَّد.",
-  "introduction.federation.home.headline": "Home",
+  "introduction.federation.home.headline": "الرئيسي",
   "introduction.federation.home.text": "سوف تُعرَض منشورات الأشخاص الذين تُتابِعهم على الخيط الرئيسي. بإمكانك متابعة أي حساب أيا كان الخادم الذي هو عليه!",
-  "introduction.federation.local.headline": "Local",
-  "introduction.federation.local.text": "المنشورات المُوجّهة للعامة على نفس الخادم الذي أنتم عليه ستظهر على الخيط الزمني المحلي.",
+  "introduction.federation.local.headline": "الخيط العام المحلي",
+  "introduction.federation.local.text": "المنشورات المُوجّهة للعامة على نفس الخادم الذي أنتم عليه ستظهر على الخيط العام المحلي.",
   "introduction.interactions.action": "إنهاء العرض التوضيحي!",
   "introduction.interactions.favourite.headline": "الإضافة إلى المفضلة",
   "introduction.interactions.favourite.text": "يمكِنك إضافة أي تبويق إلى المفضلة و إعلام صاحبه أنك أعجِبت بذاك التبويق.",
@@ -165,24 +175,24 @@
   "introduction.interactions.reply.text": "يمكنكم الرد على تبويقاتكم و تبويقات الآخرين على شكل سلسلة محادثة.",
   "introduction.welcome.action": "هيا بنا!",
   "introduction.welcome.headline": "الخطوات الأولى",
-  "introduction.welcome.text": "مرحبا بكم على الفيديفيرس! بعد لحظات قليلة ، سيكون بمقدوركم بث رسائل والتحدث إلى أصدقائكم عبر تشكيلة واسعة من الخوادم المختلفة. هذا الخادم ، {domain} ، يستضيف ملفكم الشخصي ، لذا يجب تذكر اسمه جيدا.",
+  "introduction.welcome.text": "مرحبا بكم على الفديفرس! بعد لحظات قليلة ، سيكون بمقدوركم بث رسائل والتحدث إلى أصدقائكم عبر تشكيلة واسعة من الخوادم المختلفة. هذا الخادم ، {domain} ، يستضيف ملفكم الشخصي ، لذا يجب تذكر اسمه جيدا.",
   "keyboard_shortcuts.back": "للعودة",
   "keyboard_shortcuts.blocked": "لفتح قائمة المستخدمين المحظورين",
   "keyboard_shortcuts.boost": "للترقية",
   "keyboard_shortcuts.column": "للتركيز على منشور على أحد الأعمدة",
   "keyboard_shortcuts.compose": "للتركيز على نافذة تحرير النصوص",
-  "keyboard_shortcuts.description": "Description",
+  "keyboard_shortcuts.description": "الوصف",
   "keyboard_shortcuts.direct": "لفتح عمود الرسائل المباشرة",
-  "keyboard_shortcuts.down": "للإنتقال إلى أسفل القائمة",
-  "keyboard_shortcuts.enter": "to open status",
+  "keyboard_shortcuts.down": "للانتقال إلى أسفل القائمة",
+  "keyboard_shortcuts.enter": "لفتح المنشور",
   "keyboard_shortcuts.favourite": "للإضافة إلى المفضلة",
   "keyboard_shortcuts.favourites": "لفتح قائمة المفضلات",
   "keyboard_shortcuts.federated": "لفتح الخيط الزمني الفديرالي",
   "keyboard_shortcuts.heading": "Keyboard Shortcuts",
   "keyboard_shortcuts.home": "لفتح الخيط الرئيسي",
-  "keyboard_shortcuts.hotkey": "مفتاح الإختصار",
+  "keyboard_shortcuts.hotkey": "مفتاح الاختصار",
   "keyboard_shortcuts.legend": "لعرض هذا المفتاح",
-  "keyboard_shortcuts.local": "لفتح الخيط الزمني المحلي",
+  "keyboard_shortcuts.local": "لفتح الخيط العام المحلي",
   "keyboard_shortcuts.mention": "لذِكر الناشر",
   "keyboard_shortcuts.muted": "لفتح قائمة المستخدِمين المكتومين",
   "keyboard_shortcuts.my_profile": "لفتح ملفك الشخصي",
@@ -194,21 +204,24 @@
   "keyboard_shortcuts.search": "للتركيز على البحث",
   "keyboard_shortcuts.start": "لفتح عمود \"هيا نبدأ\"",
   "keyboard_shortcuts.toggle_hidden": "لعرض أو إخفاء النص مِن وراء التحذير",
+  "keyboard_shortcuts.toggle_sensitivity": "لعرض/إخفاء الوسائط",
   "keyboard_shortcuts.toot": "لتحرير تبويق جديد",
   "keyboard_shortcuts.unfocus": "لإلغاء التركيز على حقل النص أو نافذة البحث",
-  "keyboard_shortcuts.up": "للإنتقال إلى أعلى القائمة",
+  "keyboard_shortcuts.up": "للانتقال إلى أعلى القائمة",
   "lightbox.close": "إغلاق",
   "lightbox.next": "التالي",
   "lightbox.previous": "العودة",
+  "lightbox.view_context": "اعرض السياق",
   "lists.account.add": "أضف إلى القائمة",
-  "lists.account.remove": "إحذف من القائمة",
-  "lists.delete": "Delete list",
+  "lists.account.remove": "احذف من القائمة",
+  "lists.delete": "احذف القائمة",
   "lists.edit": "تعديل القائمة",
+  "lists.edit.submit": "تعديل العنوان",
   "lists.new.create": "إنشاء قائمة",
   "lists.new.title_placeholder": "عنوان القائمة الجديدة",
   "lists.search": "إبحث في قائمة الحسابات التي تُتابِعها",
   "lists.subheading": "قوائمك",
-  "loading_indicator.label": "تحميل ...",
+  "loading_indicator.label": "تحميل...",
   "media_gallery.toggle_visible": "عرض / إخفاء",
   "missing_indicator.label": "تعذر العثور عليه",
   "missing_indicator.sublabel": "تعذر العثور على هذا المورد",
@@ -218,46 +231,57 @@
   "navigation_bar.community_timeline": "الخيط العام المحلي",
   "navigation_bar.compose": "تحرير تبويق جديد",
   "navigation_bar.direct": "الرسائل المباشِرة",
-  "navigation_bar.discover": "إكتشف",
+  "navigation_bar.discover": "اكتشف",
   "navigation_bar.domain_blocks": "النطاقات المخفية",
   "navigation_bar.edit_profile": "تعديل الملف الشخصي",
   "navigation_bar.favourites": "المفضلة",
   "navigation_bar.filters": "الكلمات المكتومة",
   "navigation_bar.follow_requests": "طلبات المتابعة",
-  "navigation_bar.info": "معلومات إضافية",
-  "navigation_bar.keyboard_shortcuts": "إختصارات لوحة المفاتيح",
+  "navigation_bar.follows_and_followers": "المتابِعين والمتابَعون",
+  "navigation_bar.info": "عن هذا الخادم",
+  "navigation_bar.keyboard_shortcuts": "اختصارات لوحة المفاتيح",
   "navigation_bar.lists": "القوائم",
   "navigation_bar.logout": "خروج",
   "navigation_bar.mutes": "الحسابات المكتومة",
-  "navigation_bar.personal": "Personal",
+  "navigation_bar.personal": "شخصي",
   "navigation_bar.pins": "التبويقات المثبتة",
   "navigation_bar.preferences": "التفضيلات",
+  "navigation_bar.profile_directory": "دليل المستخدِمين",
   "navigation_bar.public_timeline": "الخيط العام الموحد",
   "navigation_bar.security": "الأمان",
   "notification.favourite": "أُعجِب {name} بمنشورك",
   "notification.follow": "{name} يتابعك",
   "notification.mention": "{name} ذكرك",
+  "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "{name} قام بترقية تبويقك",
-  "notifications.clear": "إمسح الإخطارات",
+  "notifications.clear": "امسح الإخطارات",
   "notifications.clear_confirmation": "أمتأكد من أنك تود مسح جل الإخطارات الخاصة بك و المتلقاة إلى حد الآن ؟",
   "notifications.column_settings.alert": "إشعارات سطح المكتب",
-  "notifications.column_settings.favourite": "المُفَضَّلة :",
+  "notifications.column_settings.favourite": "المُفَضَّلة:",
   "notifications.column_settings.filter_bar.advanced": "عرض كافة الفئات",
   "notifications.column_settings.filter_bar.category": "شريط الفلترة السريعة",
   "notifications.column_settings.filter_bar.show": "عرض",
-  "notifications.column_settings.follow": "متابعُون جُدُد :",
-  "notifications.column_settings.mention": "الإشارات :",
+  "notifications.column_settings.follow": "متابعُون جُدُد:",
+  "notifications.column_settings.mention": "الإشارات:",
+  "notifications.column_settings.poll": "نتائج استطلاع الرأي:",
   "notifications.column_settings.push": "الإخطارات المدفوعة",
   "notifications.column_settings.reblog": "الترقيّات:",
-  "notifications.column_settings.show": "إعرِضها في عمود",
+  "notifications.column_settings.show": "اعرِضها في عمود",
   "notifications.column_settings.sound": "أصدر صوتا",
   "notifications.filter.all": "الكل",
   "notifications.filter.boosts": "الترقيات",
   "notifications.filter.favourites": "المفضلة",
   "notifications.filter.follows": "يتابِع",
   "notifications.filter.mentions": "الإشارات",
+  "notifications.filter.polls": "نتائج استطلاع الرأي",
   "notifications.group": "{count} إشعارات",
-  "privacy.change": "إضبط خصوصية المنشور",
+  "poll.closed": "انتهى",
+  "poll.refresh": "تحديث",
+  "poll.total_votes": "{count, plural, one {# صوت} other {# أصوات}}",
+  "poll.vote": "صَوّت",
+  "poll_button.add_poll": "إضافة استطلاع للرأي",
+  "poll_button.remove_poll": "إزالة استطلاع الرأي",
+  "privacy.change": "اضبط خصوصية المنشور",
   "privacy.direct.long": "أنشر إلى المستخدمين المشار إليهم فقط",
   "privacy.direct.short": "مباشر",
   "privacy.private.long": "أنشر لمتابعيك فقط",
@@ -266,20 +290,20 @@
   "privacy.public.short": "للعامة",
   "privacy.unlisted.long": "لا تقم بإدراجه على الخيوط العامة",
   "privacy.unlisted.short": "غير مدرج",
-  "regeneration_indicator.label": "جارٍ التحميل …",
-  "regeneration_indicator.sublabel": "جارٍ تجهيز تغذية صفحتك الرئيسية !",
-  "relative_time.days": "{number}d",
-  "relative_time.hours": "{number}h",
+  "regeneration_indicator.label": "جارٍ التحميل…",
+  "regeneration_indicator.sublabel": "جارٍ تجهيز تغذية صفحتك الرئيسية!",
+  "relative_time.days": "{number}ÙŠ",
+  "relative_time.hours": "{number}سا",
   "relative_time.just_now": "الآن",
-  "relative_time.minutes": "{number}m",
-  "relative_time.seconds": "{number}s",
+  "relative_time.minutes": "{number}د",
+  "relative_time.seconds": "{number}ثا",
   "reply_indicator.cancel": "إلغاء",
   "report.forward": "التحويل إلى {target}",
-  "report.forward_hint": "هذا الحساب ينتمي إلى خادوم آخَر. هل تودّ إرسال نسخة مجهولة مِن التقرير إلى هنالك أيضًا ؟",
-  "report.hint": "سوف يتم إرسال التقرير إلى مُشرِفي مثيل خادومكم. بإمكانك الإدلاء بشرح عن سبب الإبلاغ عن الحساب أسفله :",
+  "report.forward_hint": "هذا الحساب ينتمي إلى خادوم آخَر. هل تودّ إرسال نسخة مجهولة مِن التقرير إلى هنالك أيضًا؟",
+  "report.hint": "سوف يتم إرسال التقرير إلى المُشرِفين على خادومكم. بإمكانكم الإدلاء بشرح عن سبب الإبلاغ عن الحساب أسفله:",
   "report.placeholder": "تعليقات إضافية",
   "report.submit": "إرسال",
-  "report.target": "إبلاغ",
+  "report.target": "ابلغ عن {target}",
   "search.placeholder": "ابحث",
   "search_popout.search_format": "نمط البحث المتقدم",
   "search_popout.tips.full_text": "النص البسيط يقوم بعرض المنشورات التي كتبتها أو قمت بإرسالها أو ترقيتها أو تمت الإشارة إليك فيها من طرف آخرين ، بالإضافة إلى مطابقة أسماء المستخدمين وأسماء العرض وعلامات التصنيف.",
@@ -291,13 +315,13 @@
   "search_results.hashtags": "الوُسوم",
   "search_results.statuses": "التبويقات",
   "search_results.total": "{count, number} {count, plural, one {result} Ùˆ {results}}",
-  "standalone.public_title": "نظرة على ...",
   "status.admin_account": "افتح الواجهة الإدارية لـ @{name}",
   "status.admin_status": "افتح هذا المنشور على واجهة الإشراف",
-  "status.block": "Block @{name}",
+  "status.block": "احجب @{name}",
   "status.cancel_reblog_private": "إلغاء الترقية",
   "status.cannot_reblog": "تعذرت ترقية هذا المنشور",
-  "status.delete": "إحذف",
+  "status.copy": "نسخ رابط المنشور",
+  "status.delete": "احذف",
   "status.detailed_status": "تفاصيل المحادثة",
   "status.direct": "رسالة خاصة إلى @{name}",
   "status.embed": "إدماج",
@@ -320,28 +344,34 @@
   "status.redraft": "إزالة و إعادة الصياغة",
   "status.reply": "ردّ",
   "status.replyAll": "رُد على الخيط",
-  "status.report": "إبلِغ عن @{name}",
-  "status.sensitive_toggle": "اضغط للعرض",
+  "status.report": "ابلِغ عن @{name}",
   "status.sensitive_warning": "محتوى حساس",
   "status.share": "مشاركة",
-  "status.show_less": "إعرض أقلّ",
+  "status.show_less": "اعرض أقلّ",
   "status.show_less_all": "طي الكل",
   "status.show_more": "أظهر المزيد",
   "status.show_more_all": "توسيع الكل",
   "status.show_thread": "الكشف عن المحادثة",
   "status.unmute_conversation": "فك الكتم عن المحادثة",
   "status.unpin": "فك التدبيس من الملف الشخصي",
-  "suggestions.dismiss": "إلغاء الإقتراح",
+  "suggestions.dismiss": "إلغاء الاقتراح",
   "suggestions.header": "يمكن أن يهمك…",
   "tabs_bar.federated_timeline": "الموحَّد",
   "tabs_bar.home": "الرئيسية",
-  "tabs_bar.local_timeline": "المحلي",
+  "tabs_bar.local_timeline": "الخيط العام المحلي",
   "tabs_bar.notifications": "الإخطارات",
   "tabs_bar.search": "البحث",
+  "time_remaining.days": "{number, plural, one {# يوم} other {# أيام}} متبقية",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "لحظات متبقية",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} آخرون {people}} يتحدثون",
   "ui.beforeunload": "سوف تفقد مسودتك إن تركت ماستدون.",
-  "upload_area.title": "إسحب ثم أفلت للرفع",
-  "upload_button.label": "إضافة وسائط (JPEG، PNG، GIF، WebM، MP4، MOV)",
+  "upload_area.title": "اسحب ثم أفلت للرفع",
+  "upload_button.label": "إضافة وسائط ({formats})",
+  "upload_error.limit": "لقد تم بلوغ الحد الأقصى المسموح به لإرسال الملفات.",
+  "upload_error.poll": "لا يمكن إدراج ملفات في استطلاعات الرأي.",
   "upload_form.description": "وصف للمعاقين بصريا",
   "upload_form.focus": "قص",
   "upload_form.undo": "حذف",
diff --git a/app/javascript/mastodon/locales/ast.json b/app/javascript/mastodon/locales/ast.json
index a9407e82dd0671d4ec77073458ed04a67a0e34bb..b911848ee00871c2434cc751e4ecc76548931ef3 100644
--- a/app/javascript/mastodon/locales/ast.json
+++ b/app/javascript/mastodon/locales/ast.json
@@ -5,7 +5,6 @@
   "account.block_domain": "Anubrir tolo de {domain}",
   "account.blocked": "Blocked",
   "account.direct": "Unviar un mensaxe direutu a @{name}",
-  "account.disclaimer_full": "La información d'embaxo podría reflexar de mou incompletu'l perfil del usuariu.",
   "account.domain_blocked": "Dominiu anubríu",
   "account.edit_profile": "Editar el perfil",
   "account.endorse": "Destacar nel perfil",
@@ -36,7 +35,6 @@
   "account.unfollow": "Unfollow",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account.view_full_profile": "Ver el perfil completu",
   "alert.unexpected.message": "Asocedió un fallu inesperáu.",
   "alert.unexpected.title": "¡Ups!",
   "boost_modal.combo": "Pues primir {combo} pa saltar esto la próxima vegada",
@@ -73,14 +71,20 @@
   "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",
   "compose_form.placeholder": "¿En qué pienses?",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
   "compose_form.sensitive.marked": "Media is marked as sensitive",
   "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
   "compose_form.spoiler.marked": "El testu nun va anubrise darrera d'una alvertencia",
   "compose_form.spoiler.unmarked": "El testu va anubrise",
   "compose_form.spoiler_placeholder": "Escribi equí l'avertencia",
   "confirmation_modal.cancel": "Encaboxar",
+  "confirmations.block.block_and_report": "Block & Report",
   "confirmations.block.confirm": "Block",
   "confirmations.block.message": "¿De xuru que quies bloquiar a {name}?",
   "confirmations.delete.confirm": "Delete",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Símbolos",
   "emoji_button.travel": "Viaxes y llugares",
   "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_unavailable": "Profile unavailable",
   "empty_column.blocks": "Entá nun bloquiesti a dengún usuariu.",
   "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
   "empty_column.direct": "Entá nun tienes dengún mensaxe direutu. Cuando unvies o recibas dalgún, va apaecer equí.",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "and {additional}",
   "hashtag.column_header.tag_mode.any": "or {additional}",
   "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
   "hashtag.column_settings.tag_mode.all": "All of these",
   "hashtag.column_settings.tag_mode.any": "Any of these",
   "hashtag.column_settings.tag_mode.none": "None of these",
@@ -149,6 +156,9 @@
   "home.column_settings.basic": "Basic",
   "home.column_settings.show_reblogs": "Amosar toots compartíos",
   "home.column_settings.show_replies": "Amosar rempuestes",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
   "introduction.federation.action": "Next",
   "introduction.federation.federated.headline": "Federated",
   "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
@@ -156,7 +166,7 @@
   "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
   "introduction.federation.local.headline": "Local",
   "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
+  "introduction.interactions.action": "Finish toot-orial!",
   "introduction.interactions.favourite.headline": "Favourite",
   "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
   "introduction.interactions.reblog.headline": "Boost",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "to focus search",
   "keyboard_shortcuts.start": "p'abrir la columna «entamar»",
   "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "p'apenzar un toot nuevu",
   "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
   "keyboard_shortcuts.up": "pa xubir na llista",
   "lightbox.close": "Close",
   "lightbox.next": "Siguiente",
   "lightbox.previous": "Previous",
+  "lightbox.view_context": "View context",
   "lists.account.add": "Amestar a la llista",
   "lists.account.remove": "Desaniciar de la llista",
   "lists.delete": "Desaniciar la llista",
   "lists.edit": "Editar la llista",
+  "lists.edit.submit": "Change title",
   "lists.new.create": "Add list",
   "lists.new.title_placeholder": "Títulu nuevu de la llista",
   "lists.search": "Guetar ente la xente que sigues",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "Favoritos",
   "navigation_bar.filters": "Pallabres silenciaes",
   "navigation_bar.follow_requests": "Solicitúes de siguimientu",
+  "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.info": "Tocante a esta instancia",
   "navigation_bar.keyboard_shortcuts": "Atayos",
   "navigation_bar.lists": "Llistes",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Personal",
   "navigation_bar.pins": "Toots fixaos",
   "navigation_bar.preferences": "Preferencies",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "Llinia temporal federada",
   "navigation_bar.security": "Seguranza",
   "notification.favourite": "{name} favourited your status",
   "notification.follow": "{name} siguióte",
   "notification.mention": "{name} mentóte",
+  "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "{name} compartió'l to estáu",
   "notifications.clear": "Llimpiar avisos",
   "notifications.clear_confirmation": "¿De xuru que quies llimpiar dafechu tolos avisos?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Show",
   "notifications.column_settings.follow": "Siguidores nuevos:",
   "notifications.column_settings.mention": "Menciones:",
+  "notifications.column_settings.poll": "Poll results:",
   "notifications.column_settings.push": "Push notifications",
   "notifications.column_settings.reblog": "Toots compartíos:",
   "notifications.column_settings.show": "Amosar en columna",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favourites",
   "notifications.filter.follows": "Follows",
   "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
   "notifications.group": "{count} avisos",
+  "poll.closed": "Closed",
+  "poll.refresh": "Refresh",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
   "privacy.change": "Adjust status privacy",
   "privacy.direct.long": "Post to mentioned users only",
   "privacy.direct.short": "Direct",
@@ -291,12 +315,12 @@
   "search_results.hashtags": "Etiquetes",
   "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
-  "standalone.public_title": "A look inside...",
   "status.admin_account": "Open moderation interface for @{name}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Bloquiar a @{name}",
   "status.cancel_reblog_private": "Dexar de compartir",
   "status.cannot_reblog": "Esti artículu nun pue compartise",
+  "status.copy": "Copy link to status",
   "status.delete": "Delete",
   "status.detailed_status": "Detailed conversation view",
   "status.direct": "Unviar un mensaxe direutu a @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Responder",
   "status.replyAll": "Reply to thread",
   "status.report": "Report @{name}",
-  "status.sensitive_toggle": "Fai clic pa velu",
   "status.sensitive_warning": "Conteníu sensible",
   "status.share": "Share",
   "status.show_less": "Amosar menos",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Llocal",
   "tabs_bar.notifications": "Avisos",
   "tabs_bar.search": "Search",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
   "ui.beforeunload": "El borrador va perdese si coles de Mastodon.",
   "upload_area.title": "Drag & drop to upload",
   "upload_button.label": "Add media",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "upload_form.description": "Descripción pa discapacitaos visuales",
   "upload_form.focus": "Crop",
   "upload_form.undo": "Desaniciar",
diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json
index a812f5cb1a5b4e898ba9a2623ebfae7d77fd9d89..783f9eb68814f8283b066fae74f07b17092730c4 100644
--- a/app/javascript/mastodon/locales/bg.json
+++ b/app/javascript/mastodon/locales/bg.json
@@ -5,7 +5,6 @@
   "account.block_domain": "Hide everything from {domain}",
   "account.blocked": "Blocked",
   "account.direct": "Direct Message @{name}",
-  "account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
   "account.domain_blocked": "Domain hidden",
   "account.edit_profile": "Редактирай профила си",
   "account.endorse": "Feature on profile",
@@ -36,7 +35,6 @@
   "account.unfollow": "Не следвай",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account.view_full_profile": "View full profile",
   "alert.unexpected.message": "An unexpected error occurred.",
   "alert.unexpected.title": "Oops!",
   "boost_modal.combo": "You can press {combo} to skip this next time",
@@ -73,14 +71,20 @@
   "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",
   "compose_form.placeholder": "Какво си мислиш?",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
   "compose_form.publish": "Раздумай",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
   "compose_form.sensitive.marked": "Media is marked as sensitive",
   "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
   "compose_form.spoiler.marked": "Text is hidden behind warning",
   "compose_form.spoiler.unmarked": "Text is not hidden",
   "compose_form.spoiler_placeholder": "Content warning",
   "confirmation_modal.cancel": "Cancel",
+  "confirmations.block.block_and_report": "Block & Report",
   "confirmations.block.confirm": "Block",
   "confirmations.block.message": "Are you sure you want to block {name}?",
   "confirmations.delete.confirm": "Delete",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Symbols",
   "emoji_button.travel": "Travel & Places",
   "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_unavailable": "Profile unavailable",
   "empty_column.blocks": "You haven't blocked any users yet.",
   "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
   "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "and {additional}",
   "hashtag.column_header.tag_mode.any": "or {additional}",
   "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
   "hashtag.column_settings.tag_mode.all": "All of these",
   "hashtag.column_settings.tag_mode.any": "Any of these",
   "hashtag.column_settings.tag_mode.none": "None of these",
@@ -149,6 +156,9 @@
   "home.column_settings.basic": "Basic",
   "home.column_settings.show_reblogs": "Show boosts",
   "home.column_settings.show_replies": "Show replies",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
   "introduction.federation.action": "Next",
   "introduction.federation.federated.headline": "Federated",
   "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
@@ -156,7 +166,7 @@
   "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
   "introduction.federation.local.headline": "Local",
   "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
+  "introduction.interactions.action": "Finish toot-orial!",
   "introduction.interactions.favourite.headline": "Favourite",
   "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
   "introduction.interactions.reblog.headline": "Boost",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "to focus search",
   "keyboard_shortcuts.start": "to open \"get started\" column",
   "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "to start a brand new toot",
   "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
   "keyboard_shortcuts.up": "to move up in the list",
   "lightbox.close": "Затвори",
   "lightbox.next": "Next",
   "lightbox.previous": "Previous",
+  "lightbox.view_context": "View context",
   "lists.account.add": "Add to list",
   "lists.account.remove": "Remove from list",
   "lists.delete": "Delete list",
   "lists.edit": "Edit list",
+  "lists.edit.submit": "Change title",
   "lists.new.create": "Add list",
   "lists.new.title_placeholder": "New list title",
   "lists.search": "Search among people you follow",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "Favourites",
   "navigation_bar.filters": "Muted words",
   "navigation_bar.follow_requests": "Follow requests",
+  "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.info": "Extended information",
   "navigation_bar.keyboard_shortcuts": "Keyboard shortcuts",
   "navigation_bar.lists": "Lists",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Personal",
   "navigation_bar.pins": "Pinned toots",
   "navigation_bar.preferences": "Предпочитания",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "Публичен канал",
   "navigation_bar.security": "Security",
   "notification.favourite": "{name} хареса твоята публикация",
   "notification.follow": "{name} те последва",
   "notification.mention": "{name} те спомена",
+  "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "{name} сподели твоята публикация",
   "notifications.clear": "Clear notifications",
   "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Show",
   "notifications.column_settings.follow": "Нови последователи:",
   "notifications.column_settings.mention": "Споменавания:",
+  "notifications.column_settings.poll": "Poll results:",
   "notifications.column_settings.push": "Push notifications",
   "notifications.column_settings.reblog": "Споделяния:",
   "notifications.column_settings.show": "Покажи в колона",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favourites",
   "notifications.filter.follows": "Follows",
   "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
   "notifications.group": "{count} notifications",
+  "poll.closed": "Closed",
+  "poll.refresh": "Refresh",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
   "privacy.change": "Adjust status privacy",
   "privacy.direct.long": "Post to mentioned users only",
   "privacy.direct.short": "Direct",
@@ -291,12 +315,12 @@
   "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.admin_account": "Open moderation interface for @{name}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "This post cannot be boosted",
+  "status.copy": "Copy link to status",
   "status.delete": "Изтриване",
   "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Отговор",
   "status.replyAll": "Reply to thread",
   "status.report": "Report @{name}",
-  "status.sensitive_toggle": "Покажи",
   "status.sensitive_warning": "Деликатно съдържание",
   "status.share": "Share",
   "status.show_less": "Show less",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Local",
   "tabs_bar.notifications": "Известия",
   "tabs_bar.search": "Search",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
   "upload_area.title": "Drag & drop to upload",
   "upload_button.label": "Добави медия",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.focus": "Crop",
   "upload_form.undo": "Отмяна",
diff --git a/app/javascript/mastodon/locales/bn.json b/app/javascript/mastodon/locales/bn.json
new file mode 100644
index 0000000000000000000000000000000000000000..5b7162ec122254cebd34ed874f80d18aa962b31e
--- /dev/null
+++ b/app/javascript/mastodon/locales/bn.json
@@ -0,0 +1,388 @@
+{
+  "account.add_or_remove_from_list": "তালিকাতে আরো যুক্ত বা মুছে ফেলুন",
+  "account.badges.bot": "রোবট",
+  "account.block": "@{name} বন্ধ করুন",
+  "account.block_domain": "{domain} থেকে সব সরিয়ে ফেলুন",
+  "account.blocked": "বন্ধ করা হয়েছে",
+  "account.direct": "@{name}কে সরকারি লিখুন",
+  "account.domain_blocked": "ওয়েবসাইট সরিয়ে ফেলা হয়েছে",
+  "account.edit_profile": "নিজের পাতা সম্পাদনা করুন",
+  "account.endorse": "নিজের পাতায় দেখান",
+  "account.follow": "অনুসরণ করুন",
+  "account.followers": "অনুসরণকারক",
+  "account.followers.empty": "এই ব্যবহারকারীকে কেও এখনো অনুসরণ করে না।",
+  "account.follows": "যাদেরকে অনুসরণ করেন",
+  "account.follows.empty": "এই ব্যবহারকারী কাওকে এখনো অনুসরণ করেন না।",
+  "account.follows_you": "আপনাকে অনুসরণ করে",
+  "account.hide_reblogs": "@{name}র সমর্থনগুলি সরিয়ে ফেলুন",
+  "account.link_verified_on": "এই লিংকের মালিকানা চেক করা হয়েছে {date} তারিকে",
+  "account.locked_info": "এই নিবন্ধনের গোপনীয়তার ক্ষেত্র তালা দেওয়া আছে। নিবন্ধনকারী অনুসরণ করার অনুমতি যাদেরকে দেবেন, শুধু তারাই অনুসরণ করতে পারবেন।",
+  "account.media": "ছবি বা ভিডিও",
+  "account.mention": "@{name} কে উল্লেখ করুন",
+  "account.moved_to": "{name} চলে গেছে এখানে:",
+  "account.mute": "@{name}র কার্যক্রম সরিয়ে ফেলুন",
+  "account.mute_notifications": "@{name}র প্রজ্ঞাপন আপনার কাছ থেকে সরিয়ে ফেলুন",
+  "account.muted": "সরানো আছে",
+  "account.posts": "টুট",
+  "account.posts_with_replies": "টুট এবং মতামত",
+  "account.report": "@{name}কে রিপোর্ট করে দিন",
+  "account.requested": "অনুমতির অপেক্ষায় আছে। অনুসরণ করার অনুরোধ বাতিল করতে এখানে ক্লিক করুন",
+  "account.share": "@{name}র পাতা অন্যদের দেখান",
+  "account.show_reblogs": "@{name}র সমর্থনগুলো দেখুন",
+  "account.unblock": "@{name}র কার্যকলাপ আবার দেখুন",
+  "account.unblock_domain": "{domain}থেকে আবার দেখুন",
+  "account.unendorse": "নিজের পাতায় এটা দেখতে চান না",
+  "account.unfollow": "অনুসরণ বন্ধ করুন",
+  "account.unmute": "@{name}র কার্যকলাপ আবার দেখুন",
+  "account.unmute_notifications": "@{name}র প্রজ্ঞাপন দেওয়ার অনুমতি দিন",
+  "alert.unexpected.message": "অপ্রত্যাশিত একটি সমস্যা হয়েছে।",
+  "alert.unexpected.title": "ওহো!",
+  "boost_modal.combo": "পরেরবার আপনি {combo} চাপ দিলে এটার শেষে চলে যেতে পারবেন",
+  "bundle_column_error.body": "এই অংশটি দেখতে যেয়ে কোনো সমস্যা হয়েছে।",
+  "bundle_column_error.retry": "আবার চেষ্টা করুন",
+  "bundle_column_error.title": "নেটওয়ার্কের সমস্যা হচ্ছে",
+  "bundle_modal_error.close": "বন্ধ করুন",
+  "bundle_modal_error.message": "এই অংশটি দেখতে যেয়ে কোনো সমস্যা হয়েছে।",
+  "bundle_modal_error.retry": "আবার চেষ্টা করুন",
+  "column.blocks": "যাদের বন্ধ করে রাখা হয়েছে",
+  "column.community": "স্থানীয় সময়সারি",
+  "column.direct": "সরাসরি লেখা",
+  "column.domain_blocks": "সরিয়ে ফেলা ওয়েবসাইট",
+  "column.favourites": "পছন্দের গুলো",
+  "column.follow_requests": "অনুসরণের অনুমতি চেয়েছে যারা",
+  "column.home": "বাড়ি",
+  "column.lists": "তালিকাগুলো",
+  "column.mutes": "যাদের কার্যক্রম দেখা বন্ধ আছে",
+  "column.notifications": "প্রজ্ঞাপনগুলো",
+  "column.pins": "পিন করা টুট",
+  "column.public": "যুক্ত সময়রেখা",
+  "column_back_button.label": "পেছনে",
+  "column_header.hide_settings": "সেটিংগুলো সরান",
+  "column_header.moveLeft_settings": "কলমটা বামে সরান",
+  "column_header.moveRight_settings": "কলমটা ডানে সরান",
+  "column_header.pin": "পিন দিয়ে রাখুন",
+  "column_header.show_settings": "সেটিং দেখান",
+  "column_header.unpin": "পিন খুলুন",
+  "column_subheading.settings": "সেটিং",
+  "community.column_settings.media_only": "শুধুমাত্র ছবি বা ভিডিও",
+  "compose_form.direct_message_warning": "শুধুমাত্র যাদেরকে উল্লেখ করা হয়েছে তাদেরকেই এই টুটটি পাঠানো হবে ।",
+  "compose_form.direct_message_warning_learn_more": "আরো জানুন",
+  "compose_form.hashtag_warning": "কোনো হ্যাশট্যাগের ভেতরে এই টুটটি থাকবেনা কারণ এটি তালিকাবহির্ভূত। শুধুমাত্র প্রকাশ্য ঠোটগুলো হ্যাশট্যাগের ভেতরে খুঁজে পাওয়া যাবে।",
+  "compose_form.lock_disclaimer": "আপনার নিবন্ধনে তালা দেওয়া নেই, যে কেও আপনাকে অনুসরণ করতে পারবে এবং অনুশারকদের জন্য লেখা দেখতে পারবে।",
+  "compose_form.lock_disclaimer.lock": "তালা দেওয়া",
+  "compose_form.placeholder": "আপনি কি ভাবছেন ?",
+  "compose_form.poll.add_option": "আরেকটি বিকল্প যোগ করুন",
+  "compose_form.poll.duration": "ভোটগ্রহনের সময়",
+  "compose_form.poll.option_placeholder": "বিকল্প {number}",
+  "compose_form.poll.remove_option": "এই বিকল্পটি মুছে ফেলুন",
+  "compose_form.publish": "টুট",
+  "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
+  "compose_form.sensitive.marked": "এই ছবি বা ভিডিওটি সংবেদনশীল হিসেবে চিহ্নিত করা হয়েছে",
+  "compose_form.sensitive.unmarked": "এই ছবি বা ভিডিওটি সংবেদনশীল হিসেবে চিহ্নিত করা হয়নি",
+  "compose_form.spoiler.marked": "লেখাটি সাবধানতার পেছনে লুকানো আছে",
+  "compose_form.spoiler.unmarked": "লেখাটি লুকানো নেই",
+  "compose_form.spoiler_placeholder": "আপনার সাবধানতা এখানে লিখুন",
+  "confirmation_modal.cancel": "বাতিল করুন",
+  "confirmations.block.block_and_report": "বন্ধ করুন এবং রিপোর্ট করুন",
+  "confirmations.block.confirm": "বন্ধ করুন",
+  "confirmations.block.message": "আপনি কি নিশ্চিত {name} কে বন্ধ করতে চান ?",
+  "confirmations.delete.confirm": "মুছে ফেলুন",
+  "confirmations.delete.message": "আপনি কি নিশ্চিত যে এই লেখাটি মুছে ফেলতে চান ?",
+  "confirmations.delete_list.confirm": "মুছে ফেলুন",
+  "confirmations.delete_list.message": "আপনি কি নিশ্চিত যে আপনি এই তালিকাটি স্থায়িভাবে মুছে ফেলতে চান ?",
+  "confirmations.domain_block.confirm": "এই ওয়েবসাইট থেকে সব সরান",
+  "confirmations.domain_block.message": "আপনি কি সত্যি সত্যি নিশ্চিত যে {domain} ওয়েবসাইট থেকে সব সরাতে চান ? সাধারণত কিছু লক্ষ্যবস্তু বন্ধ এবং সরানোযা যথেষ্ট। নিশ্চিত করলে ওই ওয়েবসাইট থেকে কোনোকিছু কোনখানে দেখবেন না। যারা আপনাকে অনুসরণ করে ওই ওয়েবসাইট থেকে তাদেরকেও মুছে ফেলা হবে।",
+  "confirmations.mute.confirm": "সরিয়ে ফেলুন",
+  "confirmations.mute.message": "আপনি কি নিশ্চিত {name} সরিয়ে ফেলতে চান ?",
+  "confirmations.redraft.confirm": "মুছে ফেলুন এবং আবার সম্পাদন করুন",
+  "confirmations.redraft.message": "আপনি কি নিশ্চিত এটি মুছে ফেলে  এবং আবার সম্পাদন করতে চান ? এটাতে যা পছন্দিত, সমর্থন বা মতামত আছে সেগুলো নতুন লেখার সাথে যুক্ত থাকবে না।",
+  "confirmations.reply.confirm": "মতামত",
+  "confirmations.reply.message": "এখন মতামত লিখতে গেলে আপনার এখন যেটা লিখছেন সেটা মুছে যাবে। আপনি নি নিশ্চিত এটা করতে চান ?",
+  "confirmations.unfollow.confirm": "অনুসরণ বন্ধ করুন",
+  "confirmations.unfollow.message": "আপনি কি নিশ্চিত {name} কে আর অনুসরণ করতে চান না ?",
+  "embed.instructions": "এই লেখাটি আপনার ওয়েবসাইটে যুক্ত করতে নিচের কোডটি বেবহার করুন।",
+  "embed.preview": "সেটা দেখতে এরকম হবে:",
+  "emoji_button.activity": "কার্যকলাপ",
+  "emoji_button.custom": "প্রথা",
+  "emoji_button.flags": "পতাকা",
+  "emoji_button.food": "খাদ্য ও পানীয়",
+  "emoji_button.label": "এমজি যুক্ত করুন",
+  "emoji_button.nature": "প্রকৃতি",
+  "emoji_button.not_found": "ইমোজি পাওয়া যায়নি !! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.objects": "বস্তূ",
+  "emoji_button.people": "মানুষ",
+  "emoji_button.recent": "ঘন ব্যাবহৃত",
+  "emoji_button.search": "খুজুন...",
+  "emoji_button.search_results": "খোঁজার ফলাফল",
+  "emoji_button.symbols": "প্রতীক",
+  "emoji_button.travel": "ভ্রমণ এবং স্থান",
+  "empty_column.account_timeline": "এখানে কোনো টুট নেই!",
+  "empty_column.account_unavailable": "নিজস্ব পাতা নেই",
+  "empty_column.blocks": "আপনি কোনো ব্যবহারকারীদের বন্ধ করেন নি।",
+  "empty_column.community": "স্থানীয় সময়রেখাতে কিছু নেই। প্রকাশ্যভাবে কিছু লিখে লেখালেখির উদ্বোধন করে ফেলুন!",
+  "empty_column.direct": "আপনার কাছে সরাসরি পাঠানো কোনো লেখা নেই। যদি কেও পাঠায়, সেটা এখানে দেখা যাবে।",
+  "empty_column.domain_blocks": "এখনো কোনো সরানো ওয়েবসাইট নেই।",
+  "empty_column.favourited_statuses": "আপনার পছন্দের কোনো টুট এখনো নেই। আপনি কোনো লেখা পছন্দের হিসেবে চিহ্নিত করলে এখানে পাওয়া যাবে।",
+  "empty_column.favourites": "কেও এখনো এটাকে পছন্দের টুট হিসেবে চিহ্নিত করেনি। যদি করে, তখন তাদের এখানে পাওয়া যাবে।",
+  "empty_column.follow_requests": "আপনার এখনো কোনো অনুসরণের আবেদন পাঠানো নেই। যদি পাঠায়, এখানে পাওয়া যাবে।",
+  "empty_column.hashtag": "এই হেসটাগে এখনো কিছু নেই।",
+  "empty_column.home": "আপনার বাড়ির সময়রেখা এখনো খালি!  {public}এ ঘুরে আসুন অথবা অনুসন্ধান বেবহার করে শুরু করতে পারেন এবং অন্য ব্যবহারকারীদের সাথে সাক্ষাৎ করতে পারেন।",
+  "empty_column.home.public_timeline": "প্রকাশ্য সময়রেখা",
+  "empty_column.list": "এই তালিকাতে এখনো কিছু নেই. যখন এই তালিকায় থাকা ব্যবহারকারী নতুন কিছু লিখবে, সেগুলো এখানে পাওয়া যাবে।",
+  "empty_column.lists": "আপনার এখনো কোনো তালিকা তৈরী নেই। যদি বা যখন তৈরী করেন, সেগুলো এখানে পাওয়া যাবে।",
+  "empty_column.mutes": "আপনি এখনো কোনো ব্যবহারকারীকে সরাননি।",
+  "empty_column.notifications": "আপনার এখনো কোনো প্রজ্ঞাপন নেই। কথোপকথন শুরু করতে,  অন্যদের সাথে মেলামেশা করতে পারেন।",
+  "empty_column.public": "এখানে এখনো কিছু নেই! প্রকাশ্য ভাবে কিছু লিখুন বা অন্য সার্ভার থেকে কাওকে অনুসরণ করে এই জায়গা ভরে ফেলুন",
+  "follow_request.authorize": "অনুমতি দিন",
+  "follow_request.reject": "প্রত্যাখ্যান করুন",
+  "getting_started.developers": "তৈরিকারকদের জন্য",
+  "getting_started.directory": "নিজস্ব পাতার তালিকা",
+  "getting_started.documentation": "নথিপত্র",
+  "getting_started.heading": "শুরু করা",
+  "getting_started.invite": "অন্যদের আমন্ত্রণ করুন",
+  "getting_started.open_source_notice": "মাস্টাডন একটি মুক্ত সফটওয়্যার। আপনি তৈরিতে সাহায্য করতে পারেন অথবা সমস্যা রিপোর্ট করতে পারেন গিটহাবে {github}।",
+  "getting_started.security": "নিরাপত্তা",
+  "getting_started.terms": "ব্যবহারের নিয়মাবলী",
+  "hashtag.column_header.tag_mode.all": "এবং {additional}",
+  "hashtag.column_header.tag_mode.any": "অথবা {additional}",
+  "hashtag.column_header.tag_mode.none": "বাদ দিয়ে {additional}",
+  "hashtag.column_settings.select.no_options_message": "কোনটা পাওয়া যায় নি",
+  "hashtag.column_settings.select.placeholder": "হ্যাশট্যাগের ভেতরে ঢুকুন…",
+  "hashtag.column_settings.tag_mode.all": "এগুলো সব",
+  "hashtag.column_settings.tag_mode.any": "এর ভেতরে যেকোনোটা",
+  "hashtag.column_settings.tag_mode.none": "এগুলোর একটাও না",
+  "hashtag.column_settings.tag_toggle": "আরো ট্যাগ এই কলামে যুক্ত করুন",
+  "home.column_settings.basic": "সাধারণ",
+  "home.column_settings.show_reblogs": "সমর্থনগুলো দেখান",
+  "home.column_settings.show_replies": "মতামত দেখান",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# ঘটা} other {# ঘটা}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
+  "introduction.federation.action": "পরবর্তী",
+  "introduction.federation.federated.headline": "যুক্তবিশ্ব",
+  "introduction.federation.federated.text": "অন্যান্য যুক্তবিশ্বের সার্ভারের লেখাগুলি যুক্তবিশ্বের সময়রেখাতে আসবে ।",
+  "introduction.federation.home.headline": "বাড়ি",
+  "introduction.federation.home.text": "যাদেরকে অনুসরণ করেন তাদের লেখাগুলো  আপনার বাড়ি-সময়রেখাতে আসবে। আপনি এখান থেকে যুক্তবিশ্বে যেকোনো সার্ভারের যে কাওকে  অনুসরণ করতে পারেন!",
+  "introduction.federation.local.headline": "স্থানীয়",
+  "introduction.federation.local.text": "আপনি যে সার্ভারে আছেন সেখানকার মানুষের প্রকাশ্য লেখাগুলো স্থানীয় সময়রেখাতে আসবে।",
+  "introduction.interactions.action": "ব্যবহার জানার অংশটি শেষ করুন!",
+  "introduction.interactions.favourite.headline": "পছন্দের",
+  "introduction.interactions.favourite.text": "পরে পড়ার জন্য বা লেখা পছন্ধ হয়েছে সেটা লেখককে জানাতে, কোনো লেখা পছন্দের হিসেবে চিহ্নিত করতে পারেন।",
+  "introduction.interactions.reblog.headline": "সমর্থন",
+  "introduction.interactions.reblog.text": "কারোর লেখা সমর্থন দিয়ে চিহ্নিত করে সেটা আপনার অনুসরণকারীদের দেখতে পারেন।",
+  "introduction.interactions.reply.headline": "মতামত",
+  "introduction.interactions.reply.text": "আপনি অন্যদের এবং নিজের লেখায় মতামত টুট করতে পারেন, যেগুলো লেখার সাথে কথোপকথন হিসেবে যুক্ত থাকবে।",
+  "introduction.welcome.action": "শুরু করা যাক!",
+  "introduction.welcome.headline": "প্রথম ধাপ",
+  "introduction.welcome.text": "যুক্তবিশ্বে স্বাগতম! কিছুক্ষনের মধ্যেই আপনি আপনার লেখা বিভিন্ন সার্ভারে সম্প্রচার করতে পারবেন। কিন্তু মনে রাখবে যে এটা একটা বিশেষ সার্ভার, {domain} কারণ এখানে আপনার নিজেস্ব পাতা রাখা হচ্ছে।",
+  "keyboard_shortcuts.back": "পেছনে যেতে",
+  "keyboard_shortcuts.blocked": "বন্ধ করা ব্যবহারকারীদের তালিকা দেখতে",
+  "keyboard_shortcuts.boost": "সমর্থন করতে",
+  "keyboard_shortcuts.column": "কোনো কলামএ কোনো লেখা ফোকাস করতে",
+  "keyboard_shortcuts.compose": "লেখা সম্পদনার জায়গায় ফোকাস করতে",
+  "keyboard_shortcuts.description": "বিবরণ",
+  "keyboard_shortcuts.direct": "সরাসরি পাঠানো লেখা দেখতে",
+  "keyboard_shortcuts.down": "তালিকার ভেতরে নিচে যেতে",
+  "keyboard_shortcuts.enter": "অবস্থা দেখতে",
+  "keyboard_shortcuts.favourite": "পছন্দের দেখতে",
+  "keyboard_shortcuts.favourites": "পছন্দের তালিকা বের করতে",
+  "keyboard_shortcuts.federated": "যুক্তবিশ্বের সময়রেখাতে যেতে",
+  "keyboard_shortcuts.heading": "কিবোর্ডের দ্রুতকারক (শর্টকাট)",
+  "keyboard_shortcuts.home": "বাড়ির সময়রেখা খুলতে",
+  "keyboard_shortcuts.hotkey": "দ্রুতকারক ছবিগুলো",
+  "keyboard_shortcuts.legend": "এই প্রদর্শনঅর্থ(legend) দেখতে",
+  "keyboard_shortcuts.local": "স্থানীয় সময়রেখাতে যেতে",
+  "keyboard_shortcuts.mention": "লেখককে উল্লেখ করতে",
+  "keyboard_shortcuts.muted": "বন্ধ করা ব্যবহারকারীদের তালিকা খুলতে",
+  "keyboard_shortcuts.my_profile": "নিজের পাতা দেখতে",
+  "keyboard_shortcuts.notifications": "প্রজ্ঞাপনের কলাম খুলতে",
+  "keyboard_shortcuts.pinned": "পিন দেওয়া টুটের তালিকা খুলতে",
+  "keyboard_shortcuts.profile": "লেখকের পাতা দেখতে",
+  "keyboard_shortcuts.reply": "মতামত দিতে",
+  "keyboard_shortcuts.requests": "অনুসরণ অনুরোধের তালিকা দেখতে",
+  "keyboard_shortcuts.search": "খোঁজার অংশে ফোকাস করতে",
+  "keyboard_shortcuts.start": "\"প্রথম শুরুর\" কলাম বের করতে",
+  "keyboard_shortcuts.toggle_hidden": "CW লেখা দেখতে বা লুকাতে",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
+  "keyboard_shortcuts.toot": "নতুন একটা টুট লেখা শুরু করতে",
+  "keyboard_shortcuts.unfocus": "লেখা বা খোঁজার জায়গায় ফোকাস না করতে",
+  "keyboard_shortcuts.up": "তালিকার উপরের দিকে যেতে",
+  "lightbox.close": "বন্ধ",
+  "lightbox.next": "পরবর্তী",
+  "lightbox.previous": "পূর্ববর্তী",
+  "lightbox.view_context": "View context",
+  "lists.account.add": "তালিকাতে যুক্ত করতে",
+  "lists.account.remove": "তালিকা থেকে বাদ দিতে",
+  "lists.delete": "তালিকা মুছে ফেলতে",
+  "lists.edit": "তালিকা সম্পাদনা করতে",
+  "lists.edit.submit": "শিরোনাম সম্পাদনা করতে",
+  "lists.new.create": "তালিকাতে যুক্ত করতে",
+  "lists.new.title_placeholder": "তালিকার নতুন শিরোনাম দিতে",
+  "lists.search": "যাদের অনুসরণ করেন তাদের ভেতরে খুঁজুন",
+  "lists.subheading": "আপনার তালিকা",
+  "loading_indicator.label": "আসছে...",
+  "media_gallery.toggle_visible": "দৃশ্যতার অবস্থা বদলান",
+  "missing_indicator.label": "খুঁজে পাওয়া যায়নি",
+  "missing_indicator.sublabel": "জিনিসটা খুঁজে পাওয়া যায়নি",
+  "mute_modal.hide_notifications": "এই ব্যবহারকারীর প্রজ্ঞাপন বন্ধ করবেন ?",
+  "navigation_bar.apps": "মোবাইলের আপ্প",
+  "navigation_bar.blocks": "বন্ধ করা ব্যবহারকারী",
+  "navigation_bar.community_timeline": "স্থানীয় সময়রেখা",
+  "navigation_bar.compose": "নতুন টুট লিখুন",
+  "navigation_bar.direct": "সরাসরি লেখা",
+  "navigation_bar.discover": "ঘুরে দেখুন",
+  "navigation_bar.domain_blocks": "বন্ধ করা ওয়েবসাইট",
+  "navigation_bar.edit_profile": "নিজের পাতা সম্পাদনা করুন",
+  "navigation_bar.favourites": "পছন্দের",
+  "navigation_bar.filters": "বন্ধ করা শব্দ",
+  "navigation_bar.follow_requests": "অনুসরণের অনুরোধগুলি",
+  "navigation_bar.follows_and_followers": "Follows and followers",
+  "navigation_bar.info": "এই সার্ভার সম্পর্কে",
+  "navigation_bar.keyboard_shortcuts": "হটকীগুলি",
+  "navigation_bar.lists": "তালিকাগুলো",
+  "navigation_bar.logout": "বাইরে যান",
+  "navigation_bar.mutes": "যেসব বেভহারকারীদের কার্যক্রম বন্ধ করা আছে",
+  "navigation_bar.personal": "নিজস্ব",
+  "navigation_bar.pins": "পিন দেওয়া টুট",
+  "navigation_bar.preferences": "পছন্দসমূহ",
+  "navigation_bar.profile_directory": "Profile directory",
+  "navigation_bar.public_timeline": "যুক্তবিশ্বের সময়রেখা",
+  "navigation_bar.security": "নিরাপত্তা",
+  "notification.favourite": "{name} আপনার কার্যক্রম পছন্দ করেছেন",
+  "notification.follow": "{name} আপনাকে অনুসরণ করেছেন",
+  "notification.mention": "{name} আপনাকে উল্লেখ করেছেন",
+  "notification.poll": "আপনি ভোট দিয়েছিলেন এমন এক  নির্বাচনের ভোটের সময় শেষ হয়েছে",
+  "notification.reblog": "{name} আপনার কার্যক্রমে সমর্থন দেখিয়েছেন",
+  "notifications.clear": "প্রজ্ঞাপনগুলো মুছে ফেলতে",
+  "notifications.clear_confirmation": "আপনি কি নির্চিত প্রজ্ঞাপনগুলো মুছে ফেলতে চান ?",
+  "notifications.column_settings.alert": "কম্পিউটারে প্রজ্ঞাপন",
+  "notifications.column_settings.favourite": "পছন্দের:",
+  "notifications.column_settings.filter_bar.advanced": "সব শ্রেণীগুলো দেখতে",
+  "notifications.column_settings.filter_bar.category": "দ্রুত ছাঁকনি বার",
+  "notifications.column_settings.filter_bar.show": "দেখতে",
+  "notifications.column_settings.follow": "নতুন অনুসরণকারীরা:",
+  "notifications.column_settings.mention": "প্রজ্ঞাপনগুলো:",
+  "notifications.column_settings.poll": "নির্বাচনের ফলাফল:",
+  "notifications.column_settings.push": "পুশ প্রজ্ঞাপন",
+  "notifications.column_settings.reblog": "সমর্থনগুলো:",
+  "notifications.column_settings.show": "কলামে দেখান",
+  "notifications.column_settings.sound": "শব্দ বাজাতে",
+  "notifications.filter.all": "সব",
+  "notifications.filter.boosts": "সমর্থনগুলো",
+  "notifications.filter.favourites": "পছন্দের গুলো",
+  "notifications.filter.follows": "অনুসরণের",
+  "notifications.filter.mentions": "উল্লেখিত",
+  "notifications.filter.polls": "নির্বাচনের ফলাফল",
+  "notifications.group": "{count} প্রজ্ঞাপন",
+  "poll.closed": "বন্ধ",
+  "poll.refresh": "আবার সতেজ করতে",
+  "poll.total_votes": "{count, plural, one {# ভোট} other {# ভোট}}",
+  "poll.vote": "ভোট",
+  "poll_button.add_poll": "একটা নির্বাচন যোগ করতে",
+  "poll_button.remove_poll": "নির্বাচন বাদ দিতে",
+  "privacy.change": "লেখার গোপনীয়তা অবস্থা ঠিক করতে",
+  "privacy.direct.long": "শুধুমাত্র উল্লেখিত ব্যবহারকারীদের কাছে লিখতে",
+  "privacy.direct.short": "সরাসরি",
+  "privacy.private.long": "শুধুমাত্র আপনার অনুসরণকারীদের লিখতে",
+  "privacy.private.short": "শুধুমাত্র অনুসরণকারীদের জন্য",
+  "privacy.public.long": "সর্বজনীন প্রকাশ্য সময়রেখাতে লিখতে",
+  "privacy.public.short": "সর্বজনীন প্রকাশ্য",
+  "privacy.unlisted.long": "সর্বজনীন প্রকাশ্য সময়রেখাতে না দেখাতে",
+  "privacy.unlisted.short": "প্রকাশ্য নয়",
+  "regeneration_indicator.label": "আসছে…",
+  "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} রিপোর্ট করুন",
+  "search.placeholder": "খুঁজতে",
+  "search_popout.search_format": "বিস্তারিতভাবে খোঁজার পদ্ধতি",
+  "search_popout.tips.full_text": "সাধারণ লেখা দিয়ে খুঁজলে বের হবে সেরকম আপনার লেখা, পছন্দের লেখা, সমর্থন করা লেখা, আপনাকে উল্লেখকরা কোনো লেখা,  যা খুঁজছেন সেরকম কোনো ব্যবহারকারীর নাম বা কোনো হ্যাশট্যাগগুলো।",
+  "search_popout.tips.hashtag": "হ্যাশট্যাগ",
+  "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} {count, plural, one {ফলাফল} other {ফলাফল}}",
+  "status.admin_account": "@{name} র জন্য পরিচালনার ইন্টারফেসে ঢুকুন",
+  "status.admin_status": "যায় লেখাটি পরিচালনার ইন্টারফেসে খুলুন",
+  "status.block": "@{name}কে বন্ধ করুন",
+  "status.cancel_reblog_private": "সমর্থন বাতিল করতে",
+  "status.cannot_reblog": "এটিতে সমর্থন দেওয়া যাবেনা",
+  "status.copy": "লেখাটির লিংক কপি করতে",
+  "status.delete": "মুছে ফেলতে",
+  "status.detailed_status": "বিস্তারিত কথোপকথনের হিসেবে দেখতে",
+  "status.direct": "@{name} কে সরাসরি পাঠান",
+  "status.embed": "এমবেড করতে",
+  "status.favourite": "পছন্দের করতে",
+  "status.filtered": "ছাঁকনিদিত",
+  "status.load_more": "আরো দেখুন",
+  "status.media_hidden": "ছবি বা ভিডিও পেছনে",
+  "status.mention": "@{name}কে উল্লেখ করতে",
+  "status.more": "আরো",
+  "status.mute": "@{name}র কার্যক্রম সরিয়ে ফেলতে",
+  "status.mute_conversation": "কথোপকথননের প্রজ্ঞাপন সরিয়ে ফেলতে",
+  "status.open": "এটার সম্পূর্ণটা দেখতে",
+  "status.pin": "নিজের পাতায় এটা পিন করতে",
+  "status.pinned": "পিন করা টুট",
+  "status.read_more": "আরো পড়ুন",
+  "status.reblog": "সমর্থন দিতে",
+  "status.reblog_private": "আপনার অনুসরণকারীদের কাছে এটার সমর্থন দেখাতে",
+  "status.reblogged_by": "{name} সমর্থন দিয়েছে",
+  "status.reblogs.empty": "এখনো কেও এটাতে সমর্থন দেয়নি। যখন কেও দেয়, সেটা তখন এখানে দেখা যাবে।",
+  "status.redraft": "মুছে আবার নতুন করে লিখতে",
+  "status.reply": "মতামত জানাতে",
+  "status.replyAll": "লেখাযুক্ত সবার কাছে মতামত জানাতে",
+  "status.report": "@{name}কে রিপোর্ট করতে",
+  "status.sensitive_warning": "সংবেদনশীল কিছু",
+  "status.share": "অন্যদের জানান",
+  "status.show_less": "কম দেখতে",
+  "status.show_less_all": "সবগুলোতে কম দেখতে",
+  "status.show_more": "আরো দেখাতে",
+  "status.show_more_all": "সবগুলোতে আরো দেখতে",
+  "status.show_thread": "আলোচনা দেখতে",
+  "status.unmute_conversation": "আলোচনার প্রজ্ঞাপন চালু করতে",
+  "status.unpin": "নিজের পাতা থেকে পিন করে রাখাটির পিন খুলতে",
+  "suggestions.dismiss": "সাহায্যের জন্য পরামর্শগুলো সরাতে",
+  "suggestions.header": "আপনি হয়তোবা এগুলোতে আগ্রহী হতে পারেন…",
+  "tabs_bar.federated_timeline": "যুক্তবিশ্ব",
+  "tabs_bar.home": "বাড়ি",
+  "tabs_bar.local_timeline": "স্থানীয়",
+  "tabs_bar.notifications": "প্রজ্ঞাপনগুলো",
+  "tabs_bar.search": "খুঁজতে",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} বাকি আছে",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} বাকি আছে",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} বাকি আছে",
+  "time_remaining.moments": "সময় বাকি আছে",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} বাকি আছে",
+  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} কথা বলছে",
+  "ui.beforeunload": "যে পর্যন্ত এটা লেখা হয়েছে, মাস্টাডন থেকে চলে গেলে এটা মুছে যাবে।",
+  "upload_area.title": "টেনে এখানে ছেড়ে দিলে এখানে যুক্ত করা যাবে",
+  "upload_button.label": "ছবি বা ভিডিও যুক্ত করতে (এসব ধরণের JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "যা যুক্ত করতে চাচ্ছেন সেটি বেশি বড়, এখানকার সর্বাধিকের মেমোরির উপরে চলে গেছে।",
+  "upload_error.poll": "নির্বাচনক্ষেত্রে কোনো ফাইল যুক্ত করা যাবেনা।",
+  "upload_form.description": "যারা দেখতে পায়না তাদের জন্য এটা বর্ণনা করতে",
+  "upload_form.focus": "সাধারণ দেখাটি পরিবর্তন করতে",
+  "upload_form.undo": "মুছে ফেলতে",
+  "upload_progress.label": "যুক্ত করতে পাঠানো হচ্ছে...",
+  "video.close": "ভিডিওটি বন্ধ করতে",
+  "video.exit_fullscreen": "পূর্ণ পর্দা থেকে বাইরে বের হতে",
+  "video.expand": "ভিডিওটি বড়ো করতে",
+  "video.fullscreen": "পূর্ণ পর্দা করতে",
+  "video.hide": "ভিডিওটি লুকাতে",
+  "video.mute": "শব্দ বন্ধ করতে",
+  "video.pause": "থামাতে",
+  "video.play": "শুরু করতে",
+  "video.unmute": "শব্দ চালু করতে"
+}
diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json
index 07a4f01746c3b8e08325a639552d4747d6dbda0a..bb73b2a419e45eed1ac48e623008e250a6d0f7d6 100644
--- a/app/javascript/mastodon/locales/ca.json
+++ b/app/javascript/mastodon/locales/ca.json
@@ -1,24 +1,23 @@
 {
   "account.add_or_remove_from_list": "Afegir o Treure de les llistes",
   "account.badges.bot": "Bot",
-  "account.block": "Bloca @{name}",
+  "account.block": "Bloqueja @{name}",
   "account.block_domain": "Amaga-ho tot de {domain}",
   "account.blocked": "Bloquejat",
   "account.direct": "Missatge directe @{name}",
-  "account.disclaimer_full": "La informació següent pot reflectir incompleta el perfil de l'usuari.",
   "account.domain_blocked": "Domini ocult",
   "account.edit_profile": "Editar el perfil",
   "account.endorse": "Recomanar en el teu perfil",
   "account.follow": "Segueix",
   "account.followers": "Seguidors",
   "account.followers.empty": "Encara ningú no segueix aquest usuari.",
-  "account.follows": "Seguint",
+  "account.follows": "Seguiments",
   "account.follows.empty": "Aquest usuari encara no segueix a ningú.",
   "account.follows_you": "Et segueix",
   "account.hide_reblogs": "Amaga els impulsos de @{name}",
   "account.link_verified_on": "La propietat d'aquest enllaç es va verificar el dia {date}",
   "account.locked_info": "Aquest estat de privadesa del compte està definit com a bloquejat. El propietari revisa manualment qui pot seguir-lo.",
-  "account.media": "Media",
+  "account.media": "Mèdia",
   "account.mention": "Esmentar @{name}",
   "account.moved_to": "{name} s'ha mogut a:",
   "account.mute": "Silencia @{name}",
@@ -36,7 +35,6 @@
   "account.unfollow": "Deixa de seguir",
   "account.unmute": "Treure silenci de @{name}",
   "account.unmute_notifications": "Activar notificacions de @{name}",
-  "account.view_full_profile": "Mostra el perfil complet",
   "alert.unexpected.message": "S'ha produït un error inesperat.",
   "alert.unexpected.title": "Vaja!",
   "boost_modal.combo": "Pots premer {combo} per saltar-te això el proper cop",
@@ -46,7 +44,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 blocats",
+  "column.blocks": "Usuaris bloquejats",
   "column.community": "Línia de temps local",
   "column.direct": "Missatges directes",
   "column.domain_blocks": "Dominis ocults",
@@ -56,7 +54,7 @@
   "column.lists": "Llistes",
   "column.mutes": "Usuaris silenciats",
   "column.notifications": "Notificacions",
-  "column.pins": "Toot fixat",
+  "column.pins": "Toots fixats",
   "column.public": "Línia de temps federada",
   "column_back_button.label": "Enrere",
   "column_header.hide_settings": "Amaga la configuració",
@@ -67,24 +65,30 @@
   "column_header.unpin": "No fixis",
   "column_subheading.settings": "Configuració",
   "community.column_settings.media_only": "Només multimèdia",
-  "compose_form.direct_message_warning": "Aquest toot només serà enviat als usuaris esmentats. De totes maneres, els operadors de la teva o de qualsevol de les instàncies receptores poden inspeccionar aquest missatge.",
+  "compose_form.direct_message_warning": "Aquest toot només serà enviat als usuaris esmentats.",
   "compose_form.direct_message_warning_learn_more": "Aprèn més",
   "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": "blocat",
-  "compose_form.placeholder": "En què estàs pensant?",
+  "compose_form.lock_disclaimer.lock": "bloquejat",
+  "compose_form.placeholder": "En què penses?",
+  "compose_form.poll.add_option": "Afegeix una opció",
+  "compose_form.poll.duration": "Durada de l'enquesta",
+  "compose_form.poll.option_placeholder": "Opció {number}",
+  "compose_form.poll.remove_option": "Elimina aquesta opció",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Marcar mèdia com a sensible",
   "compose_form.sensitive.marked": "Mèdia marcat com a sensible",
   "compose_form.sensitive.unmarked": "Mèdia no està marcat com a sensible",
   "compose_form.spoiler.marked": "Text es ocult sota l'avís",
   "compose_form.spoiler.unmarked": "Text no ocult",
   "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.block.block_and_report": "Bloquejar i informar",
+  "confirmations.block.confirm": "Bloqueja",
+  "confirmations.block.message": "Estàs segur que vols bloquejar a {name}?",
   "confirmations.delete.confirm": "Suprimeix",
-  "confirmations.delete.message": "Estàs segur que vols suprimir aquest estat?",
+  "confirmations.delete.message": "Estàs segur que vols suprimir aquest toot?",
   "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",
@@ -92,12 +96,12 @@
   "confirmations.mute.confirm": "Silencia",
   "confirmations.mute.message": "Estàs segur que vols silenciar {name}?",
   "confirmations.redraft.confirm": "Esborrar i refer",
-  "confirmations.redraft.message": "Estàs segur que vols esborrar aquesta publicació i tornar a redactar-la? Perderàs totes els impulsos i favorits, i les respostes a la publicació original es quedaran orfes.",
+  "confirmations.redraft.message": "Estàs segur que vols esborrar aquest toot i tornar a redactar-lo? Perderàs totes els impulsos i favorits, i les respostes al toot original es quedaran orfes.",
   "confirmations.reply.confirm": "Respon",
   "confirmations.reply.message": "Responen ara es sobreescriurà el missatge que estàs editant. Estàs segur que vols continuar?",
   "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.instructions": "Incrusta aquest toot al lloc web copiant el codi a continuació.",
   "embed.preview": "Aquí tenim quin aspecte tindrá:",
   "emoji_button.activity": "Activitat",
   "emoji_button.custom": "Personalitzat",
@@ -105,7 +109,7 @@
   "emoji_button.food": "Menjar i beure",
   "emoji_button.label": "Insereix un emoji",
   "emoji_button.nature": "Natura",
-  "emoji_button.not_found": "Emojos no!! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.not_found": "Emojis no!! (╯°□°)╯︵ ┻━┻",
   "emoji_button.objects": "Objectes",
   "emoji_button.people": "Gent",
   "emoji_button.recent": "Usats freqüentment",
@@ -114,21 +118,22 @@
   "emoji_button.symbols": "Símbols",
   "emoji_button.travel": "Viatges i Llocs",
   "empty_column.account_timeline": "No hi ha toots aquí!",
+  "empty_column.account_unavailable": "Perfil no disponible",
   "empty_column.blocks": "Encara no has bloquejat cap usuari.",
-  "empty_column.community": "La línia de temps local és buida. Escriu alguna cosa públicament per fer rodar la pilota!",
+  "empty_column.community": "La línia de temps local és buida. Escriu alguna cosa públicament per a fer rodar la pilota!",
   "empty_column.direct": "Encara no tens missatges directes. Quan enviïs o rebis un, es mostrarà aquí.",
   "empty_column.domain_blocks": "Encara no hi ha dominis ocults.",
   "empty_column.favourited_statuses": "Encara no tens cap toot favorit. Quan en tinguis, apareixerà aquí.",
   "empty_column.favourites": "Encara ningú ha marcat aquest toot com a favorit. Quan algú ho faci, apareixera aquí.",
-  "empty_column.follow_requests": "Encara no teniu cap petició de seguiment. Quan rebeu una, apareixerà aquí.",
-  "empty_column.hashtag": "Encara no hi ha res amb aquesta etiqueta.",
+  "empty_column.follow_requests": "Encara no teniu cap petició de seguiment. Quan rebis una, apareixerà aquí.",
+  "empty_column.hashtag": "Encara no hi ha res en aquesta etiqueta.",
   "empty_column.home": "Encara no segueixes ningú. Visita {public} o fes cerca per començar i conèixer altres usuaris.",
   "empty_column.home.public_timeline": "la línia de temps pública",
-  "empty_column.list": "Encara no hi ha res en aquesta llista. Quan els membres d'aquesta llista publiquin nous estats, apareixeran aquí.",
+  "empty_column.list": "Encara no hi ha res en aquesta llista. Quan els membres d'aquesta llista publiquin nous toots, apareixeran aquí.",
   "empty_column.lists": "Encara no tens cap llista. Quan en facis una, apareixerà aquí.",
   "empty_column.mutes": "Encara no has silenciat cap usuari.",
   "empty_column.notifications": "Encara no tens notificacions. Interactua amb altres per iniciar la conversa.",
-  "empty_column.public": "No hi ha res aquí! Escriu alguna cosa públicament o segueix manualment usuaris d'altres instàncies per omplir-ho",
+  "empty_column.public": "No hi ha res aquí! Escriu públicament alguna cosa o manualment segueix usuaris d'altres servidors per omplir-ho",
   "follow_request.authorize": "Autoritzar",
   "follow_request.reject": "Rebutjar",
   "getting_started.developers": "Desenvolupadors",
@@ -142,13 +147,18 @@
   "hashtag.column_header.tag_mode.all": "i {additional}",
   "hashtag.column_header.tag_mode.any": "o {additional}",
   "hashtag.column_header.tag_mode.none": "sense {additional}",
+  "hashtag.column_settings.select.no_options_message": "No s'ha trobat cap suggeriment",
+  "hashtag.column_settings.select.placeholder": "Introdueix etiquetes…",
   "hashtag.column_settings.tag_mode.all": "Tots aquests",
   "hashtag.column_settings.tag_mode.any": "Qualsevol d’aquests",
   "hashtag.column_settings.tag_mode.none": "Cap d’aquests",
-  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "hashtag.column_settings.tag_toggle": "Inclou etiquetes addicionals per a aquesta columna",
   "home.column_settings.basic": "Bàsic",
   "home.column_settings.show_reblogs": "Mostrar impulsos",
   "home.column_settings.show_replies": "Mostrar respostes",
+  "intervals.full.days": "{number, plural, one {# dia} other {# dies}}",
+  "intervals.full.hours": "{number, plural, one {# hora} other {# hores}}",
+  "intervals.full.minutes": "{number, plural, one {# minut} other {# minuts}}",
   "introduction.federation.action": "Següent",
   "introduction.federation.federated.headline": "Federada",
   "introduction.federation.federated.text": "Les publicacions públiques d'altres servidors del fedivers apareixeran a la línia de temps federada.",
@@ -169,41 +179,44 @@
   "keyboard_shortcuts.back": "navegar enrera",
   "keyboard_shortcuts.blocked": "per obrir la llista d'usuaris bloquejats",
   "keyboard_shortcuts.boost": "impulsar",
-  "keyboard_shortcuts.column": "per centrar un estat en una de les columnes",
+  "keyboard_shortcuts.column": "per a centrar un toot en una de les columnes",
   "keyboard_shortcuts.compose": "per centrar l'area de composició de text",
-  "keyboard_shortcuts.description": "Description",
+  "keyboard_shortcuts.description": "Descripció",
   "keyboard_shortcuts.direct": "per obrir la columna de missatges directes",
   "keyboard_shortcuts.down": "per baixar en la llista",
-  "keyboard_shortcuts.enter": "ampliar estat",
+  "keyboard_shortcuts.enter": "ampliar el toot",
   "keyboard_shortcuts.favourite": "afavorir",
   "keyboard_shortcuts.favourites": "per obrir la llista de favorits",
   "keyboard_shortcuts.federated": "per obrir la línia de temps federada",
-  "keyboard_shortcuts.heading": "Keyboard Shortcuts",
-  "keyboard_shortcuts.home": "per obrir la línia de temps Inici",
+  "keyboard_shortcuts.heading": "Dreçeres de teclat",
+  "keyboard_shortcuts.home": "per a obrir la línia de temps Inici",
   "keyboard_shortcuts.hotkey": "Tecla d'accés directe",
   "keyboard_shortcuts.legend": "per a mostrar aquesta llegenda",
-  "keyboard_shortcuts.local": "per obrir la línia de temps local",
-  "keyboard_shortcuts.mention": "per esmentar l'autor",
-  "keyboard_shortcuts.muted": "per obrir la llista d'usuaris silenciats",
-  "keyboard_shortcuts.my_profile": "per obrir el teu perfil",
-  "keyboard_shortcuts.notifications": "per obrir la columna de notificacions",
-  "keyboard_shortcuts.pinned": "per obrir la llista de toots fixats",
-  "keyboard_shortcuts.profile": "per obrir el perfil de l'autor",
+  "keyboard_shortcuts.local": "per a obrir la línia de temps local",
+  "keyboard_shortcuts.mention": "per a esmentar l'autor",
+  "keyboard_shortcuts.muted": "per a obrir la llista d'usuaris silenciats",
+  "keyboard_shortcuts.my_profile": "per a obrir el teu perfil",
+  "keyboard_shortcuts.notifications": "per a obrir la columna de notificacions",
+  "keyboard_shortcuts.pinned": "per a obrir la llista de toots fixats",
+  "keyboard_shortcuts.profile": "per a obrir el perfil de l'autor",
   "keyboard_shortcuts.reply": "respondre",
-  "keyboard_shortcuts.requests": "per obrir la llista de sol·licituds de seguiment",
-  "keyboard_shortcuts.search": "per centrar la cerca",
-  "keyboard_shortcuts.start": "per obrir la columna \"Començar\"",
+  "keyboard_shortcuts.requests": "per a obrir la llista de sol·licituds de seguiment",
+  "keyboard_shortcuts.search": "per a centrar la cerca",
+  "keyboard_shortcuts.start": "per a obrir la columna \"Començar\"",
   "keyboard_shortcuts.toggle_hidden": "per a mostrar/amagar text sota CW",
+  "keyboard_shortcuts.toggle_sensitivity": "per a mostrar/amagar mèdia",
   "keyboard_shortcuts.toot": "per a començar un toot nou de trinca",
   "keyboard_shortcuts.unfocus": "descentrar l'area de composició de text/cerca",
   "keyboard_shortcuts.up": "moure amunt en la llista",
   "lightbox.close": "Tancar",
   "lightbox.next": "Següent",
   "lightbox.previous": "Anterior",
+  "lightbox.view_context": "Veure el context",
   "lists.account.add": "Afegir a la llista",
   "lists.account.remove": "Treure de la llista",
-  "lists.delete": "Delete list",
+  "lists.delete": "Esborrar llista",
   "lists.edit": "Editar llista",
+  "lists.edit.submit": "Canvi de títol",
   "lists.new.create": "Afegir llista",
   "lists.new.title_placeholder": "Nova llista",
   "lists.search": "Cercar entre les persones que segueixes",
@@ -213,7 +226,7 @@
   "missing_indicator.label": "No trobat",
   "missing_indicator.sublabel": "Aquest recurs no pot ser trobat",
   "mute_modal.hide_notifications": "Amagar notificacions d'aquest usuari?",
-  "navigation_bar.apps": "Apps Mòbils",
+  "navigation_bar.apps": "Apps mòbils",
   "navigation_bar.blocks": "Usuaris bloquejats",
   "navigation_bar.community_timeline": "Línia de temps Local",
   "navigation_bar.compose": "Redacta nou toot",
@@ -224,7 +237,8 @@
   "navigation_bar.favourites": "Favorits",
   "navigation_bar.filters": "Paraules silenciades",
   "navigation_bar.follow_requests": "Sol·licituds de seguiment",
-  "navigation_bar.info": "Informació addicional",
+  "navigation_bar.follows_and_followers": "Seguits i seguidors",
+  "navigation_bar.info": "Sobre aquest servidor",
   "navigation_bar.keyboard_shortcuts": "Dreceres de teclat",
   "navigation_bar.lists": "Llistes",
   "navigation_bar.logout": "Tancar sessió",
@@ -232,12 +246,14 @@
   "navigation_bar.personal": "Personal",
   "navigation_bar.pins": "Toots fixats",
   "navigation_bar.preferences": "Preferències",
+  "navigation_bar.profile_directory": "Directori de perfils",
   "navigation_bar.public_timeline": "Línia de temps federada",
   "navigation_bar.security": "Seguretat",
   "notification.favourite": "{name} ha afavorit el teu estat",
   "notification.follow": "{name} et segueix",
   "notification.mention": "{name} t'ha esmentat",
-  "notification.reblog": "{name} ha retootejat el teu estat",
+  "notification.poll": "Ha finalitzat una enquesta en la que has votat",
+  "notification.reblog": "{name} ha impulsat el teu estat",
   "notifications.clear": "Netejar notificacions",
   "notifications.clear_confirmation": "Estàs segur que vols esborrar permanenment totes les teves notificacions?",
   "notifications.column_settings.alert": "Notificacions d'escriptori",
@@ -247,7 +263,8 @@
   "notifications.column_settings.filter_bar.show": "Mostra",
   "notifications.column_settings.follow": "Nous seguidors:",
   "notifications.column_settings.mention": "Mencions:",
-  "notifications.column_settings.push": "Push notificacions",
+  "notifications.column_settings.poll": "Resultats de l’enquesta:",
+  "notifications.column_settings.push": "Notificacions push",
   "notifications.column_settings.reblog": "Impulsos:",
   "notifications.column_settings.show": "Mostrar en la columna",
   "notifications.column_settings.sound": "Reproduïr so",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favorits",
   "notifications.filter.follows": "Seguiments",
   "notifications.filter.mentions": "Mencions",
+  "notifications.filter.polls": "Resultats de l'enquesta",
   "notifications.group": "{count} notificacions",
+  "poll.closed": "Finalitzada",
+  "poll.refresh": "Actualitza",
+  "poll.total_votes": "{count, plural, one {# vot} other {# vots}}",
+  "poll.vote": "Vota",
+  "poll_button.add_poll": "Afegeix una enquesta",
+  "poll_button.remove_poll": "Elimina l'enquesta",
   "privacy.change": "Ajusta l'estat de privacitat",
   "privacy.direct.long": "Publicar només per als usuaris esmentats",
   "privacy.direct.short": "Directe",
@@ -276,27 +300,27 @@
   "reply_indicator.cancel": "Cancel·lar",
   "report.forward": "Reenvia a {target}",
   "report.forward_hint": "Aquest compte és d'un altre servidor. Enviar-hi també una copia anònima del informe?",
-  "report.hint": "El informe s'enviarà als moderadors de la teva instància. Pots explicar perquè vols informar d'aquest compte aquí:",
+  "report.hint": "El informe s'enviarà als moderadors del teu servidor. Pots explicar perquè vols informar d'aquest compte aquí:",
   "report.placeholder": "Comentaris addicionals",
   "report.submit": "Enviar",
-  "report.target": "Informes",
+  "report.target": "Informes {target}",
   "search.placeholder": "Cercar",
   "search_popout.search_format": "Format de cerca avançada",
   "search_popout.tips.full_text": "Text simple recupera publicacions que has escrit, les marcades com a favorites, les impulsades o en les que has estat esmentat, així com usuaris, noms d'usuari i etiquetes.",
   "search_popout.tips.hashtag": "etiqueta",
-  "search_popout.tips.status": "status",
+  "search_popout.tips.status": "estat",
   "search_popout.tips.text": "El text simple retorna coincidències amb els noms de visualització, els noms d'usuari i les etiquetes",
   "search_popout.tips.user": "usuari",
   "search_results.accounts": "Gent",
   "search_results.hashtags": "Etiquetes",
   "search_results.statuses": "Toots",
-  "search_results.total": "{count, number} {count, plural, un {result} altres {results}}",
-  "standalone.public_title": "Una mirada a l'interior ...",
+  "search_results.total": "{count, number} {count, plural, one {resultat} other {resultats}}",
   "status.admin_account": "Obre l'interfície de moderació per a @{name}",
-  "status.admin_status": "Obre aquest estat a la interfície de moderació",
-  "status.block": "Block @{name}",
+  "status.admin_status": "Obre aquest toot a la interfície de moderació",
+  "status.block": "Bloqueja @{name}",
   "status.cancel_reblog_private": "Desfer l'impuls",
-  "status.cannot_reblog": "Aquesta publicació no pot ser retootejada",
+  "status.cannot_reblog": "Aquesta publicació no pot ser impulsada",
+  "status.copy": "Copia l'enllaç al toot",
   "status.delete": "Esborrar",
   "status.detailed_status": "Visualització detallada de la conversa",
   "status.direct": "Missatge directe @{name}",
@@ -315,13 +339,12 @@
   "status.read_more": "Llegir més",
   "status.reblog": "Impuls",
   "status.reblog_private": "Impulsar a l'audiència original",
-  "status.reblogged_by": "{name} ha retootejat",
+  "status.reblogged_by": "{name} ha impulsat",
   "status.reblogs.empty": "Encara ningú no ha impulsat aquest toot. Quan algú ho faci, apareixeran aquí.",
   "status.redraft": "Esborrar i reescriure",
   "status.reply": "Respondre",
   "status.replyAll": "Respondre al tema",
   "status.report": "Informar sobre @{name}",
-  "status.sensitive_toggle": "Clic per veure",
   "status.sensitive_warning": "Contingut sensible",
   "status.share": "Compartir",
   "status.show_less": "Mostra menys",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Local",
   "tabs_bar.notifications": "Notificacions",
   "tabs_bar.search": "Cerca",
-  "trends.count_by_accounts": "{count} {rawCount, plural, una {person} altres {people}} parlant",
-  "ui.beforeunload": "El vostre esborrany es perdrà si sortiu de Mastodon.",
-  "upload_area.title": "Arrossega i deixa anar per carregar",
+  "time_remaining.days": "{number, plural, one {# dia} other {# dies}} restants",
+  "time_remaining.hours": "{number, plural, one {# hora} other {# hores}} restants",
+  "time_remaining.minutes": "{number, plural, one {# minut} other {# minuts}} restants",
+  "time_remaining.moments": "Moments restants",
+  "time_remaining.seconds": "{number, plural, one {# segon} other {# segons}} restants",
+  "trends.count_by_accounts": "{count} {rawCount, plural, one {persona} other {gent}} talking",
+  "ui.beforeunload": "El teu esborrany es perdrà si surts de Mastodon.",
+  "upload_area.title": "Arrossega i deixa anar per a carregar",
   "upload_button.label": "Afegir multimèdia (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "S'ha superat el límit de càrrega d'arxius.",
+  "upload_error.poll": "No es permet l'enviament de fitxers en les enquestes.",
   "upload_form.description": "Descriure els problemes visuals",
   "upload_form.focus": "Modificar la previsualització",
   "upload_form.undo": "Esborra",
diff --git a/app/javascript/mastodon/locales/co.json b/app/javascript/mastodon/locales/co.json
index 496f13e7d58f698b374572d2477f7b9ffbf5ba90..fb8ffdd51020645b8cb4b072d158eeb96a30d2d7 100644
--- a/app/javascript/mastodon/locales/co.json
+++ b/app/javascript/mastodon/locales/co.json
@@ -5,7 +5,6 @@
   "account.block_domain": "Piattà tuttu da {domain}",
   "account.blocked": "Bluccatu",
   "account.direct": "Missaghju direttu @{name}",
-  "account.disclaimer_full": "Ghjè pussibule chì l’infurmazione quì sottu ùn rifletta micca u prufile sanu di l’utilizatore.",
   "account.domain_blocked": "Duminiu piattatu",
   "account.edit_profile": "Mudificà u prufile",
   "account.endorse": "Fà figurà nant'à u prufilu",
@@ -36,7 +35,6 @@
   "account.unfollow": "Ùn siguità più",
   "account.unmute": "Ùn piattà più @{name}",
   "account.unmute_notifications": "Ùn piattà più nutificazione da @{name}",
-  "account.view_full_profile": "Vede tuttu u prufile",
   "alert.unexpected.message": "Un prublemu inaspettatu hè accadutu.",
   "alert.unexpected.title": "Uups!",
   "boost_modal.combo": "Pudete appughjà nant'à {combo} per saltà quessa a prussima volta",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "U vostru contu ùn hè micca {locked}. Tuttu u mondu pò seguitavi è vede i vostri statuti privati.",
   "compose_form.lock_disclaimer.lock": "privatu",
   "compose_form.placeholder": "À chè pensate?",
+  "compose_form.poll.add_option": "Aghjustà una scelta",
+  "compose_form.poll.duration": "Durata di u scandagliu",
+  "compose_form.poll.option_placeholder": "Scelta {number}",
+  "compose_form.poll.remove_option": "Toglie sta scelta",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Indicà u media cum'è sensibile",
   "compose_form.sensitive.marked": "Media indicatu cum'è sensibile",
   "compose_form.sensitive.unmarked": "Media micca indicatu cum'è sensibile",
   "compose_form.spoiler.marked": "Testu piattatu daret'à un'avertimentu",
   "compose_form.spoiler.unmarked": "Testu micca piattatu",
   "compose_form.spoiler_placeholder": "Scrive u vostr'avertimentu quì",
   "confirmation_modal.cancel": "Annullà",
+  "confirmations.block.block_and_report": "Bluccà è signalà",
   "confirmations.block.confirm": "Bluccà",
   "confirmations.block.message": "Site sicuru·a che vulete bluccà @{name}?",
   "confirmations.delete.confirm": "Toglie",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Simbuli",
   "emoji_button.travel": "Lochi è Viaghju",
   "empty_column.account_timeline": "Nisun statutu quì!",
+  "empty_column.account_unavailable": "Prufile micca dispunibule",
   "empty_column.blocks": "Per avà ùn avete bluccatu manc'un utilizatore.",
   "empty_column.community": "Ùn c'hè nunda indè a linea lucale. Scrivete puru qualcosa!",
   "empty_column.direct": "Ùn avete ancu nisun missaghju direttu. S'è voi mandate o ricevete unu, u vidarete quì.",
@@ -128,12 +133,12 @@
   "empty_column.lists": "Ùn avete manc'una lista. Quandu farete una, sarà mustrata quì.",
   "empty_column.mutes": "Per avà ùn avete manc'un utilizatore piattatu.",
   "empty_column.notifications": "Ùn avete ancu nisuna nutificazione. Interact with others to start the conversation.",
-  "empty_column.public": "Ùn c'hè nunda quì! Scrivete qualcosa in pubblicu o seguitate utilizatori d'altre istanze per empie a linea pubblica",
+  "empty_column.public": "Ùn c'hè nunda quì! Scrivete qualcosa in pubblicu o seguitate utilizatori d'altri servori per empie a linea pubblica",
   "follow_request.authorize": "Auturizà",
   "follow_request.reject": "Righjittà",
   "getting_started.developers": "Sviluppatori",
   "getting_started.directory": "Annuariu di i prufili",
-  "getting_started.documentation": "Documentation",
+  "getting_started.documentation": "Ducumentazione",
   "getting_started.heading": "Per principià",
   "getting_started.invite": "Invità ghjente",
   "getting_started.open_source_notice": "Mastodon ghjè un lugiziale liberu. Pudete cuntribuisce à u codice o a traduzione, o palisà un bug, nant'à GitHub: {github}.",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "è {additional}",
   "hashtag.column_header.tag_mode.any": "o {additional}",
   "hashtag.column_header.tag_mode.none": "senza {additional}",
+  "hashtag.column_settings.select.no_options_message": "Nisuna sugestione trova",
+  "hashtag.column_settings.select.placeholder": "Entrà l'hashtag…",
   "hashtag.column_settings.tag_mode.all": "Tutti quessi",
   "hashtag.column_settings.tag_mode.any": "Unu di quessi",
   "hashtag.column_settings.tag_mode.none": "Nisunu di quessi",
@@ -149,9 +156,12 @@
   "home.column_settings.basic": "Bàsichi",
   "home.column_settings.show_reblogs": "Vede e spartere",
   "home.column_settings.show_replies": "Vede e risposte",
+  "intervals.full.days": "{number, plural, one {# ghjornu} other {# ghjorni}}",
+  "intervals.full.hours": "{number, plural, one {# ora} other {# ore}}",
+  "intervals.full.minutes": "{number, plural, one {# minuta} other {# minute}}",
   "introduction.federation.action": "Cuntinuà",
   "introduction.federation.federated.headline": "Federata",
-  "introduction.federation.federated.text": "I statuti pubblichi da l'altri servori di u fediverse saranu mustrati nant'à a linea pubblica federata.",
+  "introduction.federation.federated.text": "I statuti pubblichi da l'altri servori di u fediverse saranu mustrati nant'à a linea pubblica glubale.",
   "introduction.federation.home.headline": "Accolta",
   "introduction.federation.home.text": "I statuti da a ghjente che vo siguitate saranu affissati nant'à a linea d'accolta. Pudete seguità qualvogliasia nant'à tutti i servori!",
   "introduction.federation.local.headline": "Lucale",
@@ -177,7 +187,7 @@
   "keyboard_shortcuts.enter": "apre u statutu",
   "keyboard_shortcuts.favourite": "aghjunghje à i favuriti",
   "keyboard_shortcuts.favourites": "per apre a lista di i favuriti",
-  "keyboard_shortcuts.federated": "per apre a linea pubblica federata",
+  "keyboard_shortcuts.federated": "per apre a linea pubblica glubale",
   "keyboard_shortcuts.heading": "Accorte cù a tastera",
   "keyboard_shortcuts.home": "per apre a linea d'accolta",
   "keyboard_shortcuts.hotkey": "Accorta",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "fucalizà nant'à l'area di circata",
   "keyboard_shortcuts.start": "per apre a culonna \"per principià\"",
   "keyboard_shortcuts.toggle_hidden": "vede/piattà u testu daretu à l'avertimentu CW",
+  "keyboard_shortcuts.toggle_sensitivity": "vede/piattà i media",
   "keyboard_shortcuts.toot": "scrive un novu statutu",
   "keyboard_shortcuts.unfocus": "ùn fucalizà più l'area di testu",
   "keyboard_shortcuts.up": "cullà indè a lista",
   "lightbox.close": "Chjudà",
   "lightbox.next": "Siguente",
   "lightbox.previous": "Pricidente",
+  "lightbox.view_context": "Vede u cuntestu",
   "lists.account.add": "Aghjunghje à a lista",
   "lists.account.remove": "Toglie di a lista",
   "lists.delete": "Supprime a lista",
   "lists.edit": "Mudificà a lista",
+  "lists.edit.submit": "Cambià u titulu",
   "lists.new.create": "Aghjustà una lista",
   "lists.new.title_placeholder": "Titulu di a lista",
   "lists.search": "Circà indè i vostr'abbunamenti",
@@ -224,19 +237,22 @@
   "navigation_bar.favourites": "Favuriti",
   "navigation_bar.filters": "Parolle silenzate",
   "navigation_bar.follow_requests": "Dumande d'abbunamentu",
-  "navigation_bar.info": "À prupositu di l'istanza",
+  "navigation_bar.follows_and_followers": "Abbunati è abbunamenti",
+  "navigation_bar.info": "À prupositu di u servore",
   "navigation_bar.keyboard_shortcuts": "Accorte cù a tastera",
   "navigation_bar.lists": "Liste",
   "navigation_bar.logout": "Scunnettassi",
   "navigation_bar.mutes": "Utilizatori piattati",
-  "navigation_bar.personal": "Personal",
+  "navigation_bar.personal": "Persunale",
   "navigation_bar.pins": "Statuti puntarulati",
   "navigation_bar.preferences": "Preferenze",
+  "navigation_bar.profile_directory": "Annuariu di i prufili",
   "navigation_bar.public_timeline": "Linea pubblica glubale",
   "navigation_bar.security": "Sicurità",
   "notification.favourite": "{name} hà aghjuntu u vostru statutu à i so favuriti",
   "notification.follow": "{name} v'hà seguitatu",
   "notification.mention": "{name} v'hà mintuvatu",
+  "notification.poll": "Un scandagliu induve avete vutatu hè finitu",
   "notification.reblog": "{name} hà spartutu u vostru statutu",
   "notifications.clear": "Purgà e nutificazione",
   "notifications.clear_confirmation": "Site sicuru·a che vulete toglie tutte ste nutificazione?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Mustrà",
   "notifications.column_settings.follow": "Abbunati novi:",
   "notifications.column_settings.mention": "Minzione:",
+  "notifications.column_settings.poll": "Risultati:",
   "notifications.column_settings.push": "Nutificazione Push",
   "notifications.column_settings.reblog": "Spartere:",
   "notifications.column_settings.show": "Mustrà indè a colonna",
@@ -256,27 +273,34 @@
   "notifications.filter.favourites": "Favuriti",
   "notifications.filter.follows": "Abbunamenti",
   "notifications.filter.mentions": "Minzione",
+  "notifications.filter.polls": "Risultati di u scandagliu",
   "notifications.group": "{count} nutificazione",
+  "poll.closed": "Chjosu",
+  "poll.refresh": "Attualizà",
+  "poll.total_votes": "{count, plural, one {# votu} other {# voti}}",
+  "poll.vote": "Vutà",
+  "poll_button.add_poll": "Aghjustà un scandagliu",
+  "poll_button.remove_poll": "Toglie u scandagliu",
   "privacy.change": "Mudificà a cunfidenzialità di u statutu",
   "privacy.direct.long": "Mandà solu à quelli chì so mintuvati",
   "privacy.direct.short": "Direttu",
   "privacy.private.long": "Mustrà solu à l'abbunati",
   "privacy.private.short": "Privatu",
-  "privacy.public.long": "Mustrà à tuttu u mondu nant'a linea pubblica",
+  "privacy.public.long": "Mustrà à tuttu u mondu nant'à e linee pubbliche",
   "privacy.public.short": "Pubblicu",
-  "privacy.unlisted.long": "Ùn mette micca nant'a linea pubblica (ma tutt'u mondu pò vede u statutu nant'à u vostru prufile)",
+  "privacy.unlisted.long": "Ùn mette micca nant'à e linee pubbliche",
   "privacy.unlisted.short": "Micca listatu",
   "regeneration_indicator.label": "Caricamentu…",
   "regeneration_indicator.sublabel": "Priparazione di a vostra pagina d'accolta!",
-  "relative_time.days": "{number}d",
-  "relative_time.hours": "{number}h",
+  "relative_time.days": "{number}ghj",
+  "relative_time.hours": "{number}o",
   "relative_time.just_now": "avà",
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Annullà",
   "report.forward": "Trasferisce à {target}",
   "report.forward_hint": "U contu hè nant'à un'altru servore. Vulete ancu mandà una copia anonima di u signalamentu quallà?",
-  "report.hint": "U signalamentu sarà mandatu à i muderatori di l'istanza. Pudete spiegà perchè avete palisatu stu contu quì sottu:",
+  "report.hint": "U signalamentu sarà mandatu à i muderatori di u servore. Pudete spiegà perchè avete palisatu stu contu quì sottu:",
   "report.placeholder": "Altri cummenti",
   "report.submit": "Mandà",
   "report.target": "Signalamentu",
@@ -291,12 +315,12 @@
   "search_results.hashtags": "Hashtag",
   "search_results.statuses": "Statuti",
   "search_results.total": "{count, number} {count, plural, one {risultatu} other {risultati}}",
-  "standalone.public_title": "Una vista à l'internu...",
   "status.admin_account": "Apre l'interfaccia di muderazione per @{name}",
   "status.admin_status": "Apre stu statutu in l'interfaccia di muderazione",
   "status.block": "Bluccà @{name}",
   "status.cancel_reblog_private": "Ùn sparte più",
   "status.cannot_reblog": "Stu statutu ùn pò micca esse spartutu",
+  "status.copy": "Cupià ligame indè u statutu",
   "status.delete": "Toglie",
   "status.detailed_status": "Vista in ditagliu di a cunversazione",
   "status.direct": "Mandà un missaghju @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Risponde",
   "status.replyAll": "Risponde à tutti",
   "status.report": "Palisà @{name}",
-  "status.sensitive_toggle": "Cliccate per vede",
   "status.sensitive_warning": "Cuntinutu sensibile",
   "status.share": "Sparte",
   "status.show_less": "Ripiegà",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Lucale",
   "tabs_bar.notifications": "Nutificazione",
   "tabs_bar.search": "Cercà",
+  "time_remaining.days": "{number, plural, one {# ghjornu ferma} other {# ghjorni fermanu}}",
+  "time_remaining.hours": "{number, plural, one {# ora ferma} other {# ore fermanu}}",
+  "time_remaining.minutes": "{number, plural, one {# minuta ferma} other {# minute fermanu}} left",
+  "time_remaining.moments": "Ci fermanu qualchi mumentu",
+  "time_remaining.seconds": "{number, plural, one {# siconda ferma} other {# siconde fermanu}}",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} parlanu",
   "ui.beforeunload": "A bruttacopia sarà persa s'ellu hè chjosu Mastodon.",
   "upload_area.title": "Drag & drop per caricà un fugliale",
   "upload_button.label": "Aghjunghje un media (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "Limita di caricamentu di fugliali trapassata.",
+  "upload_error.poll": "Ùn si pò micca caricà fugliali cù i scandagli.",
   "upload_form.description": "Discrive per i malvistosi",
   "upload_form.focus": "Cambià a vista",
   "upload_form.undo": "Sguassà",
diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json
index e11e0be93e73d5f4585f50e678884b9469aa5693..f10a3f38b72a03a9c906ace3a5a9bcfc24a7be8f 100644
--- a/app/javascript/mastodon/locales/cs.json
+++ b/app/javascript/mastodon/locales/cs.json
@@ -4,13 +4,12 @@
   "account.block": "Zablokovat uživatele @{name}",
   "account.block_domain": "Skrýt vše z {domain}",
   "account.blocked": "Blokován/a",
-  "account.direct": "Přímá zpráva pro uživatele @{name}",
-  "account.disclaimer_full": "Níže uvedené informace nemusejí zcela odrážet profil uživatele.",
+  "account.direct": "Poslat přímou zprávu uživateli @{name}",
   "account.domain_blocked": "Doména skryta",
   "account.edit_profile": "Upravit profil",
   "account.endorse": "Představit na profilu",
   "account.follow": "Sledovat",
-  "account.followers": "Sledovatelé",
+  "account.followers": "Sledující",
   "account.followers.empty": "Tohoto uživatele ještě nikdo nesleduje.",
   "account.follows": "Sledovaní",
   "account.follows.empty": "Tento uživatel ještě nikoho nesleduje.",
@@ -21,22 +20,21 @@
   "account.media": "Média",
   "account.mention": "Zmínit uživatele @{name}",
   "account.moved_to": "{name} se přesunul/a na:",
-  "account.mute": "Ignorovat uživatele @{name}",
+  "account.mute": "Skrýt uživatele @{name}",
   "account.mute_notifications": "Skrýt oznámení od uživatele @{name}",
-  "account.muted": "Ztišen/a",
+  "account.muted": "Skryt/a",
   "account.posts": "Tooty",
   "account.posts_with_replies": "Tooty a odpovědi",
   "account.report": "Nahlásit uživatele @{name}",
-  "account.requested": "Požadavek čeká na schválení. Kliknutím zrušíte požadavek o sledování",
+  "account.requested": "Čekám na schválení. Kliknutím zrušíte požadavek o sledování",
   "account.share": "Sdílet profil uživatele @{name}",
   "account.show_reblogs": "Zobrazit boosty od uživatele @{name}",
   "account.unblock": "Odblokovat uživatele @{name}",
   "account.unblock_domain": "Odkrýt doménu {domain}",
   "account.unendorse": "Nepředstavit na profilu",
   "account.unfollow": "Přestat sledovat",
-  "account.unmute": "Přestat ignorovat uživatele @{name}",
-  "account.unmute_notifications": "Odtišit oznámení od uživatele @{name}",
-  "account.view_full_profile": "Zobrazit celý profil",
+  "account.unmute": "Odkrýt uživatele @{name}",
+  "account.unmute_notifications": "Odkrýt oznámení od uživatele @{name}",
   "alert.unexpected.message": "Objevila se neočekávaná chyba.",
   "alert.unexpected.title": "Jejda!",
   "boost_modal.combo": "Příště můžete pro přeskočení kliknout na {combo}",
@@ -54,14 +52,14 @@
   "column.follow_requests": "Požadavky o sledování",
   "column.home": "Domů",
   "column.lists": "Seznamy",
-  "column.mutes": "Ignorovaní uživatelé",
+  "column.mutes": "Skrytí uživatelé",
   "column.notifications": "Oznámení",
   "column.pins": "Připnuté tooty",
   "column.public": "Federovaná časová osa",
   "column_back_button.label": "Zpět",
   "column_header.hide_settings": "Skrýt nastavení",
-  "column_header.moveLeft_settings": "Přesunout sloupec doleva",
-  "column_header.moveRight_settings": "Přesunout sloupec doprava",
+  "column_header.moveLeft_settings": "Posunout sloupec doleva",
+  "column_header.moveRight_settings": "Posunout sloupec doprava",
   "column_header.pin": "Připnout",
   "column_header.show_settings": "Zobrazit nastavení",
   "column_header.unpin": "Odepnout",
@@ -70,34 +68,40 @@
   "compose_form.direct_message_warning": "Tento toot bude odeslán pouze zmíněným uživatelům.",
   "compose_form.direct_message_warning_learn_more": "Zjistit více",
   "compose_form.hashtag_warning": "Tento toot nebude zobrazen pod žádným hashtagem, neboť je neuvedený. Pouze veřejné tooty mohou být vyhledány podle hashtagu.",
-  "compose_form.lock_disclaimer": "Váš účet není {locked}. Kdokoliv vás může sledovat a vidět vaše příspěvky pouze pro sledovatele.",
-  "compose_form.lock_disclaimer.lock": "zamčený",
-  "compose_form.placeholder": "Co máte na mysli?",
+  "compose_form.lock_disclaimer": "Váš účet není {locked}. Kdokoliv vás může sledovat a vidět vaše příspěvky pouze pro sledující.",
+  "compose_form.lock_disclaimer.lock": "uzamčen",
+  "compose_form.placeholder": "Co se vám honí hlavou?",
+  "compose_form.poll.add_option": "Přidat volbu",
+  "compose_form.poll.duration": "Délka ankety",
+  "compose_form.poll.option_placeholder": "Volba {number}",
+  "compose_form.poll.remove_option": "Odstranit tuto volbu",
   "compose_form.publish": "Tootnout",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive.marked": "Mediální obsah je označen jako citlivý",
-  "compose_form.sensitive.unmarked": "Mediální obsah není označen jako citlivý",
+  "compose_form.sensitive.hide": "Označit média jako citlivá",
+  "compose_form.sensitive.marked": "Média jsou označena jako citlivá",
+  "compose_form.sensitive.unmarked": "Média nejsou označena jako citlivá",
   "compose_form.spoiler.marked": "Text je skrytý za varováním",
   "compose_form.spoiler.unmarked": "Text není skrytý",
   "compose_form.spoiler_placeholder": "Sem napište vaše varování",
   "confirmation_modal.cancel": "Zrušit",
+  "confirmations.block.block_and_report": "Blokovat a nahlásit",
   "confirmations.block.confirm": "Blokovat",
   "confirmations.block.message": "Jste si jistý/á, že chcete zablokovat uživatele {name}?",
   "confirmations.delete.confirm": "Smazat",
-  "confirmations.delete.message": "Jste si jistý/á, že chcete smazat tento příspěvek?",
+  "confirmations.delete.message": "Jste si jistý/á, že chcete smazat tento toot?",
   "confirmations.delete_list.confirm": "Smazat",
-  "confirmations.delete_list.message": "Jste si jistý/á, že chcete tento seznam navždy vymazat?",
+  "confirmations.delete_list.message": "Jste si jistý/á, že chcete tento seznam navždy smazat?",
   "confirmations.domain_block.confirm": "Skrýt celou doménu",
-  "confirmations.domain_block.message": "Jste si opravdu, opravdu jistý/á, že chcete blokovat celou {domain}? Ve většině případů stačí zablokovat nebo ignorovat pár konkrétních uživatelů, což se doporučuje. Z této domény neuvidíte obsah v žádné veřejné časové ose ani v oznámeních. Vaši sledovatelé z této domény budou odstraněni.",
-  "confirmations.mute.confirm": "Ignorovat",
-  "confirmations.mute.message": "Jste si jistý/á, že chcete ignorovat uživatele {name}?",
-  "confirmations.redraft.confirm": "Vymazat a přepsat",
-  "confirmations.redraft.message": "Jste si jistý/á, že chcete vymazat a přepsat tento příspěvek? Oblíbení a boosty budou ztraceny a odpovědi na původní příspěvek budou opuštěny.",
+  "confirmations.domain_block.message": "Jste si opravdu, opravdu jistý/á, že chcete blokovat celou doménu {domain}? Ve většině případů stačí zablokovat nebo skrýt pár konkrétních uživatelů, což se doporučuje. Z této domény neuvidíte obsah v žádné veřejné časové ose ani v oznámeních. Vaši sledující z této domény budou odstraněni.",
+  "confirmations.mute.confirm": "Skrýt",
+  "confirmations.mute.message": "Jste si jistý/á, že chcete skrýt uživatele {name}?",
+  "confirmations.redraft.confirm": "Smazat a přepsat",
+  "confirmations.redraft.message": "Jste si jistý/á, že chcete smazat a přepsat tento toot? Oblíbení a boosty budou ztraceny a odpovědi na původní příspěvek budou opuštěny.",
   "confirmations.reply.confirm": "Odpovědět",
   "confirmations.reply.message": "Odpovězením nyní přepíšete zprávu, kterou aktuálně píšete. Jste si jistý/á, že chcete pokračovat?",
   "confirmations.unfollow.confirm": "Přestat sledovat",
   "confirmations.unfollow.message": "jste si jistý/á, že chcete přestat sledovat uživatele {name}?",
-  "embed.instructions": "Pro přidání příspěvku na vaši webovou stránku zkopírujte níže uvedený kód.",
+  "embed.instructions": "Pro přidání tootu na vaši webovou stránku zkopírujte níže uvedený kód.",
   "embed.preview": "Takhle to bude vypadat:",
   "emoji_button.activity": "Aktivita",
   "emoji_button.custom": "Vlastní",
@@ -105,15 +109,16 @@
   "emoji_button.food": "Jídla a nápoje",
   "emoji_button.label": "Vložit emoji",
   "emoji_button.nature": "Příroda",
-  "emoji_button.not_found": "Žádné emoji!! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.not_found": "Žádná emoji!! (╯°□°)╯︵ ┻━┻",
   "emoji_button.objects": "Předměty",
   "emoji_button.people": "Lidé",
-  "emoji_button.recent": "Často používané",
-  "emoji_button.search": "Hledat...",
+  "emoji_button.recent": "Často používaná",
+  "emoji_button.search": "Hledat…",
   "emoji_button.search_results": "Výsledky hledání",
   "emoji_button.symbols": "Symboly",
   "emoji_button.travel": "Cestování a místa",
   "empty_column.account_timeline": "Tady nejsou žádné tooty!",
+  "empty_column.account_unavailable": "Profil nedostupný",
   "empty_column.blocks": "Ještě jste nezablokoval/a žádného uživatele.",
   "empty_column.community": "Místní časová osa je prázdná. Napište něco veřejně a rozhýbejte to tu!",
   "empty_column.direct": "Ještě nemáte žádné přímé zprávy. Pokud nějakou pošlete nebo dostanete, zobrazí se zde.",
@@ -124,11 +129,11 @@
   "empty_column.hashtag": "Pod tímto hashtagem ještě nic není.",
   "empty_column.home": "Vaše domovská časová osa je prázdná! Začněte navštívením {public} nebo použijte hledání a seznamte se s dalšími uživateli.",
   "empty_column.home.public_timeline": "veřejné časové osy",
-  "empty_column.list": "V tomto seznamu ještě nic není. Pokud budou členové tohoto seznamu psát nové příspěvky, objeví se zde.",
+  "empty_column.list": "V tomto seznamu ještě nic není. Pokud budou členové tohoto seznamu psát nové tooty, objeví se zde.",
   "empty_column.lists": "Ještě nemáte žádný seznam. Pokud nějaký vytvoříte, zobrazí se zde.",
-  "empty_column.mutes": "Ještě neignorujete žádné uživatele.",
+  "empty_column.mutes": "Ještě jste neskryl/a žádné uživatele.",
   "empty_column.notifications": "Ještě nemáte žádná oznámení. Začněte konverzaci komunikováním s ostatními.",
-  "empty_column.public": "Tady nic není! Napište něco veřejně, nebo manuálně začněte sledovat uživatele z jiných instancí, aby tu něco přibylo",
+  "empty_column.public": "Tady nic není! Napište něco veřejně, nebo začněte ručně sledovat uživatele z jiných serverů, aby tu něco přibylo",
   "follow_request.authorize": "Autorizovat",
   "follow_request.reject": "Odmítnout",
   "getting_started.developers": "Vývojáři",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "a {additional}",
   "hashtag.column_header.tag_mode.any": "nebo {additional}",
   "hashtag.column_header.tag_mode.none": "bez {additional}",
+  "hashtag.column_settings.select.no_options_message": "Žádné návrhy nenalezeny",
+  "hashtag.column_settings.select.placeholder": "Zadejte hashtagy…",
   "hashtag.column_settings.tag_mode.all": "Všechny z těchto",
   "hashtag.column_settings.tag_mode.any": "Jakékoliv z těchto",
   "hashtag.column_settings.tag_mode.none": "Žádné z těchto",
@@ -149,42 +156,45 @@
   "home.column_settings.basic": "Základní",
   "home.column_settings.show_reblogs": "Zobrazit boosty",
   "home.column_settings.show_replies": "Zobrazit odpovědi",
+  "intervals.full.days": "{number, plural, one {# den} few {# dny} many {# dne} other {# dní}}",
+  "intervals.full.hours": "{number, plural, one {# hodina} few {# hodiny} many {# hodiny} other {# hodin}}",
+  "intervals.full.minutes": "{number, plural, one {# minuta} few {# minuty} many {# minuty} other {# minut}}",
   "introduction.federation.action": "Další",
   "introduction.federation.federated.headline": "Federovaná",
-  "introduction.federation.federated.text": "Veřejné příspěvky z jiných serverů na fediverse se zobrazí na federované časové ose.",
+  "introduction.federation.federated.text": "Veřejné příspěvky z jiných serverů ve fedivesmíru se zobrazí na federované časové ose.",
   "introduction.federation.home.headline": "Domů",
   "introduction.federation.home.text": "Příspěvky od lidí, které sledujete, se objeví ve vašem domovském proudu. Můžete sledovat kohokoliv na jakémkoliv serveru!",
   "introduction.federation.local.headline": "Místní",
-  "introduction.federation.local.text": "Veřejné příspěvky od lidí ze stejného serveru, jako vy, se zobrazí na místní časové ose.",
+  "introduction.federation.local.text": "Veřejné příspěvky od lidí ze stejného serveru jako vy se zobrazí na místní časové ose.",
   "introduction.interactions.action": "Dokončit tutoriál!",
   "introduction.interactions.favourite.headline": "Oblíbení",
   "introduction.interactions.favourite.text": "Oblíbením si můžete uložit toot na později a dát jeho autorovi vědět, že se vám líbí.",
   "introduction.interactions.reblog.headline": "Boost",
-  "introduction.interactions.reblog.text": "Boostnutím můžete sdílet tooty jiných lidí s vašimi sledovately.",
+  "introduction.interactions.reblog.text": "Boostnutím můžete sdílet tooty jiných lidí s vašimi sledujícími.",
   "introduction.interactions.reply.headline": "Odpověď",
   "introduction.interactions.reply.text": "Můžete odpovídat na tooty jiných lidí i vaše vlastní, což je propojí do konverzace.",
   "introduction.welcome.action": "Jdeme na to!",
   "introduction.welcome.headline": "První kroky",
-  "introduction.welcome.text": "Vítejte na fediverse! Za malou chvíli budete moci posílat zprávy a povídat si se svými přátely přes širokou škálu serverů. Tento server, {domain}, je však speciální—je na něm váš profil, proto si zapamatujte jeho jméno.",
+  "introduction.welcome.text": "Vítejte ve fedivesmíru! Za malou chvíli budete moci posílat zprávy a povídat si se svými přátely přes širokou škálu serverů. Tento server, {domain}, je však speciální—je na něm váš profil, proto si zapamatujte jeho jméno.",
   "keyboard_shortcuts.back": "k návratu zpět",
   "keyboard_shortcuts.blocked": "k otevření seznamu blokovaných uživatelů",
   "keyboard_shortcuts.boost": "k boostnutí",
-  "keyboard_shortcuts.column": "k zaměření na příspěvek v jednom ze sloupců",
+  "keyboard_shortcuts.column": "k zaměření na toot v jednom ze sloupců",
   "keyboard_shortcuts.compose": "k zaměření na psací prostor",
   "keyboard_shortcuts.description": "Popis",
   "keyboard_shortcuts.direct": "k otevření sloupce s přímými zprávami",
   "keyboard_shortcuts.down": "k posunutí dolů v seznamu",
-  "keyboard_shortcuts.enter": "k otevření příspěvku",
+  "keyboard_shortcuts.enter": "k otevření tootu",
   "keyboard_shortcuts.favourite": "k oblíbení",
   "keyboard_shortcuts.favourites": "k otevření seznamu oblíbených",
   "keyboard_shortcuts.federated": "k otevření federované časové osy",
   "keyboard_shortcuts.heading": "Klávesové zkratky",
   "keyboard_shortcuts.home": "k otevření domovské časové osy",
-  "keyboard_shortcuts.hotkey": "Horká klávesa",
+  "keyboard_shortcuts.hotkey": "Klávesová zkratka",
   "keyboard_shortcuts.legend": "k zobrazení této legendy",
   "keyboard_shortcuts.local": "k otevření místní časové osy",
   "keyboard_shortcuts.mention": "ke zmínění autora",
-  "keyboard_shortcuts.muted": "k otevření seznamu ignorovaných uživatelů",
+  "keyboard_shortcuts.muted": "k otevření seznamu skrytých uživatelů",
   "keyboard_shortcuts.my_profile": "k otevření vašeho profilu",
   "keyboard_shortcuts.notifications": "k otevření sloupce s oznámeními",
   "keyboard_shortcuts.pinned": "k otevření seznamu připnutých tootů",
@@ -194,21 +204,24 @@
   "keyboard_shortcuts.search": "k zaměření na hledání",
   "keyboard_shortcuts.start": "k otevření sloupce „začínáme“",
   "keyboard_shortcuts.toggle_hidden": "k zobrazení/skrytí textu za varováním o obsahu",
+  "keyboard_shortcuts.toggle_sensitivity": "k zobrazení/skrytí médií",
   "keyboard_shortcuts.toot": "k napsání úplně nového tootu",
-  "keyboard_shortcuts.unfocus": "ke zrušení soustředění na psací prostor/hledání",
+  "keyboard_shortcuts.unfocus": "ke zrušení zaměření na psací prostor/hledání",
   "keyboard_shortcuts.up": "k posunutí nahoru v seznamu",
   "lightbox.close": "Zavřít",
   "lightbox.next": "Další",
   "lightbox.previous": "Předchozí",
+  "lightbox.view_context": "Zobrazit kontext",
   "lists.account.add": "Přidat do seznamu",
   "lists.account.remove": "Odebrat ze seznamu",
   "lists.delete": "Smazat seznam",
   "lists.edit": "Upravit seznam",
+  "lists.edit.submit": "Změnit název",
   "lists.new.create": "Přidat seznam",
   "lists.new.title_placeholder": "Název nového seznamu",
   "lists.search": "Hledejte mezi lidmi, které sledujete",
   "lists.subheading": "Vaše seznamy",
-  "loading_indicator.label": "Načítám...",
+  "loading_indicator.label": "Načítám…",
   "media_gallery.toggle_visible": "Přepínat viditelnost",
   "missing_indicator.label": "Nenalezeno",
   "missing_indicator.sublabel": "Tento zdroj se nepodařilo najít",
@@ -224,29 +237,33 @@
   "navigation_bar.favourites": "Oblíbené",
   "navigation_bar.filters": "Skrytá slova",
   "navigation_bar.follow_requests": "Požadavky o sledování",
-  "navigation_bar.info": "O této instanci",
+  "navigation_bar.follows_and_followers": "Sledovaní a sledující",
+  "navigation_bar.info": "O tomto serveru",
   "navigation_bar.keyboard_shortcuts": "Klávesové zkratky",
   "navigation_bar.lists": "Seznamy",
-  "navigation_bar.logout": "Odhlásit se",
-  "navigation_bar.mutes": "Ignorovaní uživatelé",
+  "navigation_bar.logout": "Odhlásit",
+  "navigation_bar.mutes": "Skrytí uživatelé",
   "navigation_bar.personal": "Osobní",
   "navigation_bar.pins": "Připnuté tooty",
   "navigation_bar.preferences": "Předvolby",
+  "navigation_bar.profile_directory": "Adresář profilů",
   "navigation_bar.public_timeline": "Federovaná časová osa",
   "navigation_bar.security": "Zabezpečení",
-  "notification.favourite": "{name} si oblíbil/a váš příspěvek",
+  "notification.favourite": "{name} si oblíbil/a váš toot",
   "notification.follow": "{name} vás začal/a sledovat",
   "notification.mention": "{name} vás zmínil/a",
-  "notification.reblog": "{name} boostnul/a váš příspěvek",
+  "notification.poll": "Anketa, ve které jste hlasoval/a, skončila",
+  "notification.reblog": "{name} boostnul/a váš toot",
   "notifications.clear": "Vymazat oznámení",
   "notifications.clear_confirmation": "Jste si jistý/á, že chcete trvale vymazat všechna vaše oznámení?",
   "notifications.column_settings.alert": "Desktopová oznámení",
-  "notifications.column_settings.favourite": "Oblíbené:",
+  "notifications.column_settings.favourite": "Oblíbení:",
   "notifications.column_settings.filter_bar.advanced": "Zobrazit všechny kategorie",
   "notifications.column_settings.filter_bar.category": "Panel rychlého filtrování",
   "notifications.column_settings.filter_bar.show": "Zobrazit",
-  "notifications.column_settings.follow": "Noví sledovatelé:",
+  "notifications.column_settings.follow": "Noví sledující:",
   "notifications.column_settings.mention": "Zmínky:",
+  "notifications.column_settings.poll": "Výsledky anket:",
   "notifications.column_settings.push": "Push oznámení",
   "notifications.column_settings.reblog": "Boosty:",
   "notifications.column_settings.show": "Zobrazit ve sloupci",
@@ -256,12 +273,19 @@
   "notifications.filter.favourites": "Oblíbení",
   "notifications.filter.follows": "Sledování",
   "notifications.filter.mentions": "Zmínky",
+  "notifications.filter.polls": "Výsledky anket",
   "notifications.group": "{count} oznámení",
-  "privacy.change": "Změnit soukromí příspěvku",
+  "poll.closed": "Uzavřena",
+  "poll.refresh": "Obnovit",
+  "poll.total_votes": "{count, plural, one {# hlas} few {# hlasy} many {# hlasu} other {# hlasů}}",
+  "poll.vote": "Hlasovat",
+  "poll_button.add_poll": "Přidat anketu",
+  "poll_button.remove_poll": "Odstranit anketu",
+  "privacy.change": "Změnit soukromí tootu",
   "privacy.direct.long": "Odeslat pouze zmíněným uživatelům",
   "privacy.direct.short": "Přímý",
-  "privacy.private.long": "Odeslat pouze sledovatelům",
-  "privacy.private.short": "Pouze pro sledovatele",
+  "privacy.private.long": "Odeslat pouze sledujícím",
+  "privacy.private.short": "Pouze pro sledující",
   "privacy.public.long": "Odeslat na veřejné časové osy",
   "privacy.public.short": "Veřejný",
   "privacy.unlisted.long": "Neodeslat na veřejné časové osy",
@@ -276,40 +300,40 @@
   "reply_indicator.cancel": "Zrušit",
   "report.forward": "Přeposlat na {target}",
   "report.forward_hint": "Tento účet je z jiného serveru. Chcete na něj také poslat anonymizovanou kopii?",
-  "report.hint": "Toto nahlášení bude zasláno moderátorům vaší instance. Níže můžete uvést, proč tento účet nahlašujete:",
+  "report.hint": "Nahlášení bude zasláno moderátorům vašeho serveru. Níže můžete uvést, proč tento účet nahlašujete:",
   "report.placeholder": "Dodatečné komentáře",
   "report.submit": "Odeslat",
   "report.target": "Nahlášení uživatele {target}",
   "search.placeholder": "Hledat",
   "search_popout.search_format": "Pokročilé hledání",
-  "search_popout.tips.full_text": "Jednoduchý textový výpis příspěvků, které jste napsal/a, oblíbil/a si, boostnul/a, nebo v nich byl/a zmíněn/a, včetně odpovídajících přezdívek, zobrazovaných jmen a hashtagů.",
+  "search_popout.tips.full_text": "Jednoduchý text navrátí tooty, které jste napsal/a, oblíbil/a si, boostnul/a, nebo v nich byl/a zmíněn/a, a také odpovídající přezdívky, zobrazovaná jména a hashtagy.",
   "search_popout.tips.hashtag": "hashtag",
-  "search_popout.tips.status": "příspěvek",
-  "search_popout.tips.text": "Jednoduchý textový výpis odpovídajících zobrazovaných jmen, přezdívek a hashtagů",
+  "search_popout.tips.status": "toot",
+  "search_popout.tips.text": "Jednoduchý text navrátí odpovídající zobrazovaná jména, přezdívky a hashtagy",
   "search_popout.tips.user": "uživatel",
   "search_results.accounts": "Lidé",
   "search_results.hashtags": "Hashtagy",
   "search_results.statuses": "Tooty",
   "search_results.total": "{count, number} {count, plural, one {výsledek} few {výsledky} many {výsledku} other {výsledků}}",
-  "standalone.public_title": "Nahlédněte dovnitř...",
-  "status.admin_account": "Otevřít moderační rozhraní pro uživatele @{name}",
-  "status.admin_status": "Otevřít tento příspěvek v moderačním rozhraní",
+  "status.admin_account": "Otevřít moderátorské rozhraní pro uživatele @{name}",
+  "status.admin_status": "Otevřít tento toot v moderátorském rozhraní",
   "status.block": "Zablokovat uživatele @{name}",
   "status.cancel_reblog_private": "Zrušit boost",
   "status.cannot_reblog": "Tento příspěvek nemůže být boostnutý",
+  "status.copy": "Kopírovat odkaz k tootu",
   "status.delete": "Smazat",
   "status.detailed_status": "Detailní zobrazení konverzace",
   "status.direct": "Poslat přímou zprávu uživateli @{name}",
-  "status.embed": "Vložit",
+  "status.embed": "Vložit na web",
   "status.favourite": "Oblíbit",
   "status.filtered": "Filtrováno",
   "status.load_more": "Zobrazit více",
   "status.media_hidden": "Média skryta",
   "status.mention": "Zmínit uživatele @{name}",
   "status.more": "Více",
-  "status.mute": "Ignorovat uživatele @{name}",
-  "status.mute_conversation": "Ignorovat konverzaci",
-  "status.open": "Rozbalit tento příspěvek",
+  "status.mute": "Skrýt uživatele @{name}",
+  "status.mute_conversation": "Skrýt konverzaci",
+  "status.open": "Otevřít tento toot",
   "status.pin": "Připnout na profil",
   "status.pinned": "Připnutý toot",
   "status.read_more": "Číst více",
@@ -317,11 +341,10 @@
   "status.reblog_private": "Boostnout původnímu publiku",
   "status.reblogged_by": "{name} boostnul/a",
   "status.reblogs.empty": "Tento toot ještě nikdo neboostnul. Pokud to někdo udělá, zobrazí se zde.",
-  "status.redraft": "Vymazat a přepsat",
+  "status.redraft": "Smazat a přepsat",
   "status.reply": "Odpovědět",
   "status.replyAll": "Odpovědět na vlákno",
   "status.report": "Nahlásit uživatele @{name}",
-  "status.sensitive_toggle": "Klikněte pro zobrazení",
   "status.sensitive_warning": "Citlivý obsah",
   "status.share": "Sdílet",
   "status.show_less": "Zobrazit méně",
@@ -329,23 +352,30 @@
   "status.show_more": "Zobrazit více",
   "status.show_more_all": "Zobrazit více pro všechny",
   "status.show_thread": "Zobrazit vlákno",
-  "status.unmute_conversation": "Přestat ignorovat konverzaci",
+  "status.unmute_conversation": "Odkrýt konverzaci",
   "status.unpin": "Odepnout z profilu",
   "suggestions.dismiss": "Odmítnout návrh",
-  "suggestions.header": "Mohlo by vás zajímat…",
+  "suggestions.header": "Mohli by vás zajímat…",
   "tabs_bar.federated_timeline": "Federovaná",
   "tabs_bar.home": "Domů",
   "tabs_bar.local_timeline": "Místní",
   "tabs_bar.notifications": "Oznámení",
   "tabs_bar.search": "Hledat",
+  "time_remaining.days": "{number, plural, one {Zbývá # den} few {Zbývají # dny} many {Zbývá # dne} other {Zbývá # dní}}",
+  "time_remaining.hours": "{number, plural, one {Zbývá # hodina} few {Zbývají # hodiny} many {Zbývá # hodiny} other {Zbývá # hodin}}",
+  "time_remaining.minutes": "{number, plural, one {Zbývá # minuta} few {Zbývají # minuty} many {Zbývá # minuty} other {Zbývá # minut}}",
+  "time_remaining.moments": "Zbývá několik sekund",
+  "time_remaining.seconds": "{number, plural, one {Zbývá # sekunda} few {Zbývají # sekundy} many {Zbývá # sekundy} other {Zbývá # sekund}}",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {člověk} few {lidé} many {lidí} other {lidí}} hovoří",
   "ui.beforeunload": "Váš koncept se ztratí, pokud Mastodon opustíte.",
   "upload_area.title": "Přetažením nahrajete",
   "upload_button.label": "Přidat média (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "Byl překročen limit nahraných souborů.",
+  "upload_error.poll": "Nahrávání souborů není povoleno u anket.",
   "upload_form.description": "Popis pro zrakově postižené",
   "upload_form.focus": "Změnit náhled",
   "upload_form.undo": "Smazat",
-  "upload_progress.label": "Nahrávám...",
+  "upload_progress.label": "Nahrávám…",
   "video.close": "Zavřít video",
   "video.exit_fullscreen": "Ukončit celou obrazovku",
   "video.expand": "Otevřít video",
diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json
index f35b96244ebbcd05f69573b933ffa2f9fa167839..4ce5d7ad974dd10cc7bc9b997d7bc306784a6ac0 100644
--- a/app/javascript/mastodon/locales/cy.json
+++ b/app/javascript/mastodon/locales/cy.json
@@ -1,11 +1,10 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "Ychwanegu neu Dileu o'r rhestrau",
   "account.badges.bot": "Bot",
   "account.block": "Blocio @{name}",
   "account.block_domain": "Cuddio popeth rhag {domain}",
   "account.blocked": "Blociwyd",
   "account.direct": "Neges breifat @{name}",
-  "account.disclaimer_full": "Gall y wybodaeth isod adlewyrchu darlun anghyflawn o broffil defnyddiwr.",
   "account.domain_blocked": "Parth wedi ei guddio",
   "account.edit_profile": "Golygu proffil",
   "account.endorse": "Arddangos ar fy mhroffil",
@@ -17,7 +16,7 @@
   "account.follows_you": "Yn eich dilyn chi",
   "account.hide_reblogs": "Cuddio bwstiau o @{name}",
   "account.link_verified_on": "Gwiriwyd perchnogaeth y ddolen yma ar {date}",
-  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
+  "account.locked_info": "Mae'r statws preifatrwydd cyfrif hwn wedi'i osod i gloi. Mae'r perchennog yn adolygu'r sawl sy'n gallu eu dilyn.",
   "account.media": "Cyfryngau",
   "account.mention": "Crybwyll @{name}",
   "account.moved_to": "Mae @{name} wedi symud i:",
@@ -36,7 +35,6 @@
   "account.unfollow": "Dad-ddilyn",
   "account.unmute": "Dad-dawelu @{name}",
   "account.unmute_notifications": "Dad-dawelu hysbysiadau o @{name}",
-  "account.view_full_profile": "Gweld proffil llawn",
   "alert.unexpected.message": "Digwyddodd gwall annisgwyl.",
   "alert.unexpected.title": "Wps!",
   "boost_modal.combo": "Mae modd gwasgu {combo} er mwyn sgipio hyn tro nesa",
@@ -47,7 +45,7 @@
   "bundle_modal_error.message": "Aeth rhywbeth o'i le tra'n llwytho'r elfen hon.",
   "bundle_modal_error.retry": "Ceiswich eto",
   "column.blocks": "Defnyddwyr a flociwyd",
-  "column.community": "Llinell amser lleol",
+  "column.community": "Ffrwd lleol",
   "column.direct": "Negeseuon preifat",
   "column.domain_blocks": "Parthau cuddiedig",
   "column.favourites": "Ffefrynnau",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "Nid yw eich cyfri wedi'i {locked}. Gall unrhyw un eich dilyn i weld eich tŵtiau dilynwyr-yn-unig.",
   "compose_form.lock_disclaimer.lock": "wedi ei gloi",
   "compose_form.placeholder": "Beth sydd ar eich meddwl?",
+  "compose_form.poll.add_option": "Ychwanegu Dewisiad",
+  "compose_form.poll.duration": "Cyfnod pleidlais",
+  "compose_form.poll.option_placeholder": "Dewisiad {number}",
+  "compose_form.poll.remove_option": "Tynnu'r dewisiad",
   "compose_form.publish": "Tŵt",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Marcio cyfryngau fel eu bod yn sensitif",
   "compose_form.sensitive.marked": "Cyfryngau wedi'u marcio'n sensitif",
   "compose_form.sensitive.unmarked": "Nid yw'r cyfryngau wedi'u marcio'n sensitif",
   "compose_form.spoiler.marked": "Testun wedi ei guddio gan rybudd",
   "compose_form.spoiler.unmarked": "Nid yw'r testun wedi ei guddio",
   "compose_form.spoiler_placeholder": "Ysgrifenwch eich rhybudd yma",
   "confirmation_modal.cancel": "Canslo",
+  "confirmations.block.block_and_report": "Rhwystro ac Adrodd",
   "confirmations.block.confirm": "Blocio",
   "confirmations.block.message": "Ydych chi'n sicr eich bod eisiau blocio {name}?",
   "confirmations.delete.confirm": "Dileu",
@@ -105,7 +109,7 @@
   "emoji_button.food": "Bwyd a Diod",
   "emoji_button.label": "Mewnosodwch emoji",
   "emoji_button.nature": "Natur",
-  "emoji_button.not_found": "Dim emojo!! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.not_found": "Dim emojau!! (╯°□°)╯︵ ┻━┻",
   "emoji_button.objects": "Gwrthrychau",
   "emoji_button.people": "Pobl",
   "emoji_button.recent": "Defnyddir yn aml",
@@ -113,7 +117,8 @@
   "emoji_button.search_results": "Canlyniadau chwilio",
   "emoji_button.symbols": "Symbolau",
   "emoji_button.travel": "Teithio & Llefydd",
-  "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_timeline": "Dim tŵtiau fama!",
+  "empty_column.account_unavailable": "Proffil ddim ar gael",
   "empty_column.blocks": "Nid ydych wedi blocio unrhyw ddefnyddwyr eto.",
   "empty_column.community": "Mae'r ffrwd lleol yn wag. Ysgrifenwch rhywbeth yn gyhoeddus i gael dechrau arni!",
   "empty_column.direct": "Nid oes gennych unrhyw negeseuon preifat eto. Pan y byddwch yn anfon neu derbyn un, mi fydd yn ymddangos yma.",
@@ -132,7 +137,7 @@
   "follow_request.authorize": "Caniatau",
   "follow_request.reject": "Gwrthod",
   "getting_started.developers": "Datblygwyr",
-  "getting_started.directory": "Profile directory",
+  "getting_started.directory": "Cyfeiriadur proffil",
   "getting_started.documentation": "Dogfennaeth",
   "getting_started.heading": "Dechrau",
   "getting_started.invite": "Gwahodd pobl",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "a {additional}",
   "hashtag.column_header.tag_mode.any": "neu {additional}",
   "hashtag.column_header.tag_mode.none": "heb {additional}",
+  "hashtag.column_settings.select.no_options_message": "Dim awgrymiadau i'w weld",
+  "hashtag.column_settings.select.placeholder": "Mewnbynnu hashnodau…",
   "hashtag.column_settings.tag_mode.all": "Pob un o'r rhain",
   "hashtag.column_settings.tag_mode.any": "Unrhyw un o'r rhain",
   "hashtag.column_settings.tag_mode.none": "Dim o'r rhain",
@@ -149,23 +156,26 @@
   "home.column_settings.basic": "Syml",
   "home.column_settings.show_reblogs": "Dangos bŵstiau",
   "home.column_settings.show_replies": "Dangos ymatebion",
+  "intervals.full.days": "{number, plural, one {# ddydd} other {# o ddyddiau}}",
+  "intervals.full.hours": "{number, plural, one {# awr} other {# o oriau}}",
+  "intervals.full.minutes": "{number, plural, one {# funud} other {# o funudau}}",
   "introduction.federation.action": "Nesaf",
   "introduction.federation.federated.headline": "Ffederasiwn",
-  "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
-  "introduction.federation.home.headline": "Home",
-  "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
-  "introduction.federation.local.headline": "Local",
-  "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
+  "introduction.federation.federated.text": "Bydd pyst cyhoeddus o gweinyddion arall yn y Ffedysawd yn cael ai arddangos yn ffrwd y ffederasiwn.",
+  "introduction.federation.home.headline": "Hafan",
+  "introduction.federation.home.text": "Bydd pyst o bobl rydych yn ei ddilyn yn dangos yn eich ffrwd gatref. Gallwch dilyn unrhyw un ar unrhyw gweinydd!",
+  "introduction.federation.local.headline": "Lleol",
+  "introduction.federation.local.text": "Bydd pyst gyhoeddus o bobl ar yr un gweinydd a chi yn cael ei arddangos yn y ffrwd lleol.",
+  "introduction.interactions.action": "Gorffen tiwtorial!",
   "introduction.interactions.favourite.headline": "Ffefryn",
-  "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
+  "introduction.interactions.favourite.text": "Gallwch cadw tŵt am hwyrach, a gadael i'r awdur gwybod roeddech yn ei hoffi, trwy ei hoffi.",
   "introduction.interactions.reblog.headline": "Hwb",
-  "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
+  "introduction.interactions.reblog.text": "Gallwch rhannu tŵtiau pobl eraill gyda'ch dilynwyr trwy eu bŵstio.",
   "introduction.interactions.reply.headline": "Ateb",
-  "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
-  "introduction.welcome.action": "Let's go!",
-  "introduction.welcome.headline": "First steps",
-  "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
+  "introduction.interactions.reply.text": "Gallwch ateb i dŵtiau pobl eraill a thŵtiau eich hun, a fydd yn eu cadwyno at ei gilydd mewn sgwrs.",
+  "introduction.welcome.action": "Awn ni!",
+  "introduction.welcome.headline": "Camau cyntaf",
+  "introduction.welcome.text": "Croeso i'r ffedysawd! Mewn ychydig o funudau, byddwch yn gallu darlledu negeseuon a siarad i'ch ffrindiau ar draws amrywiaeth eang o weinyddion. Ond mae'r gweinydd hyn, {domain}, yn arbennig - mae o'n gweinyddu eich proffil, fellu cofiwch ei enw.",
   "keyboard_shortcuts.back": "i lywio nôl",
   "keyboard_shortcuts.blocked": "i agor rhestr defnyddwyr a flociwyd",
   "keyboard_shortcuts.boost": "i fŵstio",
@@ -180,7 +190,7 @@
   "keyboard_shortcuts.federated": "i agor ffrwd y ffederasiwn",
   "keyboard_shortcuts.heading": "Llwybrau byr allweddell",
   "keyboard_shortcuts.home": "i agor ffrwd cartref",
-  "keyboard_shortcuts.hotkey": "Hotkey",
+  "keyboard_shortcuts.hotkey": "Bysell brys",
   "keyboard_shortcuts.legend": "i ddangos yr arwr yma",
   "keyboard_shortcuts.local": "i agor ffrwd lleol",
   "keyboard_shortcuts.mention": "i grybwyll yr awdur",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "i ffocysu chwilio",
   "keyboard_shortcuts.start": "i agor colofn \"dechrau arni\"",
   "keyboard_shortcuts.toggle_hidden": "i ddangos/cuddio testun tu ôl i CW",
+  "keyboard_shortcuts.toggle_sensitivity": "i ddangos/gyddio cyfryngau",
   "keyboard_shortcuts.toot": "i ddechrau tŵt newydd sbon",
   "keyboard_shortcuts.unfocus": "i ddad-ffocysu ardal cyfansoddi testun/chwilio",
   "keyboard_shortcuts.up": "i symud yn uwch yn y rhestr",
   "lightbox.close": "Cau",
   "lightbox.next": "Nesaf",
   "lightbox.previous": "Blaenorol",
+  "lightbox.view_context": "Gweld cyd-destyn",
   "lists.account.add": "Ychwanegwch at restr",
   "lists.account.remove": "Dileu o'r rhestr",
   "lists.delete": "Dileu rhestr",
   "lists.edit": "Golygwch rhestr",
+  "lists.edit.submit": "Newid teitl",
   "lists.new.create": "Ychwanegu rhestr",
   "lists.new.title_placeholder": "Teitl rhestr newydd",
   "lists.search": "Chwilio ymysg pobl yr ydych yn ei ddilyn",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "Ffefrynnau",
   "navigation_bar.filters": "Geiriau a dawelwyd",
   "navigation_bar.follow_requests": "Ceisiadau dilyn",
+  "navigation_bar.follows_and_followers": "Dilynion a ddilynwyr",
   "navigation_bar.info": "Ynghylch yr achos hwn",
   "navigation_bar.keyboard_shortcuts": "Bysellau brys",
   "navigation_bar.lists": "Rhestrau",
@@ -232,22 +246,25 @@
   "navigation_bar.personal": "Personol",
   "navigation_bar.pins": "Tŵtiau wedi eu pinio",
   "navigation_bar.preferences": "Dewisiadau",
+  "navigation_bar.profile_directory": "Cyfeiriadur Proffil",
   "navigation_bar.public_timeline": "Ffrwd y ffederasiwn",
   "navigation_bar.security": "Diogelwch",
   "notification.favourite": "hoffodd {name} eich tŵt",
   "notification.follow": "dilynodd {name} chi",
   "notification.mention": "Soniodd {name} amdanoch chi",
+  "notification.poll": "Mae pleidlais rydych wedi pleidleisio ynddi wedi dod i ben",
   "notification.reblog": "Hysbysebodd {name} eich tŵt",
   "notifications.clear": "Clirio hysbysiadau",
   "notifications.clear_confirmation": "Ydych chi'n sicr eich bod am glirio'ch holl hysbysiadau am byth?",
   "notifications.column_settings.alert": "Hysbysiadau bwrdd gwaith",
   "notifications.column_settings.favourite": "Ffefrynnau:",
-  "notifications.column_settings.filter_bar.advanced": "Display all categories",
-  "notifications.column_settings.filter_bar.category": "Quick filter bar",
+  "notifications.column_settings.filter_bar.advanced": "Dangos pob categori",
+  "notifications.column_settings.filter_bar.category": "Bar hidlo",
   "notifications.column_settings.filter_bar.show": "Dangos",
   "notifications.column_settings.follow": "Dilynwyr newydd:",
   "notifications.column_settings.mention": "Crybwylliadau:",
-  "notifications.column_settings.push": "Hysbysiadau push",
+  "notifications.column_settings.poll": "Canlyniadau pleidlais:",
+  "notifications.column_settings.push": "Hysbysiadau gwthiadwy",
   "notifications.column_settings.reblog": "Hybiadau:",
   "notifications.column_settings.show": "Dangos yn y golofn",
   "notifications.column_settings.sound": "Chwarae sain",
@@ -255,8 +272,15 @@
   "notifications.filter.boosts": "Hybiadau",
   "notifications.filter.favourites": "Ffefrynnau",
   "notifications.filter.follows": "Yn dilyn",
-  "notifications.filter.mentions": "Mentions",
+  "notifications.filter.mentions": "Crybwylliadau",
+  "notifications.filter.polls": "Canlyniadau pleidlais",
   "notifications.group": "{count} o hysbysiadau",
+  "poll.closed": "Ar gau",
+  "poll.refresh": "Adnewyddu",
+  "poll.total_votes": "{count, plural, one {# bleidlais} other {# o bleidleisiau}}",
+  "poll.vote": "Pleidleisio",
+  "poll_button.add_poll": "Ychwanegu pleidlais",
+  "poll_button.remove_poll": "Tynnu pleidlais",
   "privacy.change": "Addasu preifatrwdd y tŵt",
   "privacy.direct.long": "Cyhoeddi i'r defnyddwyr sy'n cael eu crybwyll yn unig",
   "privacy.direct.short": "Uniongyrchol",
@@ -268,11 +292,11 @@
   "privacy.unlisted.short": "Heb ei restru",
   "regeneration_indicator.label": "Llwytho…",
   "regeneration_indicator.sublabel": "Mae eich ffrwd cartref yn cael ei baratoi!",
-  "relative_time.days": "{number}d",
-  "relative_time.hours": "{number}h",
+  "relative_time.days": "{number}dydd",
+  "relative_time.hours": "{number}awr",
   "relative_time.just_now": "nawr",
-  "relative_time.minutes": "{number}m",
-  "relative_time.seconds": "{number}s",
+  "relative_time.minutes": "{number}munud",
+  "relative_time.seconds": "{number}eiliad",
   "reply_indicator.cancel": "Canslo",
   "report.forward": "Ymlaen i {target}",
   "report.forward_hint": "Mae'r cyfrif o weinydd arall. Anfon copi anhysbys o'r adroddiad yno hefyd?",
@@ -291,12 +315,12 @@
   "search_results.hashtags": "Hanshnodau",
   "search_results.statuses": "Tŵtiau",
   "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
-  "standalone.public_title": "Golwg tu fewn...",
-  "status.admin_account": "Open moderation interface for @{name}",
-  "status.admin_status": "Open this tŵt in the moderation interface",
+  "status.admin_account": "Agor rhyngwyneb goruwchwylio ar gyfer @{name}",
+  "status.admin_status": "Agor y tŵt yn y rhyngwyneb goruwchwylio",
   "status.block": "Blocio @{name}",
   "status.cancel_reblog_private": "Dadfŵstio",
   "status.cannot_reblog": "Ni ellir sbarduno'r tŵt hwn",
+  "status.copy": "Copïo cysylltiad i'r tŵt",
   "status.delete": "Dileu",
   "status.detailed_status": "Golwg manwl o'r sgwrs",
   "status.direct": "Neges breifat @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Ateb",
   "status.replyAll": "Ateb i edefyn",
   "status.report": "Adrodd @{name}",
-  "status.sensitive_toggle": "Clicio i weld",
   "status.sensitive_warning": "Cynnwys sensitif",
   "status.share": "Rhannu",
   "status.show_less": "Dangos llai",
@@ -331,17 +354,24 @@
   "status.show_thread": "Dangos edefyn",
   "status.unmute_conversation": "Dad-dawelu sgwrs",
   "status.unpin": "Dadbinio o'r proffil",
-  "suggestions.dismiss": "Dismiss suggestion",
-  "suggestions.header": "You might be interested in…",
+  "suggestions.dismiss": "Diswyddo",
+  "suggestions.header": "Efallai y bydd gennych ddiddordeb mewn…",
   "tabs_bar.federated_timeline": "Ffederasiwn",
   "tabs_bar.home": "Hafan",
   "tabs_bar.local_timeline": "Lleol",
   "tabs_bar.notifications": "Hysbysiadau",
   "tabs_bar.search": "Chwilio",
+  "time_remaining.days": "{number, plural, one {# ddydd} other {# o ddyddiau}} ar ôl",
+  "time_remaining.hours": "{number, plural, one {# awr} other {# o oriau}} ar ôl",
+  "time_remaining.minutes": "{number, plural, one {# funud} other {# o funudau}} ar ôl",
+  "time_remaining.moments": "Munudau ar ôl",
+  "time_remaining.seconds": "{number, plural, one {# eiliad} other {# o eiliadau}} ar ôl",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} yn siarad",
   "ui.beforeunload": "Mi fyddwch yn colli eich drafft os gadewch Mastodon.",
   "upload_area.title": "Llusgwch & gollwing i uwchlwytho",
   "upload_button.label": "Ychwanegwch gyfryngau (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "Wedi mynd heibio'r uchafswm terfyn uwchlwytho.",
+  "upload_error.poll": "Nid oes modd uwchlwytho ffeiliau â phleidleisiau.",
   "upload_form.description": "Disgrifio i'r rheini a nam ar ei golwg",
   "upload_form.focus": "Newid rhagolwg",
   "upload_form.undo": "Dileu",
diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json
index 60315211adfdd51ddcc03695e16b7ea488e86e66..ba8ba7a28e99d6195886e36af4ea1ba81725a150 100644
--- a/app/javascript/mastodon/locales/da.json
+++ b/app/javascript/mastodon/locales/da.json
@@ -5,7 +5,6 @@
   "account.block_domain": "Skjul alt fra {domain}",
   "account.blocked": "Blokeret",
   "account.direct": "Send en direkte besked til @{name}",
-  "account.disclaimer_full": "Nedenstående oplysninger reflekterer ikke nødvendigvis brugerens profil fuldstændigt.",
   "account.domain_blocked": "Domænet er blevet skjult",
   "account.edit_profile": "Rediger profil",
   "account.endorse": "Fremhæv på profil",
@@ -36,7 +35,6 @@
   "account.unfollow": "Følg ikke længere",
   "account.unmute": "Fjern dæmpningen af @{name}",
   "account.unmute_notifications": "Fjern dæmpningen af notifikationer fra @{name}",
-  "account.view_full_profile": "Se fuld profil",
   "alert.unexpected.message": "Der opstod en uventet fejl.",
   "alert.unexpected.title": "Ups!",
   "boost_modal.combo": "Du kan trykke {combo} for at springe dette over næste gang",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "Din konto er ikke {locked}. Alle kan følge dig for at se dine følger-kun indlæg.",
   "compose_form.lock_disclaimer.lock": "låst",
   "compose_form.placeholder": "Hvad har du på hjertet?",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
   "compose_form.publish": "Trut",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
   "compose_form.sensitive.marked": "Medie er markeret som værende følsomt",
   "compose_form.sensitive.unmarked": "Mediet er ikke markeret som værende følsomt",
   "compose_form.spoiler.marked": "Teksten er skjult bag en advarsel",
   "compose_form.spoiler.unmarked": "Teksten er ikke skjult",
   "compose_form.spoiler_placeholder": "Skriv din advarsel her",
   "confirmation_modal.cancel": "Annuller",
+  "confirmations.block.block_and_report": "Block & Report",
   "confirmations.block.confirm": "Bloker",
   "confirmations.block.message": "Er du sikker på, du vil blokere {name}?",
   "confirmations.delete.confirm": "Slet",
@@ -113,7 +117,8 @@
   "emoji_button.search_results": "Søgeresultater",
   "emoji_button.symbols": "Symboler",
   "emoji_button.travel": "Rejser & steder",
-  "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_timeline": "Ingen bidrag her!",
+  "empty_column.account_unavailable": "Profile unavailable",
   "empty_column.blocks": "Du har ikke blokeret nogen endnu.",
   "empty_column.community": "Den lokale tidslinje er tom. Skriv noget offentligt for at starte lavinen!",
   "empty_column.direct": "Du har endnu ingen direkte beskeder. NÃ¥r du sender eller modtager en, vil den vises her.",
@@ -128,7 +133,7 @@
   "empty_column.lists": "Du har endnu ingen lister. NÃ¥r du opretter en, vil den blive vist her.",
   "empty_column.mutes": "Du har endnu ikke dæmpet nogen som helst bruger.",
   "empty_column.notifications": "Du har endnu ingen notifikationer. Tag ud og bland dig med folkemængden for at starte samtalen.",
-  "empty_column.public": "Der er ikke noget at se her! Skriv noget offentligt eller start ud med manuelt at følge brugere fra andre instanser for st udfylde tomrummet",
+  "empty_column.public": "Der er ikke noget at se her! Skriv noget offentligt eller start ud med manuelt at følge brugere fra andre server for at udfylde tomrummet",
   "follow_request.authorize": "Godkend",
   "follow_request.reject": "Afvis",
   "getting_started.developers": "Udviklere",
@@ -139,9 +144,11 @@
   "getting_started.open_source_notice": "Mastodon er et open source software. Du kan bidrage eller rapporterer fejl på GitHub {github}.",
   "getting_started.security": "Sikkerhed",
   "getting_started.terms": "Vilkår",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_header.tag_mode.all": "og {additional}",
+  "hashtag.column_header.tag_mode.any": "eller {additional}",
+  "hashtag.column_header.tag_mode.none": "uden {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
   "hashtag.column_settings.tag_mode.all": "All of these",
   "hashtag.column_settings.tag_mode.any": "Any of these",
   "hashtag.column_settings.tag_mode.none": "None of these",
@@ -149,22 +156,25 @@
   "home.column_settings.basic": "Grundlæggende",
   "home.column_settings.show_reblogs": "Vis fremhævelser",
   "home.column_settings.show_replies": "Vis svar",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
   "introduction.federation.action": "Næste",
   "introduction.federation.federated.headline": "Federated",
-  "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
+  "introduction.federation.federated.text": "Offentlige bidrag fra andre servere af fediversen vil komme til syne i den federated timeline.",
   "introduction.federation.home.headline": "Home",
   "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
   "introduction.federation.local.headline": "Local",
   "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
-  "introduction.interactions.favourite.headline": "Favourite",
+  "introduction.interactions.action": "Slut tutorial!",
+  "introduction.interactions.favourite.headline": "Favorisere",
   "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
   "introduction.interactions.reblog.headline": "Boost",
   "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
-  "introduction.interactions.reply.headline": "Reply",
-  "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
-  "introduction.welcome.action": "Let's go!",
-  "introduction.welcome.headline": "First steps",
+  "introduction.interactions.reply.headline": "Svar",
+  "introduction.interactions.reply.text": "Du kan svare andres og din egen bidrag, hvilke vil kæde dem sammen i en konversation.",
+  "introduction.welcome.action": "Læd os gå!",
+  "introduction.welcome.headline": "Første skridt",
   "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
   "keyboard_shortcuts.back": "for at navigere dig tilbage",
   "keyboard_shortcuts.blocked": "for at åbne listen over blokerede brugere",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "for at fokusere søgningen",
   "keyboard_shortcuts.start": "for at åbne \"kom igen\" kolonnen",
   "keyboard_shortcuts.toggle_hidden": "for at vise/skjule tekst bag CW",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "for at påbegynde et helt nyt trut",
   "keyboard_shortcuts.unfocus": "for at fjerne fokus fra skriveområde/søgning",
   "keyboard_shortcuts.up": "for at bevæge dig op ad listen",
   "lightbox.close": "Luk",
   "lightbox.next": "Næste",
   "lightbox.previous": "Forrige",
+  "lightbox.view_context": "View context",
   "lists.account.add": "Tilføj til liste",
   "lists.account.remove": "Fjern fra liste",
   "lists.delete": "Slet liste",
   "lists.edit": "Rediger liste",
+  "lists.edit.submit": "Change title",
   "lists.new.create": "Tilføj liste",
   "lists.new.title_placeholder": "Ny liste titel",
   "lists.search": "Søg iblandt folk du følger",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "Favoritter",
   "navigation_bar.filters": "Dæmpede ord",
   "navigation_bar.follow_requests": "Følgeanmodninger",
+  "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.info": "Om denne instans",
   "navigation_bar.keyboard_shortcuts": "Hurtigtast",
   "navigation_bar.lists": "Lister",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Personligt",
   "navigation_bar.pins": "Fastgjorte trut",
   "navigation_bar.preferences": "Præferencer",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "Fælles tidslinje",
   "navigation_bar.security": "Sikkerhed",
   "notification.favourite": "{name} favoriserede din status",
   "notification.follow": "{name} fulgte dig",
   "notification.mention": "{name} nævnte dig",
+  "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "{name} fremhævede din status",
   "notifications.clear": "Ryd notifikationer",
   "notifications.clear_confirmation": "Er du sikker på, du vil rydde alle dine notifikationer permanent?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Show",
   "notifications.column_settings.follow": "Nye følgere:",
   "notifications.column_settings.mention": "Omtale:",
+  "notifications.column_settings.poll": "Poll results:",
   "notifications.column_settings.push": "Push notifikationer",
   "notifications.column_settings.reblog": "Fremhævelser:",
   "notifications.column_settings.show": "Vis i kolonne",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favoritter",
   "notifications.filter.follows": "Følger",
   "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
   "notifications.group": "{count} notifikationer",
+  "poll.closed": "Closed",
+  "poll.refresh": "Refresh",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
   "privacy.change": "Ændre status privatliv",
   "privacy.direct.long": "Post til kun de nævnte brugere",
   "privacy.direct.short": "Direkte",
@@ -291,12 +315,12 @@
   "search_results.hashtags": "Emnetags",
   "search_results.statuses": "Trut",
   "search_results.total": "{count, number} {count, plural, et {result} andre {results}}",
-  "standalone.public_title": "Et kig indenfor...",
   "status.admin_account": "Open moderation interface for @{name}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Bloker @{name}",
   "status.cancel_reblog_private": "Fremhæv ikke længere",
   "status.cannot_reblog": "Denne post kan ikke fremhæves",
+  "status.copy": "Copy link to status",
   "status.delete": "Slet",
   "status.detailed_status": "Detaljeret visning af samtale",
   "status.direct": "Send direkte besked til @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Svar",
   "status.replyAll": "Svar samtale",
   "status.report": "Anmeld @{name}",
-  "status.sensitive_toggle": "Tryk for at se",
   "status.sensitive_warning": "Følsomt indhold",
   "status.share": "Del",
   "status.show_less": "Vis mindre",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Lokal",
   "tabs_bar.notifications": "Notifikationer",
   "tabs_bar.search": "Søg",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} snakker",
   "ui.beforeunload": "Din kladde vil gå tabt hvis du forlader Mastodon.",
   "upload_area.title": "Træk og slip for at uploade",
   "upload_button.label": "Tilføj medie (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "upload_form.description": "Beskriv for de svagtseende",
   "upload_form.focus": "Beskær",
   "upload_form.undo": "Slet",
diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json
index 3a55f26a7521d933085a2299488e1ea453ae009b..ac8bc9b9f7521e3e4b65c2f4c45c6ec2bd3f99b3 100644
--- a/app/javascript/mastodon/locales/de.json
+++ b/app/javascript/mastodon/locales/de.json
@@ -5,12 +5,11 @@
   "account.block_domain": "Alles von {domain} verstecken",
   "account.blocked": "Blockiert",
   "account.direct": "Direktnachricht an @{name}",
-  "account.disclaimer_full": "Das Profil wird möglicherweise unvollständig wiedergegeben.",
   "account.domain_blocked": "Domain versteckt",
   "account.edit_profile": "Profil bearbeiten",
   "account.endorse": "Auf Profil hervorheben",
   "account.follow": "Folgen",
-  "account.followers": "Folgende",
+  "account.followers": "Folger_innen",
   "account.followers.empty": "Diesem Profil folgt noch niemand.",
   "account.follows": "Folgt",
   "account.follows.empty": "Dieses Profil folgt noch niemandem.",
@@ -36,10 +35,9 @@
   "account.unfollow": "Entfolgen",
   "account.unmute": "@{name} nicht mehr stummschalten",
   "account.unmute_notifications": "Benachrichtigungen von @{name} einschalten",
-  "account.view_full_profile": "Vollständiges Profil anzeigen",
   "alert.unexpected.message": "Ein unerwarteter Fehler ist aufgetreten.",
   "alert.unexpected.title": "Hoppla!",
-  "boost_modal.combo": "Du kannst {combo} drücken, um dies beim nächsten Mal zu überspringen",
+  "boost_modal.combo": "Drücke {combo}, um dieses Fenster zu überspringen",
   "bundle_column_error.body": "Etwas ist beim Laden schiefgelaufen.",
   "bundle_column_error.retry": "Erneut versuchen",
   "bundle_column_error.title": "Netzwerkfehler",
@@ -57,7 +55,7 @@
   "column.mutes": "Stummgeschaltete Profile",
   "column.notifications": "Mitteilungen",
   "column.pins": "Angeheftete Beiträge",
-  "column.public": "Gesamtes bekanntes Netz",
+  "column.public": "Föderierte Zeitleiste",
   "column_back_button.label": "Zurück",
   "column_header.hide_settings": "Einstellungen verbergen",
   "column_header.moveLeft_settings": "Spalte nach links verschieben",
@@ -69,30 +67,36 @@
   "community.column_settings.media_only": "Nur Medien",
   "compose_form.direct_message_warning": "Dieser Beitrag wird nur für die erwähnten Nutzer sichtbar sein.",
   "compose_form.direct_message_warning_learn_more": "Mehr erfahren",
-  "compose_form.hashtag_warning": "Dieser Beitrag wird nicht unter einen dieser Hashtags sichtbar sein, solange er ungelistet ist. Bei einer Suche kann er nicht gefunden werden.",
+  "compose_form.hashtag_warning": "Dieser Beitrag wird nicht durch Hashtags entdeckbar sein, weil er ungelistet ist. Nur öffentliche Beiträge tauchen in Hashtag-Zeitleisten auf.",
   "compose_form.lock_disclaimer": "Dein Profil ist nicht {locked}. Wer dir folgen will, kann das jederzeit tun und dann auch deine privaten Beiträge sehen.",
   "compose_form.lock_disclaimer.lock": "gesperrt",
   "compose_form.placeholder": "Was gibt's Neues?",
+  "compose_form.poll.add_option": "Eine Wahl hinzufügen",
+  "compose_form.poll.duration": "Umfragedauer",
+  "compose_form.poll.option_placeholder": "Wahl {number}",
+  "compose_form.poll.remove_option": "Wahl entfernen",
   "compose_form.publish": "Tröt",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Medien als heikel markieren",
   "compose_form.sensitive.marked": "Medien sind als heikel markiert",
   "compose_form.sensitive.unmarked": "Medien sind nicht als heikel markiert",
   "compose_form.spoiler.marked": "Text ist hinter einer Warnung versteckt",
   "compose_form.spoiler.unmarked": "Text ist nicht versteckt",
   "compose_form.spoiler_placeholder": "Inhaltswarnung",
   "confirmation_modal.cancel": "Abbrechen",
+  "confirmations.block.block_and_report": "Blockieren und melden",
   "confirmations.block.confirm": "Blockieren",
   "confirmations.block.message": "Bist du dir sicher, dass du {name} blockieren möchtest?",
   "confirmations.delete.confirm": "Löschen",
   "confirmations.delete.message": "Bist du dir sicher, dass du diesen Beitrag löschen möchtest?",
-  "confirmations.delete_list.confirm": "Delete",
+  "confirmations.delete_list.confirm": "Löschen",
   "confirmations.delete_list.message": "Bist du dir sicher, dass du diese Liste permanent löschen möchtest?",
   "confirmations.domain_block.confirm": "Die ganze Domain verbergen",
-  "confirmations.domain_block.message": "Bist du dir wirklich sicher, dass du die ganze Domain {domain} blockieren willst? In den meisten Fällen reichen ein paar gezielte Blockierungen oder Stummschaltungen aus. Du wirst den Inhalt von dieser Domain nicht in irgendwelchen öffentlichen Timelines oder den Benachrichtigungen finden. Deine Follower von dieser Domain werden entfernt.",
+  "confirmations.domain_block.message": "Bist du dir wirklich sicher, dass du die ganze Domain {domain} blockieren willst? In den meisten Fällen reichen ein paar gezielte Blockierungen oder Stummschaltungen aus. Nach der Blockierung wirst du nichts mehr von dieser Domain in öffentlichen Zeitleisten oder Benachrichtigungen sehen. Deine Folger_innen von dieser Domain werden auch entfernt.",
   "confirmations.mute.confirm": "Stummschalten",
   "confirmations.mute.message": "Bist du dir sicher, dass du {name} stummschalten möchtest?",
   "confirmations.redraft.confirm": "Löschen und neu erstellen",
-  "confirmations.redraft.message": "Bist du dir sicher, dass du diesen Beitrag löschen und neu machen möchtest? Favoriten und Boosts werden verloren gehen und Antworten zu diesem Beitrag werden verwaist sein.",
+  "confirmations.redraft.message": "Bist du dir sicher, dass du diesen Beitrag löschen und neu erstellen möchtest? Favorisierungen, geteilte Beiträge und Antworten werden verloren gehen.",
   "confirmations.reply.confirm": "Antworten",
   "confirmations.reply.message": "Wenn du jetzt antwortest wird es die gesamte Nachricht verwerfen, die du gerade schreibst. Möchtest du wirklich fortfahren?",
   "confirmations.unfollow.confirm": "Entfolgen",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Symbole",
   "emoji_button.travel": "Reisen und Orte",
   "empty_column.account_timeline": "Keine Beiträge!",
+  "empty_column.account_unavailable": "Konto nicht verfügbar",
   "empty_column.blocks": "Du hast keine Profile blockiert.",
   "empty_column.community": "Die lokale Zeitleiste ist leer. Schreibe einen öffentlichen Beitrag, um den Ball ins Rollen zu bringen!",
   "empty_column.direct": "Du hast noch keine Direktnachrichten erhalten. Wenn du eine sendest oder empfängst, wird sie hier zu sehen sein.",
@@ -128,7 +133,7 @@
   "empty_column.lists": "Du hast noch keine Listen. Wenn du eine anlegst, wird sie hier angezeigt.",
   "empty_column.mutes": "Du hast keine Profile stummgeschaltet.",
   "empty_column.notifications": "Du hast noch keine Mitteilungen. Interagiere mit anderen, um ins Gespräch zu kommen.",
-  "empty_column.public": "Hier ist nichts zu sehen! Schreibe etwas öffentlich oder folge Profilen von anderen Instanzen, um die Zeitleiste aufzufüllen",
+  "empty_column.public": "Hier ist nichts zu sehen! Schreibe etwas öffentlich oder folge Profilen von anderen Servern, um die Zeitleiste aufzufüllen",
   "follow_request.authorize": "Erlauben",
   "follow_request.reject": "Ablehnen",
   "getting_started.developers": "Entwickler",
@@ -142,42 +147,47 @@
   "hashtag.column_header.tag_mode.all": "und {additional}",
   "hashtag.column_header.tag_mode.any": "oder {additional}",
   "hashtag.column_header.tag_mode.none": "ohne {additional}",
+  "hashtag.column_settings.select.no_options_message": "Keine Vorschläge gefunden",
+  "hashtag.column_settings.select.placeholder": "Hashtags eintragen…",
   "hashtag.column_settings.tag_mode.all": "All diese",
-  "hashtag.column_settings.tag_mode.any": "Eine von diesen",
-  "hashtag.column_settings.tag_mode.none": "Keine von diesen",
-  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "hashtag.column_settings.tag_mode.any": "Eins von diesen",
+  "hashtag.column_settings.tag_mode.none": "Keins von diesen",
+  "hashtag.column_settings.tag_toggle": "Zusätzliche Hashtags für diese Spalte einfügen",
   "home.column_settings.basic": "Einfach",
   "home.column_settings.show_reblogs": "Geteilte Beiträge anzeigen",
   "home.column_settings.show_replies": "Antworten anzeigen",
+  "intervals.full.days": "{number, plural, one {# Tag} other {# Tage}}",
+  "intervals.full.hours": "{number, plural, one {# Stunde} other {# Stunden}}",
+  "intervals.full.minutes": "{number, plural, one {# Minute} other {# Minuten}}",
   "introduction.federation.action": "Weiter",
-  "introduction.federation.federated.headline": "Federated",
-  "introduction.federation.federated.text": "Öffentliche Beiträge von anderen Servern im Fediverse werden in der föderierten Zeitleiste erscheinen.",
-  "introduction.federation.home.headline": "Home",
-  "introduction.federation.home.text": "Beiträge von Leuten, denen du folgst werden in deiner Startseite erscheinen. Du kannst jedem auf irgendeinen Server folgen!",
-  "introduction.federation.local.headline": "Local",
-  "introduction.federation.local.text": "Öffentliche Beiträge von Leuten auf demselben Server wie du werden in der lokalen Zeitleiste erscheinen.",
+  "introduction.federation.federated.headline": "Föderiert",
+  "introduction.federation.federated.text": "Öffentliche Beiträge von anderen Servern im Fediversum erscheinen in der föderierten Zeitleiste.",
+  "introduction.federation.home.headline": "Startseite",
+  "introduction.federation.home.text": "Beiträge von Leuten, denen du folgst, erscheinen auf deiner Startseite. Du kannst Menschen auf beliebigen Servern folgen!",
+  "introduction.federation.local.headline": "Lokal",
+  "introduction.federation.local.text": "Öffentliche Beiträge von Leuten auf demselben Server wie du erscheinen in der lokalen Zeitleiste.",
   "introduction.interactions.action": "Tutorial beenden!",
   "introduction.interactions.favourite.headline": "Favorisieren",
-  "introduction.interactions.favourite.text": "Du kannst einen Beitrag für später speichern und dem Autor wissen lassen, dass du ihn magst, indem du ihn favorisierst.",
+  "introduction.interactions.favourite.text": "Du kannst Beitrage für später speichern und ihre Autor_innen wissen lassen, dass sie dir gefallen haben, indem du sie favorisierst.",
   "introduction.interactions.reblog.headline": "Teilen",
-  "introduction.interactions.reblog.text": "Du kannst Beiträge von anderen Leuten an deine Follower teilen.",
+  "introduction.interactions.reblog.text": "Du kannst Beiträge anderer mit deinen Followern teilen, indem du sie teilst.",
   "introduction.interactions.reply.headline": "Antworten",
-  "introduction.interactions.reply.text": "Du kannst auf die Beiträge von anderen Leuten antworten und die Beiträge werden dann in eine Konversation zusammengebunden.",
-  "introduction.welcome.action": "Lasst uns loslegen!",
+  "introduction.interactions.reply.text": "Du kannst auf die Beiträge anderer antworten. Diese Beiträge werden dann in einer Konversation zusammengefasst.",
+  "introduction.welcome.action": "Lass uns loslegen!",
   "introduction.welcome.headline": "Erste Schritte",
-  "introduction.welcome.text": "Willkommen im Fediverse! In wenigen Momenten wirst du in der Lage sein Nachrichten zu versenden und mit deinen Freunden über Server hinweg in Kontakt zu treten. Aber dieser Server, {domain}, ist sehr speziell — er hostet dein Profil, also merke dir den Namen.",
+  "introduction.welcome.text": "Willkommen im Fediversum! In wenigen Momenten wirst du in der Lage sein Nachrichten zu versenden und mit deinen Freunden von anderen Servern in Kontakt zu treten. Aber dieser Server, {domain}, ist für dich sehr speziell — er hostet dein Profil, also merke dir die Domain.",
   "keyboard_shortcuts.back": "zurück navigieren",
   "keyboard_shortcuts.blocked": "Liste blockierter Profile öffnen",
   "keyboard_shortcuts.boost": "teilen",
-  "keyboard_shortcuts.column": "einen Status in einer der Spalten fokussieren",
+  "keyboard_shortcuts.column": "einen Beitrag in einer der Spalten fokussieren",
   "keyboard_shortcuts.compose": "fokussiere das Eingabefeld",
   "keyboard_shortcuts.description": "Beschreibung",
   "keyboard_shortcuts.direct": "Direct-Message-Spalte öffnen",
   "keyboard_shortcuts.down": "sich in der Liste hinunter bewegen",
-  "keyboard_shortcuts.enter": "Status öffnen",
+  "keyboard_shortcuts.enter": "Beitrag öffnen",
   "keyboard_shortcuts.favourite": "um zu favorisieren",
   "keyboard_shortcuts.favourites": "Favoriten-Liste öffnen",
-  "keyboard_shortcuts.federated": "Förderierte Zeitleiste öffnen",
+  "keyboard_shortcuts.federated": "Föderierte Zeitleiste öffnen",
   "keyboard_shortcuts.heading": "Tastenkombinationen",
   "keyboard_shortcuts.home": "Startseite öffnen",
   "keyboard_shortcuts.hotkey": "Tastenkürzel",
@@ -190,20 +200,23 @@
   "keyboard_shortcuts.pinned": "Liste angehefteter Beiträge öffnen",
   "keyboard_shortcuts.profile": "Profil des Autors öffnen",
   "keyboard_shortcuts.reply": "antworten",
-  "keyboard_shortcuts.requests": "Liste der Folge-Anfragen  öffnen",
+  "keyboard_shortcuts.requests": "Liste der Folge-Anfragen öffnen",
   "keyboard_shortcuts.search": "Suche fokussieren",
-  "keyboard_shortcuts.start": "\"Erste Schritte-Spalte öffnen",
+  "keyboard_shortcuts.start": "\"Erste Schritte\"-Spalte öffnen",
   "keyboard_shortcuts.toggle_hidden": "Text hinter einer Inhaltswarnung verstecken/anzeigen",
-  "keyboard_shortcuts.toot": "einen neuen Toot beginnen",
+  "keyboard_shortcuts.toggle_sensitivity": "Medien hinter einer Inhaltswarnung verstecken/anzeigen",
+  "keyboard_shortcuts.toot": "einen neuen Beitrag beginnen",
   "keyboard_shortcuts.unfocus": "Textfeld/die Suche nicht mehr fokussieren",
   "keyboard_shortcuts.up": "sich in der Liste hinauf bewegen",
   "lightbox.close": "Schließen",
   "lightbox.next": "Weiter",
   "lightbox.previous": "Zurück",
+  "lightbox.view_context": "Beitrag sehen",
   "lists.account.add": "Zur Liste hinzufügen",
   "lists.account.remove": "Von der Liste entfernen",
-  "lists.delete": "Delete list",
+  "lists.delete": "Liste löschen",
   "lists.edit": "Liste bearbeiten",
+  "lists.edit.submit": "Titel ändern",
   "lists.new.create": "Liste hinzufügen",
   "lists.new.title_placeholder": "Neuer Titel der Liste",
   "lists.search": "Suche nach Leuten denen du folgst",
@@ -224,19 +237,22 @@
   "navigation_bar.favourites": "Favoriten",
   "navigation_bar.filters": "Stummgeschaltene Wörter",
   "navigation_bar.follow_requests": "Folgeanfragen",
-  "navigation_bar.info": "Über diese Instanz",
+  "navigation_bar.follows_and_followers": "Folger_innen und Gefolgte",
+  "navigation_bar.info": "Über diesen Server",
   "navigation_bar.keyboard_shortcuts": "Tastenkombinationen",
   "navigation_bar.lists": "Listen",
   "navigation_bar.logout": "Abmelden",
   "navigation_bar.mutes": "Stummgeschaltete Profile",
-  "navigation_bar.personal": "Personal",
+  "navigation_bar.personal": "Persönlich",
   "navigation_bar.pins": "Angeheftete Beiträge",
   "navigation_bar.preferences": "Einstellungen",
+  "navigation_bar.profile_directory": "Profilverzeichnis",
   "navigation_bar.public_timeline": "Föderierte Zeitleiste",
   "navigation_bar.security": "Sicherheit",
   "notification.favourite": "{name} hat deinen Beitrag favorisiert",
   "notification.follow": "{name} folgt dir",
   "notification.mention": "{name} hat dich erwähnt",
+  "notification.poll": "Eine Umfrage in der du abgestimmt hast ist vorbei",
   "notification.reblog": "{name} hat deinen Beitrag geteilt",
   "notifications.clear": "Mitteilungen löschen",
   "notifications.clear_confirmation": "Bist du dir sicher, dass du alle Mitteilungen löschen möchtest?",
@@ -245,29 +261,37 @@
   "notifications.column_settings.filter_bar.advanced": "Zeige alle Kategorien an",
   "notifications.column_settings.filter_bar.category": "Schnellfilterleiste",
   "notifications.column_settings.filter_bar.show": "Anzeigen",
-  "notifications.column_settings.follow": "Neue Folgende:",
+  "notifications.column_settings.follow": "Neue Folger_innen:",
   "notifications.column_settings.mention": "Erwähnungen:",
+  "notifications.column_settings.poll": "Ergebnisse von Umfragen:",
   "notifications.column_settings.push": "Push-Benachrichtigungen",
   "notifications.column_settings.reblog": "Geteilte Beiträge:",
   "notifications.column_settings.show": "In der Spalte anzeigen",
   "notifications.column_settings.sound": "Ton abspielen",
   "notifications.filter.all": "Alle",
-  "notifications.filter.boosts": "Erneut geteilte Beiträge",
-  "notifications.filter.favourites": "Favoriten",
-  "notifications.filter.follows": "Folgende",
+  "notifications.filter.boosts": "Geteilte Beiträge",
+  "notifications.filter.favourites": "Favorisierungen",
+  "notifications.filter.follows": "Folger_innen",
   "notifications.filter.mentions": "Erwähnungen",
+  "notifications.filter.polls": "Ergebnisse der Umfrage",
   "notifications.group": "{count} Benachrichtigungen",
+  "poll.closed": "Geschlossen",
+  "poll.refresh": "Aktualisieren",
+  "poll.total_votes": "{count, plural, one {# Stimme} other {# Stimmen}}",
+  "poll.vote": "Abstimmen",
+  "poll_button.add_poll": "Eine Umfrage erstellen",
+  "poll_button.remove_poll": "Umfrage entfernen",
   "privacy.change": "Sichtbarkeit des Beitrags anpassen",
-  "privacy.direct.long": "Beitrag nur an erwähnte Profile",
-  "privacy.direct.short": "Direkt",
-  "privacy.private.long": "Beitrag nur an Folgende",
-  "privacy.private.short": "Nur Folgende",
-  "privacy.public.long": "Beitrag an öffentliche Zeitleisten",
+  "privacy.direct.long": "Wird an erwähnte Profile gesendet",
+  "privacy.direct.short": "Direktnachricht",
+  "privacy.private.long": "Wird nur für deine Folger_innen sichtbar sein",
+  "privacy.private.short": "Nur für Folger_innen",
+  "privacy.public.long": "Wird in öffentlichen Zeitleisten erscheinen",
   "privacy.public.short": "Öffentlich",
-  "privacy.unlisted.long": "Nicht in öffentlichen Zeitleisten anzeigen",
+  "privacy.unlisted.long": "Wird in öffentlichen Zeitleisten nicht gezeigt",
   "privacy.unlisted.short": "Nicht gelistet",
   "regeneration_indicator.label": "Laden…",
-  "regeneration_indicator.sublabel": "Deine Heimzeitleiste wird gerade vorbereitet!",
+  "regeneration_indicator.sublabel": "Deine Startseite wird gerade vorbereitet!",
   "relative_time.days": "{number}d",
   "relative_time.hours": "{number}h",
   "relative_time.just_now": "jetzt",
@@ -276,27 +300,27 @@
   "reply_indicator.cancel": "Abbrechen",
   "report.forward": "An {target} weiterleiten",
   "report.forward_hint": "Dieses Konto ist von einem anderen Server. Soll eine anonymisierte Kopie des Berichts auch dorthin geschickt werden?",
-  "report.hint": "Der Bericht wird an die Moderatoren deiner Instanz geschickt. Du kannst hier eine Erklärung angeben, warum du dieses Konto meldest:",
+  "report.hint": "Der Bericht wird an die Moderatoren des Servers geschickt. Du kannst hier eine Erklärung angeben, warum du dieses Konto meldest:",
   "report.placeholder": "Zusätzliche Kommentare",
   "report.submit": "Absenden",
   "report.target": "{target} melden",
   "search.placeholder": "Suche",
   "search_popout.search_format": "Fortgeschrittenes Suchformat",
-  "search_popout.tips.full_text": "Simpler Text gibt Beiträge, die du geschrieben, favorisiert und geteilt hast zurück. Außerdem auch Beiträge in denen du erwähnt wurdest, als auch passende Nutzernamen, Anzeigenamen oder Hashtags.",
+  "search_popout.tips.full_text": "Einfache Texteingabe gibt Beiträge, die du geschrieben, favorisiert und geteilt hast zurück. Außerdem auch Beiträge in denen du erwähnt wurdest, aber auch passende Nutzernamen, Anzeigenamen oder Hashtags.",
   "search_popout.tips.hashtag": "Hashtag",
-  "search_popout.tips.status": "status",
-  "search_popout.tips.text": "Einfacher Text gibt Anzeigenamen, Benutzernamen und Hashtags zurück",
+  "search_popout.tips.status": "Beitrag",
+  "search_popout.tips.text": "Einfache Texteingabe gibt Anzeigenamen, Benutzernamen und Hashtags zurück",
   "search_popout.tips.user": "Nutzer",
   "search_results.accounts": "Personen",
   "search_results.hashtags": "Hashtags",
   "search_results.statuses": "Beiträge",
   "search_results.total": "{count, number} {count, plural, one {Ergebnis} other {Ergebnisse}}",
-  "standalone.public_title": "Ein kleiner Einblick …",
   "status.admin_account": "Öffne Moderationsoberfläche für @{name}",
-  "status.admin_status": "Öffne diesen Status in der Moderationsoberfläche",
+  "status.admin_status": "Öffne Beitrag in der Moderationsoberfläche",
   "status.block": "Blockiere @{name}",
   "status.cancel_reblog_private": "Nicht mehr teilen",
   "status.cannot_reblog": "Dieser Beitrag kann nicht geteilt werden",
+  "status.copy": "Kopiere Link zum Beitrag",
   "status.delete": "Löschen",
   "status.detailed_status": "Detaillierte Ansicht der Konversation",
   "status.direct": "Direktnachricht @{name}",
@@ -308,42 +332,48 @@
   "status.mention": "@{name} erwähnen",
   "status.more": "Mehr",
   "status.mute": "@{name} stummschalten",
-  "status.mute_conversation": "Thread stummschalten",
+  "status.mute_conversation": "Konversation stummschalten",
   "status.open": "Diesen Beitrag öffnen",
   "status.pin": "Im Profil anheften",
   "status.pinned": "Angehefteter Beitrag",
   "status.read_more": "Mehr lesen",
   "status.reblog": "Teilen",
-  "status.reblog_private": "An das eigentliche Publikum teilen",
+  "status.reblog_private": "Mit der ursprünglichen Zielgruppe teilen",
   "status.reblogged_by": "{name} teilte",
-  "status.reblogs.empty": "Diesen Beitrag hat noch niemand geteilt. Sobald es jemand tut, wird die Person hier angezeigt.",
+  "status.reblogs.empty": "Diesen Beitrag hat noch niemand geteilt. Sobald es jemand tut, wird diese Person hier angezeigt.",
   "status.redraft": "Löschen und neu erstellen",
   "status.reply": "Antworten",
-  "status.replyAll": "Auf Thread antworten",
+  "status.replyAll": "Allen antworten",
   "status.report": "@{name} melden",
-  "status.sensitive_toggle": "Zum Ansehen klicken",
   "status.sensitive_warning": "Heikle Inhalte",
   "status.share": "Teilen",
   "status.show_less": "Weniger anzeigen",
-  "status.show_less_all": "Zeige weniger für alles",
+  "status.show_less_all": "Alle Inhaltswarnungen zuklappen",
   "status.show_more": "Mehr anzeigen",
-  "status.show_more_all": "Zeige mehr für alles",
-  "status.show_thread": "Zeige Thread",
-  "status.unmute_conversation": "Stummschaltung von Thread aufheben",
+  "status.show_more_all": "Alle Inhaltswarnungen aufklappen",
+  "status.show_thread": "Zeige Konversation",
+  "status.unmute_conversation": "Stummschaltung von Konversation aufheben",
   "status.unpin": "Vom Profil lösen",
-  "suggestions.dismiss": "Hinweis ausblenden",
-  "suggestions.header": "Du bist vielleicht interessiert in…",
+  "suggestions.dismiss": "Empfehlung ausblenden",
+  "suggestions.header": "Du bist vielleicht interessiert an…",
   "tabs_bar.federated_timeline": "Föderation",
   "tabs_bar.home": "Startseite",
   "tabs_bar.local_timeline": "Lokal",
   "tabs_bar.notifications": "Mitteilungen",
-  "tabs_bar.search": "Suchen",
+  "tabs_bar.search": "Suche",
+  "time_remaining.days": "{number, plural, one {# Tag} other {# Tage}} verbleibend",
+  "time_remaining.hours": "{number, plural, one {# Stunde} other {# Stunden}} verbleibend",
+  "time_remaining.minutes": "{number, plural, one {# Minute} other {# Minuten}} verbleibend",
+  "time_remaining.moments": "Schließt in Kürze",
+  "time_remaining.seconds": "{number, plural, one {# Sekunde} other {# Sekunden}} verbleibend",
   "trends.count_by_accounts": "{count} {rawCount, plural, eine {Person} other {Personen}} reden darüber",
   "ui.beforeunload": "Dein Entwurf geht verloren, wenn du Mastodon verlässt.",
   "upload_area.title": "Zum Hochladen hereinziehen",
-  "upload_button.label": "Mediendatei hinzufügen (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_button.label": "Mediendatei hinzufügen ({formats})",
+  "upload_error.limit": "Dateiupload-Limit erreicht.",
+  "upload_error.poll": "Dateiuploads sind in Kombination mit Umfragen nicht erlaubt.",
   "upload_form.description": "Für Menschen mit Sehbehinderung beschreiben",
-  "upload_form.focus": "Thumbnail bearbeiten",
+  "upload_form.focus": "Vorschaubild bearbeiten",
   "upload_form.undo": "Löschen",
   "upload_progress.label": "Wird hochgeladen …",
   "video.close": "Video schließen",
@@ -352,7 +382,7 @@
   "video.fullscreen": "Vollbild",
   "video.hide": "Video verbergen",
   "video.mute": "Stummschalten",
-  "video.pause": "Pause",
+  "video.pause": "Pausieren",
   "video.play": "Abspielen",
   "video.unmute": "Ton einschalten"
 }
diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json
index 6ac8160ba4dc5ec3d78c82f6ed78995a7e74f4ef..4df299d845144cff3eea06a8e4227334452d29d0 100644
--- a/app/javascript/mastodon/locales/defaultMessages.json
+++ b/app/javascript/mastodon/locales/defaultMessages.json
@@ -12,6 +12,19 @@
     ],
     "path": "app/javascript/mastodon/actions/alerts.json"
   },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "File upload limit exceeded.",
+        "id": "upload_error.limit"
+      },
+      {
+        "defaultMessage": "File upload not allowed with polls.",
+        "id": "upload_error.poll"
+      }
+    ],
+    "path": "app/javascript/mastodon/actions/compose.json"
+  },
   {
     "descriptors": [
       {
@@ -167,10 +180,6 @@
       {
         "defaultMessage": "Media hidden",
         "id": "status.media_hidden"
-      },
-      {
-        "defaultMessage": "Click to view",
-        "id": "status.sensitive_toggle"
       }
     ],
     "path": "app/javascript/mastodon/components/media_gallery.json"
@@ -188,6 +197,27 @@
     ],
     "path": "app/javascript/mastodon/components/missing_indicator.json"
   },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Closed",
+        "id": "poll.closed"
+      },
+      {
+        "defaultMessage": "Vote",
+        "id": "poll.vote"
+      },
+      {
+        "defaultMessage": "Refresh",
+        "id": "poll.refresh"
+      },
+      {
+        "defaultMessage": "{count, plural, one {# vote} other {# votes}}",
+        "id": "poll.total_votes"
+      }
+    ],
+    "path": "app/javascript/mastodon/components/poll.json"
+  },
   {
     "descriptors": [
       {
@@ -209,6 +239,26 @@
       {
         "defaultMessage": "{number}d",
         "id": "relative_time.days"
+      },
+      {
+        "defaultMessage": "Moments remaining",
+        "id": "time_remaining.moments"
+      },
+      {
+        "defaultMessage": "{number, plural, one {# second} other {# seconds}} left",
+        "id": "time_remaining.seconds"
+      },
+      {
+        "defaultMessage": "{number, plural, one {# minute} other {# minutes}} left",
+        "id": "time_remaining.minutes"
+      },
+      {
+        "defaultMessage": "{number, plural, one {# hour} other {# hours}} left",
+        "id": "time_remaining.hours"
+      },
+      {
+        "defaultMessage": "{number, plural, one {# day} other {# days}} left",
+        "id": "time_remaining.days"
       }
     ],
     "path": "app/javascript/mastodon/components/relative_timestamp.json"
@@ -310,6 +360,10 @@
       {
         "defaultMessage": "Open this status in the moderation interface",
         "id": "status.admin_status"
+      },
+      {
+        "defaultMessage": "Copy link to status",
+        "id": "status.copy"
       }
     ],
     "path": "app/javascript/mastodon/components/status_action_bar.json"
@@ -421,6 +475,10 @@
         "defaultMessage": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
         "id": "confirmations.reply.message"
       },
+      {
+        "defaultMessage": "Block & Report",
+        "id": "confirmations.block.block_and_report"
+      },
       {
         "defaultMessage": "Are you sure you want to block {name}?",
         "id": "confirmations.block.message"
@@ -468,6 +526,10 @@
         "defaultMessage": "Hide entire domain",
         "id": "confirmations.domain_block.confirm"
       },
+      {
+        "defaultMessage": "Block & Report",
+        "id": "confirmations.block.block_and_report"
+      },
       {
         "defaultMessage": "Are you sure you want to unfollow {name}?",
         "id": "confirmations.unfollow.message"
@@ -485,6 +547,10 @@
   },
   {
     "descriptors": [
+      {
+        "defaultMessage": "Profile unavailable",
+        "id": "empty_column.account_unavailable"
+      },
       {
         "defaultMessage": "No toots here!",
         "id": "empty_column.account_timeline"
@@ -495,24 +561,40 @@
   {
     "descriptors": [
       {
-        "defaultMessage": "Mention @{name}",
-        "id": "account.mention"
+        "defaultMessage": "Unfollow",
+        "id": "account.unfollow"
       },
       {
-        "defaultMessage": "Direct message @{name}",
-        "id": "account.direct"
+        "defaultMessage": "Follow",
+        "id": "account.follow"
       },
       {
-        "defaultMessage": "Edit profile",
-        "id": "account.edit_profile"
+        "defaultMessage": "Awaiting approval. Click to cancel follow request",
+        "id": "account.requested"
       },
       {
         "defaultMessage": "Unblock @{name}",
         "id": "account.unblock"
       },
       {
-        "defaultMessage": "Unfollow",
-        "id": "account.unfollow"
+        "defaultMessage": "Edit profile",
+        "id": "account.edit_profile"
+      },
+      {
+        "defaultMessage": "Ownership of this link was checked on {date}",
+        "id": "account.link_verified_on"
+      },
+      {
+        "defaultMessage": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
+        "id": "account.locked_info"
+      },
+      {
+        "defaultMessage": "Mention @{name}",
+        "id": "account.mention"
+      },
+      {
+        "defaultMessage": "Direct message @{name}",
+        "id": "account.direct"
       },
       {
         "defaultMessage": "Unmute @{name}",
@@ -526,10 +608,6 @@
         "defaultMessage": "Mute @{name}",
         "id": "account.mute"
       },
-      {
-        "defaultMessage": "Follow",
-        "id": "account.follow"
-      },
       {
         "defaultMessage": "Report @{name}",
         "id": "account.report"
@@ -606,59 +684,6 @@
         "defaultMessage": "Open moderation interface for @{name}",
         "id": "status.admin_account"
       },
-      {
-        "defaultMessage": "Information below may reflect the user's profile incompletely.",
-        "id": "account.disclaimer_full"
-      },
-      {
-        "defaultMessage": "View full profile",
-        "id": "account.view_full_profile"
-      },
-      {
-        "defaultMessage": "Toots",
-        "id": "account.posts"
-      },
-      {
-        "defaultMessage": "Follows",
-        "id": "account.follows"
-      },
-      {
-        "defaultMessage": "Followers",
-        "id": "account.followers"
-      }
-    ],
-    "path": "app/javascript/mastodon/features/account/components/action_bar.json"
-  },
-  {
-    "descriptors": [
-      {
-        "defaultMessage": "Unfollow",
-        "id": "account.unfollow"
-      },
-      {
-        "defaultMessage": "Follow",
-        "id": "account.follow"
-      },
-      {
-        "defaultMessage": "Awaiting approval. Click to cancel follow request",
-        "id": "account.requested"
-      },
-      {
-        "defaultMessage": "Unblock @{name}",
-        "id": "account.unblock"
-      },
-      {
-        "defaultMessage": "Edit profile",
-        "id": "account.edit_profile"
-      },
-      {
-        "defaultMessage": "Ownership of this link was checked on {date}",
-        "id": "account.link_verified_on"
-      },
-      {
-        "defaultMessage": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
-        "id": "account.locked_info"
-      },
       {
         "defaultMessage": "Follows you",
         "id": "account.follows_you"
@@ -678,6 +703,18 @@
       {
         "defaultMessage": "Bot",
         "id": "account.badges.bot"
+      },
+      {
+        "defaultMessage": "Toots",
+        "id": "account.posts"
+      },
+      {
+        "defaultMessage": "Follows",
+        "id": "account.follows"
+      },
+      {
+        "defaultMessage": "Followers",
+        "id": "account.followers"
       }
     ],
     "path": "app/javascript/mastodon/features/account/components/header.json"
@@ -853,6 +890,52 @@
     ],
     "path": "app/javascript/mastodon/features/compose/components/navigation_bar.json"
   },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Add a poll",
+        "id": "poll_button.add_poll"
+      },
+      {
+        "defaultMessage": "Remove poll",
+        "id": "poll_button.remove_poll"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/compose/components/poll_button.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Choice {number}",
+        "id": "compose_form.poll.option_placeholder"
+      },
+      {
+        "defaultMessage": "Add a choice",
+        "id": "compose_form.poll.add_option"
+      },
+      {
+        "defaultMessage": "Remove this choice",
+        "id": "compose_form.poll.remove_option"
+      },
+      {
+        "defaultMessage": "Poll duration",
+        "id": "compose_form.poll.duration"
+      },
+      {
+        "defaultMessage": "{number, plural, one {# minute} other {# minutes}}",
+        "id": "intervals.full.minutes"
+      },
+      {
+        "defaultMessage": "{number, plural, one {# hour} other {# hours}}",
+        "id": "intervals.full.hours"
+      },
+      {
+        "defaultMessage": "{number, plural, one {# day} other {# days}}",
+        "id": "intervals.full.days"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/compose/components/poll_form.json"
+  },
   {
     "descriptors": [
       {
@@ -968,7 +1051,7 @@
   {
     "descriptors": [
       {
-        "defaultMessage": "Add media (JPEG, PNG, GIF, WebM, MP4, MOV)",
+        "defaultMessage": "Add media ({formats})",
         "id": "upload_button.label"
       }
     ],
@@ -1009,6 +1092,10 @@
       {
         "defaultMessage": "Media is not marked as sensitive",
         "id": "compose_form.sensitive.unmarked"
+      },
+      {
+        "defaultMessage": "Mark media as sensitive",
+        "id": "compose_form.sensitive.hide"
       }
     ],
     "path": "app/javascript/mastodon/features/compose/containers/sensitive_button_container.json"
@@ -1168,6 +1255,10 @@
   },
   {
     "descriptors": [
+      {
+        "defaultMessage": "Profile unavailable",
+        "id": "empty_column.account_unavailable"
+      },
       {
         "defaultMessage": "No one follows this user yet.",
         "id": "account.followers.empty"
@@ -1177,6 +1268,10 @@
   },
   {
     "descriptors": [
+      {
+        "defaultMessage": "Profile unavailable",
+        "id": "empty_column.account_unavailable"
+      },
       {
         "defaultMessage": "This user doesn't follow anyone yet.",
         "id": "account.follows.empty"
@@ -1261,52 +1356,20 @@
       {
         "defaultMessage": "Profile directory",
         "id": "getting_started.directory"
-      },
-      {
-        "defaultMessage": "Invite people",
-        "id": "getting_started.invite"
-      },
-      {
-        "defaultMessage": "Hotkeys",
-        "id": "navigation_bar.keyboard_shortcuts"
-      },
-      {
-        "defaultMessage": "Security",
-        "id": "getting_started.security"
-      },
-      {
-        "defaultMessage": "About this instance",
-        "id": "navigation_bar.info"
-      },
-      {
-        "defaultMessage": "Mobile apps",
-        "id": "navigation_bar.apps"
-      },
-      {
-        "defaultMessage": "Terms of service",
-        "id": "getting_started.terms"
-      },
-      {
-        "defaultMessage": "Developers",
-        "id": "getting_started.developers"
-      },
-      {
-        "defaultMessage": "Documentation",
-        "id": "getting_started.documentation"
-      },
-      {
-        "defaultMessage": "Logout",
-        "id": "navigation_bar.logout"
-      },
-      {
-        "defaultMessage": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.",
-        "id": "getting_started.open_source_notice"
       }
     ],
     "path": "app/javascript/mastodon/features/getting_started/index.json"
   },
   {
     "descriptors": [
+      {
+        "defaultMessage": "Enter hashtags…",
+        "id": "hashtag.column_settings.select.placeholder"
+      },
+      {
+        "defaultMessage": "No suggestions found",
+        "id": "hashtag.column_settings.select.no_options_message"
+      },
       {
         "defaultMessage": "Any of these",
         "id": "hashtag.column_settings.tag_mode.any"
@@ -1448,7 +1511,7 @@
         "id": "introduction.interactions.favourite.text"
       },
       {
-        "defaultMessage": "Finish tutorial!",
+        "defaultMessage": "Finish toot-orial!",
         "id": "introduction.interactions.action"
       }
     ],
@@ -1496,6 +1559,10 @@
         "defaultMessage": "to show/hide text behind CW",
         "id": "keyboard_shortcuts.toggle_hidden"
       },
+      {
+        "defaultMessage": "to show/hide media",
+        "id": "keyboard_shortcuts.toggle_sensitivity"
+      },
       {
         "defaultMessage": "to move up in the list",
         "id": "keyboard_shortcuts.up"
@@ -1609,6 +1676,15 @@
     ],
     "path": "app/javascript/mastodon/features/list_editor/components/account.json"
   },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Change title",
+        "id": "lists.edit.submit"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/list_editor/components/edit_list_form.json"
+  },
   {
     "descriptors": [
       {
@@ -1740,6 +1816,10 @@
       {
         "defaultMessage": "Boosts:",
         "id": "notifications.column_settings.reblog"
+      },
+      {
+        "defaultMessage": "Poll results:",
+        "id": "notifications.column_settings.poll"
       }
     ],
     "path": "app/javascript/mastodon/features/notifications/components/column_settings.json"
@@ -1758,6 +1838,10 @@
         "defaultMessage": "Boosts",
         "id": "notifications.filter.boosts"
       },
+      {
+        "defaultMessage": "Poll results",
+        "id": "notifications.filter.polls"
+      },
       {
         "defaultMessage": "Follows",
         "id": "notifications.filter.follows"
@@ -1782,6 +1866,10 @@
       {
         "defaultMessage": "{name} boosted your status",
         "id": "notification.reblog"
+      },
+      {
+        "defaultMessage": "A poll you have voted in has ended",
+        "id": "notification.poll"
       }
     ],
     "path": "app/javascript/mastodon/features/notifications/components/notification.json"
@@ -1828,7 +1916,7 @@
         "id": "column.public"
       },
       {
-        "defaultMessage": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up",
+        "defaultMessage": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up",
         "id": "empty_column.public"
       }
     ],
@@ -1843,24 +1931,6 @@
     ],
     "path": "app/javascript/mastodon/features/reblogs/index.json"
   },
-  {
-    "descriptors": [
-      {
-        "defaultMessage": "A look inside...",
-        "id": "standalone.public_title"
-      }
-    ],
-    "path": "app/javascript/mastodon/features/standalone/community_timeline/index.json"
-  },
-  {
-    "descriptors": [
-      {
-        "defaultMessage": "A look inside...",
-        "id": "standalone.public_title"
-      }
-    ],
-    "path": "app/javascript/mastodon/features/standalone/public_timeline/index.json"
-  },
   {
     "descriptors": [
       {
@@ -1946,6 +2016,10 @@
       {
         "defaultMessage": "Open this status in the moderation interface",
         "id": "status.admin_status"
+      },
+      {
+        "defaultMessage": "Copy link to status",
+        "id": "status.copy"
       }
     ],
     "path": "app/javascript/mastodon/features/status/components/action_bar.json"
@@ -1980,6 +2054,10 @@
         "defaultMessage": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
         "id": "confirmations.reply.message"
       },
+      {
+        "defaultMessage": "Block & Report",
+        "id": "confirmations.block.block_and_report"
+      },
       {
         "defaultMessage": "Are you sure you want to block {name}?",
         "id": "confirmations.block.message"
@@ -2029,6 +2107,10 @@
         "defaultMessage": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
         "id": "confirmations.reply.message"
       },
+      {
+        "defaultMessage": "Block & Report",
+        "id": "confirmations.block.block_and_report"
+      },
       {
         "defaultMessage": "Are you sure you want to block {name}?",
         "id": "confirmations.block.message"
@@ -2038,6 +2120,10 @@
   },
   {
     "descriptors": [
+      {
+        "defaultMessage": "Unboost",
+        "id": "status.cancel_reblog_private"
+      },
       {
         "defaultMessage": "Boost",
         "id": "status.reblog"
@@ -2118,6 +2204,60 @@
     ],
     "path": "app/javascript/mastodon/features/ui/components/embed_modal.json"
   },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Follow requests",
+        "id": "navigation_bar.follow_requests"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/ui/components/follow_requests_nav_link.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Invite people",
+        "id": "getting_started.invite"
+      },
+      {
+        "defaultMessage": "Hotkeys",
+        "id": "navigation_bar.keyboard_shortcuts"
+      },
+      {
+        "defaultMessage": "Security",
+        "id": "getting_started.security"
+      },
+      {
+        "defaultMessage": "About this server",
+        "id": "navigation_bar.info"
+      },
+      {
+        "defaultMessage": "Mobile apps",
+        "id": "navigation_bar.apps"
+      },
+      {
+        "defaultMessage": "Terms of service",
+        "id": "getting_started.terms"
+      },
+      {
+        "defaultMessage": "Developers",
+        "id": "getting_started.developers"
+      },
+      {
+        "defaultMessage": "Documentation",
+        "id": "getting_started.documentation"
+      },
+      {
+        "defaultMessage": "Logout",
+        "id": "navigation_bar.logout"
+      },
+      {
+        "defaultMessage": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.",
+        "id": "getting_started.open_source_notice"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/ui/components/link_footer.json"
+  },
   {
     "descriptors": [
       {
@@ -2131,6 +2271,10 @@
       {
         "defaultMessage": "Next",
         "id": "lightbox.next"
+      },
+      {
+        "defaultMessage": "View context",
+        "id": "lightbox.view_context"
       }
     ],
     "path": "app/javascript/mastodon/features/ui/components/media_modal.json"
@@ -2156,6 +2300,51 @@
     ],
     "path": "app/javascript/mastodon/features/ui/components/mute_modal.json"
   },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Home",
+        "id": "tabs_bar.home"
+      },
+      {
+        "defaultMessage": "Notifications",
+        "id": "tabs_bar.notifications"
+      },
+      {
+        "defaultMessage": "Local",
+        "id": "tabs_bar.local_timeline"
+      },
+      {
+        "defaultMessage": "Federated",
+        "id": "tabs_bar.federated_timeline"
+      },
+      {
+        "defaultMessage": "Direct messages",
+        "id": "navigation_bar.direct"
+      },
+      {
+        "defaultMessage": "Favourites",
+        "id": "navigation_bar.favourites"
+      },
+      {
+        "defaultMessage": "Lists",
+        "id": "navigation_bar.lists"
+      },
+      {
+        "defaultMessage": "Preferences",
+        "id": "navigation_bar.preferences"
+      },
+      {
+        "defaultMessage": "Follows and followers",
+        "id": "navigation_bar.follows_and_followers"
+      },
+      {
+        "defaultMessage": "Profile directory",
+        "id": "navigation_bar.profile_directory"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/ui/components/navigation_panel.json"
+  },
   {
     "descriptors": [
       {
@@ -2175,7 +2364,7 @@
         "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:",
+        "defaultMessage": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:",
         "id": "report.hint"
       },
       {
@@ -2223,6 +2412,15 @@
     ],
     "path": "app/javascript/mastodon/features/ui/components/upload_area.json"
   },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "View context",
+        "id": "lightbox.view_context"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/ui/components/video_modal.json"
+  },
   {
     "descriptors": [
       {
@@ -2277,10 +2475,6 @@
       {
         "defaultMessage": "Media hidden",
         "id": "status.media_hidden"
-      },
-      {
-        "defaultMessage": "Click to view",
-        "id": "status.sensitive_toggle"
       }
     ],
     "path": "app/javascript/mastodon/features/video/index.json"
diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json
index 7b4852271bc08ba649ee4cb995a59454bc66cb90..e118e427b0388fb6974a74c72385ea766e428276 100644
--- a/app/javascript/mastodon/locales/el.json
+++ b/app/javascript/mastodon/locales/el.json
@@ -1,13 +1,12 @@
 {
-  "account.add_or_remove_from_list": "Προσθήκη ή αφαίρεση από λίστες",
+  "account.add_or_remove_from_list": "Προσθήκη ή Αφαίρεση από λίστες",
   "account.badges.bot": "Μποτ",
-  "account.block": "Απόκλεισε τον/την @{name}",
+  "account.block": "Αποκλισμός @{name}",
   "account.block_domain": "Απόκρυψε τα πάντα από το {domain}",
   "account.blocked": "Αποκλεισμένος/η",
   "account.direct": "Προσωπικό μήνυμα προς @{name}",
-  "account.disclaimer_full": "Οι παρακάτω πληροφορίες μπορει να μην αντανακλούν το προφίλ του χρήστη επαρκως.",
   "account.domain_blocked": "Κρυμμένος τομέας",
-  "account.edit_profile": "Επεξεργάσου το προφίλ",
+  "account.edit_profile": "Επεξεργασία προφίλ",
   "account.endorse": "Προβολή στο προφίλ",
   "account.follow": "Ακολούθησε",
   "account.followers": "Ακόλουθοι",
@@ -16,35 +15,34 @@
   "account.follows.empty": "Αυτός ο χρήστης δεν ακολουθεί κανέναν ακόμα.",
   "account.follows_you": "Σε ακολουθεί",
   "account.hide_reblogs": "Απόκρυψη προωθήσεων από @{name}",
-  "account.link_verified_on": "Η ιδιοκτησία αυτού του συνδέσμου εκλέχθηκε την {date}",
+  "account.link_verified_on": "Η ιδιοκτησία αυτού του συνδέσμου ελέχθηκε την {date}",
   "account.locked_info": "Η κατάσταση απορρήτου αυτού του λογαριασμού είναι κλειδωμένη. Ο ιδιοκτήτης επιβεβαιώνει χειροκίνητα ποιος μπορεί να τον ακολουθήσει.",
   "account.media": "Πολυμέσα",
   "account.mention": "Ανάφερε @{name}",
   "account.moved_to": "{name} μεταφέρθηκε στο:",
-  "account.mute": "Σώπασε τον/την @{name}",
-  "account.mute_notifications": "Σώπασε τις ειδοποιήσεις από τον/την @{name}",
+  "account.mute": "Σώπασε @{name}",
+  "account.mute_notifications": "Σώπασε τις ειδοποιήσεις από @{name}",
   "account.muted": "Αποσιωπημένος/η",
   "account.posts": "Τουτ",
   "account.posts_with_replies": "Τουτ και απαντήσεις",
-  "account.report": "Κατάγγειλε τον/την @{name}",
+  "account.report": "Κατάγγειλε @{name}",
   "account.requested": "Εκκρεμεί έγκριση. Κάνε κλικ για να ακυρώσεις το αίτημα παρακολούθησης",
-  "account.share": "Μοιράσου το προφίλ του/της @{name}",
-  "account.show_reblogs": "Δείξε τις προωθήσεις του/της @{name}",
-  "account.unblock": "Ξεμπλόκαρε τον/την @{name}",
+  "account.share": "Μοίρασμα του προφίλ @{name}",
+  "account.show_reblogs": "Εμφάνιση προωθήσεων από @{name}",
+  "account.unblock": "Ξεμπλόκαρε @{name}",
   "account.unblock_domain": "Αποκάλυψε το {domain}",
   "account.unendorse": "Άνευ προβολής στο προφίλ",
   "account.unfollow": "Διακοπή παρακολούθησης",
-  "account.unmute": "Διακοπή αποσιώπησης του/της @{name}",
+  "account.unmute": "Διακοπή αποσιώπησης @{name}",
   "account.unmute_notifications": "Διακοπή αποσιώπησης ειδοποιήσεων του/της @{name}",
-  "account.view_full_profile": "Δες το πλήρες προφίλ",
   "alert.unexpected.message": "Προέκυψε απροσδόκητο σφάλμα.",
   "alert.unexpected.title": "Εεπ!",
   "boost_modal.combo": "Μπορείς να πατήσεις {combo} για να το προσπεράσεις αυτό την επόμενη φορά",
   "bundle_column_error.body": "Κάτι πήγε στραβά ενώ φορτωνόταν αυτό το στοιχείο.",
   "bundle_column_error.retry": "Δοκίμασε ξανά",
   "bundle_column_error.title": "Σφάλμα δικτύου",
-  "bundle_modal_error.close": "Κλείσε",
-  "bundle_modal_error.message": "Κάτι πήγε στραβά ενώ φορτωνόταν αυτό το στοιχείο.",
+  "bundle_modal_error.close": "Κλείσιμο",
+  "bundle_modal_error.message": "Κάτι πήγε στραβά κατά τη φόρτωση του στοιχείου.",
   "bundle_modal_error.retry": "Δοκίμασε ξανά",
   "column.blocks": "Αποκλεισμένοι χρήστες",
   "column.community": "Τοπική ροή",
@@ -71,26 +69,32 @@
   "compose_form.direct_message_warning_learn_more": "Μάθετε περισσότερα",
   "compose_form.hashtag_warning": "Αυτό το τουτ δεν θα εμφανίζεται κάτω από κανένα hashtag καθώς είναι αφανές. Μόνο τα δημόσια τουτ μπορούν να αναζητηθούν ανά hashtag.",
   "compose_form.lock_disclaimer": "Ο λογαριασμός σου δεν είναι {locked}. Οποιοσδήποτε μπορεί να σε ακολουθήσει για να δει τις δημοσιεύσεις σας προς τους ακολούθους σας.",
-  "compose_form.lock_disclaimer.lock": "κλειδωμένος",
+  "compose_form.lock_disclaimer.lock": "κλειδωμένο",
   "compose_form.placeholder": "Τι σκέφτεσαι;",
+  "compose_form.poll.add_option": "Προσθήκη επιλογής",
+  "compose_form.poll.duration": "Διάρκεια δημοσκόπησης",
+  "compose_form.poll.option_placeholder": "Επιλογή {number}",
+  "compose_form.poll.remove_option": "Αφαίρεση επιλογής",
   "compose_form.publish": "Τουτ",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Σημείωσε τα πολυμέσα ως ευαίσθητα",
   "compose_form.sensitive.marked": "Το πολυμέσο έχει σημειωθεί ως ευαίσθητο",
   "compose_form.sensitive.unmarked": "Το πολυμέσο δεν έχει σημειωθεί ως ευαίσθητο",
   "compose_form.spoiler.marked": "Κείμενο κρυμμένο πίσω από προειδοποίηση",
   "compose_form.spoiler.unmarked": "Μη κρυμμένο κείμενο",
   "compose_form.spoiler_placeholder": "Γράψε την προειδοποίησή σου εδώ",
   "confirmation_modal.cancel": "Άκυρο",
+  "confirmations.block.block_and_report": "Αποκλεισμός & Καταγγελία",
   "confirmations.block.confirm": "Απόκλεισε",
-  "confirmations.block.message": "Σίγουρα θες να αποκλείσεις τον/την {name};",
+  "confirmations.block.message": "Σίγουρα θες να αποκλείσεις {name};",
   "confirmations.delete.confirm": "Διέγραψε",
-  "confirmations.delete.message": "Σίγουρα θες να διαγράψεις αυτή την κατάσταση;",
+  "confirmations.delete.message": "Σίγουρα θες να διαγράψεις αυτή τη δημοσίευση;",
   "confirmations.delete_list.confirm": "Διέγραψε",
   "confirmations.delete_list.message": "Σίγουρα θες να διαγράψεις οριστικά αυτή τη λίστα;",
   "confirmations.domain_block.confirm": "Απόκρυψη ολόκληρου του τομέα",
   "confirmations.domain_block.message": "Σίγουρα θες να μπλοκάρεις ολόκληρο το {domain}; Συνήθως μερικά εστιασμένα μπλοκ ή αποσιωπήσεις επαρκούν και προτιμούνται. Δεν θα βλέπεις περιεχόμενο από αυτό τον κόμβο σε καμία δημόσια ροή, ούτε στις ειδοποιήσεις σου. Όσους ακόλουθους έχεις αυτό αυτό τον κόμβο θα αφαιρεθούν.",
   "confirmations.mute.confirm": "Αποσιώπηση",
-  "confirmations.mute.message": "Σίγουρα θες να αποσιωπήσεις τον/την {name};",
+  "confirmations.mute.message": "Σίγουρα θες να αποσιωπήσεις {name};",
   "confirmations.redraft.confirm": "Διαγραφή & ξαναγράψιμο",
   "confirmations.redraft.message": "Σίγουρα θέλεις να σβήσεις αυτή την κατάσταση και να την ξαναγράψεις; Οι αναφορές και τα αγαπημένα της θα χαθούν ενώ οι απαντήσεις προς αυτή θα μείνουν ορφανές.",
   "confirmations.reply.confirm": "Απάντησε",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Σύμβολα",
   "emoji_button.travel": "Ταξίδια & Τοποθεσίες",
   "empty_column.account_timeline": "Δεν έχει τουτ εδώ!",
+  "empty_column.account_unavailable": "Μη διαθέσιμο προφίλ",
   "empty_column.blocks": "Δεν έχεις αποκλείσει κανέναν χρήστη ακόμα.",
   "empty_column.community": "Η τοπική ροή είναι κενή. Γράψε κάτι δημόσιο παραμύθι ν' αρχινίσει!",
   "empty_column.direct": "Δεν έχεις προσωπικά μηνύματα ακόμα. Όταν στείλεις ή λάβεις κανένα, θα εμφανιστεί εδώ.",
@@ -128,7 +133,7 @@
   "empty_column.lists": "Δεν έχεις καμία λίστα ακόμα. Μόλις φτιάξεις μια, θα εμφανιστεί εδώ.",
   "empty_column.mutes": "Δεν έχεις αποσιωπήσει κανένα χρήστη ακόμα.",
   "empty_column.notifications": "Δεν έχεις ειδοποιήσεις ακόμα. Αλληλεπίδρασε με άλλους χρήστες για να ξεκινήσεις την κουβέντα.",
-  "empty_column.public": "Δεν υπάρχει τίποτα εδώ! Γράψε κάτι δημόσιο, ή ακολούθησε χειροκίνητα χρήστες από άλλα instances για να τη γεμίσεις",
+  "empty_column.public": "Δεν υπάρχει τίποτα εδώ! Γράψε κάτι δημόσιο, ή ακολούθησε χειροκίνητα χρήστες από άλλους κόμβους για να τη γεμίσεις",
   "follow_request.authorize": "Ενέκρινε",
   "follow_request.reject": "Απέρριψε",
   "getting_started.developers": "Ανάπτυξη",
@@ -142,19 +147,24 @@
   "hashtag.column_header.tag_mode.all": "και {additional}",
   "hashtag.column_header.tag_mode.any": "ή {additional}",
   "hashtag.column_header.tag_mode.none": "χωρίς {additional}",
-  "hashtag.column_settings.tag_mode.all": "Όλα αυτα",
+  "hashtag.column_settings.select.no_options_message": "Δεν βρέθηκαν προτάσεις",
+  "hashtag.column_settings.select.placeholder": "Γράψε μερικές ταμπέλες…",
+  "hashtag.column_settings.tag_mode.all": "Όλα αυτά",
   "hashtag.column_settings.tag_mode.any": "Οποιοδήποτε από αυτά",
   "hashtag.column_settings.tag_mode.none": "Κανένα από αυτά",
-  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "hashtag.column_settings.tag_toggle": "Προσθήκη επιπλέον ταμπελών για την κολώνα",
   "home.column_settings.basic": "Βασικά",
   "home.column_settings.show_reblogs": "Εμφάνιση προωθήσεων",
   "home.column_settings.show_replies": "Εμφάνιση απαντήσεων",
+  "intervals.full.days": "{number, plural, one {# μέρα} other {# μέρες}}",
+  "intervals.full.hours": "{number, plural, one {# ώρα} other {# ώρες}}",
+  "intervals.full.minutes": "{number, plural, one {# λεπτό} other {# λεπτά}}",
   "introduction.federation.action": "Επόμενο",
-  "introduction.federation.federated.headline": "Federated",
+  "introduction.federation.federated.headline": "Ομοσπονδιακή",
   "introduction.federation.federated.text": "Οι δημόσιες αναρτήσεις από άλλους κόμβους του fediverse θα εμφανίζονται στην ομοσπονδιακή ροή.",
-  "introduction.federation.home.headline": "Home",
+  "introduction.federation.home.headline": "Αρχική",
   "introduction.federation.home.text": "Οι αναρτήσεις όσων ακολουθείς θα εμφανίζονται στην αρχική ροή. Μπορείς να ακολουθήσεις όποιον θέλεις σε οποιονδήποτε κόμβο!",
-  "introduction.federation.local.headline": "Local",
+  "introduction.federation.local.headline": "Τοπική",
   "introduction.federation.local.text": "Οι δημόσιες αναρτήσεις από άτομα στον ίδιο κόμβο με εσένα θα εμφανίζονται στην τοπική ροή.",
   "introduction.interactions.action": "Τέλος μαθήματος!",
   "introduction.interactions.favourite.headline": "Αγαπημένο",
@@ -165,7 +175,7 @@
   "introduction.interactions.reply.text": "Μπορείς να απαντήσεις στα τουτ άλλων αλλά ακόμα και στα δικά σου, δένοντας τα όλα μαζί σε μια συζήτηση.",
   "introduction.welcome.action": "Ας ξεκινήσουμε!",
   "introduction.welcome.headline": "Πρώτα βήματα",
-  "introduction.welcome.text": "Καλώς ήρθες στο fediverse! Σε πολύ λίγο θα μπορείς να στέλνεις δημοσιεύσεις και να μιλάς με τους φίλους σου σε πολλούς, διαφορετικούς κόμβους. Ο κόμβος {domain} όμως είναι ξεχωριστός — φιλοξενεί τον λογαριασμό σου, για αυτό μα θυμάσαι το όνομά του.",
+  "introduction.welcome.text": "Καλώς ήρθες στο fediverse! Σε πολύ λίγο θα μπορείς να στέλνεις δημοσιεύσεις και να μιλάς με τους φίλους σου σε πολλούς, διαφορετικούς κόμβους. Ο κόμβος {domain} όμως είναι ξεχωριστός — φιλοξενεί τον λογαριασμό σου, για αυτό να θυμάσαι το όνομά του.",
   "keyboard_shortcuts.back": "επιστροφή",
   "keyboard_shortcuts.blocked": "άνοιγμα λίστας αποκλεισμένων χρηστών",
   "keyboard_shortcuts.boost": "προώθηση",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "εστίαση αναζήτησης",
   "keyboard_shortcuts.start": "άνοιγμα κολώνας \"Ξεκινώντας\"",
   "keyboard_shortcuts.toggle_hidden": "εμφάνιση/απόκρυψη κειμένου πίσω από την προειδοποίηση",
+  "keyboard_shortcuts.toggle_sensitivity": "εμφάνιση/απόκρυψη πολυμέσων",
   "keyboard_shortcuts.toot": "δημιουργία νέου τουτ",
   "keyboard_shortcuts.unfocus": "απο-εστίαση του πεδίου σύνθεσης/αναζήτησης",
   "keyboard_shortcuts.up": "κίνηση προς την κορυφή της λίστας",
   "lightbox.close": "Κλείσιμο",
   "lightbox.next": "Επόμενο",
   "lightbox.previous": "Προηγούμενο",
+  "lightbox.view_context": "Εμφάνιση πλαισίου",
   "lists.account.add": "Πρόσθεσε στη λίστα",
   "lists.account.remove": "Βγάλε από τη λίστα",
   "lists.delete": "Διαγραφή λίστας",
   "lists.edit": "Επεξεργασία λίστας",
+  "lists.edit.submit": "Αλλαγή τίτλου",
   "lists.new.create": "Προσθήκη λίστας",
   "lists.new.title_placeholder": "Τίτλος νέας λίστα",
   "lists.search": "Αναζήτησε μεταξύ των ανθρώπων που ακουλουθείς",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "Αγαπημένα",
   "navigation_bar.filters": "Αποσιωπημένες λέξεις",
   "navigation_bar.follow_requests": "Αιτήματα ακολούθησης",
+  "navigation_bar.follows_and_followers": "Ακολουθεί και ακολουθείται",
   "navigation_bar.info": "Πληροφορίες κόμβου",
   "navigation_bar.keyboard_shortcuts": "Συντομεύσεις",
   "navigation_bar.lists": "Λίστες",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Προσωπικά",
   "navigation_bar.pins": "Καρφιτσωμένα τουτ",
   "navigation_bar.preferences": "Προτιμήσεις",
+  "navigation_bar.profile_directory": "Κατάλογος λογαριασμών",
   "navigation_bar.public_timeline": "Ομοσπονδιακή ροή",
   "navigation_bar.security": "Ασφάλεια",
   "notification.favourite": "Ο/Η {name} σημείωσε ως αγαπημένη την κατάστασή σου",
   "notification.follow": "Ο/Η {name} σε ακολούθησε",
   "notification.mention": "Ο/Η {name} σε ανέφερε",
+  "notification.poll": "Έλαβε τέλος μια από τις ψηφοφορίες που συμμετείχες",
   "notification.reblog": "Ο/Η {name} προώθησε την κατάστασή σου",
   "notifications.clear": "Καθαρισμός ειδοποιήσεων",
   "notifications.clear_confirmation": "Σίγουρα θέλεις να καθαρίσεις όλες τις ειδοποιήσεις σου;",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Εμφάνιση",
   "notifications.column_settings.follow": "Νέοι ακόλουθοι:",
   "notifications.column_settings.mention": "Αναφορές:",
+  "notifications.column_settings.poll": "Αποτελέσματα ψηφοφορίας:",
   "notifications.column_settings.push": "Άμεσες ειδοποιήσεις",
   "notifications.column_settings.reblog": "Προωθήσεις:",
   "notifications.column_settings.show": "Εμφάνισε σε στήλη",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Αγαπημένα",
   "notifications.filter.follows": "Ακόλουθοι",
   "notifications.filter.mentions": "Αναφορές",
+  "notifications.filter.polls": "Αποτελέσματα ψηφοφορίας",
   "notifications.group": "{count} ειδοποιήσεις",
+  "poll.closed": "Κλειστή",
+  "poll.refresh": "Ανανέωση",
+  "poll.total_votes": "{count, plural, one {# ψήφος} other {# ψήφοι}}",
+  "poll.vote": "Ψήφισε",
+  "poll_button.add_poll": "Προσθήκη δημοσκόπησης",
+  "poll_button.remove_poll": "Αφαίρεση δημοσκόπησης",
   "privacy.change": "Προσαρμογή ιδιωτικότητας δημοσίευσης",
   "privacy.direct.long": "Δημοσίευση μόνο σε όσους και όσες αναφέρονται",
   "privacy.direct.short": "Προσωπικά",
@@ -276,7 +300,7 @@
   "reply_indicator.cancel": "Άκυρο",
   "report.forward": "Προώθηση προς {target}",
   "report.forward_hint": "Ο λογαριασμός είναι από διαφορετικό διακομιστή. Να σταλεί ανώνυμο αντίγραφο της καταγγελίας κι εκεί;",
-  "report.hint": "Η καταγγελία θα σταλεί στους διαχειριστές του κόμβου σου. Μπορείς να περιγράψεις γιατί καταγγέλεις το λογαριασμό παρακάτω:",
+  "report.hint": "Η καταγγελία θα σταλεί στους διαχειριστές του κόμβου σου. Μπορείς να περιγράψεις γιατί καταγγέλεις αυτόν το λογαριασμό παρακάτω:",
   "report.placeholder": "Επιπλέον σχόλια",
   "report.submit": "Υποβολή",
   "report.target": "Καταγγελία {target}",
@@ -290,13 +314,13 @@
   "search_results.accounts": "Άνθρωποι",
   "search_results.hashtags": "Ταμπέλες",
   "search_results.statuses": "Τουτ",
-  "search_results.total": "{count, number} {count, plural, ένα {result} υπόλοιπα {results}}",
-  "standalone.public_title": "Μια πρώτη γεύση...",
-  "status.admin_account": "Open moderation interface for @{name}",
-  "status.admin_status": "Open this status in the moderation interface",
+  "search_results.total": "{count, number} {count, plural, zero {αποτελέσματα} one {αποτέλεσμα} other {αποτελέσματα}}",
+  "status.admin_account": "Άνοιγμα λειτουργίας διαμεσολάβησης για τον/την @{name}",
+  "status.admin_status": "Άνοιγμα αυτής της δημοσίευσης στη λειτουργία διαμεσολάβησης",
   "status.block": "Αποκλεισμός @{name}",
   "status.cancel_reblog_private": "Ακύρωσε την προώθηση",
   "status.cannot_reblog": "Αυτή η δημοσίευση δεν μπορεί να προωθηθεί",
+  "status.copy": "Αντιγραφή συνδέσμου της δημοσίευσης",
   "status.delete": "Διαγραφή",
   "status.detailed_status": "Προβολή λεπτομερειών συζήτησης",
   "status.direct": "Προσωπικό μήνυμα προς @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Απάντησε",
   "status.replyAll": "Απάντησε στην συζήτηση",
   "status.report": "Κατάγγειλε @{name}",
-  "status.sensitive_toggle": "Κλικ για να δεις",
   "status.sensitive_warning": "Ευαίσθητο περιεχόμενο",
   "status.share": "Μοιράσου",
   "status.show_less": "Δείξε λιγότερα",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Τοπικά",
   "tabs_bar.notifications": "Ειδοποιήσεις",
   "tabs_bar.search": "Αναζήτηση",
+  "time_remaining.days": "απομένουν {number, plural, one {# ημέρα} other {# ημέρες}}",
+  "time_remaining.hours": "απομένουν {number, plural, one {# ώρα} other {# ώρες}}",
+  "time_remaining.minutes": "απομένουν {number, plural, one {# λεπτό} other {# λεπτά}}",
+  "time_remaining.moments": "Απομένουν στιγμές",
+  "time_remaining.seconds": "απομένουν {number, plural, one {# δευτερόλεπτο} other {# δευτερόλεπτα}}",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} μιλάνε",
   "ui.beforeunload": "Το προσχέδιό σου θα χαθεί αν φύγεις από το Mastodon.",
   "upload_area.title": "Drag & drop για να ανεβάσεις",
   "upload_button.label": "Πρόσθεσε πολυμέσα (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "Υπέρβαση ορίου μεγέθους ανεβασμένων αρχείων.",
+  "upload_error.poll": "Στις δημοσκοπήσεις δεν επιτρέπεται η μεταφόρτωση αρχείου.",
   "upload_form.description": "Περιέγραψε για όσους & όσες έχουν προβλήματα όρασης",
   "upload_form.focus": "Αλλαγή προεπισκόπησης",
   "upload_form.undo": "Διαγραφή",
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index 1dbf2802226aeb444519e3bef60d5cd63df8479e..67e1e01f85a3a68e2b5b017c29ed2aae69e94532 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -5,7 +5,6 @@
   "account.block_domain": "Hide everything from {domain}",
   "account.blocked": "Blocked",
   "account.direct": "Direct message @{name}",
-  "account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
   "account.domain_blocked": "Domain hidden",
   "account.edit_profile": "Edit profile",
   "account.endorse": "Feature on profile",
@@ -36,7 +35,6 @@
   "account.unfollow": "Unfollow",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account.view_full_profile": "View full profile",
   "alert.unexpected.message": "An unexpected error occurred.",
   "alert.unexpected.title": "Oops!",
   "boost_modal.combo": "You can press {combo} to skip this next time",
@@ -73,14 +71,20 @@
   "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",
   "compose_form.placeholder": "What's on your mind?",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
   "compose_form.sensitive.marked": "Media is marked as sensitive",
   "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
   "compose_form.spoiler.marked": "Text is hidden behind warning",
   "compose_form.spoiler.unmarked": "Text is not hidden",
   "compose_form.spoiler_placeholder": "Write your warning here",
   "confirmation_modal.cancel": "Cancel",
+  "confirmations.block.block_and_report": "Block & Report",
   "confirmations.block.confirm": "Block",
   "confirmations.block.message": "Are you sure you want to block {name}?",
   "confirmations.delete.confirm": "Delete",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Symbols",
   "emoji_button.travel": "Travel & Places",
   "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_unavailable": "Profile unavailable",
   "empty_column.blocks": "You haven't blocked any users yet.",
   "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
   "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
@@ -128,7 +133,7 @@
   "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
   "empty_column.mutes": "You haven't muted any users 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",
+  "empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up",
   "follow_request.authorize": "Authorize",
   "follow_request.reject": "Reject",
   "getting_started.developers": "Developers",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "and {additional}",
   "hashtag.column_header.tag_mode.any": "or {additional}",
   "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
   "hashtag.column_settings.tag_mode.all": "All of these",
   "hashtag.column_settings.tag_mode.any": "Any of these",
   "hashtag.column_settings.tag_mode.none": "None of these",
@@ -149,6 +156,9 @@
   "home.column_settings.basic": "Basic",
   "home.column_settings.show_reblogs": "Show boosts",
   "home.column_settings.show_replies": "Show replies",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
   "introduction.federation.action": "Next",
   "introduction.federation.federated.headline": "Federated",
   "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "to focus search",
   "keyboard_shortcuts.start": "to open \"get started\" column",
   "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "to start a brand new toot",
   "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
   "keyboard_shortcuts.up": "to move up in the list",
   "lightbox.close": "Close",
   "lightbox.next": "Next",
   "lightbox.previous": "Previous",
+  "lightbox.view_context": "View context",
   "lists.account.add": "Add to list",
   "lists.account.remove": "Remove from list",
   "lists.delete": "Delete list",
   "lists.edit": "Edit list",
+  "lists.edit.submit": "Change title",
   "lists.new.create": "Add list",
   "lists.new.title_placeholder": "New list title",
   "lists.search": "Search among people you follow",
@@ -224,7 +237,8 @@
   "navigation_bar.favourites": "Favourites",
   "navigation_bar.filters": "Muted words",
   "navigation_bar.follow_requests": "Follow requests",
-  "navigation_bar.info": "About this instance",
+  "navigation_bar.follows_and_followers": "Follows and followers",
+  "navigation_bar.info": "About this server",
   "navigation_bar.keyboard_shortcuts": "Hotkeys",
   "navigation_bar.lists": "Lists",
   "navigation_bar.logout": "Logout",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Personal",
   "navigation_bar.pins": "Pinned toots",
   "navigation_bar.preferences": "Preferences",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "Federated timeline",
   "navigation_bar.security": "Security",
   "notification.favourite": "{name} favourited your status",
   "notification.follow": "{name} followed you",
   "notification.mention": "{name} mentioned you",
+  "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "{name} boosted your status",
   "notifications.clear": "Clear notifications",
   "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Show",
   "notifications.column_settings.follow": "New followers:",
   "notifications.column_settings.mention": "Mentions:",
+  "notifications.column_settings.poll": "Poll results:",
   "notifications.column_settings.push": "Push notifications",
   "notifications.column_settings.reblog": "Boosts:",
   "notifications.column_settings.show": "Show in column",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favourites",
   "notifications.filter.follows": "Follows",
   "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
   "notifications.group": "{count} notifications",
+  "poll.closed": "Closed",
+  "poll.refresh": "Refresh",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
   "privacy.change": "Adjust status privacy",
   "privacy.direct.long": "Post to mentioned users only",
   "privacy.direct.short": "Direct",
@@ -276,7 +300,7 @@
   "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.hint": "The report will be sent to your server 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}",
@@ -291,12 +315,12 @@
   "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.admin_account": "Open moderation interface for @{name}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "This post cannot be boosted",
+  "status.copy": "Copy link to status",
   "status.delete": "Delete",
   "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Reply",
   "status.replyAll": "Reply to thread",
   "status.report": "Report @{name}",
-  "status.sensitive_toggle": "Click to view",
   "status.sensitive_warning": "Sensitive content",
   "status.share": "Share",
   "status.show_less": "Show less",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Local",
   "tabs_bar.notifications": "Notifications",
   "tabs_bar.search": "Search",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
   "upload_area.title": "Drag & drop to upload",
-  "upload_button.label": "Add media (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_button.label": "Add media ({formats})",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.focus": "Change preview",
   "upload_form.undo": "Delete",
diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json
index 8be964a52a7ab9cefee325d57350a0e0751a6b72..897cb63530479d728d5cb39f899b129d4e7feb11 100644
--- a/app/javascript/mastodon/locales/eo.json
+++ b/app/javascript/mastodon/locales/eo.json
@@ -5,7 +5,6 @@
   "account.block_domain": "Kaŝi ĉion de {domain}",
   "account.blocked": "Blokita",
   "account.direct": "Rekte mesaĝi @{name}",
-  "account.disclaimer_full": "Subaj informoj povas reflekti la profilon de la uzanto nekomplete.",
   "account.domain_blocked": "Domajno kaŝita",
   "account.edit_profile": "Redakti profilon",
   "account.endorse": "Montri en profilo",
@@ -36,7 +35,6 @@
   "account.unfollow": "Ne plu sekvi",
   "account.unmute": "Malsilentigi @{name}",
   "account.unmute_notifications": "Malsilentigi sciigojn de @{name}",
-  "account.view_full_profile": "Vidi plenan profilon",
   "alert.unexpected.message": "Neatendita eraro okazis.",
   "alert.unexpected.title": "Ups!",
   "boost_modal.combo": "Vi povas premi {combo} por preterpasi sekvafoje",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "Via konta ne estas {locked}. Iu ajn povas sekvi vin por vidi viajn mesaĝojn, kiuj estas nur por sekvantoj.",
   "compose_form.lock_disclaimer.lock": "ŝlosita",
   "compose_form.placeholder": "Pri kio vi pensas?",
+  "compose_form.poll.add_option": "Aldoni elekto",
+  "compose_form.poll.duration": "Balotenketo daÅ­ro",
+  "compose_form.poll.option_placeholder": "elekto {number}",
+  "compose_form.poll.remove_option": "Forigi ĉi tiu elekton",
   "compose_form.publish": "Hup",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Marki aŭdovidaĵojn kiel tiklaj",
   "compose_form.sensitive.marked": "Aŭdovidaĵo markita tikla",
   "compose_form.sensitive.unmarked": "Aŭdovidaĵo ne markita tikla",
   "compose_form.spoiler.marked": "Teksto kaŝita malantaŭ averto",
   "compose_form.spoiler.unmarked": "Teksto ne kaŝita",
   "compose_form.spoiler_placeholder": "Skribu vian averton ĉi tie",
   "confirmation_modal.cancel": "Nuligi",
+  "confirmations.block.block_and_report": "Bloki & Signali",
   "confirmations.block.confirm": "Bloki",
   "confirmations.block.message": "Ĉu vi certas, ke vi volas bloki {name}?",
   "confirmations.delete.confirm": "Forigi",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Simboloj",
   "emoji_button.travel": "Vojaĝoj kaj lokoj",
   "empty_column.account_timeline": "Neniu mesaĝo ĉi tie!",
+  "empty_column.account_unavailable": "Profilo ne disponebla",
   "empty_column.blocks": "Vi ankoraÅ­ ne blokis uzanton.",
   "empty_column.community": "La loka tempolinio estas malplena. Skribu ion por plenigi ĝin!",
   "empty_column.direct": "Vi ankoraŭ ne havas rektan mesaĝon. Kiam vi sendos aŭ ricevos iun, ĝi aperos ĉi tie.",
@@ -128,11 +133,11 @@
   "empty_column.lists": "Vi ankoraŭ ne havas liston. Kiam vi kreos iun, ĝi aperos ĉi tie.",
   "empty_column.mutes": "Vi ne ankoraÅ­ silentigis iun uzanton.",
   "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",
+  "empty_column.public": "Estas nenio ĉi tie! Publike skribu ion, aŭ mane sekvu uzantojn de aliaj serviloj por plenigi la publikan tempolinion",
   "follow_request.authorize": "Rajtigi",
   "follow_request.reject": "Rifuzi",
   "getting_started.developers": "Programistoj",
-  "getting_started.directory": "Profile directory",
+  "getting_started.directory": "Profilujo",
   "getting_started.documentation": "Dokumentado",
   "getting_started.heading": "Por komenci",
   "getting_started.invite": "Inviti homojn",
@@ -142,30 +147,35 @@
   "hashtag.column_header.tag_mode.all": "kaj {additional}",
   "hashtag.column_header.tag_mode.any": "aÅ­ {additional}",
   "hashtag.column_header.tag_mode.none": "sen {additional}",
+  "hashtag.column_settings.select.no_options_message": "Neniu sugesto trovita",
+  "hashtag.column_settings.select.placeholder": "Enmeti kradvortojn…",
   "hashtag.column_settings.tag_mode.all": "Ĉiuj",
   "hashtag.column_settings.tag_mode.any": "Iu ajn",
   "hashtag.column_settings.tag_mode.none": "Neniu",
-  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "hashtag.column_settings.tag_toggle": "Inkluzivi pluajn etikedojn por ĉi tiu kolumno",
   "home.column_settings.basic": "Bazaj agordoj",
   "home.column_settings.show_reblogs": "Montri diskonigojn",
   "home.column_settings.show_replies": "Montri respondojn",
+  "intervals.full.days": "{number, plural, one {# tago} other {# tagoj}}",
+  "intervals.full.hours": "{number, plural, one {# horo} other {# horoj}}",
+  "intervals.full.minutes": "{number, plural, one {# minuto} other {# minutoj}}",
   "introduction.federation.action": "Sekva",
-  "introduction.federation.federated.headline": "Federated",
-  "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
-  "introduction.federation.home.headline": "Home",
-  "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
-  "introduction.federation.local.headline": "Local",
-  "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
-  "introduction.interactions.favourite.headline": "Favourite",
-  "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
-  "introduction.interactions.reblog.headline": "Boost",
-  "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
-  "introduction.interactions.reply.headline": "Reply",
-  "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
-  "introduction.welcome.action": "Let's go!",
-  "introduction.welcome.headline": "First steps",
-  "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
+  "introduction.federation.federated.headline": "Federacio",
+  "introduction.federation.federated.text": "Publikaj mesaĝoj el aliaj serviloj de la Fediverse aperos en la fratara tempolinio.",
+  "introduction.federation.home.headline": "Heimo",
+  "introduction.federation.home.text": "Mesaĝoj de homoj, kiujn vi sekvas, aperos en via hejma fluo. Vi povas sekvi iun ajn de ajna servilo!",
+  "introduction.federation.local.headline": "Loka",
+  "introduction.federation.local.text": "Publikaj mesaĝoj de homoj de via servilo aperos en la loka tempolinio.",
+  "introduction.interactions.action": "Fini la lernilon!",
+  "introduction.interactions.favourite.headline": "Stelumi",
+  "introduction.interactions.favourite.text": "Vi povas konservi mesaĝon por posta uzo, kaj sciigi al ĝia aŭtoro ke vi ŝatis ĝin, per stelumo.",
+  "introduction.interactions.reblog.headline": "Diskonigi",
+  "introduction.interactions.reblog.text": "Vi povas diskonigi mesaĝojn al viaj sekvantoj per diskonigo.",
+  "introduction.interactions.reply.headline": "Respondi",
+  "introduction.interactions.reply.text": "Vi povas respondi al mesaĝoj aliulaj kaj viaj, kio kreos ĉenon de mesaĝoj nomata konversacio.",
+  "introduction.welcome.action": "Ek!",
+  "introduction.welcome.headline": "Unuaj paŝoj",
+  "introduction.welcome.text": "Bonvenon en Fediverse! Tre baldaŭ, vi povos disdoni mesaĝojn kaj paroli al viaj amikoj tra granda servila diverseco. Sed ĉi tiu servilo, {domain}, estas speciala: ĝi enhavas vian profilon, do memoru ĝian nomon.",
   "keyboard_shortcuts.back": "por reveni",
   "keyboard_shortcuts.blocked": "por malfermi la liston de blokitaj uzantoj",
   "keyboard_shortcuts.boost": "por diskonigi",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "por fokusigi la serĉilon",
   "keyboard_shortcuts.start": "por malfermi la kolumnon «por komenci»",
   "keyboard_shortcuts.toggle_hidden": "por montri/kaŝi tekston malantaŭ enhava averto",
+  "keyboard_shortcuts.toggle_sensitivity": "por montri/kaŝi aŭdovidaĵojn",
   "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": "Sekva",
   "lightbox.previous": "AntaÅ­a",
+  "lightbox.view_context": "Vidi kontekston",
   "lists.account.add": "Aldoni al la listo",
   "lists.account.remove": "Forigi de la listo",
   "lists.delete": "Forigi la liston",
   "lists.edit": "Redakti la liston",
+  "lists.edit.submit": "Ŝanĝi titolon",
   "lists.new.create": "Aldoni liston",
   "lists.new.title_placeholder": "Titolo de la nova listo",
   "lists.search": "Serĉi inter la homoj, kiujn vi sekvas",
@@ -224,7 +237,8 @@
   "navigation_bar.favourites": "Stelumoj",
   "navigation_bar.filters": "Silentigitaj vortoj",
   "navigation_bar.follow_requests": "Petoj de sekvado",
-  "navigation_bar.info": "Pri ĉi tiu nodo",
+  "navigation_bar.follows_and_followers": "Sekvatoj kaj sekvantoj",
+  "navigation_bar.info": "Pri ĉi tiu servilo",
   "navigation_bar.keyboard_shortcuts": "Rapidklavoj",
   "navigation_bar.lists": "Listoj",
   "navigation_bar.logout": "Elsaluti",
@@ -232,31 +246,41 @@
   "navigation_bar.personal": "Persone",
   "navigation_bar.pins": "Alpinglitaj mesaĝoj",
   "navigation_bar.preferences": "Preferoj",
+  "navigation_bar.profile_directory": "Profilujo",
   "navigation_bar.public_timeline": "Fratara tempolinio",
   "navigation_bar.security": "Sekureco",
   "notification.favourite": "{name} stelumis vian mesaĝon",
   "notification.follow": "{name} eksekvis vin",
   "notification.mention": "{name} menciis vin",
+  "notification.poll": "Balotenketo ke vi balotis estas finita",
   "notification.reblog": "{name} diskonigis vian mesaĝon",
   "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.filter_bar.advanced": "Display all categories",
-  "notifications.column_settings.filter_bar.category": "Quick filter bar",
-  "notifications.column_settings.filter_bar.show": "Show",
+  "notifications.column_settings.filter_bar.advanced": "Montri ĉiujn kategoriojn",
+  "notifications.column_settings.filter_bar.category": "Rapida filtra breto",
+  "notifications.column_settings.filter_bar.show": "Montri",
   "notifications.column_settings.follow": "Novaj sekvantoj:",
   "notifications.column_settings.mention": "Mencioj:",
+  "notifications.column_settings.poll": "Balotenketo rezulto:",
   "notifications.column_settings.push": "Puŝsciigoj",
   "notifications.column_settings.reblog": "Diskonigoj:",
   "notifications.column_settings.show": "Montri en kolumno",
   "notifications.column_settings.sound": "Eligi sonon",
-  "notifications.filter.all": "All",
-  "notifications.filter.boosts": "Boosts",
-  "notifications.filter.favourites": "Favourites",
-  "notifications.filter.follows": "Follows",
-  "notifications.filter.mentions": "Mentions",
+  "notifications.filter.all": "Ĉiuj",
+  "notifications.filter.boosts": "Diskonigoj",
+  "notifications.filter.favourites": "Stelumoj",
+  "notifications.filter.follows": "Sekvoj",
+  "notifications.filter.mentions": "Mencioj",
+  "notifications.filter.polls": "Balotenketoj rezultoj",
   "notifications.group": "{count} sciigoj",
+  "poll.closed": "Finita",
+  "poll.refresh": "Aktualigi",
+  "poll.total_votes": "{count, plural, one {# voĉdono} other {# voĉdonoj}}",
+  "poll.vote": "Voĉdoni",
+  "poll_button.add_poll": "Aldoni balotenketon",
+  "poll_button.remove_poll": "Forigi balotenketon",
   "privacy.change": "Agordi mesaĝan privatecon",
   "privacy.direct.long": "Afiŝi nur al menciitaj uzantoj",
   "privacy.direct.short": "Rekta",
@@ -276,7 +300,7 @@
   "reply_indicator.cancel": "Nuligi",
   "report.forward": "Plusendi al {target}",
   "report.forward_hint": "La konto estas en alia servilo. Ĉu sendi sennomigitan kopion de la signalo ankaŭ tien?",
-  "report.hint": "La signalo estos sendita al la kontrolantoj de via nodo. Vi povas doni klarigon pri kial vi signalas ĉi tiun konton sube:",
+  "report.hint": "La signalo estos sendita al la kontrolantoj de via servilo. Vi povas doni klarigon pri kial vi signalas ĉi tiun konton sube:",
   "report.placeholder": "Pliaj komentoj",
   "report.submit": "Sendi",
   "report.target": "Signali {target}",
@@ -291,12 +315,12 @@
   "search_results.hashtags": "Kradvortoj",
   "search_results.statuses": "Mesaĝoj",
   "search_results.total": "{count, number} {count, plural, one {rezulto} other {rezultoj}}",
-  "standalone.public_title": "Enrigardo…",
-  "status.admin_account": "Open moderation interface for @{name}",
-  "status.admin_status": "Open this status in the moderation interface",
+  "status.admin_account": "Malfermi la kontrolan interfacon por @{name}",
+  "status.admin_status": "Malfermi ĉi tiun mesaĝon en la kontrola interfaco",
   "status.block": "Bloki @{name}",
   "status.cancel_reblog_private": "Eksdiskonigi",
   "status.cannot_reblog": "Ĉi tiu mesaĝo ne diskonigeblas",
+  "status.copy": "Kopii la ligilon al la mesaĝo",
   "status.delete": "Forigi",
   "status.detailed_status": "Detala konversacia vido",
   "status.direct": "Rekte mesaĝi @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Respondi",
   "status.replyAll": "Respondi al la fadeno",
   "status.report": "Signali @{name}",
-  "status.sensitive_toggle": "Alklaki por vidi",
   "status.sensitive_warning": "Tikla enhavo",
   "status.share": "Diskonigi",
   "status.show_less": "Malgrandigi",
@@ -338,12 +361,19 @@
   "tabs_bar.local_timeline": "Loka tempolinio",
   "tabs_bar.notifications": "Sciigoj",
   "tabs_bar.search": "Serĉi",
-  "trends.count_by_accounts": "{count} {rawCount, pluraj, unu {person} alia(j) {people}} parolas",
+  "time_remaining.days": "{number, plural, one {# tago} other {# tagoj}} restanta",
+  "time_remaining.hours": "{number, plural, one {# horo} other {# horoj}} restanta",
+  "time_remaining.minutes": "{number, plural, one {# minuto} other {# minutoj}} restanta",
+  "time_remaining.moments": "Momento restanta",
+  "time_remaining.seconds": "{number, plural, one {# sekundo} other {# sekundoj}} restanta",
+  "trends.count_by_accounts": "{count} {rawCount, plural, one {persono} other {personoj}} parolas",
   "ui.beforeunload": "Via malneto perdiĝos se vi eliras de Mastodon.",
   "upload_area.title": "Altreni kaj lasi por alŝuti",
   "upload_button.label": "Aldoni aŭdovidaĵon (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "Limo de dosiera alŝutado transpasita.",
+  "upload_error.poll": "Alŝuto de dosiero ne permisita kun balotenketo",
   "upload_form.description": "Priskribi por misvidantaj homoj",
-  "upload_form.focus": "Stuci",
+  "upload_form.focus": "Antaŭvido de ŝanĝo",
   "upload_form.undo": "Forigi",
   "upload_progress.label": "Alŝutado…",
   "video.close": "Fermi videon",
diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json
index 4f73dbba244fc17d9cfbf663f92d5ce866b82cd8..8fe50ace587958c1b5a700ed9219f7f8d6ca5e23 100644
--- a/app/javascript/mastodon/locales/es.json
+++ b/app/javascript/mastodon/locales/es.json
@@ -1,11 +1,10 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "Agregar o eliminar de las listas",
   "account.badges.bot": "Bot",
   "account.block": "Bloquear",
   "account.block_domain": "Ocultar todo de {domain}",
   "account.blocked": "Bloqueado",
   "account.direct": "Direct Message @{name}",
-  "account.disclaimer_full": "La siguiente información del usuario puede estar incompleta.",
   "account.domain_blocked": "Dominio oculto",
   "account.edit_profile": "Editar perfil",
   "account.endorse": "Mostrar en perfil",
@@ -16,9 +15,9 @@
   "account.follows.empty": "Este usuario todavía no sigue a nadie.",
   "account.follows_you": "Te sigue",
   "account.hide_reblogs": "Ocultar retoots de @{name}",
-  "account.link_verified_on": "Ownership of this link was checked on {date}",
-  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
-  "account.media": "Media",
+  "account.link_verified_on": "El proprietario de este link fue verificado el {date}",
+  "account.locked_info": "El estado de privacidad de esta cuenta està configurado como bloqueado. El proprietario debe revisar manualmente quien puede seguirle.",
+  "account.media": "Multimedia",
   "account.mention": "Mencionar a @{name}",
   "account.moved_to": "{name} se ha mudado a:",
   "account.mute": "Silenciar a @{name}",
@@ -36,9 +35,8 @@
   "account.unfollow": "Dejar de seguir",
   "account.unmute": "Dejar de silenciar a @{name}",
   "account.unmute_notifications": "Dejar de silenciar las notificaciones de @{name}",
-  "account.view_full_profile": "Ver perfil completo",
   "alert.unexpected.message": "Hubo un error inesperado.",
-  "alert.unexpected.title": "Oops!",
+  "alert.unexpected.title": "¡Ups!",
   "boost_modal.combo": "Puedes presionar {combo} para saltear este aviso la próxima vez",
   "bundle_column_error.body": "Algo salió mal al cargar este componente.",
   "bundle_column_error.retry": "Inténtalo de nuevo",
@@ -73,19 +71,25 @@
   "compose_form.lock_disclaimer": "Tu cuenta no está bloqueada. Todos pueden seguirte para ver tus toots solo para seguidores.",
   "compose_form.lock_disclaimer.lock": "bloqueado",
   "compose_form.placeholder": "¿En qué estás pensando?",
+  "compose_form.poll.add_option": "Añadir una opción",
+  "compose_form.poll.duration": "Duración de la encuesta",
+  "compose_form.poll.option_placeholder": "Elección {number}",
+  "compose_form.poll.remove_option": "Eliminar esta opción",
   "compose_form.publish": "Tootear",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Marcar multimedia como sensible",
   "compose_form.sensitive.marked": "Material marcado como sensible",
   "compose_form.sensitive.unmarked": "Material no marcado como sensible",
   "compose_form.spoiler.marked": "Texto oculto tras la advertencia",
   "compose_form.spoiler.unmarked": "Texto no oculto",
   "compose_form.spoiler_placeholder": "Advertencia de contenido",
   "confirmation_modal.cancel": "Cancelar",
+  "confirmations.block.block_and_report": "Bloquear y Reportar",
   "confirmations.block.confirm": "Bloquear",
   "confirmations.block.message": "¿Estás seguro de que quieres bloquear a {name}?",
   "confirmations.delete.confirm": "Eliminar",
   "confirmations.delete.message": "¿Estás seguro de que quieres borrar este toot?",
-  "confirmations.delete_list.confirm": "Delete",
+  "confirmations.delete_list.confirm": "Eliminar",
   "confirmations.delete_list.message": "¿Seguro que quieres borrar esta lista permanentemente?",
   "confirmations.domain_block.confirm": "Ocultar dominio entero",
   "confirmations.domain_block.message": "¿Seguro de que quieres bloquear al dominio {domain} entero? En general unos cuantos bloqueos y silenciados concretos es suficiente y preferible.",
@@ -93,7 +97,7 @@
   "confirmations.mute.message": "¿Estás seguro de que quieres silenciar a {name}?",
   "confirmations.redraft.confirm": "Borrar y volver a borrador",
   "confirmations.redraft.message": "Estás seguro de que quieres borrar este estado y volverlo a borrador? Perderás todas las respuestas, impulsos y favoritos asociados a él, y las respuestas a la publicación original quedarán huérfanos.",
-  "confirmations.reply.confirm": "Reply",
+  "confirmations.reply.confirm": "Responder",
   "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
   "confirmations.unfollow.confirm": "Dejar de seguir",
   "confirmations.unfollow.message": "¿Estás seguro de que quieres dejar de seguir a {name}?",
@@ -113,7 +117,8 @@
   "emoji_button.search_results": "Resultados de búsqueda",
   "emoji_button.symbols": "Símbolos",
   "emoji_button.travel": "Viajes y lugares",
-  "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_timeline": "¡No hay toots aquí!",
+  "empty_column.account_unavailable": "Perfil no disponible",
   "empty_column.blocks": "Aún no has bloqueado a ningún usuario.",
   "empty_column.community": "La línea de tiempo local está vacía. ¡Escribe algo para empezar la fiesta!",
   "empty_column.direct": "Aún no tienes ningún mensaje directo. Cuando envíes o recibas uno, se mostrará aquí.",
@@ -132,46 +137,51 @@
   "follow_request.authorize": "Autorizar",
   "follow_request.reject": "Rechazar",
   "getting_started.developers": "Desarrolladores",
-  "getting_started.directory": "Profile directory",
-  "getting_started.documentation": "Documentation",
+  "getting_started.directory": "Directorio de perfil",
+  "getting_started.documentation": "Documentación",
   "getting_started.heading": "Primeros pasos",
   "getting_started.invite": "Invitar usuarios",
   "getting_started.open_source_notice": "Mastodon es software libre. Puedes contribuir o reportar errores en {github}.",
   "getting_started.security": "Seguridad",
   "getting_started.terms": "Términos de servicio",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_header.tag_mode.all": "y {additional}",
+  "hashtag.column_header.tag_mode.any": "o {additional}",
+  "hashtag.column_header.tag_mode.none": "sin {additional}",
+  "hashtag.column_settings.select.no_options_message": "No se encontraron sugerencias",
+  "hashtag.column_settings.select.placeholder": "Introduzca hashtags…",
   "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_settings.tag_mode.any": "Cualquiera de estos",
+  "hashtag.column_settings.tag_mode.none": "Ninguno de estos",
   "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
   "home.column_settings.basic": "Básico",
   "home.column_settings.show_reblogs": "Mostrar retoots",
   "home.column_settings.show_replies": "Mostrar respuestas",
-  "introduction.federation.action": "Next",
-  "introduction.federation.federated.headline": "Federated",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
+  "introduction.federation.action": "Siguiente",
+  "introduction.federation.federated.headline": "Federado",
   "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
-  "introduction.federation.home.headline": "Home",
+  "introduction.federation.home.headline": "Inicio",
   "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
   "introduction.federation.local.headline": "Local",
   "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
-  "introduction.interactions.favourite.headline": "Favourite",
+  "introduction.interactions.action": "¡Terminar tutorial!",
+  "introduction.interactions.favourite.headline": "Favorito",
   "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
   "introduction.interactions.reblog.headline": "Boost",
   "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
-  "introduction.interactions.reply.headline": "Reply",
+  "introduction.interactions.reply.headline": "Responder",
   "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
-  "introduction.welcome.action": "Let's go!",
-  "introduction.welcome.headline": "First steps",
+  "introduction.welcome.action": "¡Vamos!",
+  "introduction.welcome.headline": "Primeros pasos",
   "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
   "keyboard_shortcuts.back": "volver atrás",
   "keyboard_shortcuts.blocked": "abrir una lista de usuarios bloqueados",
   "keyboard_shortcuts.boost": "retootear",
   "keyboard_shortcuts.column": "enfocar un estado en una de las columnas",
   "keyboard_shortcuts.compose": "enfocar el área de texto de redacción",
-  "keyboard_shortcuts.description": "Description",
+  "keyboard_shortcuts.description": "Descripción",
   "keyboard_shortcuts.direct": "abrir la columna de mensajes directos",
   "keyboard_shortcuts.down": "mover hacia abajo en la lista",
   "keyboard_shortcuts.enter": "to open status",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "para poner el foco en la búsqueda",
   "keyboard_shortcuts.start": "abrir la columna \"comenzar\"",
   "keyboard_shortcuts.toggle_hidden": "mostrar/ocultar texto tras aviso de contenido (CW)",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "para comenzar un nuevo toot",
   "keyboard_shortcuts.unfocus": "para retirar el foco de la caja de redacción/búsqueda",
   "keyboard_shortcuts.up": "para ir hacia arriba en la lista",
   "lightbox.close": "Cerrar",
   "lightbox.next": "Siguiente",
   "lightbox.previous": "Anterior",
+  "lightbox.view_context": "Ver contexto",
   "lists.account.add": "Añadir a lista",
   "lists.account.remove": "Quitar de lista",
-  "lists.delete": "Delete list",
+  "lists.delete": "Borrar lista",
   "lists.edit": "Editar lista",
+  "lists.edit.submit": "Change title",
   "lists.new.create": "Añadir lista",
   "lists.new.title_placeholder": "Título de la nueva lista",
   "lists.search": "Buscar entre la gente a la que sigues",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "Favoritos",
   "navigation_bar.filters": "Palabras silenciadas",
   "navigation_bar.follow_requests": "Solicitudes para seguirte",
+  "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.info": "Información adicional",
   "navigation_bar.keyboard_shortcuts": "Atajos",
   "navigation_bar.lists": "Listas",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Personal",
   "navigation_bar.pins": "Toots fijados",
   "navigation_bar.preferences": "Preferencias",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "Historia federada",
   "navigation_bar.security": "Seguridad",
   "notification.favourite": "{name} marcó tu estado como favorito",
   "notification.follow": "{name} te empezó a seguir",
   "notification.mention": "{name} te ha mencionado",
+  "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "{name} ha retooteado tu estado",
   "notifications.clear": "Limpiar notificaciones",
   "notifications.clear_confirmation": "¿Seguro que quieres limpiar permanentemente todas tus notificaciones?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Show",
   "notifications.column_settings.follow": "Nuevos seguidores:",
   "notifications.column_settings.mention": "Menciones:",
+  "notifications.column_settings.poll": "Poll results:",
   "notifications.column_settings.push": "Notificaciones push",
   "notifications.column_settings.reblog": "Retoots:",
   "notifications.column_settings.show": "Mostrar en columna",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favourites",
   "notifications.filter.follows": "Follows",
   "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
   "notifications.group": "{count} notificaciones",
+  "poll.closed": "Closed",
+  "poll.refresh": "Refresh",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
   "privacy.change": "Ajustar privacidad",
   "privacy.direct.long": "Sólo mostrar a los usuarios mencionados",
   "privacy.direct.short": "Directo",
@@ -291,12 +315,12 @@
   "search_results.hashtags": "Etiquetas",
   "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {resultado} other {resultados}}",
-  "standalone.public_title": "Un pequeño vistazo...",
   "status.admin_account": "Open moderation interface for @{name}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.cancel_reblog_private": "Des-impulsar",
   "status.cannot_reblog": "Este toot no puede retootearse",
+  "status.copy": "Copy link to status",
   "status.delete": "Borrar",
   "status.detailed_status": "Vista de conversación detallada",
   "status.direct": "Mensaje directo a @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Responder",
   "status.replyAll": "Responder al hilo",
   "status.report": "Reportar",
-  "status.sensitive_toggle": "Haz clic para ver",
   "status.sensitive_warning": "Contenido sensible",
   "status.share": "Compartir",
   "status.show_less": "Mostrar menos",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Local",
   "tabs_bar.notifications": "Notificaciones",
   "tabs_bar.search": "Buscar",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
   "ui.beforeunload": "Tu borrador se perderá si sales de Mastodon.",
   "upload_area.title": "Arrastra y suelta para subir",
   "upload_button.label": "Subir multimedia (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "upload_form.description": "Describir para los usuarios con dificultad visual",
   "upload_form.focus": "Recortar",
   "upload_form.undo": "Borrar",
diff --git a/app/javascript/mastodon/locales/eu.json b/app/javascript/mastodon/locales/eu.json
index 0602fbf9e97bf590cb2508f29a3d0ede02f1f00f..3e91012b35bd924c890d7a79847fcb9f5b8573b5 100644
--- a/app/javascript/mastodon/locales/eu.json
+++ b/app/javascript/mastodon/locales/eu.json
@@ -1,11 +1,10 @@
 {
   "account.add_or_remove_from_list": "Gehitu edo kendu zerrendetatik",
-  "account.badges.bot": "Bot",
+  "account.badges.bot": "Bot-a",
   "account.block": "Blokeatu @{name}",
   "account.block_domain": "Ezkutatu {domain} domeinuko guztia",
   "account.blocked": "Blokeatuta",
   "account.direct": "Mezu zuzena @{name}(r)i",
-  "account.disclaimer_full": "Baliteke beheko informazioak erabiltzailearen profilaren zati bat baino ez erakustea.",
   "account.domain_blocked": "Ezkutatutako domeinua",
   "account.edit_profile": "Aldatu profila",
   "account.endorse": "Nabarmendu profilean",
@@ -18,13 +17,13 @@
   "account.hide_reblogs": "Ezkutatu @{name}(r)en bultzadak",
   "account.link_verified_on": "Esteka honen jabetzaren egiaztaketa data: {date}",
   "account.locked_info": "Kontu honen pribatutasun egoera blokeatuta gisa ezarri da. Jabeak eskuz erabakitzen du nork jarraitu diezaioken.",
-  "account.media": "Media",
+  "account.media": "Multimedia",
   "account.mention": "Aipatu @{name}",
   "account.moved_to": "{name} hona lekualdatu da:",
   "account.mute": "Mututu @{name}",
   "account.mute_notifications": "Mututu @{name}(r)en jakinarazpenak",
   "account.muted": "Mutututa",
-  "account.posts": "Tootak",
+  "account.posts": "Toot",
   "account.posts_with_replies": "Toot eta erantzunak",
   "account.report": "Salatu @{name}",
   "account.requested": "Onarpenaren zain. Klikatu jarraitzeko eskaera ezeztatzeko",
@@ -33,16 +32,15 @@
   "account.unblock": "Desblokeatu @{name}",
   "account.unblock_domain": "Berriz erakutsi {domain}",
   "account.unendorse": "Ez nabarmendu profilean",
-  "account.unfollow": "Jarraitzeari utzi",
+  "account.unfollow": "Utzi jarraitzeari",
   "account.unmute": "Desmututu @{name}",
   "account.unmute_notifications": "Desmututu @{name}(r)en jakinarazpenak",
-  "account.view_full_profile": "Ikusi profil osoa",
   "alert.unexpected.message": "Ustekabeko errore bat gertatu da.",
   "alert.unexpected.title": "Ene!",
   "boost_modal.combo": "{combo} sakatu dezakezu hurrengoan hau saltatzeko",
   "bundle_column_error.body": "Zerbait okerra gertatu da osagai hau kargatzean.",
   "bundle_column_error.retry": "Saiatu berriro",
-  "bundle_column_error.title": "Network error",
+  "bundle_column_error.title": "Sareko errorea",
   "bundle_modal_error.close": "Itxi",
   "bundle_modal_error.message": "Zerbait okerra gertatu da osagai hau kargatzean.",
   "bundle_modal_error.retry": "Saiatu berriro",
@@ -73,15 +71,21 @@
   "compose_form.lock_disclaimer": "Zure kontua ez dago {locked}. Edonork jarraitu zaitzake zure jarraitzaileentzako soilik diren mezuak ikusteko.",
   "compose_form.lock_disclaimer.lock": "giltzapetuta",
   "compose_form.placeholder": "Zer duzu buruan?",
+  "compose_form.poll.add_option": "Gehitu aukera bat",
+  "compose_form.poll.duration": "Inkestaren iraupena",
+  "compose_form.poll.option_placeholder": "{number}. aukera",
+  "compose_form.poll.remove_option": "Kendu aukera hau",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Markatu multimedia hunkigarri gisa",
   "compose_form.sensitive.marked": "Multimedia edukia hunkigarri gisa markatu da",
   "compose_form.sensitive.unmarked": "Multimedia edukia ez da hunkigarri gisa markatu",
   "compose_form.spoiler.marked": "Testua abisu batek ezkutatzen du",
   "compose_form.spoiler.unmarked": "Testua ez dago ezkutatuta",
   "compose_form.spoiler_placeholder": "Idatzi zure abisua hemen",
   "confirmation_modal.cancel": "Utzi",
-  "confirmations.block.confirm": "Block",
+  "confirmations.block.block_and_report": "Blokeatu eta salatu",
+  "confirmations.block.confirm": "Blokeatu",
   "confirmations.block.message": "Ziur {name} blokeatu nahi duzula?",
   "confirmations.delete.confirm": "Ezabatu",
   "confirmations.delete.message": "Ziur mezu hau ezabatu nahi duzula?",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Sinboloak",
   "emoji_button.travel": "Bidaiak eta tokiak",
   "empty_column.account_timeline": "Ez dago toot-ik hemen!",
+  "empty_column.account_unavailable": "Profila ez dago eskuragarri",
   "empty_column.blocks": "Ez duzu erabiltzailerik blokeatu oraindik.",
   "empty_column.community": "Denbora-lerro lokala hutsik dago. Idatzi zerbait publikoki pilota biraka jartzeko!",
   "empty_column.direct": "Ez duzu mezu zuzenik oraindik. Baten bat bidali edo jasotzen duzunean, hemen agertuko da.",
@@ -128,7 +133,7 @@
   "empty_column.lists": "Ez duzu zerrendarik oraindik. Baten bat sortzen duzunean hemen agertuko da.",
   "empty_column.mutes": "Ez duzu erabiltzailerik mututu oraindik.",
   "empty_column.notifications": "Ez duzu jakinarazpenik oraindik. Jarri besteekin harremanetan elkarrizketa abiatzeko.",
-  "empty_column.public": "Ez dago ezer hemen! Idatzi zerbait publikoki edo jarraitu eskuz beste instantzia batzuetako erabiltzailean hau betetzeko",
+  "empty_column.public": "Ez dago ezer hemen! Idatzi zerbait publikoki edo jarraitu eskuz beste zerbitzari batzuetako erabiltzaileak hau betetzen joateko",
   "follow_request.authorize": "Baimendu",
   "follow_request.reject": "Ukatu",
   "getting_started.developers": "Garatzaileak",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "eta {osagarria}",
   "hashtag.column_header.tag_mode.any": "edo {osagarria}",
   "hashtag.column_header.tag_mode.none": "gabe {osagarria}",
+  "hashtag.column_settings.select.no_options_message": "Ez da proposamenik aurkitu",
+  "hashtag.column_settings.select.placeholder": "Sartu traolak…",
   "hashtag.column_settings.tag_mode.all": "Hauetako guztiak",
   "hashtag.column_settings.tag_mode.any": "Hautako edozein",
   "hashtag.column_settings.tag_mode.none": "Hauetako bat ere ez",
@@ -149,12 +156,15 @@
   "home.column_settings.basic": "Oinarrizkoa",
   "home.column_settings.show_reblogs": "Erakutsi bultzadak",
   "home.column_settings.show_replies": "Erakutsi erantzunak",
+  "intervals.full.days": "{number, plural, one {egun #} other {# egun}}",
+  "intervals.full.hours": "{number, plural, one {ordu #} other {# ordu}}",
+  "intervals.full.minutes": "{number, plural, one {minutu #} other {# minutu}}",
   "introduction.federation.action": "Hurrengoa",
-  "introduction.federation.federated.headline": "Federated",
+  "introduction.federation.federated.headline": "Federatua",
   "introduction.federation.federated.text": "Fedibertsoko beste zerbitzarietako bidalketa publikoak federatutako denbora-lerroan agertuko dira.",
-  "introduction.federation.home.headline": "Home",
+  "introduction.federation.home.headline": "Hasiera",
   "introduction.federation.home.text": "Jarraitzen dituzun horien mezuak zure hasierako jarioan agertuko dira. Edozein zerbitzariko edonor jarraitu dezakezu!",
-  "introduction.federation.local.headline": "Local",
+  "introduction.federation.local.headline": "Lokala",
   "introduction.federation.local.text": "Zure zerbitzari berean dauden horien mezu publikoak denbora-lerro lokalean agertuko dira.",
   "introduction.interactions.action": "Amaitu tutoriala!",
   "introduction.interactions.favourite.headline": "Gogokoa",
@@ -171,10 +181,10 @@
   "keyboard_shortcuts.boost": "bultzada ematea",
   "keyboard_shortcuts.column": "mezu bat zutabe batean fokatzea",
   "keyboard_shortcuts.compose": "testua konposatzeko arean fokatzea",
-  "keyboard_shortcuts.description": "Description",
+  "keyboard_shortcuts.description": "Deskripzioa",
   "keyboard_shortcuts.direct": "mezu zuzenen zutabea irekitzeko",
   "keyboard_shortcuts.down": "zerrendan behera mugitzea",
-  "keyboard_shortcuts.enter": "to open status",
+  "keyboard_shortcuts.enter": "mezua irekitzeko",
   "keyboard_shortcuts.favourite": "gogoko egitea",
   "keyboard_shortcuts.favourites": "gogokoen zerrenda irekitzeko",
   "keyboard_shortcuts.federated": "federatutako denbora-lerroa irekitzeko",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "bilaketan fokua jartzea",
   "keyboard_shortcuts.start": "\"Menua\" zutabea irekitzeko",
   "keyboard_shortcuts.toggle_hidden": "testua erakustea/ezkutatzea abisu baten atzean",
+  "keyboard_shortcuts.toggle_sensitivity": "multimedia erakutsi/ezkutatzeko",
   "keyboard_shortcuts.toot": "toot berria hastea",
   "keyboard_shortcuts.unfocus": "testua konposatzeko area / bilaketatik fokua kentzea",
   "keyboard_shortcuts.up": "zerrendan gora mugitzea",
   "lightbox.close": "Itxi",
   "lightbox.next": "Hurrengoa",
   "lightbox.previous": "Aurrekoa",
+  "lightbox.view_context": "Ikusi testuingurua",
   "lists.account.add": "Gehitu zerrendara",
   "lists.account.remove": "Kendu zerrendatik",
   "lists.delete": "Ezabatu zerrenda",
   "lists.edit": "Editatu zerrenda",
+  "lists.edit.submit": "Aldatu izenburua",
   "lists.new.create": "Gehitu zerrenda",
   "lists.new.title_placeholder": "Zerrenda berriaren izena",
   "lists.search": "Bilatu jarraitzen dituzun pertsonen artean",
@@ -224,19 +237,22 @@
   "navigation_bar.favourites": "Gogokoak",
   "navigation_bar.filters": "Mutututako hitzak",
   "navigation_bar.follow_requests": "Jarraitzeko eskariak",
-  "navigation_bar.info": "Instantzia honi buruz",
+  "navigation_bar.follows_and_followers": "Jarraitutakoak eta jarraitzaileak",
+  "navigation_bar.info": "Zerbitzari honi buruz",
   "navigation_bar.keyboard_shortcuts": "Laster-teklak",
   "navigation_bar.lists": "Zerrendak",
   "navigation_bar.logout": "Amaitu saioa",
   "navigation_bar.mutes": "Mutututako erabiltzaileak",
-  "navigation_bar.personal": "Personal",
+  "navigation_bar.personal": "Pertsonala",
   "navigation_bar.pins": "Finkatutako toot-ak",
   "navigation_bar.preferences": "Hobespenak",
+  "navigation_bar.profile_directory": "Profilen direktorioa",
   "navigation_bar.public_timeline": "Federatutako denbora-lerroa",
   "navigation_bar.security": "Segurtasuna",
   "notification.favourite": "{name}(e)k zure mezua gogoko du",
   "notification.follow": "{name}(e)k jarraitzen zaitu",
   "notification.mention": "{name}(e)k aipatu zaitu",
+  "notification.poll": "Zuk erantzun duzun inkesta bat bukatu da",
   "notification.reblog": "{name}(e)k bultzada eman dio zure mezuari",
   "notifications.clear": "Garbitu jakinarazpenak",
   "notifications.clear_confirmation": "Ziur zure jakinarazpen guztiak behin betirako garbitu nahi dituzula?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Erakutsi",
   "notifications.column_settings.follow": "Jarraitzaile berriak:",
   "notifications.column_settings.mention": "Aipamenak:",
+  "notifications.column_settings.poll": "Inkestaren emaitzak:",
   "notifications.column_settings.push": "Push jakinarazpenak",
   "notifications.column_settings.reblog": "Bultzadak:",
   "notifications.column_settings.show": "Erakutsi zutabean",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Gogokoak",
   "notifications.filter.follows": "Jarraipenak",
   "notifications.filter.mentions": "Aipamenak",
+  "notifications.filter.polls": "Inkestaren emaitza",
   "notifications.group": "{count} jakinarazpen",
+  "poll.closed": "Itxita",
+  "poll.refresh": "Berritu",
+  "poll.total_votes": "{count, plural, one {boto #} other {# boto}}",
+  "poll.vote": "Bozkatu",
+  "poll_button.add_poll": "Gehitu inkesta bat",
+  "poll_button.remove_poll": "Kendu inkesta",
   "privacy.change": "Doitu mezuaren pribatutasuna",
   "privacy.direct.long": "Bidali aipatutako erabiltzaileei besterik ez",
   "privacy.direct.short": "Zuzena",
@@ -276,27 +300,27 @@
   "reply_indicator.cancel": "Utzi",
   "report.forward": "Birbidali hona: {target}",
   "report.forward_hint": "Kontu hau beste zerbitzari batekoa da. Bidali txostenaren kopia anonimo hara ere?",
-  "report.hint": "Txostena zure instantziaren moderatzaileei bidaliko zaio. Kontu hau zergatik salatzen duzun behean azaldu dezakezu:",
+  "report.hint": "Txostena zure zerbitzariaren moderatzaileei bidaliko zaie. Kontu hau zergatik salatzen duzun behean azaldu dezakezu:",
   "report.placeholder": "Iruzkin gehigarriak",
-  "report.submit": "Submit",
+  "report.submit": "Bidali",
   "report.target": "{target} salatzen",
   "search.placeholder": "Bilatu",
   "search_popout.search_format": "Bilaketa aurreratuaren formatua",
   "search_popout.tips.full_text": "Testu hutsarekin zuk idatzitako mezuak, gogokoak, bultzadak edo aipamenak aurkitu ditzakezu, bat datozen erabiltzaile-izenak, pantaila-izenak, eta traolak.",
   "search_popout.tips.hashtag": "traola",
-  "search_popout.tips.status": "status",
+  "search_popout.tips.status": "mezua",
   "search_popout.tips.text": "Testu hutsak pantaila-izenak, erabiltzaile-izenak eta traolak bilatzen ditu",
   "search_popout.tips.user": "erabiltzailea",
   "search_results.accounts": "Jendea",
   "search_results.hashtags": "Traolak",
   "search_results.statuses": "Toot-ak",
-  "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
-  "standalone.public_title": "Begiradatxo bat...",
-  "status.admin_account": "Open moderation interface for @{name}",
-  "status.admin_status": "Open this status in the moderation interface",
-  "status.block": "Block @{name}",
+  "search_results.total": "{count, number} {count, plural, one {emaitza} other {emaitzak}}",
+  "status.admin_account": "Ireki @{name} erabiltzailearen moderazio interfazea",
+  "status.admin_status": "Ireki mezu hau moderazio interfazean",
+  "status.block": "Blokeatu @{name}",
   "status.cancel_reblog_private": "Kendu bultzada",
   "status.cannot_reblog": "Mezu honi ezin zaio bultzada eman",
+  "status.copy": "Kopiatu mezuaren esteka",
   "status.delete": "Ezabatu",
   "status.detailed_status": "Elkarrizketaren ikuspegi xehetsua",
   "status.direct": "Mezu zuzena @{name}(r)i",
@@ -321,7 +345,6 @@
   "status.reply": "Erantzun",
   "status.replyAll": "Erantzun harian",
   "status.report": "Salatu @{name}",
-  "status.sensitive_toggle": "Egin klik ikusteko",
   "status.sensitive_warning": "Kontuz: Eduki hunkigarria",
   "status.share": "Partekatu",
   "status.show_less": "Erakutsi gutxiago",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Lokala",
   "tabs_bar.notifications": "Jakinarazpenak",
   "tabs_bar.search": "Bilatu",
+  "time_remaining.days": "{number, plural, one {egun #} other {# egun}} amaitzeko",
+  "time_remaining.hours": "{number, plural, one {ordu #} other {# ordu}} amaitzeko",
+  "time_remaining.minutes": "{number, plural, one {minutu #} other {# minutu}} amaitzeko",
+  "time_remaining.moments": "Amaitzekotan",
+  "time_remaining.seconds": "{number, plural, one {segundo #} other {# segundo}} amaitzeko",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} hitz egiten",
   "ui.beforeunload": "Zure zirriborroa galduko da Mastodon uzten baduzu.",
   "upload_area.title": "Arrastatu eta jaregin igotzeko",
   "upload_button.label": "Gehitu multimedia  (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "Fitxategi igoera muga gaindituta.",
+  "upload_error.poll": "Ez da inkestetan fitxategiak igotzea onartzen.",
   "upload_form.description": "Deskribatu ikusmen arazoak dituztenentzat",
   "upload_form.focus": "Aldatu aurrebista",
   "upload_form.undo": "Ezabatu",
@@ -349,10 +379,10 @@
   "video.close": "Itxi bideoa",
   "video.exit_fullscreen": "Irten pantaila osotik",
   "video.expand": "Hedatu bideoa",
-  "video.fullscreen": "Full screen",
+  "video.fullscreen": "Pantaila osoa",
   "video.hide": "Ezkutatu bideoa",
   "video.mute": "Mututu soinua",
-  "video.pause": "Pause",
+  "video.pause": "Pausatu",
   "video.play": "Jo",
   "video.unmute": "Desmututu soinua"
 }
diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json
index b11d88d8757b33d3c0cc0c9786c56e163eeabaf4..68d231ce95f436939e14bbd31c6ccfc66c022f62 100644
--- a/app/javascript/mastodon/locales/fa.json
+++ b/app/javascript/mastodon/locales/fa.json
@@ -1,11 +1,10 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "افزودن یا حذف از فهرست‌ها",
   "account.badges.bot": "ربات",
   "account.block": "مسدودسازی @{name}",
   "account.block_domain": "پنهان‌سازی همه چیز از سرور {domain}",
   "account.blocked": "مسدودشده",
   "account.direct": "پیغام خصوصی به @{name}",
-  "account.disclaimer_full": "اطلاعات زیر ممکن است نمایهٔ این کاربر را به تمامی نشان ندهد.",
   "account.domain_blocked": "دامین پنهان‌شده",
   "account.edit_profile": "ویرایش نمایه",
   "account.endorse": "نمایش در نمایه",
@@ -17,7 +16,7 @@
   "account.follows_you": "پیگیر شماست",
   "account.hide_reblogs": "پنهان کردن بازبوق‌های @{name}",
   "account.link_verified_on": "مالکیت این نشانی در تایخ {date} بررسی شد",
-  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
+  "account.locked_info": "این حساب خصوصی است. صاحب این حساب تصمیم می‌گیرد که چه کسی می‌تواند پیگیرش باشد.",
   "account.media": "عکس و ویدیو",
   "account.mention": "نام‌بردن از @{name}",
   "account.moved_to": "{name} منتقل شده است به:",
@@ -36,7 +35,6 @@
   "account.unfollow": "پایان پیگیری",
   "account.unmute": "باصدا کردن @{name}",
   "account.unmute_notifications": "باصداکردن اعلان‌ها از طرف @{name}",
-  "account.view_full_profile": "نمایش نمایهٔ کامل",
   "alert.unexpected.message": "خطای پیش‌بینی‌نشده‌ای رخ داد.",
   "alert.unexpected.title": "ای وای!",
   "boost_modal.combo": "دکمهٔ {combo} را بزنید تا دیگر این را نبینید",
@@ -73,19 +71,25 @@
   "compose_form.lock_disclaimer": "حساب شما {locked} نیست. هر کسی می‌تواند پیگیر شما شود و نوشته‌های ویژهٔ پیگیران شما را ببیند.",
   "compose_form.lock_disclaimer.lock": "قفل",
   "compose_form.placeholder": "تازه چه خبر؟",
+  "compose_form.poll.add_option": "افزودن گزینه",
+  "compose_form.poll.duration": "مدت نظرسنجی",
+  "compose_form.poll.option_placeholder": "گزینهٔ {number}",
+  "compose_form.poll.remove_option": "حذف این گزینه",
   "compose_form.publish": "بوق",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "علامت‌گذاری به عنوان حساس",
   "compose_form.sensitive.marked": "این تصویر به عنوان حساس علامت‌گذاری شده",
   "compose_form.sensitive.unmarked": "این تصویر به عنوان حساس علامت‌گذاری نشده",
   "compose_form.spoiler.marked": "نوشته پشت هشدار محتوا پنهان است",
   "compose_form.spoiler.unmarked": "نوشته پنهان نیست",
   "compose_form.spoiler_placeholder": "هشدار محتوا",
   "confirmation_modal.cancel": "بی‌خیال",
+  "confirmations.block.block_and_report": "مسدودسازی و گزارش",
   "confirmations.block.confirm": "مسدود کن",
   "confirmations.block.message": "آیا واقعاً می‌خواهید {name} را مسدود کنید؟",
   "confirmations.delete.confirm": "پاک کن",
   "confirmations.delete.message": "آیا واقعاً می‌خواهید این نوشته را پاک کنید؟",
-  "confirmations.delete_list.confirm": "Delete",
+  "confirmations.delete_list.confirm": "پاک کن",
   "confirmations.delete_list.message": "آیا واقعاً می‌خواهید این فهرست را برای همیشه پاک کنید؟",
   "confirmations.domain_block.confirm": "پنهان‌سازی کل دامین",
   "confirmations.domain_block.message": "آیا جدی جدی می‌خواهید کل دامین {domain} را مسدود کنید؟ بیشتر وقت‌ها مسدودکردن یا بی‌صداکردن چند حساب کاربری خاص کافی است و توصیه می‌شود. پس از این کار شما هیچ نوشته‌ای را از این دامین در فهرست نوشته‌های عمومی یا اعلان‌هایتان نخواهید دید. پیگیران شما از این دامین هم حذف خواهد شد.",
@@ -113,7 +117,8 @@
   "emoji_button.search_results": "نتایج جستجو",
   "emoji_button.symbols": "نمادها",
   "emoji_button.travel": "سفر و مکان",
-  "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_timeline": "هیچ بوقی این‌جا نیست!",
+  "empty_column.account_unavailable": "نمایهٔ ناموجود",
   "empty_column.blocks": "شما هنوز هیچ کسی را مسدود نکرده‌اید.",
   "empty_column.community": "فهرست نوشته‌های محلی خالی است. چیزی بنویسید تا چرخش بچرخد!",
   "empty_column.direct": "شما هیچ پیغام مستقیمی ندارید. اگر چنین پیغامی بگیرید یا بفرستید این‌جا نمایش خواهد یافت.",
@@ -128,44 +133,49 @@
   "empty_column.lists": "شما هنوز هیچ فهرستی ندارید. اگر فهرستی بسازید، این‌جا نمایش خواهد یافت.",
   "empty_column.mutes": "شما هنوز هیچ کاربری را بی‌صدا نکرده‌اید.",
   "empty_column.notifications": "هنوز هیچ اعلانی ندارید. به نوشته‌های دیگران واکنش نشان دهید تا گفتگو آغاز شود.",
-  "empty_column.public": "این‌جا هنوز چیزی نیست! خودتان چیزی بنویسید یا کاربران دیگر را پی بگیرید تا این‌جا پر شود",
+  "empty_column.public": "این‌جا هنوز چیزی نیست! خودتان چیزی بنویسید یا کاربران سرورهای دیگر را پی بگیرید تا این‌جا پر شود",
   "follow_request.authorize": "اجازه دهید",
   "follow_request.reject": "اجازه ندهید",
   "getting_started.developers": "برای برنامه‌نویسان",
-  "getting_started.directory": "Profile directory",
+  "getting_started.directory": "فهرست گزیدهٔ کاربران",
   "getting_started.documentation": "راهنما",
   "getting_started.heading": "آغاز کنید",
   "getting_started.invite": "دعوت از دوستان",
   "getting_started.open_source_notice": "ماستدون یک نرم‌افزار آزاد است. می‌توانید در ساخت آن مشارکت کنید یا مشکلاتش را در {github} گزارش دهید.",
   "getting_started.security": "امنیت",
   "getting_started.terms": "شرایط استفاده",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
-  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "hashtag.column_header.tag_mode.all": "Ùˆ {additional}",
+  "hashtag.column_header.tag_mode.any": "یا {additional}",
+  "hashtag.column_header.tag_mode.none": "بدون {additional}",
+  "hashtag.column_settings.select.no_options_message": "هیچ پیشنهادی پیدا نشد",
+  "hashtag.column_settings.select.placeholder": "برچسب‌ها را وارد کنید…",
+  "hashtag.column_settings.tag_mode.all": "همهٔ این‌ها",
+  "hashtag.column_settings.tag_mode.any": "هرکدام از این‌ها",
+  "hashtag.column_settings.tag_mode.none": "هیچ‌کدام از این‌ها",
+  "hashtag.column_settings.tag_toggle": "برچسب‌های بیشتری به این ستون بیفزایید",
   "home.column_settings.basic": "اصلی",
   "home.column_settings.show_reblogs": "نمایش بازبوق‌ها",
   "home.column_settings.show_replies": "نمایش پاسخ‌ها",
-  "introduction.federation.action": "Next",
-  "introduction.federation.federated.headline": "Federated",
-  "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
-  "introduction.federation.home.headline": "Home",
-  "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
-  "introduction.federation.local.headline": "Local",
-  "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
-  "introduction.interactions.favourite.headline": "Favourite",
-  "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
-  "introduction.interactions.reblog.headline": "Boost",
-  "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
-  "introduction.interactions.reply.headline": "Reply",
-  "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
-  "introduction.welcome.action": "Let's go!",
-  "introduction.welcome.headline": "First steps",
-  "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
+  "intervals.full.days": "{number, plural, one {# روز} other {# روز}}",
+  "intervals.full.hours": "{number, plural, one {# ساعت} other {# ساعت}}",
+  "intervals.full.minutes": "{number, plural, one {# دقیقه} other {# دقیقه}}",
+  "introduction.federation.action": "بعدی",
+  "introduction.federation.federated.headline": "فهرست همهٔ سرورها",
+  "introduction.federation.federated.text": "نوشته‌های عمومی سرورهای دیگر در این فهرست نمایش می‌یابند.",
+  "introduction.federation.home.headline": "خانه",
+  "introduction.federation.home.text": "نوشته‌های کسانی که شما آن‌ها را پی می‌گیرید این‌جا نمایش می‌یابند. شما می‌توانید هر کسی را از هر سروری پی بگیرید!",
+  "introduction.federation.local.headline": "محلی",
+  "introduction.federation.local.text": "نوشته‌های عمومی کسانی که روی سرور شما هستند در فهرست نوشته‌های محلی نمایش می‌یابند.",
+  "introduction.interactions.action": "پایان خودآموز!",
+  "introduction.interactions.favourite.headline": "پسندیدن",
+  "introduction.interactions.favourite.text": "با پسندیدن یک بوق، شما آن را برای آینده ذخیره می‌کنید و به نویسنده می‌گویید که از بوقش خوشتان آمده.",
+  "introduction.interactions.reblog.headline": "بازبوقیدن",
+  "introduction.interactions.reblog.text": "اگر بخواهید نوشته‌ای را با پیگیران خودتان به اشتراک بگذارید، آن را بازمی‌بوقید.",
+  "introduction.interactions.reply.headline": "پاسخ",
+  "introduction.interactions.reply.text": "شما می‌توانید به بوق‌های خودتان و دیگران پاسخ دهید، تا همهٔ این بوق‌ها به شکل رشتهٔ به‌هم‌پیوسته‌ای در یک گفتگو درآیند.",
+  "introduction.welcome.action": "بزن بریم!",
+  "introduction.welcome.headline": "نخستین گام‌ها",
+  "introduction.welcome.text": "به دنیای شبکه‌های اجتماعی غیرمتمرکز خوش آمدید! به زودی می‌توانید نوشته‌های خودتان را منتشر کنید و با دوستانتان که روی سرورهای مختلفی هستند حرف بزنید. ولی این سرور، {domain}، با بقیه فرق دارد زیرا حساب شما روی آن ساخته شده است، پس نامش را یادتان نگه دارید.",
   "keyboard_shortcuts.back": "برای بازگشت",
   "keyboard_shortcuts.blocked": "برای گشودن کاربران بی‌صداشده",
   "keyboard_shortcuts.boost": "برای بازبوقیدن",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "برای فعال‌کردن جستجو",
   "keyboard_shortcuts.start": "برای گشودن ستون «آغاز کنید»",
   "keyboard_shortcuts.toggle_hidden": "برای نمایش/نهفتن نوشتهٔ پشت هشدار محتوا",
+  "keyboard_shortcuts.toggle_sensitivity": "برای نمایش/نهفتن عکس و ویدیو",
   "keyboard_shortcuts.toot": "برای آغاز یک بوق تازه",
   "keyboard_shortcuts.unfocus": "برای برداشتن توجه از نوشتن/جستجو",
   "keyboard_shortcuts.up": "برای بالا رفتن در فهرست",
   "lightbox.close": "بستن",
   "lightbox.next": "بعدی",
   "lightbox.previous": "قبلی",
+  "lightbox.view_context": "نمایش گفتگو",
   "lists.account.add": "افزودن به فهرست",
   "lists.account.remove": "پاک‌کردن از فهرست",
   "lists.delete": "حذف فهرست",
   "lists.edit": "ویرایش فهرست",
+  "lists.edit.submit": "تغییر عنوان",
   "lists.new.create": "افزودن فهرست",
   "lists.new.title_placeholder": "نام فهرست تازه",
   "lists.search": "بین کسانی که پی می‌گیرید بگردید",
@@ -224,7 +237,8 @@
   "navigation_bar.favourites": "پسندیده‌ها",
   "navigation_bar.filters": "واژگان بی‌صداشده",
   "navigation_bar.follow_requests": "درخواست‌های پیگیری",
-  "navigation_bar.info": "اطلاعات تکمیلی",
+  "navigation_bar.follows_and_followers": "پیگیری‌ها و پیگیران",
+  "navigation_bar.info": "دربارهٔ این سرور",
   "navigation_bar.keyboard_shortcuts": "میان‌برهای صفحه‌کلید",
   "navigation_bar.lists": "فهرست‌ها",
   "navigation_bar.logout": "خروج",
@@ -232,31 +246,41 @@
   "navigation_bar.personal": "شخصی",
   "navigation_bar.pins": "نوشته‌های ثابت",
   "navigation_bar.preferences": "ترجیحات",
+  "navigation_bar.profile_directory": "فهرست گزیدهٔ کاربران",
   "navigation_bar.public_timeline": "نوشته‌های همه‌جا",
   "navigation_bar.security": "امنیت",
   "notification.favourite": "‫{name}‬ نوشتهٔ شما را پسندید",
   "notification.follow": "‫{name}‬ پیگیر شما شد",
   "notification.mention": "‫{name}‬ از شما نام برد",
+  "notification.poll": "نظرسنجی‌ای که در آن رأی دادید به پایان رسیده است",
   "notification.reblog": "‫{name}‬ نوشتهٔ شما را بازبوقید",
   "notifications.clear": "پاک‌کردن اعلان‌ها",
   "notifications.clear_confirmation": "واقعاً می‌خواهید همهٔ اعلان‌هایتان را برای همیشه پاک کنید؟",
   "notifications.column_settings.alert": "اعلان در کامپیوتر",
   "notifications.column_settings.favourite": "پسندیده‌ها:",
-  "notifications.column_settings.filter_bar.advanced": "Display all categories",
-  "notifications.column_settings.filter_bar.category": "Quick filter bar",
-  "notifications.column_settings.filter_bar.show": "Show",
+  "notifications.column_settings.filter_bar.advanced": "نمایش همهٔ گروه‌ها",
+  "notifications.column_settings.filter_bar.category": "فیلتر سریع",
+  "notifications.column_settings.filter_bar.show": "نمایش",
   "notifications.column_settings.follow": "پیگیران تازه:",
   "notifications.column_settings.mention": "نام‌بردن‌ها:",
+  "notifications.column_settings.poll": "نتایج نظرسنجی:",
   "notifications.column_settings.push": "اعلان‌ها از سمت سرور",
   "notifications.column_settings.reblog": "بازبوق‌ها:",
   "notifications.column_settings.show": "نمایش در ستون",
   "notifications.column_settings.sound": "پخش صدا",
-  "notifications.filter.all": "All",
-  "notifications.filter.boosts": "Boosts",
-  "notifications.filter.favourites": "Favourites",
-  "notifications.filter.follows": "Follows",
-  "notifications.filter.mentions": "Mentions",
+  "notifications.filter.all": "همه",
+  "notifications.filter.boosts": "بازبوق‌ها",
+  "notifications.filter.favourites": "پسندیده‌ها",
+  "notifications.filter.follows": "پیگیری‌ها",
+  "notifications.filter.mentions": "گفتگوها",
+  "notifications.filter.polls": "نتایج نظرسنجی",
   "notifications.group": "{count} اعلان",
+  "poll.closed": "پایان‌یافته",
+  "poll.refresh": "به‌روزرسانی",
+  "poll.total_votes": "{count, plural, one {# رأی} other {# رأی}}",
+  "poll.vote": "رأی",
+  "poll_button.add_poll": "افزودن نظرسنجی",
+  "poll_button.remove_poll": "حذف نظرسنجی",
   "privacy.change": "تنظیم حریم خصوصی نوشته‌ها",
   "privacy.direct.long": "تنها به کاربران نام‌برده‌شده نشان بده",
   "privacy.direct.short": "مستقیم",
@@ -268,11 +292,11 @@
   "privacy.unlisted.short": "فهرست‌نشده",
   "regeneration_indicator.label": "در حال باز شدن…",
   "regeneration_indicator.sublabel": "این فهرست دارد آماده می‌شود!",
-  "relative_time.days": "{number}d",
-  "relative_time.hours": "{number}h",
+  "relative_time.days": "{number} روز",
+  "relative_time.hours": "{number} ساعت",
   "relative_time.just_now": "الان",
-  "relative_time.minutes": "{number}m",
-  "relative_time.seconds": "{number}s",
+  "relative_time.minutes": "{number} دقیقه",
+  "relative_time.seconds": "{number} ثانیه",
   "reply_indicator.cancel": "لغو",
   "report.forward": "فرستادن به {target}",
   "report.forward_hint": "این حساب در سرور دیگری ثبت شده. آیا می‌خواهید رونوشتی از این گزارش به طور ناشناس به آن‌جا هم فرستاده شود؟",
@@ -291,12 +315,12 @@
   "search_results.hashtags": "هشتگ‌ها",
   "search_results.statuses": "بوق‌ها",
   "search_results.total": "{count, number} {count, plural, one {نتیجه} other {نتیجه}}",
-  "standalone.public_title": "نگاهی به کاربران این سرور...",
-  "status.admin_account": "Open moderation interface for @{name}",
-  "status.admin_status": "Open this status in the moderation interface",
+  "status.admin_account": "محیط مدیریت مربوط به @{name} را باز کن",
+  "status.admin_status": "این نوشته را در محیط مدیریت باز کن",
   "status.block": "مسدودسازی @{name}",
   "status.cancel_reblog_private": "حذف بازبوق",
   "status.cannot_reblog": "این نوشته را نمی‌شود بازبوقید",
+  "status.copy": "رونوشت‌برداری از نشانی این نوشته",
   "status.delete": "پاک‌کردن",
   "status.detailed_status": "نمایش کامل گفتگو",
   "status.direct": "پیغام مستقیم به @{name}",
@@ -321,29 +345,35 @@
   "status.reply": "پاسخ",
   "status.replyAll": "به نوشته پاسخ دهید",
   "status.report": "گزارش دادن @{name}",
-  "status.sensitive_toggle": "برای دیدن کلیک کنید",
   "status.sensitive_warning": "محتوای حساس",
   "status.share": "هم‌رسانی",
   "status.show_less": "نهفتن",
   "status.show_less_all": "نمایش کمتر همه",
   "status.show_more": "نمایش",
   "status.show_more_all": "نمایش بیشتر همه",
-  "status.show_thread": "Show thread",
+  "status.show_thread": "نمایش گفتگو",
   "status.unmute_conversation": "باصداکردن گفتگو",
   "status.unpin": "برداشتن نوشتهٔ ثابت نمایه",
-  "suggestions.dismiss": "Dismiss suggestion",
-  "suggestions.header": "You might be interested in…",
+  "suggestions.dismiss": "پیشنهاد را نادیده بگیر",
+  "suggestions.header": "شاید این هم برایتان جالب باشد…",
   "tabs_bar.federated_timeline": "همگانی",
   "tabs_bar.home": "خانه",
   "tabs_bar.local_timeline": "محلی",
   "tabs_bar.notifications": "اعلان‌ها",
   "tabs_bar.search": "جستجو",
+  "time_remaining.days": "{number, plural, one {# روز} other {# روز}} باقی مانده",
+  "time_remaining.hours": "{number, plural, one {# ساعت} other {# ساعت}} باقی مانده",
+  "time_remaining.minutes": "{number, plural, one {# دقیقه} other {# دقیقه}} باقی مانده",
+  "time_remaining.moments": "زمان باقی‌مانده",
+  "time_remaining.seconds": "{number, plural, one {# ثانیه} other {# ثانیه}} باقی مانده",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {نفر نوشته است} other {نفر نوشته‌اند}}",
   "ui.beforeunload": "اگر از ماستدون خارج شوید پیش‌نویس شما پاک خواهد شد.",
   "upload_area.title": "برای بارگذاری به این‌جا بکشید",
   "upload_button.label": "افزودن عکس و ویدیو (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "از حد مجاز باگذاری فراتر رفتید.",
+  "upload_error.poll": "باگذاری پرونده در نظرسنجی‌ها ممکن نیست.",
   "upload_form.description": "نوشتهٔ توضیحی برای کم‌بینایان و نابینایان",
-  "upload_form.focus": "بریدن لبه‌ها",
+  "upload_form.focus": "تغییر پیش‌نمایش",
   "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 c8d2586723b89f24451f5f8e3b0a893f3a46d5e3..342a15bfb06ea9313096a174054f607d713771b5 100644
--- a/app/javascript/mastodon/locales/fi.json
+++ b/app/javascript/mastodon/locales/fi.json
@@ -1,11 +1,10 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "Lisää tai poista listoilta",
   "account.badges.bot": "Botti",
   "account.block": "Estä @{name}",
   "account.block_domain": "Piilota kaikki sisältö verkkotunnuksesta {domain}",
   "account.blocked": "Estetty",
   "account.direct": "Viesti käyttäjälle @{name}",
-  "account.disclaimer_full": "Alla olevat käyttäjän profiilitiedot saattavat olla epätäydellisiä.",
   "account.domain_blocked": "Verkko-osoite piilotettu",
   "account.edit_profile": "Muokkaa",
   "account.endorse": "Suosittele profiilissasi",
@@ -17,7 +16,7 @@
   "account.follows_you": "Seuraa sinua",
   "account.hide_reblogs": "Piilota buustaukset käyttäjältä @{name}",
   "account.link_verified_on": "Tämän linkin omistaja tarkistettiin {date}",
-  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
+  "account.locked_info": "Tämän tili on yksityinen. Käyttäjä vahvistaa itse kuka voi seurata häntä.",
   "account.media": "Media",
   "account.mention": "Mainitse @{name}",
   "account.moved_to": "{name} on muuttanut instanssiin:",
@@ -36,7 +35,6 @@
   "account.unfollow": "Lakkaa seuraamasta",
   "account.unmute": "Poista käyttäjän @{name} mykistys",
   "account.unmute_notifications": "Poista mykistys käyttäjän @{name} ilmoituksilta",
-  "account.view_full_profile": "Näytä koko profiili",
   "alert.unexpected.message": "Tapahtui odottamaton virhe.",
   "alert.unexpected.title": "Hups!",
   "boost_modal.combo": "Ensi kerralla voit ohittaa tämän painamalla {combo}",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "Tilisi ei ole {locked}. Kuka tahansa voi seurata tiliäsi ja nähdä vain seuraajille rajaamasi julkaisut.",
   "compose_form.lock_disclaimer.lock": "lukittu",
   "compose_form.placeholder": "Mitä mietit?",
+  "compose_form.poll.add_option": "Lisää valinta",
+  "compose_form.poll.duration": "Äänestyksen kesto",
+  "compose_form.poll.option_placeholder": "Valinta numero",
+  "compose_form.poll.remove_option": "Poista tämä valinta",
   "compose_form.publish": "Tuuttaa",
-  "compose_form.publish_loud": "{publish}!",
+  "compose_form.publish_loud": "Julkista!",
+  "compose_form.sensitive.hide": "Valitse tämä arkaluontoisena",
   "compose_form.sensitive.marked": "Media on merkitty arkaluontoiseksi",
   "compose_form.sensitive.unmarked": "Mediaa ei ole merkitty arkaluontoiseksi",
   "compose_form.spoiler.marked": "Teksti on piilotettu varoituksen taakse",
   "compose_form.spoiler.unmarked": "Teksti ei ole piilotettu",
   "compose_form.spoiler_placeholder": "Sisältövaroitus",
   "confirmation_modal.cancel": "Peruuta",
+  "confirmations.block.block_and_report": "Estä ja raportoi",
   "confirmations.block.confirm": "Estä",
   "confirmations.block.message": "Haluatko varmasti estää käyttäjän {name}?",
   "confirmations.delete.confirm": "Poista",
@@ -113,7 +117,8 @@
   "emoji_button.search_results": "Hakutulokset",
   "emoji_button.symbols": "Symbolit",
   "emoji_button.travel": "Matkailu",
-  "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_timeline": "Ei ole 'toots' täällä!",
+  "empty_column.account_unavailable": "Profiilia ei löydy",
   "empty_column.blocks": "Et ole vielä estänyt yhtään käyttäjää.",
   "empty_column.community": "Paikallinen aikajana on tyhjä. Homma lähtee käyntiin, kun kirjoitat jotain julkista!",
   "empty_column.direct": "Sinulla ei ole vielä yhtään viestiä yksittäiselle käyttäjälle. Kun lähetät tai vastaanotat sellaisen, se näkyy täällä.",
@@ -128,43 +133,48 @@
   "empty_column.lists": "Sinulla ei ole vielä yhtään listaa. Kun luot sellaisen, näkyy se tässä.",
   "empty_column.mutes": "Et ole mykistänyt vielä yhtään käyttäjää.",
   "empty_column.notifications": "Sinulle ei ole vielä ilmoituksia. Aloita keskustelu juttelemalla muille.",
-  "empty_column.public": "Täällä ei ole mitään! Saat sisältöä, kun kirjoitat jotain julkisesti tai käyt manuaalisesti seuraamassa muiden instanssien käyttäjiä",
+  "empty_column.public": "Täällä ei ole mitään! Saat sisältöä, kun kirjoitat jotain julkisesti tai käyt seuraamassa muiden instanssien käyttäjiä",
   "follow_request.authorize": "Valtuuta",
   "follow_request.reject": "Hylkää",
   "getting_started.developers": "Kehittäjille",
-  "getting_started.directory": "Profile directory",
-  "getting_started.documentation": "Documentation",
+  "getting_started.directory": "Profiili hakemisto",
+  "getting_started.documentation": "Documentaatio",
   "getting_started.heading": "Aloitus",
   "getting_started.invite": "Kutsu ihmisiä",
   "getting_started.open_source_notice": "Mastodon on avoimen lähdekoodin ohjelma. Voit avustaa tai raportoida ongelmia GitHubissa: {github}.",
   "getting_started.security": "Tunnukset",
   "getting_started.terms": "Käyttöehdot",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_header.tag_mode.all": "ja {additional}",
+  "hashtag.column_header.tag_mode.any": "tai {additional}",
+  "hashtag.column_header.tag_mode.none": "ilman {additional}",
+  "hashtag.column_settings.select.no_options_message": "Ehdostuta ei löydetty",
+  "hashtag.column_settings.select.placeholder": "Laita häshtägejä…",
+  "hashtag.column_settings.tag_mode.all": "Kaikki",
+  "hashtag.column_settings.tag_mode.any": "Kaikki",
+  "hashtag.column_settings.tag_mode.none": "Ei mikään",
   "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
   "home.column_settings.basic": "Perusasetukset",
   "home.column_settings.show_reblogs": "Näytä buustaukset",
   "home.column_settings.show_replies": "Näytä vastaukset",
-  "introduction.federation.action": "Next",
-  "introduction.federation.federated.headline": "Federated",
-  "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
-  "introduction.federation.home.headline": "Home",
-  "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
-  "introduction.federation.local.headline": "Local",
-  "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
-  "introduction.interactions.favourite.headline": "Favourite",
-  "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
-  "introduction.interactions.reblog.headline": "Boost",
-  "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
-  "introduction.interactions.reply.headline": "Reply",
-  "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
-  "introduction.welcome.action": "Let's go!",
-  "introduction.welcome.headline": "First steps",
+  "intervals.full.days": "Päivä päiviä",
+  "intervals.full.hours": "Tunti tunteja",
+  "intervals.full.minutes": "Minuuti minuuteja",
+  "introduction.federation.action": "Seuraava",
+  "introduction.federation.federated.headline": "Federaatioitettu",
+  "introduction.federation.federated.text": "Julkisia viestejä muiden serverien that is not a word aikoo tulla federoituun aikajanaan.",
+  "introduction.federation.home.headline": "Koti",
+  "introduction.federation.home.text": "Viestit muilta pelaajilta jota seuraat aikovat tulla koti sivuusi. Voit seurata ketä vain missä vain serverillä!",
+  "introduction.federation.local.headline": "Paikallinen",
+  "introduction.federation.local.text": "Julkiset viestit muilta pelaajilta samalla serverillä tulevat sinun paikalliseen aikajanaan.",
+  "introduction.interactions.action": "Suorita harjoitus!",
+  "introduction.interactions.favourite.headline": "Lempi",
+  "introduction.interactions.favourite.text": "Toot is not a word.",
+  "introduction.interactions.reblog.headline": "Nopeutus",
+  "introduction.interactions.reblog.text": "Toot is not a word",
+  "introduction.interactions.reply.headline": "Vastaa",
+  "introduction.interactions.reply.text": "TOOT IS NOT A WORD",
+  "introduction.welcome.action": "Mennään!",
+  "introduction.welcome.headline": "Ensimmäiset askeleet",
   "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
   "keyboard_shortcuts.back": "liiku taaksepäin",
   "keyboard_shortcuts.blocked": "avaa lista estetyistä käyttäjistä",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "siirry hakukenttään",
   "keyboard_shortcuts.start": "avaa \"Aloitus\" -sarake",
   "keyboard_shortcuts.toggle_hidden": "näytä/piilota sisältövaroituksella merkitty teksti",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "ala kirjoittaa uutta tuuttausta",
   "keyboard_shortcuts.unfocus": "siirry pois tekstikentästä tai hakukentästä",
   "keyboard_shortcuts.up": "siirry listassa ylöspäin",
   "lightbox.close": "Sulje",
   "lightbox.next": "Seuraava",
   "lightbox.previous": "Edellinen",
+  "lightbox.view_context": "View context",
   "lists.account.add": "Lisää listaan",
   "lists.account.remove": "Poista listasta",
   "lists.delete": "Poista lista",
   "lists.edit": "Muokkaa listaa",
+  "lists.edit.submit": "Change title",
   "lists.new.create": "Lisää lista",
   "lists.new.title_placeholder": "Uuden listan nimi",
   "lists.search": "Etsi seuraamistasi henkilöistä",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "Suosikit",
   "navigation_bar.filters": "Mykistetyt sanat",
   "navigation_bar.follow_requests": "Seuraamispyynnöt",
+  "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.info": "Tietoa tästä instanssista",
   "navigation_bar.keyboard_shortcuts": "Näppäinkomennot",
   "navigation_bar.lists": "Listat",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Personal",
   "navigation_bar.pins": "Kiinnitetyt tuuttaukset",
   "navigation_bar.preferences": "Asetukset",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "Yleinen aikajana",
   "navigation_bar.security": "Tunnukset",
   "notification.favourite": "{name} tykkäsi tilastasi",
   "notification.follow": "{name} seurasi sinua",
   "notification.mention": "{name} mainitsi sinut",
+  "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "{name} buustasi tilaasi",
   "notifications.clear": "Tyhjennä ilmoitukset",
   "notifications.clear_confirmation": "Haluatko varmasti poistaa kaikki ilmoitukset pysyvästi?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Show",
   "notifications.column_settings.follow": "Uudet seuraajat:",
   "notifications.column_settings.mention": "Maininnat:",
+  "notifications.column_settings.poll": "Poll results:",
   "notifications.column_settings.push": "Push-ilmoitukset",
   "notifications.column_settings.reblog": "Buustit:",
   "notifications.column_settings.show": "Näytä sarakkeessa",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favourites",
   "notifications.filter.follows": "Follows",
   "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
   "notifications.group": "{count} notifications",
+  "poll.closed": "Closed",
+  "poll.refresh": "Refresh",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
   "privacy.change": "Säädä tuuttauksen näkyvyyttä",
   "privacy.direct.long": "Julkaise vain mainituille käyttäjille",
   "privacy.direct.short": "Suora viesti",
@@ -291,12 +315,12 @@
   "search_results.hashtags": "Hashtagit",
   "search_results.statuses": "Tuuttaukset",
   "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
-  "standalone.public_title": "Kurkistus sisälle...",
   "status.admin_account": "Open moderation interface for @{name}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Estä @{name}",
   "status.cancel_reblog_private": "Peru buustaus",
   "status.cannot_reblog": "Tätä julkaisua ei voi buustata",
+  "status.copy": "Copy link to status",
   "status.delete": "Poista",
   "status.detailed_status": "Detailed conversation view",
   "status.direct": "Viesti käyttäjälle @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Vastaa",
   "status.replyAll": "Vastaa ketjuun",
   "status.report": "Raportoi @{name}",
-  "status.sensitive_toggle": "Klikkaa nähdäksesi",
   "status.sensitive_warning": "Arkaluontoista sisältöä",
   "status.share": "Jaa",
   "status.show_less": "Näytä vähemmän",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Paikallinen",
   "tabs_bar.notifications": "Ilmoitukset",
   "tabs_bar.search": "Hae",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
   "ui.beforeunload": "Luonnos häviää, jos poistut Mastodonista.",
   "upload_area.title": "Lataa raahaamalla ja pudottamalla tähän",
   "upload_button.label": "Lisää mediaa",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "upload_form.description": "Anna kuvaus näkörajoitteisia varten",
   "upload_form.focus": "Rajaa",
   "upload_form.undo": "Peru",
diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json
index 7628968879244b9e21781418621b6cce8727c4b8..06bb70e0285405faef10ecdb78e6018ab3fe9036 100644
--- a/app/javascript/mastodon/locales/fr.json
+++ b/app/javascript/mastodon/locales/fr.json
@@ -1,43 +1,41 @@
 {
   "account.add_or_remove_from_list": "Ajouter ou retirer des listes",
-  "account.badges.bot": "Bot",
+  "account.badges.bot": "Robot",
   "account.block": "Bloquer @{name}",
   "account.block_domain": "Tout masquer venant de {domain}",
   "account.blocked": "Bloqué",
   "account.direct": "Envoyer un message direct à @{name}",
-  "account.disclaimer_full": "Les données ci-dessous peuvent ne pas refléter ce profil dans sa totalité.",
   "account.domain_blocked": "Domaine caché",
   "account.edit_profile": "Modifier le profil",
   "account.endorse": "Figure sur le profil",
   "account.follow": "Suivre",
   "account.followers": "Abonné⋅e⋅s",
-  "account.followers.empty": "Personne ne suit cet utilisateur pour l’instant.",
+  "account.followers.empty": "Personne ne suit cet utilisateur·rice pour l’instant.",
   "account.follows": "Abonnements",
-  "account.follows.empty": "Cet utilisateur ne suit personne pour l’instant.",
+  "account.follows.empty": "Cet·te utilisateur·rice ne suit personne pour l’instant.",
   "account.follows_you": "Vous suit",
   "account.hide_reblogs": "Masquer les partages de @{name}",
   "account.link_verified_on": "La propriété de ce lien a été vérifiée le {date}",
   "account.locked_info": "Ce compte est verrouillé. Son propriétaire approuve manuellement qui peut le ou la suivre.",
   "account.media": "Média",
-  "account.mention": "Mentionner",
+  "account.mention": "Mentionner @{name}",
   "account.moved_to": "{name} a déménagé vers :",
   "account.mute": "Masquer @{name}",
   "account.mute_notifications": "Ignorer les notifications de @{name}",
   "account.muted": "Silencé",
   "account.posts": "Pouets",
   "account.posts_with_replies": "Pouets et réponses",
-  "account.report": "Signaler",
+  "account.report": "Signaler @{name}",
   "account.requested": "En attente d’approbation. Cliquez pour annuler la requête",
   "account.share": "Partager le profil de @{name}",
   "account.show_reblogs": "Afficher les partages de @{name}",
-  "account.unblock": "Débloquer",
+  "account.unblock": "Débloquer @{name}",
   "account.unblock_domain": "Ne plus masquer {domain}",
   "account.unendorse": "Ne figure pas sur le profil",
   "account.unfollow": "Ne plus suivre",
-  "account.unmute": "Ne plus masquer",
+  "account.unmute": "Ne plus masquer @{name}",
   "account.unmute_notifications": "Réactiver les notifications de @{name}",
-  "account.view_full_profile": "Afficher le profil complet",
-  "alert.unexpected.message": "Une erreur non attendue s’est produite.",
+  "alert.unexpected.message": "Une erreur inattendue s’est produite.",
   "alert.unexpected.title": "Oups !",
   "boost_modal.combo": "Vous pouvez appuyer sur {combo} pour pouvoir passer ceci, la prochaine fois",
   "bundle_column_error.body": "Une erreur s’est produite lors du chargement de ce composant.",
@@ -73,20 +71,26 @@
   "compose_form.lock_disclaimer": "Votre compte n’est pas {locked}. Tout le monde peut vous suivre et voir vos pouets privés.",
   "compose_form.lock_disclaimer.lock": "verrouillé",
   "compose_form.placeholder": "Qu’avez-vous en tête ?",
+  "compose_form.poll.add_option": "Ajouter un choix",
+  "compose_form.poll.duration": "Durée du sondage",
+  "compose_form.poll.option_placeholder": "Choix {number}",
+  "compose_form.poll.remove_option": "Supprimer ce choix",
   "compose_form.publish": "Pouet",
   "compose_form.publish_loud": "{publish} !",
+  "compose_form.sensitive.hide": "Marquer le média comme sensible",
   "compose_form.sensitive.marked": "Média marqué comme sensible",
   "compose_form.sensitive.unmarked": "Média non marqué comme sensible",
   "compose_form.spoiler.marked": "Le texte est caché derrière un avertissement",
   "compose_form.spoiler.unmarked": "Le texte n’est pas caché",
   "compose_form.spoiler_placeholder": "Écrivez ici votre avertissement",
   "confirmation_modal.cancel": "Annuler",
+  "confirmations.block.block_and_report": "Bloquer et signaler",
   "confirmations.block.confirm": "Bloquer",
   "confirmations.block.message": "Confirmez-vous le blocage de {name} ?",
   "confirmations.delete.confirm": "Supprimer",
   "confirmations.delete.message": "Confirmez-vous la suppression de ce pouet ?",
   "confirmations.delete_list.confirm": "Supprimer",
-  "confirmations.delete_list.message": "Êtes-vous sûr de vouloir supprimer définitivement cette liste ?",
+  "confirmations.delete_list.message": "Êtes-vous sûr·e de vouloir supprimer définitivement cette liste ?",
   "confirmations.domain_block.confirm": "Masquer le domaine entier",
   "confirmations.domain_block.message": "Êtes-vous vraiment, vraiment sûr⋅e de vouloir bloquer {domain} en entier ? Dans la plupart des cas, quelques blocages ou masquages ciblés sont suffisants et préférables. Vous ne verrez plus de contenu provenant de ce domaine, ni dans fils publics, ni dans vos notifications. Vos abonné·e·s utilisant ce domaine seront retiré·e·s.",
   "confirmations.mute.confirm": "Masquer",
@@ -114,7 +118,8 @@
   "emoji_button.symbols": "Symboles",
   "emoji_button.travel": "Lieux & Voyages",
   "empty_column.account_timeline": "Aucun pouet ici !",
-  "empty_column.blocks": "Vous n’avez bloqué aucun utilisateur pour le moment.",
+  "empty_column.account_unavailable": "Profil non disponible",
+  "empty_column.blocks": "Vous n’avez bloqué aucun·e utilisateur·rice pour le moment.",
   "empty_column.community": "Le fil public local est vide. Écrivez donc quelque chose pour le remplir !",
   "empty_column.direct": "Vous n’avez pas encore de messages directs. Lorsque vous en enverrez ou recevrez un, il s’affichera ici.",
   "empty_column.domain_blocks": "Il n’y a aucun domaine caché pour le moment.",
@@ -126,12 +131,12 @@
   "empty_column.home.public_timeline": "le fil public",
   "empty_column.list": "Il n’y a rien dans cette liste pour l’instant. Dès que des personnes de cette liste publieront de nouveaux statuts, ils apparaîtront ici.",
   "empty_column.lists": "Vous n’avez pas encore de liste. Lorsque vous en créerez une, elle apparaîtra ici.",
-  "empty_column.mutes": "Vous n’avez pas encore mis des utilisateurs en silence.",
+  "empty_column.mutes": "Vous n’avez pas encore mis d'utilisateur·rice·s en silence.",
   "empty_column.notifications": "Vous n’avez pas encore de notification. Interagissez avec d’autres personnes pour débuter la conversation.",
   "empty_column.public": "Il n’y a rien ici ! Écrivez quelque chose publiquement, ou bien suivez manuellement des personnes d’autres instances pour remplir le fil public",
   "follow_request.authorize": "Accepter",
   "follow_request.reject": "Rejeter",
-  "getting_started.developers": "Développeurs",
+  "getting_started.developers": "Développeur·euse·s",
   "getting_started.directory": "Annuaire des profils",
   "getting_started.documentation": "Documentation",
   "getting_started.heading": "Pour commencer",
@@ -142,40 +147,45 @@
   "hashtag.column_header.tag_mode.all": "et {additional}",
   "hashtag.column_header.tag_mode.any": "ou {additional}",
   "hashtag.column_header.tag_mode.none": "sans {additional}",
+  "hashtag.column_settings.select.no_options_message": "Aucune suggestion trouvée",
+  "hashtag.column_settings.select.placeholder": "Ajouter des hashtags…",
   "hashtag.column_settings.tag_mode.all": "Tous ces éléments",
   "hashtag.column_settings.tag_mode.any": "Au moins un de ces éléments",
   "hashtag.column_settings.tag_mode.none": "Aucun de ces éléments",
-  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "hashtag.column_settings.tag_toggle": "Inclure des tags additionnels dans cette colonne",
   "home.column_settings.basic": "Basique",
   "home.column_settings.show_reblogs": "Afficher les partages",
   "home.column_settings.show_replies": "Afficher les réponses",
+  "intervals.full.days": "{number, plural, one {# jour} other {# jours}}",
+  "intervals.full.hours": "{number, plural, one {# heure} other {# heures}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
   "introduction.federation.action": "Suivant",
-  "introduction.federation.federated.headline": "Federated",
+  "introduction.federation.federated.headline": "Fil public global",
   "introduction.federation.federated.text": "Les messages publics provenant d'autres serveurs du fediverse apparaîtront dans le fil public global.",
-  "introduction.federation.home.headline": "Home",
+  "introduction.federation.home.headline": "Accueil",
   "introduction.federation.home.text": "Les messages des personnes que vous suivez apparaîtront dans votre fil d'accueil. Vous pouvez suivre n'importe qui sur n'importe quel serveur !",
-  "introduction.federation.local.headline": "Local",
+  "introduction.federation.local.headline": "Fil public local",
   "introduction.federation.local.text": "Les messages publics de personnes se trouvant sur le même serveur que vous apparaîtront sur le fil public local.",
   "introduction.interactions.action": "Finir le tutoriel !",
   "introduction.interactions.favourite.headline": "Favoris",
-  "introduction.interactions.favourite.text": "Vous pouvez garder un pouet pour plus tard, et faire savoir à l'auteur que vous l'avez aimé, en le favorisant.",
+  "introduction.interactions.favourite.text": "Vous pouvez garder un pouet pour plus tard, et faire savoir à son auteur·ice que vous l'avez aimé, en le favorisant.",
   "introduction.interactions.reblog.headline": "Repartager",
-  "introduction.interactions.reblog.text": "Vous pouvez partager les pouets d'autres personnes avec vos suiveurs en les repartageant.",
+  "introduction.interactions.reblog.text": "Vous pouvez partager les pouets d'autres personnes avec vos abonné·e·s en les repartageant.",
   "introduction.interactions.reply.headline": "Répondre",
   "introduction.interactions.reply.text": "Vous pouvez répondre aux pouets d'autres personnes et à vos propres pouets, ce qui les enchaînera dans une conversation.",
   "introduction.welcome.action": "Allons-y !",
   "introduction.welcome.headline": "Premiers pas",
   "introduction.welcome.text": "Bienvenue dans le fediverse ! Dans quelques instants, vous pourrez diffuser des messages et parler à vos amis sur une grande variété de serveurs. Mais ce serveur, {domain}, est spécial - il héberge votre profil, alors souvenez-vous de son nom.",
-  "keyboard_shortcuts.back": "revenir en arrière",
-  "keyboard_shortcuts.blocked": "pour ouvrir une liste d’utilisateurs bloqués",
-  "keyboard_shortcuts.boost": "partager",
-  "keyboard_shortcuts.column": "focaliser un statut dans l’une des colonnes",
+  "keyboard_shortcuts.back": "pour revenir en arrière",
+  "keyboard_shortcuts.blocked": "pour ouvrir une liste d’utilisateur·rice·s bloqué·e·s",
+  "keyboard_shortcuts.boost": "pour partager",
+  "keyboard_shortcuts.column": "pour focaliser un statut dans l’une des colonnes",
   "keyboard_shortcuts.compose": "pour centrer la zone de rédaction",
   "keyboard_shortcuts.description": "Description",
   "keyboard_shortcuts.direct": "pour ouvrir une colonne des messages directs",
   "keyboard_shortcuts.down": "pour descendre dans la liste",
   "keyboard_shortcuts.enter": "pour ouvrir le statut",
-  "keyboard_shortcuts.favourite": "vers les favoris",
+  "keyboard_shortcuts.favourite": "pour ajouter aux favoris",
   "keyboard_shortcuts.favourites": "pour ouvrir une liste de favoris",
   "keyboard_shortcuts.federated": "pour ouvrir le fil public global",
   "keyboard_shortcuts.heading": "Raccourcis clavier",
@@ -184,7 +194,7 @@
   "keyboard_shortcuts.legend": "pour afficher cette légende",
   "keyboard_shortcuts.local": "pour ouvrir le fil public local",
   "keyboard_shortcuts.mention": "pour mentionner l’auteur·rice",
-  "keyboard_shortcuts.muted": "pour ouvrir la liste des utilisateurs rendus muets",
+  "keyboard_shortcuts.muted": "pour ouvrir la liste des utilisateur·rice·s rendu·e·s muet·te·s",
   "keyboard_shortcuts.my_profile": "pour ouvrir votre profil",
   "keyboard_shortcuts.notifications": "pour ouvrir votre colonne de notifications",
   "keyboard_shortcuts.pinned": "pour ouvrir une liste des pouets épinglés",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "pour cibler la recherche",
   "keyboard_shortcuts.start": "pour ouvrir la colonne \"pour commencer\"",
   "keyboard_shortcuts.toggle_hidden": "pour afficher/cacher un texte derrière CW",
+  "keyboard_shortcuts.toggle_sensitivity": "pour afficher/cacher les médias",
   "keyboard_shortcuts.toot": "pour démarrer un tout nouveau pouet",
-  "keyboard_shortcuts.unfocus": "pour recentrer composer textarea/search",
+  "keyboard_shortcuts.unfocus": "pour quitter la zone de composition/recherche",
   "keyboard_shortcuts.up": "pour remonter dans la liste",
   "lightbox.close": "Fermer",
   "lightbox.next": "Suivant",
   "lightbox.previous": "Précédent",
+  "lightbox.view_context": "Voir le contexte",
   "lists.account.add": "Ajouter à la liste",
   "lists.account.remove": "Supprimer de la liste",
   "lists.delete": "Effacer la liste",
   "lists.edit": "Éditer la liste",
+  "lists.edit.submit": "Changer le titre",
   "lists.new.create": "Ajouter une liste",
   "lists.new.title_placeholder": "Titre de la nouvelle liste",
   "lists.search": "Rechercher parmi les gens que vous suivez",
@@ -224,29 +237,33 @@
   "navigation_bar.favourites": "Favoris",
   "navigation_bar.filters": "Mots silenciés",
   "navigation_bar.follow_requests": "Demandes de suivi",
+  "navigation_bar.follows_and_followers": "Abonnements et abonné⋅e·s",
   "navigation_bar.info": "Plus d’informations",
-  "navigation_bar.keyboard_shortcuts": "Raccourcis-clavier",
+  "navigation_bar.keyboard_shortcuts": "Raccourcis clavier",
   "navigation_bar.lists": "Listes",
   "navigation_bar.logout": "Déconnexion",
   "navigation_bar.mutes": "Comptes masqués",
-  "navigation_bar.personal": "Personal",
+  "navigation_bar.personal": "Personnel",
   "navigation_bar.pins": "Pouets épinglés",
   "navigation_bar.preferences": "Préférences",
+  "navigation_bar.profile_directory": "Annuaire des profils",
   "navigation_bar.public_timeline": "Fil public global",
   "navigation_bar.security": "Sécurité",
   "notification.favourite": "{name} a ajouté à ses favoris :",
   "notification.follow": "{name} vous suit",
-  "notification.mention": "{name} vous a mentionné⋅e :",
+  "notification.mention": "{name} vous a mentionné :",
+  "notification.poll": "Un sondage auquel vous avez participé vient de se terminer",
   "notification.reblog": "{name} a partagé votre statut :",
   "notifications.clear": "Nettoyer les notifications",
   "notifications.clear_confirmation": "Voulez-vous vraiment supprimer toutes vos notifications ?",
   "notifications.column_settings.alert": "Notifications locales",
   "notifications.column_settings.favourite": "Favoris :",
   "notifications.column_settings.filter_bar.advanced": "Afficher toutes les catégories",
-  "notifications.column_settings.filter_bar.category": "Barre de recherche rapide",
+  "notifications.column_settings.filter_bar.category": "Barre de filtrage rapide",
   "notifications.column_settings.filter_bar.show": "Afficher",
   "notifications.column_settings.follow": "Nouveaux⋅elles abonné⋅e·s :",
   "notifications.column_settings.mention": "Mentions :",
+  "notifications.column_settings.poll": "Résultats du sondage :",
   "notifications.column_settings.push": "Notifications",
   "notifications.column_settings.reblog": "Partages :",
   "notifications.column_settings.show": "Afficher dans la colonne",
@@ -254,9 +271,16 @@
   "notifications.filter.all": "Tout",
   "notifications.filter.boosts": "Repartages",
   "notifications.filter.favourites": "Favoris",
-  "notifications.filter.follows": "Suiveurs",
+  "notifications.filter.follows": "Abonné·e·s",
   "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Résultats des sondages",
   "notifications.group": "{count} notifications",
+  "poll.closed": "Fermé",
+  "poll.refresh": "Actualiser",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Voter",
+  "poll_button.add_poll": "Ajouter un sondage",
+  "poll_button.remove_poll": "Supprimer le sondage",
   "privacy.change": "Ajuster la confidentialité du message",
   "privacy.direct.long": "N’envoyer qu’aux personnes mentionnées",
   "privacy.direct.short": "Direct",
@@ -276,7 +300,7 @@
   "reply_indicator.cancel": "Annuler",
   "report.forward": "Transférer à {target}",
   "report.forward_hint": "Le compte provient d’un autre serveur. Envoyez également une copie anonyme du rapport ?",
-  "report.hint": "Le rapport sera envoyé aux modérateur·rice·s de votre instance. Vous pouvez expliquer pourquoi vous signalez le compte ci-dessous :",
+  "report.hint": "Le rapport sera envoyé aux modérateur·rice·s de votre instance. Vous pouvez expliquer pourquoi vous signalez le compte ci-dessous :",
   "report.placeholder": "Commentaires additionnels",
   "report.submit": "Envoyer",
   "report.target": "Signalement",
@@ -291,12 +315,12 @@
   "search_results.hashtags": "Hashtags",
   "search_results.statuses": "Pouets",
   "search_results.total": "{count, number} {count, plural, one {résultat} other {résultats}}",
-  "standalone.public_title": "Un aperçu …",
   "status.admin_account": "Ouvrir l'interface de modération pour @{name}",
   "status.admin_status": "Ouvrir ce statut dans l'interface de modération",
-  "status.block": "Block @{name}",
+  "status.block": "Bloquer @{name}",
   "status.cancel_reblog_private": "Dé-booster",
   "status.cannot_reblog": "Cette publication ne peut être boostée",
+  "status.copy": "Copier le lien vers le pouet",
   "status.delete": "Effacer",
   "status.detailed_status": "Vue détaillée de la conversation",
   "status.direct": "Envoyer un message direct à @{name}",
@@ -305,7 +329,7 @@
   "status.filtered": "Filtré",
   "status.load_more": "Charger plus",
   "status.media_hidden": "Média caché",
-  "status.mention": "Mentionner",
+  "status.mention": "Mentionner @{name}",
   "status.more": "Plus",
   "status.mute": "Masquer @{name}",
   "status.mute_conversation": "Masquer la conversation",
@@ -321,27 +345,33 @@
   "status.reply": "Répondre",
   "status.replyAll": "Répondre au fil",
   "status.report": "Signaler @{name}",
-  "status.sensitive_toggle": "Cliquer pour afficher",
   "status.sensitive_warning": "Contenu sensible",
   "status.share": "Partager",
   "status.show_less": "Replier",
   "status.show_less_all": "Tout replier",
   "status.show_more": "Déplier",
   "status.show_more_all": "Tout déplier",
-  "status.show_thread": "Afficher le fil",
+  "status.show_thread": "Lire le fil",
   "status.unmute_conversation": "Ne plus masquer la conversation",
   "status.unpin": "Retirer du profil",
   "suggestions.dismiss": "Rejeter la suggestion",
-  "suggestions.header": "Vous pourriez être intéressé par.…",
+  "suggestions.header": "Vous pourriez être intéressé par…",
   "tabs_bar.federated_timeline": "Fil public global",
   "tabs_bar.home": "Accueil",
   "tabs_bar.local_timeline": "Fil public local",
   "tabs_bar.notifications": "Notifications",
   "tabs_bar.search": "Chercher",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} restants",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} restantes",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} restantes",
+  "time_remaining.moments": "Encore quelques instants",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} restantes",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {personne} other {personnes}} discutent",
   "ui.beforeunload": "Votre brouillon sera perdu si vous quittez Mastodon.",
   "upload_area.title": "Glissez et déposez pour envoyer",
   "upload_button.label": "Joindre un média (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "Taille maximale d'envoi de fichier dépassée.",
+  "upload_error.poll": "L'envoi de fichiers n'est pas autorisé avec les sondages.",
   "upload_form.description": "Décrire pour les malvoyant·e·s",
   "upload_form.focus": "Modifier l’aperçu",
   "upload_form.undo": "Supprimer",
diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json
index c1ece163d7e09de2435e47c2e68a011502589288..9b19d6f113c217668bc5bbfecf4c4dacabf5b1f7 100644
--- a/app/javascript/mastodon/locales/gl.json
+++ b/app/javascript/mastodon/locales/gl.json
@@ -5,7 +5,6 @@
   "account.block_domain": "Ocultar calquer contido de {domain}",
   "account.blocked": "Bloqueada",
   "account.direct": "Mensaxe directa @{name}",
-  "account.disclaimer_full": "A información inferior podería mostrar un perfil incompleto da usuaria.",
   "account.domain_blocked": "Dominio agochado",
   "account.edit_profile": "Editar perfil",
   "account.endorse": "Mostrado no perfil",
@@ -14,7 +13,7 @@
   "account.followers.empty": "Ninguén está a seguir esta usuaria por agora.",
   "account.follows": "Seguindo",
   "account.follows.empty": "Esta usuaria aínda non segue a ninguén.",
-  "account.follows_you": "Séguena",
+  "account.follows_you": "Séguete",
   "account.hide_reblogs": "Ocultar repeticións de @{name}",
   "account.link_verified_on": "A propiedade de esta ligazón foi comprobada en {date}",
   "account.locked_info": "O estado da intimidade de esta conta estableceuse en pechado. A persoa dona da conta revisa quen pode seguila.",
@@ -36,7 +35,6 @@
   "account.unfollow": "Non seguir",
   "account.unmute": "Non acalar @{name}",
   "account.unmute_notifications": "Desbloquear as notificacións de @{name}",
-  "account.view_full_profile": "Ver o perfil completo",
   "alert.unexpected.message": "Aconteceu un fallo non agardado.",
   "alert.unexpected.title": "Vaia!",
   "boost_modal.combo": "Pulse {combo} para saltar esto a próxima vez",
@@ -73,19 +71,25 @@
   "compose_form.lock_disclaimer": "A súa conta non está {locked}. Calquera pode seguila para ver as súas mensaxes só-para-seguidoras.",
   "compose_form.lock_disclaimer.lock": "bloqueado",
   "compose_form.placeholder": "Qué contas?",
+  "compose_form.poll.add_option": "Engadir unha opción",
+  "compose_form.poll.duration": "Duración da sondaxe",
+  "compose_form.poll.option_placeholder": "Opción {number}",
+  "compose_form.poll.remove_option": "Eliminar esta opción",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Marcar medios como sensibles",
   "compose_form.sensitive.marked": "Medios marcados como sensibles",
   "compose_form.sensitive.unmarked": "Os medios non están marcados como sensibles",
   "compose_form.spoiler.marked": "O texto está agochado tras un aviso",
   "compose_form.spoiler.unmarked": "O texto non está agochado",
   "compose_form.spoiler_placeholder": "Escriba o aviso aquí",
   "confirmation_modal.cancel": "Cancelar",
+  "confirmations.block.block_and_report": "Bloquear e Informar",
   "confirmations.block.confirm": "Bloquear",
   "confirmations.block.message": "Está segura de querer bloquear a {name}?",
   "confirmations.delete.confirm": "Borrar",
   "confirmations.delete.message": "Está segura de que quere eliminar este estado?",
-  "confirmations.delete_list.confirm": "Delete",
+  "confirmations.delete_list.confirm": "Eliminar",
   "confirmations.delete_list.message": "Estás seguro de que queres eliminar permanentemente esta lista?",
   "confirmations.domain_block.confirm": "Agochar un dominio completo",
   "confirmations.domain_block.message": "Realmente está segura de que quere bloquear por completo o dominio {domain}? Normalmente é suficiente, e preferible, bloquear de xeito selectivo varios elementos. Non verá contidos de ese dominio en ningunha liña temporal ou nas notificacións. As súas seguidoras en ese dominio serán eliminadas.",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Símbolos",
   "emoji_button.travel": "Viaxes e Lugares",
   "empty_column.account_timeline": "Sen toots por aquí!",
+  "empty_column.account_unavailable": "Perfil non dispoñible",
   "empty_column.blocks": "Non bloqueou ningunha usuaria polo de agora.",
   "empty_column.community": "A liña temporal local está baldeira. Escriba algo de xeito público para que rule!",
   "empty_column.direct": "Aínda non ten mensaxes directas. Cando envíe ou reciba unha, aparecerá aquí.",
@@ -128,12 +133,12 @@
   "empty_column.lists": "Aínda non ten listas. Cando cree unha, mostrarase aquí.",
   "empty_column.mutes": "Non acalou ningunha usuaria polo de agora.",
   "empty_column.notifications": "Aínda non ten notificacións. Interactúe con outras para iniciar unha conversa.",
-  "empty_column.public": "Nada por aquí! Escriba algo de xeito público, ou siga manualmente usuarias de outras instancias para ir enchéndoa",
+  "empty_column.public": "Nada por aquí! Escriba algo de xeito público, ou siga manualmente usuarias de outros servidores para ir enchéndoa",
   "follow_request.authorize": "Autorizar",
   "follow_request.reject": "Rexeitar",
   "getting_started.developers": "Desenvolvedoras",
   "getting_started.directory": "Directorio do perfil",
-  "getting_started.documentation": "Documentation",
+  "getting_started.documentation": "Documentación",
   "getting_started.heading": "Comezando",
   "getting_started.invite": "Convide a xente",
   "getting_started.open_source_notice": "Mastodon é software de código aberto. Pode contribuír ou informar de fallos en GitHub en {github}.",
@@ -142,17 +147,22 @@
   "hashtag.column_header.tag_mode.all": "e {additional}",
   "hashtag.column_header.tag_mode.any": "ou {additional}",
   "hashtag.column_header.tag_mode.none": "sen {additional}",
+  "hashtag.column_settings.select.no_options_message": "Non se atopan suxestións",
+  "hashtag.column_settings.select.placeholder": "Introducir etiquetas…",
   "hashtag.column_settings.tag_mode.all": "Todos estos",
   "hashtag.column_settings.tag_mode.any": "Calquera de estos",
   "hashtag.column_settings.tag_mode.none": "Ningún de estos",
-  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "hashtag.column_settings.tag_toggle": "Incluír etiquetas adicionais para esta columna",
   "home.column_settings.basic": "Básico",
   "home.column_settings.show_reblogs": "Mostrar repeticións",
   "home.column_settings.show_replies": "Mostrar respostas",
+  "intervals.full.days": "{number, plural,one {# día} other {# días}}",
+  "intervals.full.hours": "{number, plural, one {# hora} other {# horas}}",
+  "intervals.full.minutes": "{number, plural, one {# minuto} other {# minutos}}",
   "introduction.federation.action": "Seguinte",
-  "introduction.federation.federated.headline": "Federated",
+  "introduction.federation.federated.headline": "Federado",
   "introduction.federation.federated.text": "Publicacións públicas desde outros servidores do fediverso aparecerán na liña temporal federada.",
-  "introduction.federation.home.headline": "Home",
+  "introduction.federation.home.headline": "Inicio",
   "introduction.federation.home.text": "Publicacións de xente que vostede segue aparecerán no TL de Inicio. Pode seguir a calquera en calquer servidor!",
   "introduction.federation.local.headline": "Local",
   "introduction.federation.local.text": "Publicacións públicas de xente no seu mesmo servidor aparecerán na liña temporal local.",
@@ -160,7 +170,7 @@
   "introduction.interactions.favourite.headline": "Favorito",
   "introduction.interactions.favourite.text": "Pode gardar un toot para máis tarde, e facerlle saber a autora que lle gustou, dándolle a Favorito.",
   "introduction.interactions.reblog.headline": "Promocionar",
-  "introduction.interactions.reblog.text": "Pode compartir os toots de outra xente coas súas seguirodas promocionándoos.",
+  "introduction.interactions.reblog.text": "Pode compartir os toots de outra xente coas súas seguidoras promocionándoos.",
   "introduction.interactions.reply.headline": "Respostar",
   "introduction.interactions.reply.text": "Pode respostar aos toots de outras persoas e aos seus propios, así quedarán encadeados nunha conversa.",
   "introduction.welcome.action": "Imos!",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "para centrar a busca",
   "keyboard_shortcuts.start": "abrir columna \"comezando\"",
   "keyboard_shortcuts.toggle_hidden": "mostrar/agochar un texto detrás do AC",
+  "keyboard_shortcuts.toggle_sensitivity": "mostrar/ocultar medios",
   "keyboard_shortcuts.toot": "escribir un toot novo",
   "keyboard_shortcuts.unfocus": "quitar o foco do área de escritura/busca",
   "keyboard_shortcuts.up": "ir hacia arriba na lista",
   "lightbox.close": "Fechar",
   "lightbox.next": "Seguinte",
   "lightbox.previous": "Anterior",
+  "lightbox.view_context": "Ver contexto",
   "lists.account.add": "Engadir á lista",
   "lists.account.remove": "Eliminar da lista",
-  "lists.delete": "Delete list",
+  "lists.delete": "Eliminar lista",
   "lists.edit": "Editar lista",
+  "lists.edit.submit": "Cambiar título",
   "lists.new.create": "Engadir lista",
   "lists.new.title_placeholder": "Novo título da lista",
   "lists.search": "Procurar entre a xente que segues",
@@ -224,7 +237,8 @@
   "navigation_bar.favourites": "Favoritas",
   "navigation_bar.filters": "Palabras acaladas",
   "navigation_bar.follow_requests": "Peticións de seguimento",
-  "navigation_bar.info": "Sobre esta instancia",
+  "navigation_bar.follows_and_followers": "Seguindo e seguidoras",
+  "navigation_bar.info": "Sobre este servidor",
   "navigation_bar.keyboard_shortcuts": "Atallos",
   "navigation_bar.lists": "Listas",
   "navigation_bar.logout": "Sair",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Persoal",
   "navigation_bar.pins": "Mensaxes fixadas",
   "navigation_bar.preferences": "Preferencias",
+  "navigation_bar.profile_directory": "Directorio de perfil",
   "navigation_bar.public_timeline": "Liña temporal federada",
   "navigation_bar.security": "Seguridade",
   "notification.favourite": "{name} marcou como favorito o seu estado",
   "notification.follow": "{name} está a seguila",
   "notification.mention": "{name} mencionoute",
+  "notification.poll": "Unha sondaxe na que votou xa rematou",
   "notification.reblog": "{name} promoveu o seu estado",
   "notifications.clear": "Limpar notificacións",
   "notifications.clear_confirmation": "Estás seguro de que queres limpar permanentemente todas as túas notificacións?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Mostrar",
   "notifications.column_settings.follow": "Novos seguidores:",
   "notifications.column_settings.mention": "Mencións:",
+  "notifications.column_settings.poll": "Resultados da sondaxe:",
   "notifications.column_settings.push": "Enviar notificacións",
   "notifications.column_settings.reblog": "Promocións:",
   "notifications.column_settings.show": "Mostrar en columna",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favoritos",
   "notifications.filter.follows": "Seguimentos",
   "notifications.filter.mentions": "Mencións",
+  "notifications.filter.polls": "Resultados da sondaxe",
   "notifications.group": "{count} notificacións",
+  "poll.closed": "Pechado",
+  "poll.refresh": "Actualizar",
+  "poll.total_votes": "{count, plural, one {# voto} outros {# votos}}",
+  "poll.vote": "Votar",
+  "poll_button.add_poll": "Engadir sondaxe",
+  "poll_button.remove_poll": "Eliminar sondaxe",
   "privacy.change": "Axustar a intimidade do estado",
   "privacy.direct.long": "Enviar exclusivamente as usuarias mencionadas",
   "privacy.direct.short": "Directa",
@@ -276,7 +300,7 @@
   "reply_indicator.cancel": "Cancelar",
   "report.forward": "Reenviar a {target}",
   "report.forward_hint": "A conta pertence a outro servidor. Enviar unha copia anónima do informe alí tamén?",
-  "report.hint": "O informe enviarase a moderación da súa instancia. Abaixo pode explicar a razón pola que está a información:",
+  "report.hint": "O informe enviarase a moderación do seu servidor. Abaixo pode explicar a razón pola que está a informar:",
   "report.placeholder": "Comentarios adicionais",
   "report.submit": "Enviar",
   "report.target": "Informar {target}",
@@ -291,12 +315,12 @@
   "search_results.hashtags": "Etiquetas",
   "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count,plural,one {result} outros {results}}",
-  "standalone.public_title": "Ollada dentro...",
   "status.admin_account": "Abrir interface de moderación para @{name}",
   "status.admin_status": "Abrir este estado na interface de moderación",
-  "status.block": "Block @{name}",
+  "status.block": "Bloquear @{name}",
   "status.cancel_reblog_private": "Non promover",
   "status.cannot_reblog": "Esta mensaxe non pode ser promovida",
+  "status.copy": "Copiar ligazón ao estado",
   "status.delete": "Eliminar",
   "status.detailed_status": "Vista detallada da conversa",
   "status.direct": "Mensaxe directa @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Resposta",
   "status.replyAll": "Resposta a conversa",
   "status.report": "Informar @{name}",
-  "status.sensitive_toggle": "Pulse para ver",
   "status.sensitive_warning": "Contido sensible",
   "status.share": "Compartir",
   "status.show_less": "Mostrar menos",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Local",
   "tabs_bar.notifications": "Notificacións",
   "tabs_bar.search": "Buscar",
+  "time_remaining.days": "{number, plural, one {# dia} other {# días}} restantes",
+  "time_remaining.hours": "{number, plural, one {# hora} other {# horas}} restantes",
+  "time_remaining.minutes": "{number, plural, one {# minuto} other {# minutos}} restantes",
+  "time_remaining.moments": "Está rematando",
+  "time_remaining.seconds": "{number, plural, one {# segundo} other {# segundos}} restantes",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} outras {people}} conversando",
   "ui.beforeunload": "O borrador perderase se sae de Mastodon.",
   "upload_area.title": "Arrastre e solte para subir",
   "upload_button.label": "Engadir medios (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "Excedeu o límite de subida de ficheiros.",
+  "upload_error.poll": "Non se poden subir ficheiros nas sondaxes.",
   "upload_form.description": "Describa para deficientes visuais",
   "upload_form.focus": "Cambiar vista previa",
   "upload_form.undo": "Eliminar",
diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json
index e27e7f09e6c883dd75ca567d4651ed2607fec833..248be3c7b5dd415faea4c783d5fe79b814a3bc7f 100644
--- a/app/javascript/mastodon/locales/he.json
+++ b/app/javascript/mastodon/locales/he.json
@@ -5,7 +5,6 @@
   "account.block_domain": "להסתיר הכל מהקהילה {domain}",
   "account.blocked": "Blocked",
   "account.direct": "Direct Message @{name}",
-  "account.disclaimer_full": "המידע להלן עשוי להיות לא עדכני או לא שלם.",
   "account.domain_blocked": "Domain hidden",
   "account.edit_profile": "עריכת פרופיל",
   "account.endorse": "Feature on profile",
@@ -36,7 +35,6 @@
   "account.unfollow": "הפסקת מעקב",
   "account.unmute": "הפסקת השתקת @{name}",
   "account.unmute_notifications": "להפסיק הסתרת הודעות מעם @{name}",
-  "account.view_full_profile": "הצגת פרופיל מלא",
   "alert.unexpected.message": "אירעה שגיאה בלתי צפויה.",
   "alert.unexpected.title": "אופס!",
   "boost_modal.combo": "ניתן להקיש {combo} כדי לדלג בפעם הבאה",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "חשבונך אינו {locked}. כל אחד יוכל לעקוב אחריך כדי לקרוא את הודעותיך המיועדות לעוקבים בלבד.",
   "compose_form.lock_disclaimer.lock": "נעול",
   "compose_form.placeholder": "מה עובר לך בראש?",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
   "compose_form.publish": "ללחוש",
   "compose_form.publish_loud": "לחצרץ!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
   "compose_form.sensitive.marked": "Media is marked as sensitive",
   "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
   "compose_form.spoiler.marked": "Text is hidden behind warning",
   "compose_form.spoiler.unmarked": "Text is not hidden",
   "compose_form.spoiler_placeholder": "אזהרת תוכן",
   "confirmation_modal.cancel": "ביטול",
+  "confirmations.block.block_and_report": "Block & Report",
   "confirmations.block.confirm": "לחסום",
   "confirmations.block.message": "לחסום את {name}?",
   "confirmations.delete.confirm": "למחוק",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "סמלים",
   "emoji_button.travel": "טיולים ואתרים",
   "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_unavailable": "Profile unavailable",
   "empty_column.blocks": "You haven't blocked any users yet.",
   "empty_column.community": "טור הסביבה ריק. יש לפרסם משהו כדי שדברים יתרחילו להתגלגל!",
   "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "and {additional}",
   "hashtag.column_header.tag_mode.any": "or {additional}",
   "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
   "hashtag.column_settings.tag_mode.all": "All of these",
   "hashtag.column_settings.tag_mode.any": "Any of these",
   "hashtag.column_settings.tag_mode.none": "None of these",
@@ -149,6 +156,9 @@
   "home.column_settings.basic": "למתחילים",
   "home.column_settings.show_reblogs": "הצגת הדהודים",
   "home.column_settings.show_replies": "הצגת תגובות",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
   "introduction.federation.action": "Next",
   "introduction.federation.federated.headline": "Federated",
   "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
@@ -156,7 +166,7 @@
   "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
   "introduction.federation.local.headline": "Local",
   "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
+  "introduction.interactions.action": "Finish toot-orial!",
   "introduction.interactions.favourite.headline": "Favourite",
   "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
   "introduction.interactions.reblog.headline": "Boost",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "להתמקד בחלון החיפוש",
   "keyboard_shortcuts.start": "to open \"get started\" column",
   "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "להתחיל חיצרוץ חדש",
   "keyboard_shortcuts.unfocus": "לצאת מתיבת חיבור/חיפוש",
   "keyboard_shortcuts.up": "לנוע במעלה הרשימה",
   "lightbox.close": "סגירה",
   "lightbox.next": "הלאה",
   "lightbox.previous": "הקודם",
+  "lightbox.view_context": "View context",
   "lists.account.add": "Add to list",
   "lists.account.remove": "Remove from list",
   "lists.delete": "Delete list",
   "lists.edit": "Edit list",
+  "lists.edit.submit": "Change title",
   "lists.new.create": "Add list",
   "lists.new.title_placeholder": "New list title",
   "lists.search": "Search among people you follow",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "חיבובים",
   "navigation_bar.filters": "Muted words",
   "navigation_bar.follow_requests": "בקשות מעקב",
+  "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.info": "מידע נוסף",
   "navigation_bar.keyboard_shortcuts": "קיצורי מקלדת",
   "navigation_bar.lists": "Lists",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Personal",
   "navigation_bar.pins": "חיצרוצים מקובעים",
   "navigation_bar.preferences": "העדפות",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "ציר זמן בין-קהילתי",
   "navigation_bar.security": "Security",
   "notification.favourite": "חצרוצך חובב על ידי {name}",
   "notification.follow": "{name} במעקב אחרייך",
   "notification.mention": "אוזכרת על ידי {name}",
+  "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "חצרוצך הודהד על ידי {name}",
   "notifications.clear": "הסרת התראות",
   "notifications.clear_confirmation": "להסיר את כל ההתראות? בטוח?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Show",
   "notifications.column_settings.follow": "עוקבים חדשים:",
   "notifications.column_settings.mention": "פניות:",
+  "notifications.column_settings.poll": "Poll results:",
   "notifications.column_settings.push": "הודעות בדחיפה",
   "notifications.column_settings.reblog": "הדהודים:",
   "notifications.column_settings.show": "הצגה בטור",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favourites",
   "notifications.filter.follows": "Follows",
   "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
   "notifications.group": "{count} notifications",
+  "poll.closed": "Closed",
+  "poll.refresh": "Refresh",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
   "privacy.change": "שינוי פרטיות ההודעה",
   "privacy.direct.long": "הצג רק למי שהודעה זו פונה אליו",
   "privacy.direct.short": "הודעה ישירה",
@@ -291,12 +315,12 @@
   "search_results.hashtags": "Hashtags",
   "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {תוצאה} other {תוצאות}}",
-  "standalone.public_title": "הצצה פנימה...",
   "status.admin_account": "Open moderation interface for @{name}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "לא ניתן להדהד הודעה זו",
+  "status.copy": "Copy link to status",
   "status.delete": "מחיקה",
   "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "תגובה",
   "status.replyAll": "תגובה לכולם",
   "status.report": "דיווח על @{name}",
-  "status.sensitive_toggle": "לחצו כדי לראות",
   "status.sensitive_warning": "תוכן רגיש",
   "status.share": "שיתוף",
   "status.show_less": "הראה פחות",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "ציר זמן מקומי",
   "tabs_bar.notifications": "התראות",
   "tabs_bar.search": "Search",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
   "ui.beforeunload": "הטיוטא תאבד אם תעזבו את מסטודון.",
   "upload_area.title": "ניתן להעלות על ידי Drag & drop",
   "upload_button.label": "הוספת מדיה",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "upload_form.description": "תיאור לכבדי ראיה",
   "upload_form.focus": "Crop",
   "upload_form.undo": "ביטול",
diff --git a/app/javascript/mastodon/locales/hi.json b/app/javascript/mastodon/locales/hi.json
new file mode 100644
index 0000000000000000000000000000000000000000..ac58514d420791eebba0e8f7ce290ddf59340acd
--- /dev/null
+++ b/app/javascript/mastodon/locales/hi.json
@@ -0,0 +1,388 @@
+{
+  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.badges.bot": "Bot",
+  "account.block": "Block @{name}",
+  "account.block_domain": "Hide everything from {domain}",
+  "account.blocked": "Blocked",
+  "account.direct": "Direct message @{name}",
+  "account.domain_blocked": "Domain hidden",
+  "account.edit_profile": "Edit profile",
+  "account.endorse": "Feature on profile",
+  "account.follow": "Follow",
+  "account.followers": "Followers",
+  "account.followers.empty": "No one follows this user yet.",
+  "account.follows": "Follows",
+  "account.follows.empty": "This user doesn't follow anyone yet.",
+  "account.follows_you": "Follows you",
+  "account.hide_reblogs": "Hide boosts from @{name}",
+  "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
+  "account.media": "Media",
+  "account.mention": "Mention @{name}",
+  "account.moved_to": "{name} has moved to:",
+  "account.mute": "Mute @{name}",
+  "account.mute_notifications": "Mute notifications from @{name}",
+  "account.muted": "Muted",
+  "account.posts": "Toots",
+  "account.posts_with_replies": "Toots and replies",
+  "account.report": "Report @{name}",
+  "account.requested": "Awaiting approval. Click to cancel follow request",
+  "account.share": "Share @{name}'s profile",
+  "account.show_reblogs": "Show boosts from @{name}",
+  "account.unblock": "Unblock @{name}",
+  "account.unblock_domain": "Unhide {domain}",
+  "account.unendorse": "Don't feature on profile",
+  "account.unfollow": "Unfollow",
+  "account.unmute": "Unmute @{name}",
+  "account.unmute_notifications": "Unmute notifications from @{name}",
+  "alert.unexpected.message": "An unexpected error occurred.",
+  "alert.unexpected.title": "Oops!",
+  "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",
+  "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",
+  "column.community": "Local timeline",
+  "column.direct": "Direct messages",
+  "column.domain_blocks": "Hidden domains",
+  "column.favourites": "Favourites",
+  "column.follow_requests": "Follow requests",
+  "column.home": "Home",
+  "column.lists": "Lists",
+  "column.mutes": "Muted users",
+  "column.notifications": "Notifications",
+  "column.pins": "Pinned toot",
+  "column.public": "Federated timeline",
+  "column_back_button.label": "Back",
+  "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.settings": "Settings",
+  "community.column_settings.media_only": "Media Only",
+  "compose_form.direct_message_warning": "This toot will only be sent to all the mentioned users.",
+  "compose_form.direct_message_warning_learn_more": "Learn more",
+  "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",
+  "compose_form.placeholder": "What is on your mind?",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
+  "compose_form.publish": "Toot",
+  "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
+  "compose_form.sensitive.marked": "Media is marked as sensitive",
+  "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
+  "compose_form.spoiler.marked": "Text is hidden behind warning",
+  "compose_form.spoiler.unmarked": "Text is not hidden",
+  "compose_form.spoiler_placeholder": "Write your warning here",
+  "confirmation_modal.cancel": "Cancel",
+  "confirmations.block.block_and_report": "Block & Report",
+  "confirmations.block.confirm": "Block",
+  "confirmations.block.message": "Are you sure you want to block {name}?",
+  "confirmations.delete.confirm": "Delete",
+  "confirmations.delete.message": "Are you sure you want to delete this status?",
+  "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. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.",
+  "confirmations.mute.confirm": "Mute",
+  "confirmations.mute.message": "Are you sure you want to mute {name}?",
+  "confirmations.redraft.confirm": "Delete & redraft",
+  "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.",
+  "confirmations.reply.confirm": "Reply",
+  "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
+  "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.account_timeline": "No toots here!",
+  "empty_column.account_unavailable": "Profile unavailable",
+  "empty_column.blocks": "You haven't blocked any users yet.",
+  "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
+  "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
+  "empty_column.domain_blocks": "There are no hidden domains yet.",
+  "empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.",
+  "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.",
+  "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
+  "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. When members of this list post new statuses, they will appear here.",
+  "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
+  "empty_column.mutes": "You haven't muted any users 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 servers to fill it up",
+  "follow_request.authorize": "Authorize",
+  "follow_request.reject": "Reject",
+  "getting_started.developers": "Developers",
+  "getting_started.directory": "Profile directory",
+  "getting_started.documentation": "Documentation",
+  "getting_started.heading": "Getting started",
+  "getting_started.invite": "Invite people",
+  "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.",
+  "getting_started.security": "Security",
+  "getting_started.terms": "Terms of service",
+  "hashtag.column_header.tag_mode.all": "and {additional}",
+  "hashtag.column_header.tag_mode.any": "or {additional}",
+  "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
+  "hashtag.column_settings.tag_mode.all": "All of these",
+  "hashtag.column_settings.tag_mode.any": "Any of these",
+  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "home.column_settings.basic": "Basic",
+  "home.column_settings.show_reblogs": "Show boosts",
+  "home.column_settings.show_replies": "Show replies",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
+  "introduction.federation.action": "Next",
+  "introduction.federation.federated.headline": "Federated",
+  "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
+  "introduction.federation.home.headline": "Home",
+  "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
+  "introduction.federation.local.headline": "Local",
+  "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
+  "introduction.interactions.action": "Finish toot-orial!",
+  "introduction.interactions.favourite.headline": "Favourite",
+  "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
+  "introduction.interactions.reblog.headline": "Boost",
+  "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
+  "introduction.interactions.reply.headline": "Reply",
+  "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
+  "introduction.welcome.action": "Let's go!",
+  "introduction.welcome.headline": "First steps",
+  "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
+  "keyboard_shortcuts.back": "to navigate back",
+  "keyboard_shortcuts.blocked": "to open blocked users list",
+  "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",
+  "keyboard_shortcuts.description": "Description",
+  "keyboard_shortcuts.direct": "to open direct messages column",
+  "keyboard_shortcuts.down": "to move down in the list",
+  "keyboard_shortcuts.enter": "to open status",
+  "keyboard_shortcuts.favourite": "to favourite",
+  "keyboard_shortcuts.favourites": "to open favourites list",
+  "keyboard_shortcuts.federated": "to open federated timeline",
+  "keyboard_shortcuts.heading": "Keyboard Shortcuts",
+  "keyboard_shortcuts.home": "to open home timeline",
+  "keyboard_shortcuts.hotkey": "Hotkey",
+  "keyboard_shortcuts.legend": "to display this legend",
+  "keyboard_shortcuts.local": "to open local timeline",
+  "keyboard_shortcuts.mention": "to mention author",
+  "keyboard_shortcuts.muted": "to open muted users list",
+  "keyboard_shortcuts.my_profile": "to open your profile",
+  "keyboard_shortcuts.notifications": "to open notifications column",
+  "keyboard_shortcuts.pinned": "to open pinned toots list",
+  "keyboard_shortcuts.profile": "to open author's profile",
+  "keyboard_shortcuts.reply": "to reply",
+  "keyboard_shortcuts.requests": "to open follow requests list",
+  "keyboard_shortcuts.search": "to focus search",
+  "keyboard_shortcuts.start": "to open \"get started\" column",
+  "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
+  "keyboard_shortcuts.toot": "to start a brand new toot",
+  "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
+  "keyboard_shortcuts.up": "to move up in the list",
+  "lightbox.close": "Close",
+  "lightbox.next": "Next",
+  "lightbox.previous": "Previous",
+  "lightbox.view_context": "View context",
+  "lists.account.add": "Add to list",
+  "lists.account.remove": "Remove from list",
+  "lists.delete": "Delete list",
+  "lists.edit": "Edit list",
+  "lists.edit.submit": "Change title",
+  "lists.new.create": "Add list",
+  "lists.new.title_placeholder": "New list title",
+  "lists.search": "Search among people you follow",
+  "lists.subheading": "Your lists",
+  "loading_indicator.label": "Loading...",
+  "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.apps": "Mobile apps",
+  "navigation_bar.blocks": "Blocked users",
+  "navigation_bar.community_timeline": "Local timeline",
+  "navigation_bar.compose": "Compose new toot",
+  "navigation_bar.direct": "Direct messages",
+  "navigation_bar.discover": "Discover",
+  "navigation_bar.domain_blocks": "Hidden domains",
+  "navigation_bar.edit_profile": "Edit profile",
+  "navigation_bar.favourites": "Favourites",
+  "navigation_bar.filters": "Muted words",
+  "navigation_bar.follow_requests": "Follow requests",
+  "navigation_bar.follows_and_followers": "Follows and followers",
+  "navigation_bar.info": "About this server",
+  "navigation_bar.keyboard_shortcuts": "Hotkeys",
+  "navigation_bar.lists": "Lists",
+  "navigation_bar.logout": "Logout",
+  "navigation_bar.mutes": "Muted users",
+  "navigation_bar.personal": "Personal",
+  "navigation_bar.pins": "Pinned toots",
+  "navigation_bar.preferences": "Preferences",
+  "navigation_bar.profile_directory": "Profile directory",
+  "navigation_bar.public_timeline": "Federated timeline",
+  "navigation_bar.security": "Security",
+  "notification.favourite": "{name} favourited your status",
+  "notification.follow": "{name} followed you",
+  "notification.mention": "{name} mentioned you",
+  "notification.poll": "A poll you have voted in has ended",
+  "notification.reblog": "{name} boosted your status",
+  "notifications.clear": "Clear notifications",
+  "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
+  "notifications.column_settings.alert": "Desktop notifications",
+  "notifications.column_settings.favourite": "Favourites:",
+  "notifications.column_settings.filter_bar.advanced": "Display all categories",
+  "notifications.column_settings.filter_bar.category": "Quick filter bar",
+  "notifications.column_settings.filter_bar.show": "Show",
+  "notifications.column_settings.follow": "New followers:",
+  "notifications.column_settings.mention": "Mentions:",
+  "notifications.column_settings.poll": "Poll results:",
+  "notifications.column_settings.push": "Push notifications",
+  "notifications.column_settings.reblog": "Boosts:",
+  "notifications.column_settings.show": "Show in column",
+  "notifications.column_settings.sound": "Play sound",
+  "notifications.filter.all": "All",
+  "notifications.filter.boosts": "Boosts",
+  "notifications.filter.favourites": "Favourites",
+  "notifications.filter.follows": "Follows",
+  "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
+  "notifications.group": "{count} notifications",
+  "poll.closed": "Closed",
+  "poll.refresh": "Refresh",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
+  "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!",
+  "relative_time.days": "{number}d",
+  "relative_time.hours": "{number}h",
+  "relative_time.just_now": "now",
+  "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 server moderators. You can provide an explanation of why you are reporting this account below:",
+  "report.placeholder": "Additional comments",
+  "report.submit": "Submit",
+  "report.target": "Report {target}",
+  "search.placeholder": "Search",
+  "search_popout.search_format": "Advanced search format",
+  "search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
+  "search_popout.tips.hashtag": "hashtag",
+  "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}}",
+  "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_status": "Open this status in the moderation interface",
+  "status.block": "Block @{name}",
+  "status.cancel_reblog_private": "Unboost",
+  "status.cannot_reblog": "This post cannot be boosted",
+  "status.copy": "Copy link to status",
+  "status.delete": "Delete",
+  "status.detailed_status": "Detailed conversation view",
+  "status.direct": "Direct message @{name}",
+  "status.embed": "Embed",
+  "status.favourite": "Favourite",
+  "status.filtered": "Filtered",
+  "status.load_more": "Load more",
+  "status.media_hidden": "Media hidden",
+  "status.mention": "Mention @{name}",
+  "status.more": "More",
+  "status.mute": "Mute @{name}",
+  "status.mute_conversation": "Mute conversation",
+  "status.open": "Expand this status",
+  "status.pin": "Pin on profile",
+  "status.pinned": "Pinned toot",
+  "status.read_more": "Read more",
+  "status.reblog": "Boost",
+  "status.reblog_private": "Boost to original audience",
+  "status.reblogged_by": "{name} boosted",
+  "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
+  "status.redraft": "Delete & re-draft",
+  "status.reply": "Reply",
+  "status.replyAll": "Reply to thread",
+  "status.report": "Report @{name}",
+  "status.sensitive_warning": "Sensitive content",
+  "status.share": "Share",
+  "status.show_less": "Show less",
+  "status.show_less_all": "Show less for all",
+  "status.show_more": "Show more",
+  "status.show_more_all": "Show more for all",
+  "status.show_thread": "Show thread",
+  "status.unmute_conversation": "Unmute conversation",
+  "status.unpin": "Unpin from profile",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
+  "tabs_bar.federated_timeline": "Federated",
+  "tabs_bar.home": "Home",
+  "tabs_bar.local_timeline": "Local",
+  "tabs_bar.notifications": "Notifications",
+  "tabs_bar.search": "Search",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
+  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
+  "upload_area.title": "Drag & drop to upload",
+  "upload_button.label": "Add media (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
+  "upload_form.description": "Describe for the visually impaired",
+  "upload_form.focus": "Crop",
+  "upload_form.undo": "Delete",
+  "upload_progress.label": "Uploading...",
+  "video.close": "Close video",
+  "video.exit_fullscreen": "Exit full screen",
+  "video.expand": "Expand video",
+  "video.fullscreen": "Full screen",
+  "video.hide": "Hide video",
+  "video.mute": "Mute sound",
+  "video.pause": "Pause",
+  "video.play": "Play",
+  "video.unmute": "Unmute sound"
+}
diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json
index 71dd5319e77fc5d840c2b8d67ab97a2ddeb827dc..6f9b5343af3111bf4106554ee0d14ae494daa134 100644
--- a/app/javascript/mastodon/locales/hr.json
+++ b/app/javascript/mastodon/locales/hr.json
@@ -5,7 +5,6 @@
   "account.block_domain": "Sakrij sve sa {domain}",
   "account.blocked": "Blocked",
   "account.direct": "Direct Message @{name}",
-  "account.disclaimer_full": "Ovaj korisnik je sa druge instance. Ovaj broj bi mogao biti veći.",
   "account.domain_blocked": "Domain hidden",
   "account.edit_profile": "Uredi profil",
   "account.endorse": "Feature on profile",
@@ -36,7 +35,6 @@
   "account.unfollow": "Prestani slijediti",
   "account.unmute": "Poništi utišavanje @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account.view_full_profile": "View full profile",
   "alert.unexpected.message": "An unexpected error occurred.",
   "alert.unexpected.title": "Oops!",
   "boost_modal.combo": "Možeš pritisnuti {combo} kako bi ovo preskočio sljedeći put",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "Tvoj račun nije {locked}. Svatko te može slijediti kako bi vidio postove namijenjene samo tvojim sljedbenicima.",
   "compose_form.lock_disclaimer.lock": "zaključan",
   "compose_form.placeholder": "Å to ti je na umu?",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
   "compose_form.sensitive.marked": "Media is marked as sensitive",
   "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
   "compose_form.spoiler.marked": "Text is hidden behind warning",
   "compose_form.spoiler.unmarked": "Text is not hidden",
   "compose_form.spoiler_placeholder": "Upozorenje o sadržaju",
   "confirmation_modal.cancel": "Otkaži",
+  "confirmations.block.block_and_report": "Block & Report",
   "confirmations.block.confirm": "Blokiraj",
   "confirmations.block.message": "Želiš li sigurno blokirati {name}?",
   "confirmations.delete.confirm": "Obriši",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Simboli",
   "emoji_button.travel": "Putovanja & Mjesta",
   "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_unavailable": "Profile unavailable",
   "empty_column.blocks": "You haven't blocked any users yet.",
   "empty_column.community": "Lokalni timeline je prazan. Napiši nešto javno kako bi pokrenuo stvari!",
   "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "and {additional}",
   "hashtag.column_header.tag_mode.any": "or {additional}",
   "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
   "hashtag.column_settings.tag_mode.all": "All of these",
   "hashtag.column_settings.tag_mode.any": "Any of these",
   "hashtag.column_settings.tag_mode.none": "None of these",
@@ -149,6 +156,9 @@
   "home.column_settings.basic": "Osnovno",
   "home.column_settings.show_reblogs": "Pokaži boostove",
   "home.column_settings.show_replies": "Pokaži odgovore",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
   "introduction.federation.action": "Next",
   "introduction.federation.federated.headline": "Federated",
   "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
@@ -156,7 +166,7 @@
   "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
   "introduction.federation.local.headline": "Local",
   "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
+  "introduction.interactions.action": "Finish toot-orial!",
   "introduction.interactions.favourite.headline": "Favourite",
   "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
   "introduction.interactions.reblog.headline": "Boost",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "to focus search",
   "keyboard_shortcuts.start": "to open \"get started\" column",
   "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "to start a brand new toot",
   "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
   "keyboard_shortcuts.up": "to move up in the list",
   "lightbox.close": "Zatvori",
   "lightbox.next": "Next",
   "lightbox.previous": "Previous",
+  "lightbox.view_context": "View context",
   "lists.account.add": "Add to list",
   "lists.account.remove": "Remove from list",
   "lists.delete": "Delete list",
   "lists.edit": "Edit list",
+  "lists.edit.submit": "Change title",
   "lists.new.create": "Add list",
   "lists.new.title_placeholder": "New list title",
   "lists.search": "Search among people you follow",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "Favoriti",
   "navigation_bar.filters": "Muted words",
   "navigation_bar.follow_requests": "Zahtjevi za slijeđenje",
+  "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.info": "Više informacija",
   "navigation_bar.keyboard_shortcuts": "Keyboard shortcuts",
   "navigation_bar.lists": "Lists",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Personal",
   "navigation_bar.pins": "Pinned toots",
   "navigation_bar.preferences": "Postavke",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "Federalni timeline",
   "navigation_bar.security": "Security",
   "notification.favourite": "{name} je lajkao tvoj status",
   "notification.follow": "{name} te sada slijedi",
   "notification.mention": "{name} te je spomenuo",
+  "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "{name} je podigao tvoj status",
   "notifications.clear": "Očisti notifikacije",
   "notifications.clear_confirmation": "Želiš li zaista obrisati sve svoje notifikacije?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Show",
   "notifications.column_settings.follow": "Novi sljedbenici:",
   "notifications.column_settings.mention": "Spominjanja:",
+  "notifications.column_settings.poll": "Poll results:",
   "notifications.column_settings.push": "Push notifications",
   "notifications.column_settings.reblog": "Boostovi:",
   "notifications.column_settings.show": "Prikaži u stupcu",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favourites",
   "notifications.filter.follows": "Follows",
   "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
   "notifications.group": "{count} notifications",
+  "poll.closed": "Closed",
+  "poll.refresh": "Refresh",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
   "privacy.change": "Podesi status privatnosti",
   "privacy.direct.long": "Prikaži samo spomenutim korisnicima",
   "privacy.direct.short": "Direktno",
@@ -291,12 +315,12 @@
   "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.admin_account": "Open moderation interface for @{name}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "Ovaj post ne može biti boostan",
+  "status.copy": "Copy link to status",
   "status.delete": "Obriši",
   "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Odgovori",
   "status.replyAll": "Odgovori na temu",
   "status.report": "Prijavi @{name}",
-  "status.sensitive_toggle": "Klikni da bi vidio",
   "status.sensitive_warning": "Osjetljiv sadržaj",
   "status.share": "Share",
   "status.show_less": "Pokaži manje",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Lokalno",
   "tabs_bar.notifications": "Notifikacije",
   "tabs_bar.search": "Search",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
   "upload_area.title": "Povuci i spusti kako bi uploadao",
   "upload_button.label": "Dodaj media",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.focus": "Crop",
   "upload_form.undo": "Poništi",
diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json
index c2842aea7b677ad42a291f4eae30a5aa759fb772..1c3b63d7d2e70798e240257dc36e37fa1a4eadbc 100644
--- a/app/javascript/mastodon/locales/hu.json
+++ b/app/javascript/mastodon/locales/hu.json
@@ -1,103 +1,107 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "Hozzáadás és elvétel listáról",
   "account.badges.bot": "Bot",
   "account.block": "@{name} letiltása",
   "account.block_domain": "Minden elrejtése innen: {domain}",
-  "account.blocked": "Blocked",
-  "account.direct": "Direct Message @{name}",
-  "account.disclaimer_full": "Az alul található információk hiányosan mutathatják be a felhasználót.",
-  "account.domain_blocked": "Domain hidden",
+  "account.blocked": "Letiltva",
+  "account.direct": "Közvetlen üzenet @{name} számára",
+  "account.domain_blocked": "Rejtett domain",
   "account.edit_profile": "Profil szerkesztése",
-  "account.endorse": "Feature on profile",
+  "account.endorse": "Kiemelés a profilodon",
   "account.follow": "Követés",
-  "account.followers": "Követők",
-  "account.followers.empty": "No one follows this user yet.",
-  "account.follows": "Követve",
-  "account.follows.empty": "This user doesn't follow anyone yet.",
-  "account.follows_you": "Követnek téged",
-  "account.hide_reblogs": "Rejtsd el a tülkölést @{name}-tól/től",
-  "account.link_verified_on": "Ownership of this link was checked on {date}",
-  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
+  "account.followers": "Követő",
+  "account.followers.empty": "Ezt a felhasználót még senki sem követi.",
+  "account.follows": "Követett",
+  "account.follows.empty": "Ez a felhasználó még senkit sem követ.",
+  "account.follows_you": "Követ téged",
+  "account.hide_reblogs": "@{name} megtolásainak némítása",
+  "account.link_verified_on": "A linket ellenőriztük: {date}",
+  "account.locked_info": "Ez a fiók zárt. A tulaj engedélyezi, ki követheti őt.",
   "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.muted": "Muted",
-  "account.posts": "Státuszok",
-  "account.posts_with_replies": "Toots with replies",
+  "account.mute_notifications": "@{name} értesítéseinek némítása",
+  "account.muted": "Némítva",
+  "account.posts": "Tülkölés",
+  "account.posts_with_replies": "Tülkölés válaszokkal",
   "account.report": "@{name} jelentése",
-  "account.requested": "Engedélyre vár. Kattintson a követési kérés visszavonására",
+  "account.requested": "Engedélyre vár. Kattints a követési kérés visszavonásához",
   "account.share": "@{name} profiljának megosztása",
-  "account.show_reblogs": "@{name} kedvenceinek mutatása",
-  "account.unblock": "@{name} kiblokkolása",
-  "account.unblock_domain": "{domain} mutatása",
-  "account.unendorse": "Don't feature on profile",
-  "account.unfollow": "Követés abbahagyása",
-  "account.unmute": "@{name} kinémítása",
-  "account.unmute_notifications": "@{name} értesítéseinek kinémítása",
-  "account.view_full_profile": "Teljes profil megtekintése",
-  "alert.unexpected.message": "An unexpected error occurred.",
-  "alert.unexpected.title": "Oops!",
-  "boost_modal.combo": "Megnyomhatod {combo}, hogy átugord következő alkalommal",
+  "account.show_reblogs": "@{name} megtolásainak mutatása",
+  "account.unblock": "@{name} letiltásának feloldása",
+  "account.unblock_domain": "{domain} elrejtésének feloldása",
+  "account.unendorse": "Kiemelés törlése a profilodról",
+  "account.unfollow": "Követés vége",
+  "account.unmute": "@{name} némítás feloldása",
+  "account.unmute_notifications": "@{name} némított értesítéseinek feloldása",
+  "alert.unexpected.message": "Váratlan hiba történt.",
+  "alert.unexpected.title": "Hoppá!",
+  "boost_modal.combo": "Hogy átugord ezt következő alkalommal, használd {combo}",
   "bundle_column_error.body": "Hiba történt a komponens betöltése közben.",
-  "bundle_column_error.retry": "Próbálja újra",
+  "bundle_column_error.retry": "Próbáld újra",
   "bundle_column_error.title": "Hálózati hiba",
-  "bundle_modal_error.close": "Bezár",
+  "bundle_modal_error.close": "Bezárás",
   "bundle_modal_error.message": "Hiba történt a komponens betöltésekor.",
-  "bundle_modal_error.retry": "Próbálja újra",
+  "bundle_modal_error.retry": "Próbáld újra",
   "column.blocks": "Letiltott felhasználók",
   "column.community": "Helyi idővonal",
-  "column.direct": "Direct messages",
-  "column.domain_blocks": "Hidden domains",
+  "column.direct": "Közvetlen üzenetek",
+  "column.domain_blocks": "Rejtett domainek",
   "column.favourites": "Kedvencek",
-  "column.follow_requests": "Követési kérések",
+  "column.follow_requests": "Követési kérelmek",
   "column.home": "Kezdőlap",
   "column.lists": "Listák",
   "column.mutes": "Némított felhasználók",
   "column.notifications": "Értesítések",
-  "column.pins": "Kitűzött tülkölések",
+  "column.pins": "Kitűzött tülkök",
   "column.public": "Nyilvános idővonal",
   "column_back_button.label": "Vissza",
   "column_header.hide_settings": "Beállítások elrejtése",
   "column_header.moveLeft_settings": "Oszlop elmozdítása balra",
-  "column_header.moveRight_settings": "oszlop elmozdítása jobbra",
-  "column_header.pin": "Kitűz",
+  "column_header.moveRight_settings": "Oszlop elmozdítása jobbra",
+  "column_header.pin": "Kitűzés",
   "column_header.show_settings": "Beállítások mutatása",
   "column_header.unpin": "Kitűzés eltávolítása",
   "column_subheading.settings": "Beállítások",
-  "community.column_settings.media_only": "Media Only",
-  "compose_form.direct_message_warning": "This toot will only be visible to all the mentioned users.",
-  "compose_form.direct_message_warning_learn_more": "Learn more",
-  "compose_form.hashtag_warning": "Ezen tülkölés nem fog megjelenni semmilyen hashtag alatt mivel listázatlan. Csak a publikus tülkölések kereshetőek hashtag-el.",
-  "compose_form.lock_disclaimer": "Az ön fiókja nincs {locked}. Bárki követni tud, hogy megtekintse a kizárt követőknek szánt üzeneteid.",
+  "community.column_settings.media_only": "Csak média",
+  "compose_form.direct_message_warning": "Ezt a tülköt csak a benne megemlített felhasználók láthatják majd.",
+  "compose_form.direct_message_warning_learn_more": "Több infó",
+  "compose_form.hashtag_warning": "Ez a tülköd nem fog megjelenni semmilyen hashtag alatt mivel listázatlan. Csak nyilvános tülkök kereshetőek hashtaggel.",
+  "compose_form.lock_disclaimer": "A fiókod nincs {locked}. Bárki követni tud, hogy megtekintse a kizárólag követőknek szánt üzeneteidet.",
   "compose_form.lock_disclaimer.lock": "lezárva",
-  "compose_form.placeholder": "Mire gondolsz?",
+  "compose_form.placeholder": "Mi jár a fejedben?",
+  "compose_form.poll.add_option": "Lehetőség hozzáadása",
+  "compose_form.poll.duration": "Szavazás időtartama",
+  "compose_form.poll.option_placeholder": "Lehetőség {number}",
+  "compose_form.poll.remove_option": "Lehetőség törlése",
   "compose_form.publish": "Tülk",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive.marked": "Media is marked as sensitive",
-  "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
-  "compose_form.spoiler.marked": "Text is hidden behind warning",
-  "compose_form.spoiler.unmarked": "Text is not hidden",
-  "compose_form.spoiler_placeholder": "Figyelmeztetését írja ide",
-  "confirmation_modal.cancel": "Bezár",
-  "confirmations.block.confirm": "Letilt",
-  "confirmations.block.message": "Biztos benne, hogy le szeretné tiltani {name}?",
-  "confirmations.delete.confirm": "Töröl",
-  "confirmations.delete.message": "Biztos benne, hogy törölni szeretné ezt a státuszt?",
-  "confirmations.delete_list.confirm": "Töröl",
-  "confirmations.delete_list.message": "Biztos benne, hogy véglegesen törölni szeretné ezt a listát?",
-  "confirmations.domain_block.confirm": "Egész domain elrejtése",
-  "confirmations.domain_block.message": "Nagyon biztos abban, hogy le szeretné tiltani az egész {domain}-t? A legtöbb esetben néhány célszerű tiltás vagy némítás elegendő és kívánatosabb megoldás.",
-  "confirmations.mute.confirm": "Némít",
-  "confirmations.mute.message": "Biztos benne, hogy némítani szeretné {name}?",
-  "confirmations.redraft.confirm": "Delete & redraft",
-  "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.",
-  "confirmations.reply.confirm": "Reply",
-  "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
+  "compose_form.sensitive.hide": "Média megjelölése szenzitívként",
+  "compose_form.sensitive.marked": "A médiát szenzitívnek jelölték",
+  "compose_form.sensitive.unmarked": "A médiát nem jelölték szenzitívnek",
+  "compose_form.spoiler.marked": "A szöveg figyelmeztetés mögé van rejtve",
+  "compose_form.spoiler.unmarked": "A szöveg nem rejtett",
+  "compose_form.spoiler_placeholder": "Írd ide a figyelmeztetést",
+  "confirmation_modal.cancel": "Mégse",
+  "confirmations.block.block_and_report": "Letiltás és Bejelentés",
+  "confirmations.block.confirm": "Letiltás",
+  "confirmations.block.message": "Biztos, hogy le szeretnéd tiltani {name}?",
+  "confirmations.delete.confirm": "Törlés",
+  "confirmations.delete.message": "Biztos, hogy törölni szeretnéd ezt a tülkölést?",
+  "confirmations.delete_list.confirm": "Törlés",
+  "confirmations.delete_list.message": "Biztos, hogy véglegesen törölni szeretnéd ezt a listát?",
+  "confirmations.domain_block.confirm": "Teljes domain elrejtése",
+  "confirmations.domain_block.message": "Egészen biztos, hogy le szeretnéd tiltani a teljes {domain}-t? A legtöbb esetben néhány célzott tiltás vagy némítás elegendő és kívánatosabb megoldás. Semmilyen tartalmat nem fogsz látni ebből a domainből se idővonalakon, se értesítésekben. Az ebben a domainben lévő követőidet is eltávolítjuk.",
+  "confirmations.mute.confirm": "Némítás",
+  "confirmations.mute.message": "Biztos, hogy némítani szeretnéd {name}?",
+  "confirmations.redraft.confirm": "Törlés és újraírás",
+  "confirmations.redraft.message": "Biztos, hogy ezt a tülköt szeretnéd törölni és újraírni? Minden megtolást és kedvencnek jelölést elvesztesz, az eredetire adott válaszok pedig elárvulnak.",
+  "confirmations.reply.confirm": "Válasz",
+  "confirmations.reply.message": "Ha most válaszolsz, ez felülírja a most szerkesztés alatt álló üzenetet. Mégis ezt szeretnéd?",
   "confirmations.unfollow.confirm": "Követés visszavonása",
-  "confirmations.unfollow.message": "Biztos benne, hogy vissza szeretné vonni {name} követését?",
-  "embed.instructions": "Ágyazza be ezen státuszt weboldalába az alábbi kód másolásával.",
+  "confirmations.unfollow.message": "Biztos, hogy vissza szeretnéd vonni {name} követését?",
+  "embed.instructions": "Ágyazd be ezt a tülköt a weboldaladba az alábbi kód kimásolásával.",
   "embed.preview": "Így fog kinézni:",
   "emoji_button.activity": "Aktivitás",
   "emoji_button.custom": "Egyéni",
@@ -105,7 +109,7 @@
   "emoji_button.food": "Étel és Ital",
   "emoji_button.label": "Emoji beszúrása",
   "emoji_button.nature": "Természet",
-  "emoji_button.not_found": "Nincsenek emojok!! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.not_found": "Nincsenek emojik!! (╯°□°)╯︵ ┻━┻",
   "emoji_button.objects": "Tárgyak",
   "emoji_button.people": "Emberek",
   "emoji_button.recent": "Gyakran használt",
@@ -113,246 +117,272 @@
   "emoji_button.search_results": "Keresési találatok",
   "emoji_button.symbols": "Szimbólumok",
   "emoji_button.travel": "Utazás és Helyek",
-  "empty_column.account_timeline": "No toots here!",
-  "empty_column.blocks": "You haven't blocked any users yet.",
-  "empty_column.community": "A helyi idővonal üres. Írj egy publikus stástuszt, hogy elindítsd a labdát!",
-  "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
-  "empty_column.domain_blocks": "There are no hidden domains yet.",
-  "empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.",
-  "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.",
-  "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
-  "empty_column.hashtag": "Jelenleg nem található semmi ezen hashtaggel.",
-  "empty_column.home": "A hazai idővonala üres! Látogasd meg a {public} vagy használd a keresőt, hogy ismerj meg más felhasználókat.",
-  "empty_column.home.public_timeline": "publikus idővonal",
-  "empty_column.list": "A lista jelenleg üres. Mikor a listatagok új státuszt posztolnak itt meg fognak jelenni.",
-  "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
-  "empty_column.mutes": "You haven't muted any users yet.",
-  "empty_column.notifications": "Jelenleg nincsenek értesítései. Lépj kapcsolatba másokkal, hogy indítsd el a beszélgetést.",
-  "empty_column.public": "Jelenleg semmi nincs itt! Írj valamit publikusan vagy kövess más szervereken levő felhasználókat, hogy megtöltsd",
-  "follow_request.authorize": "Engedélyez",
-  "follow_request.reject": "Visszautasít",
-  "getting_started.developers": "Developers",
-  "getting_started.directory": "Profile directory",
-  "getting_started.documentation": "Documentation",
+  "empty_column.account_timeline": "Itt nincs tülkölés!",
+  "empty_column.account_unavailable": "A profil nem elérhető",
+  "empty_column.blocks": "Még senkit sem tiltottál le.",
+  "empty_column.community": "A helyi idővonal üres. Tülkölj egyet nyilvánosan, hogy elindítsd az eseményeket!",
+  "empty_column.direct": "Még nincs egy közvetlen üzeneted sem. Ha küldesz vagy kapsz egyet, itt fog megjelenni.",
+  "empty_column.domain_blocks": "Még nem rejtettél el egyetlen domaint sem.",
+  "empty_column.favourited_statuses": "Még nincs egy kedvenc tülköd sem. Ha kedvencnek jelölsz egyet, itt fog megjelenni.",
+  "empty_column.favourites": "Még senki sem jelölte ezt a tülköt kedvencként. Ha valaki mégis megteszi, itt fogjuk mutatni.",
+  "empty_column.follow_requests": "Még nincs egy követési kérésed sem. Ha kapsz egyet, itt fogjuk feltüntetni.",
+  "empty_column.hashtag": "Jelenleg nem található semmi ezzel a hashtaggel.",
+  "empty_column.home": "A saját idővonalad üres! Látogasd meg a {public} -at vagy használd a keresőt, hogy megismerj másokat.",
+  "empty_column.home.public_timeline": "nyilvános idővonal",
+  "empty_column.list": "A lista jelenleg üres. Ha a listatagok tülkölnek, itt fognak megjelenni.",
+  "empty_column.lists": "Még nem hoztál létre listát. Ha csinálsz egyet, itt látszik majd.",
+  "empty_column.mutes": "Még egy felhasználót sem némítottál le.",
+  "empty_column.notifications": "Jelenleg nincsenek értesítéseid. Lépj kapcsolatba másokkal, hogy elindítsd a beszélgetést.",
+  "empty_column.public": "Jelenleg itt nincs semmi! Írj valamit nyilvánosan vagy kövess más szervereken levő felhasználókat, hogy megtöltsd",
+  "follow_request.authorize": "Engedélyezés",
+  "follow_request.reject": "Visszautasítás",
+  "getting_started.developers": "Fejlesztőknek",
+  "getting_started.directory": "Profilok",
+  "getting_started.documentation": "Dokumentáció",
   "getting_started.heading": "Első lépések",
-  "getting_started.invite": "Invite people",
-  "getting_started.open_source_notice": "Mastodon egy nyílt forráskódú szoftver. Hozzájárulás vagy problémák jelentése a GitHub-on {github}.",
-  "getting_started.security": "Security",
-  "getting_started.terms": "Terms of service",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
-  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
-  "home.column_settings.basic": "Alap",
-  "home.column_settings.show_reblogs": "Ismétlések mutatása",
+  "getting_started.invite": "Mások meghívása",
+  "getting_started.open_source_notice": "A Mastodon nyílt forráskódú szoftver. Csatlakozhatsz a fejlesztéshez vagy jelenthetsz problémákat GitHub-on {github}.",
+  "getting_started.security": "Biztonság",
+  "getting_started.terms": "Felhasználási feltételek",
+  "hashtag.column_header.tag_mode.all": "és {additional}",
+  "hashtag.column_header.tag_mode.any": "vagy {additional}",
+  "hashtag.column_header.tag_mode.none": "nélküle {additional}",
+  "hashtag.column_settings.select.no_options_message": "Nincs javaslat",
+  "hashtag.column_settings.select.placeholder": "Addj meg hashtageket…",
+  "hashtag.column_settings.tag_mode.all": "Mindegyik",
+  "hashtag.column_settings.tag_mode.any": "Bármelyik",
+  "hashtag.column_settings.tag_mode.none": "Egyik sem",
+  "hashtag.column_settings.tag_toggle": "Új tagek felvétele ehhez az oszlophoz",
+  "home.column_settings.basic": "Alapértelmezések",
+  "home.column_settings.show_reblogs": "Megtolások mutatása",
   "home.column_settings.show_replies": "Válaszok mutatása",
-  "introduction.federation.action": "Next",
-  "introduction.federation.federated.headline": "Federated",
-  "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
-  "introduction.federation.home.headline": "Home",
-  "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
-  "introduction.federation.local.headline": "Local",
-  "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
-  "introduction.interactions.favourite.headline": "Favourite",
-  "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
-  "introduction.interactions.reblog.headline": "Boost",
-  "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
-  "introduction.interactions.reply.headline": "Reply",
-  "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
-  "introduction.welcome.action": "Let's go!",
-  "introduction.welcome.headline": "First steps",
-  "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
-  "keyboard_shortcuts.back": "vissza navigálás",
-  "keyboard_shortcuts.blocked": "to open blocked users list",
-  "keyboard_shortcuts.boost": "ismétlés",
-  "keyboard_shortcuts.column": "összpontosítson egy státuszra az egyik oszlopban",
-  "keyboard_shortcuts.compose": "fókuszálja a szerkesztési szövegdobozt",
+  "intervals.full.days": "{number, plural, one {# nap} other {# nap}}",
+  "intervals.full.hours": "{number, plural, one {# óra} other {# óra}}",
+  "intervals.full.minutes": "{number, plural, one {# perc} other {# perc}}",
+  "introduction.federation.action": "Következő",
+  "introduction.federation.federated.headline": "Föderációs",
+  "introduction.federation.federated.text": "A fediverzum más szervereiről származó nyilvános tülkök a föderációs idővonalon jelennek meg.",
+  "introduction.federation.home.headline": "Saját",
+  "introduction.federation.home.text": "A saját idővonaladon az általad követettek tülkjei jelennek meg. Bárkit követhetsz bármely szerveren.",
+  "introduction.federation.local.headline": "Helyi",
+  "introduction.federation.local.text": "A helyi idővonalon a veled közös szerveren lévő emberek nyilvános tülkjei jelennek meg.",
+  "introduction.interactions.action": "Oktatóanyag befejezése!",
+  "introduction.interactions.favourite.headline": "Kedvenc",
+  "introduction.interactions.favourite.text": "A kedvenc funkcióval elrakhatsz későbbre egy tülköt, illetve közölheted a szerzővel, hogy tetszett a megosztása.",
+  "introduction.interactions.reblog.headline": "Megtolás",
+  "introduction.interactions.reblog.text": "A saját követőiddel mások tülkjeit is megoszthatod úgy, hogy megtolod őket.",
+  "introduction.interactions.reply.headline": "Válasz",
+  "introduction.interactions.reply.text": "Saját vagy mások tülkjeire válaszolva egy beszélgetési láncot alakíthatsz ki.",
+  "introduction.welcome.action": "Csapjunk bele!",
+  "introduction.welcome.headline": "Első lépések",
+  "introduction.welcome.text": "Üdv a fediverzumban! Pár pillanat múlva már küldheted is üzeneteidet barátaidnak bármely szerveren. Ez a szerver {domain} viszont különleges. Ez tartja nyilván a profilod, szóval jegyezd meg a nevét.",
+  "keyboard_shortcuts.back": "visszafelé navigálás",
+  "keyboard_shortcuts.blocked": "letiltott felhasználók listájának megnyitása",
+  "keyboard_shortcuts.boost": "megtolás",
+  "keyboard_shortcuts.column": "fókuszálás egy tülkre az egyik oszlopban",
+  "keyboard_shortcuts.compose": "fókuszálás a szerkesztési szövegdobozra",
   "keyboard_shortcuts.description": "Leírás",
-  "keyboard_shortcuts.direct": "to open direct messages column",
+  "keyboard_shortcuts.direct": "közvetlen üzenetek megnyitása",
   "keyboard_shortcuts.down": "lefele navigálás a listában",
-  "keyboard_shortcuts.enter": "státusz megnyitása",
-  "keyboard_shortcuts.favourite": "kedvenccé tétel",
-  "keyboard_shortcuts.favourites": "to open favourites list",
-  "keyboard_shortcuts.federated": "to open federated timeline",
-  "keyboard_shortcuts.heading": "Billentyű rövidítések",
-  "keyboard_shortcuts.home": "to open home timeline",
+  "keyboard_shortcuts.enter": "tülk megnyitása",
+  "keyboard_shortcuts.favourite": "kedvencnek jelölés",
+  "keyboard_shortcuts.favourites": "kedvenc lista megnyitása",
+  "keyboard_shortcuts.federated": "föderációs idővonal megnyitása",
+  "keyboard_shortcuts.heading": "Billentyűparancsok",
+  "keyboard_shortcuts.home": "saját idővonal megnyitása",
   "keyboard_shortcuts.hotkey": "Gyorsbillentyű",
   "keyboard_shortcuts.legend": "jelmagyarázat megjelenítése",
-  "keyboard_shortcuts.local": "to open local timeline",
-  "keyboard_shortcuts.mention": "szerző megjelenítése",
-  "keyboard_shortcuts.muted": "to open muted users list",
-  "keyboard_shortcuts.my_profile": "to open your profile",
-  "keyboard_shortcuts.notifications": "to open notifications column",
-  "keyboard_shortcuts.pinned": "to open pinned toots list",
-  "keyboard_shortcuts.profile": "to open author's profile",
-  "keyboard_shortcuts.reply": "válaszolás",
-  "keyboard_shortcuts.requests": "to open follow requests list",
-  "keyboard_shortcuts.search": "kereső kiemelése",
-  "keyboard_shortcuts.start": "to open \"get started\" column",
-  "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
-  "keyboard_shortcuts.toot": "új tülk megkezdése",
+  "keyboard_shortcuts.local": "helyi idővonal megnyitása",
+  "keyboard_shortcuts.mention": "szerző megemlítése",
+  "keyboard_shortcuts.muted": "némított felhasználók listájának megnyitása",
+  "keyboard_shortcuts.my_profile": "profilod megnyitása",
+  "keyboard_shortcuts.notifications": "értesítések megnyitása",
+  "keyboard_shortcuts.pinned": "kitűzött tülkök listájának megnyitása",
+  "keyboard_shortcuts.profile": "szerző profiljának megnyitása",
+  "keyboard_shortcuts.reply": "válasz",
+  "keyboard_shortcuts.requests": "követési kérések listájának megnyitása",
+  "keyboard_shortcuts.search": "fókuszálás a keresőre",
+  "keyboard_shortcuts.start": "\"Első lépések\" megnyitása",
+  "keyboard_shortcuts.toggle_hidden": "tartalmi figyelmeztetéssel ellátott szöveg mutatása/elrejtése",
+  "keyboard_shortcuts.toggle_sensitivity": "média mutatása/elrejtése",
+  "keyboard_shortcuts.toot": "új tülk írása",
   "keyboard_shortcuts.unfocus": "tülk szerkesztés/keresés fókuszpontból való kivétele",
-  "keyboard_shortcuts.up": "fennebb helyezés a listában",
+  "keyboard_shortcuts.up": "felfelé mozdítás a listában",
   "lightbox.close": "Bezárás",
   "lightbox.next": "Következő",
   "lightbox.previous": "Előző",
+  "lightbox.view_context": "Kontextus megtekintése",
   "lists.account.add": "Hozzáadás a listához",
-  "lists.account.remove": "Eltávolít a listából",
+  "lists.account.remove": "Eltávolítás a listából",
   "lists.delete": "Lista törlése",
   "lists.edit": "Lista szerkesztése",
+  "lists.edit.submit": "Cím megváltoztatása",
   "lists.new.create": "Lista hozzáadása",
-  "lists.new.title_placeholder": "Új lista cím",
-  "lists.search": "Keresés a követtett személyek között",
+  "lists.new.title_placeholder": "Új lista címe",
+  "lists.search": "Keresés a követett személyek között",
   "lists.subheading": "Listáid",
   "loading_indicator.label": "Betöltés...",
-  "media_gallery.toggle_visible": "Láthatóság váltása",
+  "media_gallery.toggle_visible": "Láthatóság állítása",
   "missing_indicator.label": "Nincs találat",
-  "missing_indicator.sublabel": "Ezen forrás nem található",
-  "mute_modal.hide_notifications": "Értesítések elrejtése ezen felhasználótól?",
-  "navigation_bar.apps": "Mobile apps",
-  "navigation_bar.blocks": "Tiltott felhasználók",
+  "missing_indicator.sublabel": "Ez az erőforrás nem található",
+  "mute_modal.hide_notifications": "Rejtsük el a felhasználótól származó értesítéseket?",
+  "navigation_bar.apps": "Mobil appok",
+  "navigation_bar.blocks": "Letiltott felhasználók",
   "navigation_bar.community_timeline": "Helyi idővonal",
-  "navigation_bar.compose": "Compose new toot",
-  "navigation_bar.direct": "Direct messages",
-  "navigation_bar.discover": "Discover",
-  "navigation_bar.domain_blocks": "Hidden domains",
+  "navigation_bar.compose": "Új tülk írása",
+  "navigation_bar.direct": "Közvetlen üzenetek",
+  "navigation_bar.discover": "Felfedezés",
+  "navigation_bar.domain_blocks": "Rejtett domainek",
   "navigation_bar.edit_profile": "Profil szerkesztése",
   "navigation_bar.favourites": "Kedvencek",
-  "navigation_bar.filters": "Muted words",
-  "navigation_bar.follow_requests": "Követési kérések",
-  "navigation_bar.info": "Ezen szerverről",
+  "navigation_bar.filters": "Némított szavak",
+  "navigation_bar.follow_requests": "Követési kérelmek",
+  "navigation_bar.follows_and_followers": "Követettek és követők",
+  "navigation_bar.info": "Erről a szerverről",
   "navigation_bar.keyboard_shortcuts": "Gyorsbillentyűk",
   "navigation_bar.lists": "Listák",
   "navigation_bar.logout": "Kijelentkezés",
   "navigation_bar.mutes": "Némított felhasználók",
-  "navigation_bar.personal": "Personal",
+  "navigation_bar.personal": "Személyes",
   "navigation_bar.pins": "Kitűzött tülkök",
   "navigation_bar.preferences": "Beállítások",
-  "navigation_bar.public_timeline": "Nyilvános időfolyam",
-  "navigation_bar.security": "Security",
-  "notification.favourite": "{name} kedvencnek jelölte az állapotod",
+  "navigation_bar.profile_directory": "Profilok",
+  "navigation_bar.public_timeline": "Föderációs idővonal",
+  "navigation_bar.security": "Biztonság",
+  "notification.favourite": "{name} kedvencnek jelölte egy tülködet",
   "notification.follow": "{name} követ téged",
   "notification.mention": "{name} megemlített",
-  "notification.reblog": "{name} rebloggolta az állapotod",
+  "notification.poll": "Egy szavazás, melyben részt vettél, véget ért",
+  "notification.reblog": "{name} megtolta a tülködet",
   "notifications.clear": "Értesítések törlése",
-  "notifications.clear_confirmation": "Biztos benne, hogy véglegesen törölni akarja az összes értesítését?",
-  "notifications.column_settings.alert": "Asztali gépi értesítések",
+  "notifications.clear_confirmation": "Biztos, hogy véglegesen törölni akarod az összes értesítésed?",
+  "notifications.column_settings.alert": "Asztali értesítések",
   "notifications.column_settings.favourite": "Kedvencek:",
-  "notifications.column_settings.filter_bar.advanced": "Display all categories",
-  "notifications.column_settings.filter_bar.category": "Quick filter bar",
-  "notifications.column_settings.filter_bar.show": "Show",
+  "notifications.column_settings.filter_bar.advanced": "Minden kategória mutatása",
+  "notifications.column_settings.filter_bar.category": "Gyorskereső mező",
+  "notifications.column_settings.filter_bar.show": "Mutat",
   "notifications.column_settings.follow": "Új követők:",
-  "notifications.column_settings.mention": "Megemítéseim:",
+  "notifications.column_settings.mention": "Megemlítéseid:",
+  "notifications.column_settings.poll": "Szavazás eredménye:",
   "notifications.column_settings.push": "Push értesítések",
-  "notifications.column_settings.reblog": "Rebloggolások:",
+  "notifications.column_settings.reblog": "Megtolások:",
   "notifications.column_settings.show": "Oszlopban mutatás",
   "notifications.column_settings.sound": "Hang lejátszása",
-  "notifications.filter.all": "All",
-  "notifications.filter.boosts": "Boosts",
-  "notifications.filter.favourites": "Favourites",
-  "notifications.filter.follows": "Follows",
-  "notifications.filter.mentions": "Mentions",
-  "notifications.group": "{count} notifications",
-  "privacy.change": "Státusz láthatóságának módosítása",
-  "privacy.direct.long": "Posztolás csak az említett felhasználóknak",
-  "privacy.direct.short": "Egyenesen",
-  "privacy.private.long": "Posztolás csak követőknek",
+  "notifications.filter.all": "Mind",
+  "notifications.filter.boosts": "Megtolások",
+  "notifications.filter.favourites": "Kedvencnek jelölések",
+  "notifications.filter.follows": "Követések",
+  "notifications.filter.mentions": "Megemlítések",
+  "notifications.filter.polls": "Szavazások eredményei",
+  "notifications.group": "{count} értesítés",
+  "poll.closed": "Lezárva",
+  "poll.refresh": "Frissítés",
+  "poll.total_votes": "{count, plural, one {# szavazat} other {# szavazat}}",
+  "poll.vote": "Szavazás",
+  "poll_button.add_poll": "Új szavazás",
+  "poll_button.remove_poll": "Szavazás törlése",
+  "privacy.change": "Tülk láthatóságának módosítása",
+  "privacy.direct.long": "Tülk csak az említett felhasználóknak",
+  "privacy.direct.short": "Közvetlen",
+  "privacy.private.long": "Tülk csak követőknek",
   "privacy.private.short": "Csak követőknek",
-  "privacy.public.long": "Posztolás a publikus idővonalakra",
-  "privacy.public.short": "Publikus",
-  "privacy.unlisted.long": "Do not show in public timelines",
+  "privacy.public.long": "Tülk a nyilvános idővonalra",
+  "privacy.public.short": "Nyilvános",
+  "privacy.unlisted.long": "Ne mutassuk nyilvános idővonalon",
   "privacy.unlisted.short": "Listázatlan",
   "regeneration_indicator.label": "Töltődik…",
-  "regeneration_indicator.sublabel": "Your home feed is being prepared!",
-  "relative_time.days": "{number}d",
-  "relative_time.hours": "{number}h",
+  "regeneration_indicator.sublabel": "A saját idővonalad épp készül!",
+  "relative_time.days": "{number}nap",
+  "relative_time.hours": "{number}ó",
   "relative_time.just_now": "most",
-  "relative_time.minutes": "{number}m",
-  "relative_time.seconds": "{number}s",
+  "relative_time.minutes": "{number}p",
+  "relative_time.seconds": "{number}mp",
   "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",
+  "report.forward": "Továbbítás neki {target}",
+  "report.forward_hint": "Ez a fiók egy másik szerverről van. Küldjünk oda is egy anonimizált bejelentést?",
+  "report.hint": "A bejelentést a szervered moderátorainak küldjük el. Megmagyarázhatod, miért jelented az alábbi problémát:",
+  "report.placeholder": "További megjegyzések",
+  "report.submit": "Küldés",
+  "report.target": "{target} jelentése",
   "search.placeholder": "Keresés",
-  "search_popout.search_format": "Fejlett keresés",
-  "search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
+  "search_popout.search_format": "Haladó keresés",
+  "search_popout.tips.full_text": "Egyszerű szöveg. Illeszkedő, általad írt tülköket, kedvencnek jelöléseket, megtolást, megemlítést, felhasználói nevet, megjelenített nevet, hashtageket ad majd vissza.",
   "search_popout.tips.hashtag": "hashtag",
-  "search_popout.tips.status": "status",
-  "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
+  "search_popout.tips.status": "tülk",
+  "search_popout.tips.text": "Egyszerű szöveg. Illeszkedő megjelenített nevet, felhasználói nevet, hashtageket ad majd vissza",
   "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.admin_account": "Open moderation interface for @{name}",
-  "status.admin_status": "Open this status in the moderation interface",
-  "status.block": "Block @{name}",
-  "status.cancel_reblog_private": "Unboost",
-  "status.cannot_reblog": "Ezen státusz nem rebloggolható",
+  "search_results.accounts": "Emberek",
+  "search_results.hashtags": "Hashtagek",
+  "search_results.statuses": "Tülkök",
+  "search_results.total": "{count, number} {count, plural, one {találat} other {találat}}",
+  "status.admin_account": "Moderáció megnyitása @{name} felhasználóhoz",
+  "status.admin_status": "Tülk megnyitása moderációra",
+  "status.block": "@{name} letiltása",
+  "status.cancel_reblog_private": "Megtolás törlése",
+  "status.cannot_reblog": "Ez a tülk nem tolható meg",
+  "status.copy": "Link másolása tülkbe",
   "status.delete": "Törlés",
-  "status.detailed_status": "Detailed conversation view",
-  "status.direct": "Direct message @{name}",
-  "status.embed": "Beágyaz",
+  "status.detailed_status": "Részletes beszélgetési nézet",
+  "status.direct": "Közvetlen üzenet @{name} számára",
+  "status.embed": "Beágyazás",
   "status.favourite": "Kedvenc",
-  "status.filtered": "Filtered",
+  "status.filtered": "Megszűrt",
   "status.load_more": "Többet",
   "status.media_hidden": "Média elrejtve",
-  "status.mention": "Említés",
+  "status.mention": "@{name} említése",
   "status.more": "Többet",
   "status.mute": "@{name} némítása",
   "status.mute_conversation": "Beszélgetés némítása",
-  "status.open": "Státusz kinagyítása",
+  "status.open": "Tülk kibontása",
   "status.pin": "Kitűzés a profilra",
-  "status.pinned": "Pinned toot",
-  "status.read_more": "Read more",
-  "status.reblog": "Reblog",
-  "status.reblog_private": "Boost to original audience",
-  "status.reblogged_by": "{name} reblogolta",
-  "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
-  "status.redraft": "Delete & re-draft",
+  "status.pinned": "Kitűzött tülk",
+  "status.read_more": "Bővebben",
+  "status.reblog": "Megtolás",
+  "status.reblog_private": "Megtolás az eredeti közönségnek",
+  "status.reblogged_by": "{name} megtolta",
+  "status.reblogs.empty": "Senki sem tolta még meg ezt a tülköt. Ha valaki megteszi, itt fog megjelenni.",
+  "status.redraft": "Törlés és újraírás",
   "status.reply": "Válasz",
-  "status.replyAll": "Válaszolj a beszélgetésre",
-  "status.report": "Report @{name}",
-  "status.sensitive_toggle": "Katt a megtekintéshez",
-  "status.sensitive_warning": "Érzékeny tartalom",
+  "status.replyAll": "Válasz a beszélgetésre",
+  "status.report": "@{name} jelentése",
+  "status.sensitive_warning": "Szenzitív tartalom",
   "status.share": "Megosztás",
-  "status.show_less": "Kevesebb",
-  "status.show_less_all": "Show less for all",
+  "status.show_less": "Kevesebbet",
+  "status.show_less_all": "Kevesebbet mindenhol",
   "status.show_more": "Többet",
-  "status.show_more_all": "Show more for all",
-  "status.show_thread": "Show thread",
-  "status.unmute_conversation": "Beszélgetés némításának elvonása",
-  "status.unpin": "Kitűzés eltávolítása a profilról",
-  "suggestions.dismiss": "Dismiss suggestion",
-  "suggestions.header": "You might be interested in…",
-  "tabs_bar.federated_timeline": "Federált",
-  "tabs_bar.home": "Kezdőlap",
-  "tabs_bar.local_timeline": "Local",
+  "status.show_more_all": "Többet mindenhol",
+  "status.show_thread": "Szál mutatása",
+  "status.unmute_conversation": "Beszélgetés némításának kikapcsolása",
+  "status.unpin": "Kitűzés eltávolítása a profilodról",
+  "suggestions.dismiss": "Javaslat elvetése",
+  "suggestions.header": "Esetleg érdekelhet…",
+  "tabs_bar.federated_timeline": "Föderációs",
+  "tabs_bar.home": "Saját",
+  "tabs_bar.local_timeline": "Helyi",
   "tabs_bar.notifications": "Értesítések",
-  "tabs_bar.search": "Search",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
-  "ui.beforeunload": "A piszkozata el fog vesztődni ha elhagyja Mastodon-t.",
-  "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",
+  "tabs_bar.search": "Keresés",
+  "time_remaining.days": "{number, plural, one {# nap} other {# nap}} van hátra",
+  "time_remaining.hours": "{number, plural, one {# óra} other {# óra}} van hátra",
+  "time_remaining.minutes": "{number, plural, one {# perc} other {# perc}} van hátra",
+  "time_remaining.moments": "Pillanatok vannak hátra",
+  "time_remaining.seconds": "{number, plural, one {# másodperc} other {# másodperc}} van hátra",
+  "trends.count_by_accounts": "{count} {rawCount, plural, one {résztvevő} other {résztvevő}} beszélget",
+  "ui.beforeunload": "A piszkozatod el fog veszni, ha elhagyod a Mastodon-t.",
+  "upload_area.title": "Húzd ide a feltöltéshez",
+  "upload_button.label": "Média hozzáadása (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "Túllépted a fájl feltöltési limitet.",
+  "upload_error.poll": "Szavazásnál nem lehet fájlt feltölteni.",
+  "upload_form.description": "Leírás látáskorlátozottak számára",
+  "upload_form.focus": "Előnézet megváltoztatása",
   "upload_form.undo": "Mégsem",
-  "upload_progress.label": "Uploading...",
-  "video.close": "Close video",
-  "video.exit_fullscreen": "Exit full screen",
-  "video.expand": "Expand video",
-  "video.fullscreen": "Full screen",
-  "video.hide": "Hide video",
-  "video.mute": "Mute sound",
+  "upload_progress.label": "Feltöltés...",
+  "video.close": "Videó bezárása",
+  "video.exit_fullscreen": "Kilépés teljes képernyőből",
+  "video.expand": "Videó nagyítása",
+  "video.fullscreen": "Teljes képernyő",
+  "video.hide": "Videó elrejtése",
+  "video.mute": "Hang némitása",
   "video.pause": "Szünet",
   "video.play": "Lejátszás",
-  "video.unmute": "Hang kinémítása"
+  "video.unmute": "Hang némitásának vége"
 }
diff --git a/app/javascript/mastodon/locales/hy.json b/app/javascript/mastodon/locales/hy.json
index 6919948874fc5e814c32a582de975eacf9eb637c..b2dc16a484d55b283f61f6b5e2924397fb2f3c04 100644
--- a/app/javascript/mastodon/locales/hy.json
+++ b/app/javascript/mastodon/locales/hy.json
@@ -5,7 +5,6 @@
   "account.block_domain": "Թաքցնել ամենը հետեւյալ տիրույթից՝ {domain}",
   "account.blocked": "Blocked",
   "account.direct": "Direct Message @{name}",
-  "account.disclaimer_full": "Ներքոհիշյալը կարող է ոչ ամբողջությամբ արտացոլել օգտատիրոջ էջի տվյալները։",
   "account.domain_blocked": "Domain hidden",
   "account.edit_profile": "Ô½Õ´Õ¢Õ¡Õ£Ö€Õ¥Õ¬ Õ¡Õ¶Õ±Õ¶Õ¡Õ¯Õ¡Õ¶ Õ§Õ»Õ¨",
   "account.endorse": "Feature on profile",
@@ -36,7 +35,6 @@
   "account.unfollow": "Õ‰Õ°Õ¥Õ¿Õ¥Ö‚Õ¥Õ¬",
   "account.unmute": "Ապալռեցնել @{name}֊ին",
   "account.unmute_notifications": "Միացնել ծանուցումները @{name}֊ից",
-  "account.view_full_profile": "Ô´Õ«Õ¿Õ¥Õ¬ Õ¡Õ´Õ¢Õ¸Õ²Õ»Õ¡Õ¯Õ¡Õ¶ Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ¡Õ¯Õ¨Ö‰",
   "alert.unexpected.message": "An unexpected error occurred.",
   "alert.unexpected.title": "Oops!",
   "boost_modal.combo": "Կարող ես սեղմել {combo}՝ սա հաջորդ անգամ բաց թողնելու համար",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "Õ”Õ¸ Õ°Õ¡Õ·Õ«Õ¾Õ¨ {locked} Õ¹Õ§Ö‰ Õ…Õ¸Ö‚Ö€Õ¡Ö„Õ¡Õ¶Õ¹ÕµÕ¸Ö‚Ö€ Õ¸Ö„ Õ¯Õ¡Ö€Õ¸Õ² Õ§ Õ°Õ¥Õ¿Õ¥Ö‚Õ¥Õ¬ Ö„Õ¥Õ¦ Õ¥Ö‚ Õ¿Õ¥Õ½Õ¶Õ¥Õ¬ Õ´Õ«Õ¡ÕµÕ¶ Õ°Õ¥Õ¿Õ¥Ö‚Õ¸Õ²Õ¶Õ¥Ö€Õ« Õ°Õ¡Õ´Õ¡Ö€ Õ¶Õ¡Õ­Õ¡Õ¿Õ¥Õ½Õ¾Õ¡Õ® Õ£Ö€Õ¡Õ¼Õ¸Ö‚Õ´Õ¶Õ¥Ö€Õ¨Ö‰",
   "compose_form.lock_disclaimer.lock": "ÖƒÕ¡Õ¯",
   "compose_form.placeholder": "Ô»ÕžÕ¶Õ¹ Õ¯Õ¡ Õ´Õ¿Ö„Õ«Õ¤",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
   "compose_form.publish": "Ô¹Õ©Õ¥Õ¬",
   "compose_form.publish_loud": "Թթե՜լ",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
   "compose_form.sensitive.marked": "Media is marked as sensitive",
   "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
   "compose_form.spoiler.marked": "Text is hidden behind warning",
   "compose_form.spoiler.unmarked": "Text is not hidden",
   "compose_form.spoiler_placeholder": "Գրիր նախազգուշացումդ այստեղ",
   "confirmation_modal.cancel": "Õ‰Õ¥Õ²Õ¡Ö€Õ¯Õ¥Õ¬",
+  "confirmations.block.block_and_report": "Block & Report",
   "confirmations.block.confirm": "Ô±Ö€Õ£Õ¥Õ¬Õ¡ÖƒÕ¡Õ¯Õ¥Õ¬",
   "confirmations.block.message": "ÕŽÕ½Õ¿Õ¡ÕžÕ° Õ¥Õ½, Õ¸Ö€ Õ¸Ö‚Õ¦Õ¸Ö‚Õ´ Õ¥Õ½ Õ¡Ö€Õ£Õ¥Õ¬Õ¡ÖƒÕ¡Õ¯Õ¥Õ¬ {name}ÖŠÕ«Õ¶Ö‰",
   "confirmations.delete.confirm": "Õ‹Õ¶Õ»Õ¥Õ¬",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Õ†Õ·Õ¡Õ¶Õ¶Õ¥Ö€",
   "emoji_button.travel": "ÕˆÖ‚Õ²Õ¥Ö‚Õ¸Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶ Õ¥Ö‚ Õ¿Õ¥Õ²Õ¡Õ¶Ö„Õ¶Õ¥Ö€",
   "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_unavailable": "Profile unavailable",
   "empty_column.blocks": "You haven't blocked any users yet.",
   "empty_column.community": "Տեղական հոսքը դատա՛րկ է։ Հրապարակային մի բան գրիր շարժիչը խոդ տալու համար։",
   "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "and {additional}",
   "hashtag.column_header.tag_mode.any": "or {additional}",
   "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
   "hashtag.column_settings.tag_mode.all": "All of these",
   "hashtag.column_settings.tag_mode.any": "Any of these",
   "hashtag.column_settings.tag_mode.none": "None of these",
@@ -149,6 +156,9 @@
   "home.column_settings.basic": "Õ€Õ«Õ´Õ¶Õ¡Õ¯Õ¡Õ¶",
   "home.column_settings.show_reblogs": "Ցուցադրել տարածածները",
   "home.column_settings.show_replies": "Ցուցադրել պատասխանները",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
   "introduction.federation.action": "Next",
   "introduction.federation.federated.headline": "Federated",
   "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
@@ -156,7 +166,7 @@
   "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
   "introduction.federation.local.headline": "Local",
   "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
+  "introduction.interactions.action": "Finish toot-orial!",
   "introduction.interactions.favourite.headline": "Favourite",
   "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
   "introduction.interactions.reblog.headline": "Boost",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "Õ¸Ö€Õ¸Õ¶Õ´Õ¡Õ¶ Õ¤Õ¡Õ·Õ¿Õ«Õ¶ Õ½Õ¥Ö‚Õ¥Õ¼Õ¾Õ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€",
   "keyboard_shortcuts.start": "to open \"get started\" column",
   "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "Õ©Õ¡Ö€Õ´ Õ©Õ¸Ö‚Õ© Õ½Õ¯Õ½Õ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€",
   "keyboard_shortcuts.unfocus": "տեքստի/որոնման տիրույթից ապասեւեռվելու համար",
   "keyboard_shortcuts.up": "ցանկով վերեւ շարժվելու համար",
   "lightbox.close": "Õ“Õ¡Õ¯Õ¥Õ¬",
   "lightbox.next": "Õ€Õ¡Õ»Õ¸Ö€Õ¤",
   "lightbox.previous": "Õ†Õ¡Õ­Õ¸Ö€Õ¤",
+  "lightbox.view_context": "View context",
   "lists.account.add": "Ավելացնել ցանկին",
   "lists.account.remove": "Հանել ցանկից",
   "lists.delete": "Ջնջել ցանկը",
   "lists.edit": "Փոփոխել ցանկը",
+  "lists.edit.submit": "Change title",
   "lists.new.create": "Ավելացնել ցանկ",
   "lists.new.title_placeholder": "Նոր ցանկի վերնագիր",
   "lists.search": "Փնտրել քո հետեւած մարդկանց մեջ",
@@ -224,19 +237,22 @@
   "navigation_bar.favourites": "Õ€Õ¡Õ¾Õ¡Õ¶Õ¡Õ®Õ¶Õ¥Ö€",
   "navigation_bar.filters": "Muted words",
   "navigation_bar.follow_requests": "Հետեւելու հայցեր",
+  "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.info": "Այս հանգույցի մասին",
   "navigation_bar.keyboard_shortcuts": "Ստեղնաշարի կարճատներ",
   "navigation_bar.lists": "Õ‘Õ¡Õ¶Õ¯Õ¥Ö€",
   "navigation_bar.logout": "Ô´Õ¸Ö‚Ö€Õ½ Õ£Õ¡Õ¬",
   "navigation_bar.mutes": "Լռեցրած օգտատերեր",
-  "navigation_bar.personal": "Personal",
+  "navigation_bar.personal": "Ô±Õ¶Õ±Õ¶Õ¡Õ¯Õ¡Õ¶",
   "navigation_bar.pins": "Ամրացված թթեր",
   "navigation_bar.preferences": "Õ†Õ¡Õ­Õ¡ÕºÕ¡Õ¿Õ¾Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¶Õ¥Ö€",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "Ô´Õ¡Õ·Õ¶Õ¡ÕµÕ«Õ¶ Õ°Õ¸Õ½Ö„",
-  "navigation_bar.security": "Security",
+  "navigation_bar.security": "Ô±Õ¶Õ¾Õ¿Õ¡Õ¶Õ£Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶",
   "notification.favourite": "{name} հավանեց թութդ",
   "notification.follow": "{name} սկսեց հետեւել քեզ",
   "notification.mention": "{name} նշեց քեզ",
+  "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "{name} տարածեց թութդ",
   "notifications.clear": "Մաքրել ծանուցումները",
   "notifications.clear_confirmation": "Վստա՞հ ես, որ ուզում ես մշտապես մաքրել քո բոլոր ծանուցումները։",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Show",
   "notifications.column_settings.follow": "Նոր հետեւողներ՝",
   "notifications.column_settings.mention": "Նշումներ՝",
+  "notifications.column_settings.poll": "Poll results:",
   "notifications.column_settings.push": "Հրելու ծանուցումներ",
   "notifications.column_settings.reblog": "Տարածածներից՝",
   "notifications.column_settings.show": "Ցուցադրել սյունում",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favourites",
   "notifications.filter.follows": "Follows",
   "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
   "notifications.group": "{count} notifications",
+  "poll.closed": "Closed",
+  "poll.refresh": "Refresh",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
   "privacy.change": "Ô¿Õ¡Ö€Õ£Õ¡Õ¾Õ¸Ö€Õ¥Õ¬ Õ©Õ©Õ« Õ£Õ¡Õ²Õ¿Õ¶Õ«Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨",
   "privacy.direct.long": "Ô¹Õ©Õ¥Õ¬ Õ´Õ«Õ¡ÕµÕ¶ Õ¶Õ·Õ¾Õ¡Õ® Ö…Õ£Õ¿Õ¡Õ¿Õ¥Ö€Õ¥Ö€Õ« Õ°Õ¡Õ´Õ¡Ö€",
   "privacy.direct.short": "Հասցեագրված",
@@ -290,13 +314,13 @@
   "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": "Այս պահին…",
+  "search_results.total": "{count, number} {count, plural, one {Õ¡Ö€Õ¤ÕµÕ¸Ö‚Õ¶Ö„} other {Õ¡Ö€Õ¤ÕµÕ¸Ö‚Õ¶Ö„}}",
   "status.admin_account": "Open moderation interface for @{name}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Ô±Ö€Õ£Õ¥Õ¬Õ¡ÖƒÕ¡Õ¯Õ¥Õ¬ @{name}ÖŠÕ«Õ¶",
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "Ô±ÕµÕ½ Õ©Õ¸Ö‚Õ©Õ¨ Õ¹Õ« Õ¯Õ¡Ö€Õ¸Õ² Õ¿Õ¡Ö€Õ¡Õ®Õ¾Õ¥Õ¬",
+  "status.copy": "Copy link to status",
   "status.delete": "Õ‹Õ¶Õ»Õ¥Õ¬",
   "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "ÕŠÕ¡Õ¿Õ¡Õ½Õ­Õ¡Õ¶Õ¥Õ¬",
   "status.replyAll": "ÕŠÕ¡Õ¿Õ¡Õ½Õ­Õ¡Õ¶Õ¥Õ¬ Õ©Õ¥Õ¬Õ«Õ¶",
   "status.report": "Բողոքել @{name}֊ից",
-  "status.sensitive_toggle": "Կտացրու՝ դիտելու համար",
   "status.sensitive_warning": "Ô¿Õ¡Õ½Õ¯Õ¡Õ®Õ¥Õ¬Õ« Õ¢Õ¸Õ¾Õ¡Õ¶Õ¤Õ¡Õ¯Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶",
   "status.share": "Ô¿Õ«Õ½Õ¾Õ¥Õ¬",
   "status.show_less": "ÕŠÕ¡Õ¯Õ¡Õ½",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Տեղական",
   "tabs_bar.notifications": "Ծանուցումներ",
   "tabs_bar.search": "Search",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
   "ui.beforeunload": "Õ”Õ¸ Õ½Õ¥Ö‚Õ¡Õ£Õ«Ö€Õ¨ Õ¯Õ¯Õ¸Ö€Õ«, Õ¥Õ©Õ¥ Õ¬Ö„Õ¥Õ½ Õ„Õ¡Õ½Õ¿Õ¸Õ¤Õ¸Õ¶Õ¨Ö‰",
   "upload_area.title": "Քաշիր ու նետիր՝ վերբեռնելու համար",
   "upload_button.label": "Ավելացնել մեդիա",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "upload_form.description": "Նկարագրություն ավելացրու տեսողական խնդիրներ ունեցողների համար",
   "upload_form.focus": "Crop",
   "upload_form.undo": "Õ€Õ¥Õ¿Õ¡Ö€Õ¯Õ¥Õ¬",
diff --git a/app/javascript/mastodon/locales/id.json b/app/javascript/mastodon/locales/id.json
index eed61af707cce54c55980e3ecabeec8f554ceea7..07ce0eb9854e6346571db6f18531c7a3022285f9 100644
--- a/app/javascript/mastodon/locales/id.json
+++ b/app/javascript/mastodon/locales/id.json
@@ -5,7 +5,6 @@
   "account.block_domain": "Sembunyikan segalanya dari {domain}",
   "account.blocked": "Terblokir",
   "account.direct": "Direct Message @{name}",
-  "account.disclaimer_full": "Informasi di bawah mungkin tidak mencerminkan profil user secara lengkap.",
   "account.domain_blocked": "Domain disembunyikan",
   "account.edit_profile": "Ubah profil",
   "account.endorse": "Feature on profile",
@@ -36,7 +35,6 @@
   "account.unfollow": "Berhenti mengikuti",
   "account.unmute": "Berhenti membisukan @{name}",
   "account.unmute_notifications": "Munculkan notifikasi dari @{name}",
-  "account.view_full_profile": "Lihat profil lengkap",
   "alert.unexpected.message": "An unexpected error occurred.",
   "alert.unexpected.title": "Oops!",
   "boost_modal.combo": "Anda dapat menekan {combo} untuk melewati ini",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "Akun anda tidak {locked}. Semua orang dapat mengikuti anda untuk melihat postingan khusus untuk pengikut anda.",
   "compose_form.lock_disclaimer.lock": "terkunci",
   "compose_form.placeholder": "Apa yang ada di pikiran anda?",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
   "compose_form.sensitive.marked": "Sumber ini telah ditandai sebagai sumber sensitif.",
   "compose_form.sensitive.unmarked": "Sumber ini tidak ditandai sebagai sumber sensitif",
   "compose_form.spoiler.marked": "Teks disembunyikan dibalik peringatan",
   "compose_form.spoiler.unmarked": "Teks tidak tersembunyi",
   "compose_form.spoiler_placeholder": "Peringatan konten",
   "confirmation_modal.cancel": "Batal",
+  "confirmations.block.block_and_report": "Block & Report",
   "confirmations.block.confirm": "Blokir",
   "confirmations.block.message": "Apa anda yakin ingin memblokir {name}?",
   "confirmations.delete.confirm": "Hapus",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Simbol",
   "emoji_button.travel": "Tempat Wisata",
   "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_unavailable": "Profile unavailable",
   "empty_column.blocks": "You haven't blocked any users yet.",
   "empty_column.community": "Linimasa lokal masih kosong. Tulis sesuatu secara publik dan buat roda berputar!",
   "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "and {additional}",
   "hashtag.column_header.tag_mode.any": "or {additional}",
   "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
   "hashtag.column_settings.tag_mode.all": "All of these",
   "hashtag.column_settings.tag_mode.any": "Any of these",
   "hashtag.column_settings.tag_mode.none": "None of these",
@@ -149,6 +156,9 @@
   "home.column_settings.basic": "Dasar",
   "home.column_settings.show_reblogs": "Tampilkan boost",
   "home.column_settings.show_replies": "Tampilkan balasan",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
   "introduction.federation.action": "Next",
   "introduction.federation.federated.headline": "Federated",
   "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
@@ -156,7 +166,7 @@
   "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
   "introduction.federation.local.headline": "Local",
   "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
+  "introduction.interactions.action": "Finish toot-orial!",
   "introduction.interactions.favourite.headline": "Favourite",
   "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
   "introduction.interactions.reblog.headline": "Boost",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "untuk fokus mencari",
   "keyboard_shortcuts.start": "to open \"get started\" column",
   "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "to start a brand new toot",
   "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
   "keyboard_shortcuts.up": "to move up in the list",
   "lightbox.close": "Tutup",
   "lightbox.next": "Next",
   "lightbox.previous": "Previous",
+  "lightbox.view_context": "View context",
   "lists.account.add": "Add to list",
   "lists.account.remove": "Remove from list",
   "lists.delete": "Delete list",
   "lists.edit": "Edit list",
+  "lists.edit.submit": "Change title",
   "lists.new.create": "Add list",
   "lists.new.title_placeholder": "New list title",
   "lists.search": "Search among people you follow",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "Favorit",
   "navigation_bar.filters": "Muted words",
   "navigation_bar.follow_requests": "Permintaan mengikuti",
+  "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.info": "Informasi selengkapnya",
   "navigation_bar.keyboard_shortcuts": "Keyboard shortcuts",
   "navigation_bar.lists": "Lists",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Personal",
   "navigation_bar.pins": "Pinned toots",
   "navigation_bar.preferences": "Pengaturan",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "Linimasa gabungan",
   "navigation_bar.security": "Security",
   "notification.favourite": "{name} menyukai status anda",
   "notification.follow": "{name} mengikuti anda",
   "notification.mention": "{name} mentioned you",
+  "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "{name} mem-boost status anda",
   "notifications.clear": "Hapus notifikasi",
   "notifications.clear_confirmation": "Apa anda yakin hendak menghapus semua notifikasi anda?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Show",
   "notifications.column_settings.follow": "Pengikut baru:",
   "notifications.column_settings.mention": "Balasan:",
+  "notifications.column_settings.poll": "Poll results:",
   "notifications.column_settings.push": "Push notifications",
   "notifications.column_settings.reblog": "Boost:",
   "notifications.column_settings.show": "Tampilkan dalam kolom",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favourites",
   "notifications.filter.follows": "Follows",
   "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
   "notifications.group": "{count} notifications",
+  "poll.closed": "Closed",
+  "poll.refresh": "Refresh",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
   "privacy.change": "Tentukan privasi status",
   "privacy.direct.long": "Kirim hanya ke pengguna yang disebut",
   "privacy.direct.short": "Langsung",
@@ -291,12 +315,12 @@
   "search_results.hashtags": "Hashtags",
   "search_results.statuses": "Toots",
   "search_results.total": "{count, number} {count, plural, one {hasil} other {hasil}}",
-  "standalone.public_title": "A look inside...",
   "status.admin_account": "Open moderation interface for @{name}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "This post cannot be boosted",
+  "status.copy": "Copy link to status",
   "status.delete": "Hapus",
   "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Balas",
   "status.replyAll": "Balas ke semua",
   "status.report": "Laporkan @{name}",
-  "status.sensitive_toggle": "Klik untuk menampilkan",
   "status.sensitive_warning": "Konten sensitif",
   "status.share": "Share",
   "status.show_less": "Tampilkan lebih sedikit",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Lokal",
   "tabs_bar.notifications": "Notifikasi",
   "tabs_bar.search": "Search",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
   "ui.beforeunload": "Naskah anda akan hilang jika anda keluar dari Mastodon.",
   "upload_area.title": "Seret & lepaskan untuk mengunggah",
   "upload_button.label": "Tambahkan media",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "upload_form.description": "Deskripsikan untuk mereka yang tidak bisa melihat dengan jelas",
   "upload_form.focus": "Potong",
   "upload_form.undo": "Undo",
diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json
index b26fa6c4ab415f1456c6701a4eceb130de45e7ad..c3f8707d133106af119a552730813d514f7e42ee 100644
--- a/app/javascript/mastodon/locales/io.json
+++ b/app/javascript/mastodon/locales/io.json
@@ -5,7 +5,6 @@
   "account.block_domain": "Hide everything from {domain}",
   "account.blocked": "Blocked",
   "account.direct": "Direct Message @{name}",
-  "account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
   "account.domain_blocked": "Domain hidden",
   "account.edit_profile": "Modifikar profilo",
   "account.endorse": "Feature on profile",
@@ -36,7 +35,6 @@
   "account.unfollow": "Ne plus sequar",
   "account.unmute": "Ne plus celar @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account.view_full_profile": "View full profile",
   "alert.unexpected.message": "An unexpected error occurred.",
   "alert.unexpected.title": "Oops!",
   "boost_modal.combo": "Tu povas presar sur {combo} por omisar co en la venonta foyo",
@@ -73,14 +71,20 @@
   "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",
   "compose_form.placeholder": "Quo esas en tua spirito?",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
   "compose_form.publish": "Siflar",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
   "compose_form.sensitive.marked": "Media is marked as sensitive",
   "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
   "compose_form.spoiler.marked": "Text is hidden behind warning",
   "compose_form.spoiler.unmarked": "Text is not hidden",
   "compose_form.spoiler_placeholder": "Averto di kontenajo",
   "confirmation_modal.cancel": "Cancel",
+  "confirmations.block.block_and_report": "Block & Report",
   "confirmations.block.confirm": "Block",
   "confirmations.block.message": "Are you sure you want to block {name}?",
   "confirmations.delete.confirm": "Delete",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Symbols",
   "emoji_button.travel": "Travel & Places",
   "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_unavailable": "Profile unavailable",
   "empty_column.blocks": "You haven't blocked any users yet.",
   "empty_column.community": "La lokala tempolineo esas vakua. Skribez ulo publike por iniciar la agiveso!",
   "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "and {additional}",
   "hashtag.column_header.tag_mode.any": "or {additional}",
   "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
   "hashtag.column_settings.tag_mode.all": "All of these",
   "hashtag.column_settings.tag_mode.any": "Any of these",
   "hashtag.column_settings.tag_mode.none": "None of these",
@@ -149,6 +156,9 @@
   "home.column_settings.basic": "Simpla",
   "home.column_settings.show_reblogs": "Montrar repeti",
   "home.column_settings.show_replies": "Montrar respondi",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
   "introduction.federation.action": "Next",
   "introduction.federation.federated.headline": "Federated",
   "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
@@ -156,7 +166,7 @@
   "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
   "introduction.federation.local.headline": "Local",
   "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
+  "introduction.interactions.action": "Finish toot-orial!",
   "introduction.interactions.favourite.headline": "Favourite",
   "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
   "introduction.interactions.reblog.headline": "Boost",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "to focus search",
   "keyboard_shortcuts.start": "to open \"get started\" column",
   "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "to start a brand new toot",
   "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
   "keyboard_shortcuts.up": "to move up in the list",
   "lightbox.close": "Klozar",
   "lightbox.next": "Next",
   "lightbox.previous": "Previous",
+  "lightbox.view_context": "View context",
   "lists.account.add": "Add to list",
   "lists.account.remove": "Remove from list",
   "lists.delete": "Delete list",
   "lists.edit": "Edit list",
+  "lists.edit.submit": "Change title",
   "lists.new.create": "Add list",
   "lists.new.title_placeholder": "New list title",
   "lists.search": "Search among people you follow",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "Favorati",
   "navigation_bar.filters": "Muted words",
   "navigation_bar.follow_requests": "Demandi di sequado",
+  "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.info": "Detaloza informi",
   "navigation_bar.keyboard_shortcuts": "Keyboard shortcuts",
   "navigation_bar.lists": "Lists",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Personal",
   "navigation_bar.pins": "Pinned toots",
   "navigation_bar.preferences": "Preferi",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "Federata tempolineo",
   "navigation_bar.security": "Security",
   "notification.favourite": "{name} favorizis tua mesajo",
   "notification.follow": "{name} sequeskis tu",
   "notification.mention": "{name} mencionis tu",
+  "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "{name} repetis tua mesajo",
   "notifications.clear": "Efacar savigi",
   "notifications.clear_confirmation": "Ka tu esas certa, ke tu volas efacar omna tua savigi?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Show",
   "notifications.column_settings.follow": "Nova sequanti:",
   "notifications.column_settings.mention": "Mencioni:",
+  "notifications.column_settings.poll": "Poll results:",
   "notifications.column_settings.push": "Push notifications",
   "notifications.column_settings.reblog": "Repeti:",
   "notifications.column_settings.show": "Montrar en kolumno",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favourites",
   "notifications.filter.follows": "Follows",
   "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
   "notifications.group": "{count} notifications",
+  "poll.closed": "Closed",
+  "poll.refresh": "Refresh",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
   "privacy.change": "Aranjar privateso di mesaji",
   "privacy.direct.long": "Sendar nur a mencionata uzeri",
   "privacy.direct.short": "Direte",
@@ -291,12 +315,12 @@
   "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.admin_account": "Open moderation interface for @{name}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "This post cannot be boosted",
+  "status.copy": "Copy link to status",
   "status.delete": "Efacar",
   "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Respondar",
   "status.replyAll": "Respondar a filo",
   "status.report": "Denuncar @{name}",
-  "status.sensitive_toggle": "Kliktar por vidar",
   "status.sensitive_warning": "Trubliva kontenajo",
   "status.share": "Share",
   "status.show_less": "Montrar mine",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Lokala",
   "tabs_bar.notifications": "Savigi",
   "tabs_bar.search": "Search",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
   "upload_area.title": "Tranar faligar por kargar",
   "upload_button.label": "Adjuntar kontenajo",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.focus": "Crop",
   "upload_form.undo": "Desfacar",
diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json
index 1f52d37248bde2b2f067bf6efa9987c0bf20bf0c..f7e2e43538a8c66111d2fa22a633c4c2bbbea726 100644
--- a/app/javascript/mastodon/locales/it.json
+++ b/app/javascript/mastodon/locales/it.json
@@ -5,7 +5,6 @@
   "account.block_domain": "Nascondi tutto da {domain}",
   "account.blocked": "Bloccato",
   "account.direct": "Invia messaggio diretto a @{name}",
-  "account.disclaimer_full": "Il profilo dell'utente mostrato qui sotto potrebbe essere incompleto.",
   "account.domain_blocked": "Dominio nascosto",
   "account.edit_profile": "Modifica profilo",
   "account.endorse": "Metti in evidenza sul profilo",
@@ -36,13 +35,12 @@
   "account.unfollow": "Non seguire",
   "account.unmute": "Non silenziare @{name}",
   "account.unmute_notifications": "Non silenziare più le notifiche da @{name}",
-  "account.view_full_profile": "Vedi profilo completo",
   "alert.unexpected.message": "Si è verificato un errore inatteso.",
   "alert.unexpected.title": "Oops!",
   "boost_modal.combo": "Puoi premere {combo} per saltare questo passaggio la prossima volta",
   "bundle_column_error.body": "E' avvenuto un errore durante il caricamento di questo componente.",
   "bundle_column_error.retry": "Riprova",
-  "bundle_column_error.title": "Network error",
+  "bundle_column_error.title": "Errore di rete",
   "bundle_modal_error.close": "Chiudi",
   "bundle_modal_error.message": "C'è stato un errore mentre questo componente veniva caricato.",
   "bundle_modal_error.retry": "Riprova",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "Il tuo account non è {bloccato}. Chiunque può decidere di seguirti per vedere i tuoi post per soli seguaci.",
   "compose_form.lock_disclaimer.lock": "bloccato",
   "compose_form.placeholder": "A cosa stai pensando?",
+  "compose_form.poll.add_option": "Aggiungi una scelta",
+  "compose_form.poll.duration": "Durata del sondaggio",
+  "compose_form.poll.option_placeholder": "Scelta {number}",
+  "compose_form.poll.remove_option": "Rimuovi questa scelta",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Segna media come sensibile",
   "compose_form.sensitive.marked": "Questo media è contrassegnato come sensibile",
   "compose_form.sensitive.unmarked": "Questo media non è contrassegnato come sensibile",
   "compose_form.spoiler.marked": "Il testo è nascosto dall'avviso",
   "compose_form.spoiler.unmarked": "Il testo non è nascosto",
   "compose_form.spoiler_placeholder": "Content warning",
   "confirmation_modal.cancel": "Annulla",
+  "confirmations.block.block_and_report": "Blocca & Segnala",
   "confirmations.block.confirm": "Blocca",
   "confirmations.block.message": "Sei sicuro di voler bloccare {name}?",
   "confirmations.delete.confirm": "Cancella",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Simboli",
   "emoji_button.travel": "Viaggi e luoghi",
   "empty_column.account_timeline": "Non ci sono toot qui!",
+  "empty_column.account_unavailable": "Profilo non disponibile",
   "empty_column.blocks": "Non hai ancora bloccato nessun utente.",
   "empty_column.community": "La timeline locale è vuota. Condividi qualcosa pubblicamente per dare inizio alla festa!",
   "empty_column.direct": "Non hai ancora nessun messaggio diretto. Quando ne manderai o riceverai qualcuno, apparirà qui.",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "e {additional}",
   "hashtag.column_header.tag_mode.any": "o {additional}",
   "hashtag.column_header.tag_mode.none": "senza {additional}",
+  "hashtag.column_settings.select.no_options_message": "Nessun suggerimento trovato",
+  "hashtag.column_settings.select.placeholder": "Inserisci hashtag…",
   "hashtag.column_settings.tag_mode.all": "Tutti questi",
   "hashtag.column_settings.tag_mode.any": "Uno o più di questi",
   "hashtag.column_settings.tag_mode.none": "Nessuno di questi",
@@ -149,12 +156,15 @@
   "home.column_settings.basic": "Semplice",
   "home.column_settings.show_reblogs": "Mostra post condivisi",
   "home.column_settings.show_replies": "Mostra risposte",
+  "intervals.full.days": "{number, plural, one {# giorno} other {# giorni}}",
+  "intervals.full.hours": "{number, plural, one {# ora} other {# ore}}",
+  "intervals.full.minutes": "{number, plural, one {# minuto} other {# minuti}}",
   "introduction.federation.action": "Avanti",
-  "introduction.federation.federated.headline": "Federated",
+  "introduction.federation.federated.headline": "Federato",
   "introduction.federation.federated.text": "I post pubblici provenienti da altri server del fediverse saranno mostrati nella timeline federata.",
   "introduction.federation.home.headline": "Home",
   "introduction.federation.home.text": "I post scritti da persone che segui saranno mostrati nella timeline home. Puoi seguire chiunque su qualunque server!",
-  "introduction.federation.local.headline": "Local",
+  "introduction.federation.local.headline": "Locale",
   "introduction.federation.local.text": "I post pubblici scritti da persone sul tuo stesso server saranno mostrati nella timeline locale.",
   "introduction.interactions.action": "Finisci il tutorial!",
   "introduction.interactions.favourite.headline": "Apprezza",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "per spostare il focus sulla ricerca",
   "keyboard_shortcuts.start": "per aprire la colonna \"Come iniziare\"",
   "keyboard_shortcuts.toggle_hidden": "per mostrare/nascondere il testo dei CW",
+  "keyboard_shortcuts.toggle_sensitivity": "mostrare/nascondere media",
   "keyboard_shortcuts.toot": "per iniziare a scrivere un toot completamente nuovo",
   "keyboard_shortcuts.unfocus": "per uscire dall'area di composizione o dalla ricerca",
   "keyboard_shortcuts.up": "per spostarsi in alto nella lista",
   "lightbox.close": "Chiudi",
   "lightbox.next": "Successivo",
   "lightbox.previous": "Precedente",
+  "lightbox.view_context": "Mostra contesto",
   "lists.account.add": "Aggiungi alla lista",
   "lists.account.remove": "Togli dalla lista",
-  "lists.delete": "Delete list",
+  "lists.delete": "Elimina lista",
   "lists.edit": "Modifica lista",
+  "lists.edit.submit": "Cambia titolo",
   "lists.new.create": "Aggiungi lista",
   "lists.new.title_placeholder": "Titolo della nuova lista",
   "lists.search": "Cerca tra le persone che segui",
@@ -224,19 +237,22 @@
   "navigation_bar.favourites": "Apprezzati",
   "navigation_bar.filters": "Parole silenziate",
   "navigation_bar.follow_requests": "Richieste di amicizia",
-  "navigation_bar.info": "Informazioni estese",
+  "navigation_bar.follows_and_followers": "Follows and followers",
+  "navigation_bar.info": "Informazioni su questo server",
   "navigation_bar.keyboard_shortcuts": "Tasti di scelta rapida",
   "navigation_bar.lists": "Liste",
   "navigation_bar.logout": "Esci",
   "navigation_bar.mutes": "Utenti silenziati",
-  "navigation_bar.personal": "Personal",
+  "navigation_bar.personal": "Personale",
   "navigation_bar.pins": "Toot fissati in cima",
   "navigation_bar.preferences": "Impostazioni",
+  "navigation_bar.profile_directory": "Directory dei profili",
   "navigation_bar.public_timeline": "Timeline federata",
   "navigation_bar.security": "Sicurezza",
   "notification.favourite": "{name} ha apprezzato il tuo post",
   "notification.follow": "{name} ha iniziato a seguirti",
   "notification.mention": "{name} ti ha menzionato",
+  "notification.poll": "Un sondaggio in cui hai votato è terminato",
   "notification.reblog": "{name} ha condiviso il tuo post",
   "notifications.clear": "Cancella notifiche",
   "notifications.clear_confirmation": "Vuoi davvero cancellare tutte le notifiche?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Mostra",
   "notifications.column_settings.follow": "Nuovi seguaci:",
   "notifications.column_settings.mention": "Menzioni:",
+  "notifications.column_settings.poll": "Risultati del sondaggio:",
   "notifications.column_settings.push": "Notifiche push",
   "notifications.column_settings.reblog": "Post condivisi:",
   "notifications.column_settings.show": "Mostra in colonna",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Apprezzati",
   "notifications.filter.follows": "Seguaci",
   "notifications.filter.mentions": "Menzioni",
+  "notifications.filter.polls": "Risultati del sondaggio",
   "notifications.group": "{count} notifiche",
+  "poll.closed": "Chiuso",
+  "poll.refresh": "Aggiorna",
+  "poll.total_votes": "{count, plural, one {# voto} other {# voti}}",
+  "poll.vote": "Vota",
+  "poll_button.add_poll": "Aggiungi un sondaggio",
+  "poll_button.remove_poll": "Rimuovi sondaggio",
   "privacy.change": "Modifica privacy del post",
   "privacy.direct.long": "Invia solo a utenti menzionati",
   "privacy.direct.short": "Diretto",
@@ -268,35 +292,35 @@
   "privacy.unlisted.short": "Non elencato",
   "regeneration_indicator.label": "Caricamento in corso…",
   "regeneration_indicator.sublabel": "Stiamo preparando il tuo home feed!",
-  "relative_time.days": "{number}d",
-  "relative_time.hours": "{number}h",
+  "relative_time.days": "{number}g",
+  "relative_time.hours": "{number}o",
   "relative_time.just_now": "ora",
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Annulla",
   "report.forward": "Inoltra a {target}",
   "report.forward_hint": "Questo account appartiene a un altro server. Mandare anche là una copia anonima del rapporto?",
-  "report.hint": "La segnalazione sarà inviata ai moderatori della tua istanza. Di seguito, puoi fornire il motivo per il quale stai segnalando questo account:",
+  "report.hint": "La segnalazione sarà inviata ai moderatori del tuo server. Di seguito, puoi fornire il motivo per il quale stai segnalando questo account:",
   "report.placeholder": "Commenti aggiuntivi",
   "report.submit": "Invia",
   "report.target": "Invio la segnalazione {target}",
   "search.placeholder": "Cerca",
   "search_popout.search_format": "Formato di ricerca avanzato",
   "search_popout.tips.full_text": "Testo semplice per trovare gli status che hai scritto, segnato come apprezzati, condiviso o in cui sei stato citato, e inoltre i nomi utente, nomi visualizzati e hashtag che lo contengono.",
-  "search_popout.tips.hashtag": "hashtag",
-  "search_popout.tips.status": "status",
+  "search_popout.tips.hashtag": "etichetta",
+  "search_popout.tips.status": "stato",
   "search_popout.tips.text": "Testo semplice per trovare nomi visualizzati, nomi utente e hashtag che lo contengono",
   "search_popout.tips.user": "utente",
   "search_results.accounts": "Gente",
   "search_results.hashtags": "Hashtag",
   "search_results.statuses": "Toot",
   "search_results.total": "{count} {count, plural, one {risultato} other {risultati}}",
-  "standalone.public_title": "Un'occhiata all'interno...",
-  "status.admin_account": "Open moderation interface for @{name}",
-  "status.admin_status": "Open this status in the moderation interface",
-  "status.block": "Block @{name}",
+  "status.admin_account": "Apri interfaccia di moderazione per @{name}",
+  "status.admin_status": "Apri questo status nell'interfaccia di moderazione",
+  "status.block": "Blocca @{name}",
   "status.cancel_reblog_private": "Annulla condivisione",
   "status.cannot_reblog": "Questo post non può essere condiviso",
+  "status.copy": "Copia link allo status",
   "status.delete": "Elimina",
   "status.detailed_status": "Vista conversazione dettagliata",
   "status.direct": "Messaggio diretto @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Rispondi",
   "status.replyAll": "Rispondi alla conversazione",
   "status.report": "Segnala @{name}",
-  "status.sensitive_toggle": "Clicca per vedere",
   "status.sensitive_warning": "Materiale sensibile",
   "status.share": "Condividi",
   "status.show_less": "Mostra meno",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Locale",
   "tabs_bar.notifications": "Notifiche",
   "tabs_bar.search": "Cerca",
+  "time_remaining.days": "{number, plural, one {# giorno} other {# giorni}} left",
+  "time_remaining.hours": "{number, plural, one {# ora} other {# ore}} left",
+  "time_remaining.minutes": "{number, plural, one {# minuto} other {# minuti}} left",
+  "time_remaining.moments": "Restano pochi istanti",
+  "time_remaining.seconds": "{number, plural, one {# secondo} other {# secondi}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {persona ne sta} other {persone ne stanno}} parlando",
   "ui.beforeunload": "La bozza andrà persa se esci da Mastodon.",
   "upload_area.title": "Trascina per caricare",
   "upload_button.label": "Aggiungi file multimediale",
+  "upload_error.limit": "Limite al caricamento di file superato.",
+  "upload_error.poll": "Caricamento file non consentito nei sondaggi.",
   "upload_form.description": "Descrizione per utenti con disabilità visive",
   "upload_form.focus": "Modifica anteprima",
   "upload_form.undo": "Cancella",
diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json
index cd4addd68679c00e5e5ca4c5653697ff9dd8d082..83a69e5953bafe907f85a1f58316e5c73cbbbbfe 100644
--- a/app/javascript/mastodon/locales/ja.json
+++ b/app/javascript/mastodon/locales/ja.json
@@ -1,13 +1,12 @@
 {
-  "account.add_or_remove_from_list": "リストに追加または外す",
+  "account.add_or_remove_from_list": "リストから追加または外す",
   "account.badges.bot": "Bot",
   "account.block": "@{name}さんをブロック",
   "account.block_domain": "{domain}全体を非表示",
   "account.blocked": "ブロック済み",
   "account.direct": "@{name}さんにダイレクトメッセージ",
-  "account.disclaimer_full": "以下の情報は不正確な可能性があります。",
   "account.domain_blocked": "ドメイン非表示中",
-  "account.edit_profile": "プロフィールを編集",
+  "account.edit_profile": "プロフィール編集",
   "account.endorse": "プロフィールで紹介する",
   "account.follow": "フォロー",
   "account.followers": "フォロワー",
@@ -17,7 +16,7 @@
   "account.follows_you": "フォローされています",
   "account.hide_reblogs": "@{name}さんからのブーストを非表示",
   "account.link_verified_on": "このリンクの所有権は{date}に確認されました",
-  "account.locked_info": "このアカウントは承認制アカウントです。相手が確認するまでフォローは完了しません。",
+  "account.locked_info": "このアカウントは承認制アカウントです。相手が承認するまでフォローは完了しません。",
   "account.media": "メディア",
   "account.mention": "@{name}さんにトゥート",
   "account.moved_to": "{name}さんは引っ越しました:",
@@ -31,12 +30,11 @@
   "account.share": "@{name}さんのプロフィールを共有する",
   "account.show_reblogs": "@{name}さんからのブーストを表示",
   "account.unblock": "@{name}さんのブロックを解除",
-  "account.unblock_domain": "{domain}を表示",
+  "account.unblock_domain": "{domain}の非表示を解除",
   "account.unendorse": "プロフィールから外す",
   "account.unfollow": "フォロー解除",
   "account.unmute": "@{name}さんのミュートを解除",
   "account.unmute_notifications": "@{name}さんからの通知を受け取るようにする",
-  "account.view_full_profile": "全ての情報を見る",
   "alert.unexpected.message": "不明なエラーが発生しました。",
   "alert.unexpected.title": "エラー!",
   "boost_modal.combo": "次からは{combo}を押せばスキップできます",
@@ -69,18 +67,24 @@
   "community.column_settings.media_only": "メディアのみ表示",
   "compose_form.direct_message_warning": "このトゥートはメンションされた人にのみ送信されます。",
   "compose_form.direct_message_warning_learn_more": "もっと詳しく",
-  "compose_form.hashtag_warning": "このトゥートは未収載なのでハッシュタグの一覧に表示されません。公開トゥートだけがハッシュタグで検索できます。",
+  "compose_form.hashtag_warning": "このトゥートは公開設定ではないのでハッシュタグの一覧に表示されません。公開トゥートだけがハッシュタグで検索できます。",
   "compose_form.lock_disclaimer": "あなたのアカウントは{locked}になっていません。誰でもあなたをフォローすることができ、フォロワー限定の投稿を見ることができます。",
   "compose_form.lock_disclaimer.lock": "承認制",
   "compose_form.placeholder": "今なにしてる?",
+  "compose_form.poll.add_option": "追加",
+  "compose_form.poll.duration": "アンケート期間",
+  "compose_form.poll.option_placeholder": "é …ç›® {number}",
+  "compose_form.poll.remove_option": "この項目を削除",
   "compose_form.publish": "トゥート",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "メディアを閲覧注意にする",
   "compose_form.sensitive.marked": "メディアに閲覧注意が設定されています",
   "compose_form.sensitive.unmarked": "メディアに閲覧注意が設定されていません",
   "compose_form.spoiler.marked": "閲覧注意が設定されています",
   "compose_form.spoiler.unmarked": "閲覧注意が設定されていません",
   "compose_form.spoiler_placeholder": "ここに警告を書いてください",
   "confirmation_modal.cancel": "キャンセル",
+  "confirmations.block.block_and_report": "ブロックし通報",
   "confirmations.block.confirm": "ブロック",
   "confirmations.block.message": "本当に{name}さんをブロックしますか?",
   "confirmations.delete.confirm": "削除",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "記号",
   "emoji_button.travel": "旅行と場所",
   "empty_column.account_timeline": "トゥートがありません!",
+  "empty_column.account_unavailable": "プロフィールは利用できません",
   "empty_column.blocks": "まだ誰もブロックしていません。",
   "empty_column.community": "ローカルタイムラインはまだ使われていません。何か書いてみましょう!",
   "empty_column.direct": "ダイレクトメッセージはまだありません。ダイレクトメッセージをやりとりすると、ここに表示されます。",
@@ -128,7 +133,7 @@
   "empty_column.lists": "まだリストがありません。リストを作るとここに表示されます。",
   "empty_column.mutes": "まだ誰もミュートしていません。",
   "empty_column.notifications": "まだ通知がありません。他の人とふれ合って会話を始めましょう。",
-  "empty_column.public": "ここにはまだ何もありません! 公開で何かを投稿したり、他のインスタンスのユーザーをフォローしたりしていっぱいにしましょう",
+  "empty_column.public": "ここにはまだ何もありません! 公開で何かを投稿したり、他のサーバーのユーザーをフォローしたりしていっぱいにしましょう",
   "follow_request.authorize": "許可",
   "follow_request.reject": "拒否",
   "getting_started.developers": "開発",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "と {additional}",
   "hashtag.column_header.tag_mode.any": "か {additional}",
   "hashtag.column_header.tag_mode.none": "({additional} を除く)",
+  "hashtag.column_settings.select.no_options_message": "提案はありません",
+  "hashtag.column_settings.select.placeholder": "ハッシュタグを入力してください…",
   "hashtag.column_settings.tag_mode.all": "すべてを含む",
   "hashtag.column_settings.tag_mode.any": "いずれかを含む",
   "hashtag.column_settings.tag_mode.none": "これらを除く",
@@ -149,6 +156,9 @@
   "home.column_settings.basic": "基本設定",
   "home.column_settings.show_reblogs": "ブースト表示",
   "home.column_settings.show_replies": "返信表示",
+  "intervals.full.days": "{number}æ—¥",
+  "intervals.full.hours": "{number}時間",
+  "intervals.full.minutes": "{number}分",
   "introduction.federation.action": "次へ",
   "introduction.federation.federated.headline": "連合タイムライン",
   "introduction.federation.federated.text": "Fediverseの他のサーバーからの公開投稿は連合タイムラインに表示されます。",
@@ -165,7 +175,7 @@
   "introduction.interactions.reply.text": "自身や人々のトゥートに返信することで、一連の会話に繋げることができます。",
   "introduction.welcome.action": "はじめる!",
   "introduction.welcome.headline": "はじめに",
-  "introduction.welcome.text": "Fediverseの世界へようこそ!あと少しでメッセージを配信したり、さまざまなサーバーを越えた友達と話せるようになります。ところでここ{domain}は特別なサーバーです…あなたのプロフィールを持つ主体のサーバーですので、名前を覚えておきましょう。",
+  "introduction.welcome.text": "Fediverseの世界へようこそ!あと少しでメッセージを配信したり、さまざまなサーバーを越えた友達と話せるようになります。ところで、ここ{domain}は特別なサーバーです…あなたのプロフィールを持つ主体のサーバーですので、名前を覚えておきましょう。",
   "keyboard_shortcuts.back": "戻る",
   "keyboard_shortcuts.blocked": "ブロックしたユーザーのリストを開く",
   "keyboard_shortcuts.boost": "ブースト",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "検索欄に移動",
   "keyboard_shortcuts.start": "\"スタート\" カラムを開く",
   "keyboard_shortcuts.toggle_hidden": "CWで隠れた文を見る/隠す",
+  "keyboard_shortcuts.toggle_sensitivity": "非表示のメディアを見る/隠す",
   "keyboard_shortcuts.toot": "新規トゥート",
   "keyboard_shortcuts.unfocus": "トゥート入力欄・検索欄から離れる",
   "keyboard_shortcuts.up": "カラム内一つ上に移動",
   "lightbox.close": "閉じる",
   "lightbox.next": "次",
   "lightbox.previous": "前",
+  "lightbox.view_context": "トゥートを表示",
   "lists.account.add": "リストに追加",
   "lists.account.remove": "リストから外す",
   "lists.delete": "リストを削除",
   "lists.edit": "リストを編集",
+  "lists.edit.submit": "タイトルを変更",
   "lists.new.create": "リストを作成",
   "lists.new.title_placeholder": "新規リスト名",
   "lists.search": "フォローしている人の中から検索",
@@ -224,7 +237,8 @@
   "navigation_bar.favourites": "お気に入り",
   "navigation_bar.filters": "フィルター設定",
   "navigation_bar.follow_requests": "フォローリクエスト",
-  "navigation_bar.info": "このインスタンスについて",
+  "navigation_bar.follows_and_followers": "フォロー・フォロワー",
+  "navigation_bar.info": "このサーバーについて",
   "navigation_bar.keyboard_shortcuts": "ホットキー",
   "navigation_bar.lists": "リスト",
   "navigation_bar.logout": "ログアウト",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "個人用",
   "navigation_bar.pins": "固定したトゥート",
   "navigation_bar.preferences": "ユーザー設定",
+  "navigation_bar.profile_directory": "ディレクトリ",
   "navigation_bar.public_timeline": "連合タイムライン",
   "navigation_bar.security": "セキュリティ",
   "notification.favourite": "{name}さんがあなたのトゥートをお気に入りに登録しました",
   "notification.follow": "{name}さんにフォローされました",
   "notification.mention": "{name}さんがあなたに返信しました",
+  "notification.poll": "アンケートが終了しました",
   "notification.reblog": "{name}さんがあなたのトゥートをブーストしました",
   "notifications.clear": "通知を消去",
   "notifications.clear_confirmation": "本当に通知を消去しますか?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "表示",
   "notifications.column_settings.follow": "新しいフォロワー:",
   "notifications.column_settings.mention": "返信:",
+  "notifications.column_settings.poll": "アンケート結果:",
   "notifications.column_settings.push": "プッシュ通知",
   "notifications.column_settings.reblog": "ブースト:",
   "notifications.column_settings.show": "カラムに表示",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "お気に入り",
   "notifications.filter.follows": "フォロー",
   "notifications.filter.mentions": "返信",
+  "notifications.filter.polls": "アンケート結果",
   "notifications.group": "{count} 件の通知",
+  "poll.closed": "終了",
+  "poll.refresh": "æ›´æ–°",
+  "poll.total_votes": "{count}票",
+  "poll.vote": "投票",
+  "poll_button.add_poll": "アンケートを追加",
+  "poll_button.remove_poll": "アンケートを削除",
   "privacy.change": "公開範囲を変更",
   "privacy.direct.long": "メンションしたユーザーだけに公開",
   "privacy.direct.short": "ダイレクト",
@@ -275,8 +299,8 @@
   "relative_time.seconds": "{number}秒前",
   "reply_indicator.cancel": "キャンセル",
   "report.forward": "{target} に転送する",
-  "report.forward_hint": "このアカウントは別のインスタンスに所属しています。通報内容を匿名で転送しますか?",
-  "report.hint": "通報内容はあなたのインスタンスのモデレーターへ送信されます。通報理由を入力してください。:",
+  "report.forward_hint": "このアカウントは別のサーバーに所属しています。通報内容を匿名で転送しますか?",
+  "report.hint": "通報内容はあなたのサーバーのモデレーターへ送信されます。通報理由を入力してください。:",
   "report.placeholder": "追加コメント",
   "report.submit": "通報する",
   "report.target": "{target}さんを通報する",
@@ -291,12 +315,12 @@
   "search_results.hashtags": "ハッシュタグ",
   "search_results.statuses": "トゥート",
   "search_results.total": "{count, number}件の結果",
-  "standalone.public_title": "今こんな話をしています...",
   "status.admin_account": "@{name} のモデレーション画面を開く",
   "status.admin_status": "このトゥートをモデレーション画面で開く",
   "status.block": "@{name}さんをブロック",
   "status.cancel_reblog_private": "ブースト解除",
   "status.cannot_reblog": "この投稿はブーストできません",
+  "status.copy": "トゥートへのリンクをコピー",
   "status.delete": "削除",
   "status.detailed_status": "詳細な会話ビュー",
   "status.direct": "@{name}さんにダイレクトメッセージ",
@@ -321,7 +345,6 @@
   "status.reply": "返信",
   "status.replyAll": "全員に返信",
   "status.report": "@{name}さんを通報",
-  "status.sensitive_toggle": "クリックして表示",
   "status.sensitive_warning": "閲覧注意",
   "status.share": "共有",
   "status.show_less": "隠す",
@@ -330,7 +353,7 @@
   "status.show_more_all": "全て見る",
   "status.show_thread": "スレッドを表示",
   "status.unmute_conversation": "会話のミュートを解除",
-  "status.unpin": "プロフィールの固定表示を解除",
+  "status.unpin": "プロフィールへの固定を解除",
   "suggestions.dismiss": "隠す",
   "suggestions.header": "興味あるかもしれません…",
   "tabs_bar.federated_timeline": "連合",
@@ -338,12 +361,19 @@
   "tabs_bar.local_timeline": "ローカル",
   "tabs_bar.notifications": "通知",
   "tabs_bar.search": "検索",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {人} other {人}} がトゥート",
+  "time_remaining.days": "残り{number}日",
+  "time_remaining.hours": "残り{number}時間",
+  "time_remaining.minutes": "残り{number}分",
+  "time_remaining.moments": "まもなく終了",
+  "time_remaining.seconds": "残り{number}秒",
+  "trends.count_by_accounts": "{count}人がトゥート",
   "ui.beforeunload": "Mastodonから離れると送信前の投稿は失われます。",
   "upload_area.title": "ドラッグ&ドロップでアップロード",
-  "upload_button.label": "メディアを追加 (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_button.label": "メディアを追加 ({formats})",
+  "upload_error.limit": "アップロードできる上限を超えています。",
+  "upload_error.poll": "アンケートではファイルをアップロードできません。",
   "upload_form.description": "視覚障害者のための説明",
-  "upload_form.focus": "焦点",
+  "upload_form.focus": "プレビューを変更",
   "upload_form.undo": "削除",
   "upload_progress.label": "アップロード中...",
   "video.close": "動画を閉じる",
diff --git a/app/javascript/mastodon/locales/ka.json b/app/javascript/mastodon/locales/ka.json
index 93a11027a689db304c5f90c218e178fab8a9c5ad..ff7059aea287f5d393b444797698748a999863bf 100644
--- a/app/javascript/mastodon/locales/ka.json
+++ b/app/javascript/mastodon/locales/ka.json
@@ -5,7 +5,6 @@
   "account.block_domain": "დაიმალოს ყველაფერი დომენიდან {domain}",
   "account.blocked": "დაიბლოკა",
   "account.direct": "პირდაპირი წერილი @{name}-ს",
-  "account.disclaimer_full": "ქვემოთ მოცემულმა ინფორმაციამ შეიძლება სრულად არ ასახოს მომხმარებლის პროფილი.",
   "account.domain_blocked": "დომენი დამალულია",
   "account.edit_profile": "პროფილის ცვლილება",
   "account.endorse": "გამორჩევა პროფილზე",
@@ -36,7 +35,6 @@
   "account.unfollow": "ნუღარ მიჰყვები",
   "account.unmute": "ნუღარ აჩუმებ @{name}-ს",
   "account.unmute_notifications": "ნუღარ აჩუმებ შეტყობინებებს @{name}-სგან",
-  "account.view_full_profile": "სრული პროფილის ჩვენება",
   "alert.unexpected.message": "წარმოიშვა მოულოდნელი შეცდომა.",
   "alert.unexpected.title": "უპს!",
   "boost_modal.combo": "შეგიძლიათ დააჭიროთ {combo}-ს რათა შემდეგ ჯერზე გამოტოვოთ ეს",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "თქვენი ანგარიში არაა {locked}. ნებისმიერს შეიძლია გამოგყვეთ, რომ იხილოს თქვენი მიმდევრებზე გათვლილი პოსტები.",
   "compose_form.lock_disclaimer.lock": "ჩაკეტილი",
   "compose_form.placeholder": "რაზე ფიქრობ?",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
   "compose_form.publish": "ტუტი",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
   "compose_form.sensitive.marked": "მედია მონიშნულია მგრძნობიარედ",
   "compose_form.sensitive.unmarked": "მედია არაა მონიშნული მგრძნობიარედ",
   "compose_form.spoiler.marked": "გაფრთხილების უკან ტექსტი დამალულია",
   "compose_form.spoiler.unmarked": "ტექსტი არაა დამალული",
   "compose_form.spoiler_placeholder": "თქვენი გაფრთხილება დაწერეთ აქ",
   "confirmation_modal.cancel": "უარყოფა",
+  "confirmations.block.block_and_report": "Block & Report",
   "confirmations.block.confirm": "ბლოკი",
   "confirmations.block.message": "დარწმუნებული ხართ, გსურთ დაბლოკოთ {name}?",
   "confirmations.delete.confirm": "გაუქმება",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "სიმბოლოები",
   "emoji_button.travel": "მოგზაურობა და ადგილები",
   "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_unavailable": "Profile unavailable",
   "empty_column.blocks": "You haven't blocked any users yet.",
   "empty_column.community": "ლოკალური თაიმლაინი ცარიელია. დაწერეთ რაიმე ღიად ან ქენით რაიმე სხვა!",
   "empty_column.direct": "ჯერ პირდაპირი წერილები არ გაქვთ. როდესაც მიიღებთ ან გააგზავნით, გამოჩნდება აქ.",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "and {additional}",
   "hashtag.column_header.tag_mode.any": "or {additional}",
   "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
   "hashtag.column_settings.tag_mode.all": "All of these",
   "hashtag.column_settings.tag_mode.any": "Any of these",
   "hashtag.column_settings.tag_mode.none": "None of these",
@@ -149,6 +156,9 @@
   "home.column_settings.basic": "ძირითადი",
   "home.column_settings.show_reblogs": "ბუსტების ჩვენება",
   "home.column_settings.show_replies": "პასუხების ჩვენება",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
   "introduction.federation.action": "Next",
   "introduction.federation.federated.headline": "Federated",
   "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
@@ -156,7 +166,7 @@
   "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
   "introduction.federation.local.headline": "Local",
   "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
+  "introduction.interactions.action": "Finish toot-orial!",
   "introduction.interactions.favourite.headline": "Favourite",
   "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
   "introduction.interactions.reblog.headline": "Boost",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "ძიებაზე ფოკუსირებისთვის",
   "keyboard_shortcuts.start": "to open \"get started\" column",
   "keyboard_shortcuts.toggle_hidden": "გაფრთხილების უკან ტექსტის გამოსაჩენად/დასამალვად",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "ახალი ტუტის დასაწყებად",
   "keyboard_shortcuts.unfocus": "შედგენის ტექსტ-არეაზე ფოკუსის მოსაშორებლად",
   "keyboard_shortcuts.up": "სიაში ზემოთ გადასაადგილებლად",
   "lightbox.close": "დახურვა",
   "lightbox.next": "შემდეგი",
   "lightbox.previous": "წინა",
+  "lightbox.view_context": "View context",
   "lists.account.add": "სიაში დამატება",
   "lists.account.remove": "სიიდან ამოშლა",
   "lists.delete": "სიის წაშლა",
   "lists.edit": "სიის შეცვლა",
+  "lists.edit.submit": "Change title",
   "lists.new.create": "სიის დამატება",
   "lists.new.title_placeholder": "ახალი სიის სათაური",
   "lists.search": "ძებნა ადამიანებს შორის რომელთაც მიჰყვებით",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "ფავორიტები",
   "navigation_bar.filters": "გაჩუმებული სიტყვები",
   "navigation_bar.follow_requests": "დადევნების მოთხოვნები",
+  "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.info": "ამ ინსტანციის შესახებ",
   "navigation_bar.keyboard_shortcuts": "ცხელი კლავიშები",
   "navigation_bar.lists": "სიები",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "პირადი",
   "navigation_bar.pins": "აპინული ტუტები",
   "navigation_bar.preferences": "პრეფერენსიები",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "ფედერალური თაიმლაინი",
   "navigation_bar.security": "უსაფრთხოება",
   "notification.favourite": "{name}-მა თქვენი სტატუსი აქცია ფავორიტად",
   "notification.follow": "{name} გამოგყვათ",
   "notification.mention": "{name}-მა გასახელათ",
+  "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "{name}-მა დაბუსტა თქვენი სტატუსი",
   "notifications.clear": "შეტყობინებების გასუფთავება",
   "notifications.clear_confirmation": "დარწმუნებული ხართ, გსურთ სამუდამოდ წაშალოთ ყველა თქვენი შეტყობინება?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Show",
   "notifications.column_settings.follow": "ახალი მიმდევრები:",
   "notifications.column_settings.mention": "ხსენებები:",
+  "notifications.column_settings.poll": "Poll results:",
   "notifications.column_settings.push": "ფუშ შეტყობინებები",
   "notifications.column_settings.reblog": "ბუსტები:",
   "notifications.column_settings.show": "გამოჩნდეს სვეტში",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favourites",
   "notifications.filter.follows": "Follows",
   "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
   "notifications.group": "{count} შეტყობინება",
+  "poll.closed": "Closed",
+  "poll.refresh": "Refresh",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
   "privacy.change": "სტატუსის კონფიდენციალურობის მითითება",
   "privacy.direct.long": "დაიპოსტოს მხოლოდ დასახელებულ მომხმარებლებთან",
   "privacy.direct.short": "პირდაპირი",
@@ -291,12 +315,12 @@
   "search_results.hashtags": "ჰეშტეგები",
   "search_results.statuses": "ტუტები",
   "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
-  "standalone.public_title": "შიდა ხედი...",
   "status.admin_account": "Open moderation interface for @{name}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "დაბლოკე @{name}",
   "status.cancel_reblog_private": "ბუსტის მოშორება",
   "status.cannot_reblog": "ეს პოსტი ვერ დაიბუსტება",
+  "status.copy": "Copy link to status",
   "status.delete": "წაშლა",
   "status.detailed_status": "Detailed conversation view",
   "status.direct": "პირდაპირი წერილი @{name}-ს",
@@ -321,7 +345,6 @@
   "status.reply": "პასუხი",
   "status.replyAll": "უპასუხე თემას",
   "status.report": "დაარეპორტე @{name}",
-  "status.sensitive_toggle": "დააწკაპუნეთ სანახავად",
   "status.sensitive_warning": "მგრძნობიარე კონტენტი",
   "status.share": "გაზიარება",
   "status.show_less": "აჩვენე ნაკლები",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "ლოკალური",
   "tabs_bar.notifications": "შეტყობინებები",
   "tabs_bar.search": "ძებნა",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} საუბრობს",
   "ui.beforeunload": "თქვენი დრაფტი გაუქმდება თუ დატოვებთ მასტოდონს.",
   "upload_area.title": "გადმოწიეთ და ჩააგდეთ ასატვირთათ",
   "upload_button.label": "მედიის დამატება",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "upload_form.description": "აღწერილობა ვიზუალურად უფასურისთვის",
   "upload_form.focus": "კროპი",
   "upload_form.undo": "გაუქმება",
diff --git a/app/javascript/mastodon/locales/kk.json b/app/javascript/mastodon/locales/kk.json
new file mode 100644
index 0000000000000000000000000000000000000000..b9bd7cac31735bc861da23ab60c57cfd0a3d6ce4
--- /dev/null
+++ b/app/javascript/mastodon/locales/kk.json
@@ -0,0 +1,388 @@
+{
+  "account.add_or_remove_from_list": "Тізімге қосу немесе жою",
+  "account.badges.bot": "Бот",
+  "account.block": "Бұғаттау @{name}",
+  "account.block_domain": "Домендегі барлығын бұғатта {domain}",
+  "account.blocked": "Бұғатталды",
+  "account.direct": "Жеке хат @{name}",
+  "account.domain_blocked": "Домен жабық",
+  "account.edit_profile": "Профильді өңдеу",
+  "account.endorse": "Профильде рекомендеу",
+  "account.follow": "Жазылу",
+  "account.followers": "Оқырмандар",
+  "account.followers.empty": "Әлі ешкім жазылмаған.",
+  "account.follows": "Жазылғандары",
+  "account.follows.empty": "Ешкімге жазылмапты.",
+  "account.follows_you": "Сізге жазылыпты",
+  "account.hide_reblogs": "@{name} атты қолданушының әрекеттерін жасыру",
+  "account.link_verified_on": "Сілтеме меншігі расталған күн {date}",
+  "account.locked_info": "Бұл қолданушы өзі туралы мәліметтерді жасырған. Тек жазылғандар ғана көре алады.",
+  "account.media": "Медиа",
+  "account.mention": "Аталым @{name}",
+  "account.moved_to": "{name} көшіп кетті:",
+  "account.mute": "Үнсіз қылу @{name}",
+  "account.mute_notifications": "@{name} туралы ескертпелерді жасыру",
+  "account.muted": "Үнсіз",
+  "account.posts": "Жазбалар",
+  "account.posts_with_replies": "Жазбалар мен жауаптар",
+  "account.report": "Шағымдану @{name}",
+  "account.requested": "Растауын күтіңіз. Жазылудан бас тарту үшін басыңыз",
+  "account.share": "@{name} профилін бөлісу\"",
+  "account.show_reblogs": "@{name} бөліскендерін көрсету",
+  "account.unblock": "Бұғаттан шығару @{name}",
+  "account.unblock_domain": "Бұғаттан шығару {domain}",
+  "account.unendorse": "Профильде рекомендемеу",
+  "account.unfollow": "Оқымау",
+  "account.unmute": "@{name} ескертпелерін қосу",
+  "account.unmute_notifications": "@{name} ескертпелерін көрсету",
+  "alert.unexpected.message": "Бір нәрсе дұрыс болмады.",
+  "alert.unexpected.title": "Өй!",
+  "boost_modal.combo": "Келесіде өткізіп жіберу үшін басыңыз {combo}",
+  "bundle_column_error.body": "Бұл компонентті жүктеген кезде бір қате пайда болды.",
+  "bundle_column_error.retry": "Қайтадан көріңіз",
+  "bundle_column_error.title": "Желі қатесі",
+  "bundle_modal_error.close": "Жабу",
+  "bundle_modal_error.message": "Бұл компонентті жүктеген кезде бір қате пайда болды.",
+  "bundle_modal_error.retry": "Қайтадан көріңіз",
+  "column.blocks": "Бұғатталғандар",
+  "column.community": "Жергілікті желі",
+  "column.direct": "Жеке хаттар",
+  "column.domain_blocks": "Жасырылған домендер",
+  "column.favourites": "Таңдаулылар",
+  "column.follow_requests": "Жазылу сұранымдары",
+  "column.home": "Басты бет",
+  "column.lists": "Тізімдер",
+  "column.mutes": "Үнсіз қолданушылар",
+  "column.notifications": "Ескертпелер",
+  "column.pins": "Жабыстырылған жазбалар",
+  "column.public": "Жаһандық желі",
+  "column_back_button.label": "Артқа",
+  "column_header.hide_settings": "Баптауларды жасыр",
+  "column_header.moveLeft_settings": "Бағананы солға жылжыту",
+  "column_header.moveRight_settings": "Бағананы оңға жылжыту",
+  "column_header.pin": "Жабыстыру",
+  "column_header.show_settings": "Баптауларды көрсет",
+  "column_header.unpin": "Алып тастау",
+  "column_subheading.settings": "Баптаулар",
+  "community.column_settings.media_only": "Тек медиа",
+  "compose_form.direct_message_warning": "Тек аталған қолданушыларға.",
+  "compose_form.direct_message_warning_learn_more": "Көбірек білу",
+  "compose_form.hashtag_warning": "Бұл пост іздеуде хэштегпен шықпайды, өйткені ол бәріне ашық емес. Тек ашық жазбаларды ғана хэштег арқылы іздеп табуға болады.",
+  "compose_form.lock_disclaimer": "Аккаунтыңыз {locked} емес. Кез келген адам жазылып, сізді оқи алады.",
+  "compose_form.lock_disclaimer.lock": "жабық",
+  "compose_form.placeholder": "Не бөліскіңіз келеді?",
+  "compose_form.poll.add_option": "Жауап қос",
+  "compose_form.poll.duration": "Сауалнама мерзімі",
+  "compose_form.poll.option_placeholder": "Жауап {number}",
+  "compose_form.poll.remove_option": "Бұл жауапты өшір",
+  "compose_form.publish": "Түрт",
+  "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
+  "compose_form.sensitive.marked": "Медиа нәзік деп белгіленген",
+  "compose_form.sensitive.unmarked": "Медиа нәзік деп белгіленбеген",
+  "compose_form.spoiler.marked": "Мәтін ескертумен жасырылған",
+  "compose_form.spoiler.unmarked": "Мәтін жасырылмаған",
+  "compose_form.spoiler_placeholder": "Ескертуіңізді осында жазыңыз",
+  "confirmation_modal.cancel": "Қайтып алу",
+  "confirmations.block.block_and_report": "Block & Report",
+  "confirmations.block.confirm": "Бұғаттау",
+  "confirmations.block.message": "{name} атты қолданушыны бұғаттайтыныңызға сенімдісіз бе?",
+  "confirmations.delete.confirm": "Өшіру",
+  "confirmations.delete.message": "Бұл жазбаны өшіресіз бе?",
+  "confirmations.delete_list.confirm": "Өшіру",
+  "confirmations.delete_list.message": "Бұл тізімді жоясыз ба шынымен?",
+  "confirmations.domain_block.confirm": "Бұл доменді бұғатта",
+  "confirmations.domain_block.message": "Бұл домендегі {domain} жазбаларды шынымен бұғаттайсыз ба? Кейде үнсіз қылып тастау да жеткілікті.",
+  "confirmations.mute.confirm": "Үнсіз қылу",
+  "confirmations.mute.message": "{name} атты қолданушы үнсіз болсын ба?",
+  "confirmations.redraft.confirm": "Өшіруді құптау",
+  "confirmations.redraft.message": "Бұл жазбаны өшіріп, нобайларға жібереміз бе? Барлық жауаптар мен лайктарды жоғалтасыз.",
+  "confirmations.reply.confirm": "Жауап",
+  "confirmations.reply.message": "Жауабыңыз жазып жатқан жазбаңыздың үстіне кетеді. Жалғастырамыз ба?",
+  "confirmations.unfollow.confirm": "Оқымау",
+  "confirmations.unfollow.message": "\"{name} атты қолданушыға енді жазылғыңыз келмей ме?",
+  "embed.instructions": "Төмендегі кодты көшіріп алу арқылы жазбаны басқа сайттарға да орналастыра аласыз.",
+  "embed.preview": "Былай көрінетін болады:",
+  "emoji_button.activity": "Белсенділік",
+  "emoji_button.custom": "Жеке",
+  "emoji_button.flags": "Тулар",
+  "emoji_button.food": "Тамақ",
+  "emoji_button.label": "Эмодзи қосу",
+  "emoji_button.nature": "Табиғат",
+  "emoji_button.not_found": "Эмодзи жоқ!! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.objects": "Заттар",
+  "emoji_button.people": "Адамдар",
+  "emoji_button.recent": "Соңғы",
+  "emoji_button.search": "Іздеу...",
+  "emoji_button.search_results": "Іздеу нәтижелері",
+  "emoji_button.symbols": "Таңбалар",
+  "emoji_button.travel": "Саяхат",
+  "empty_column.account_timeline": "Жазба жоқ ешқандай!",
+  "empty_column.account_unavailable": "Profile unavailable",
+  "empty_column.blocks": "Ешкімді бұғаттамағансыз.",
+  "empty_column.community": "Жергілікті желі бос. Сіз бастап жазыңыз!",
+  "empty_column.direct": "Әзірше дым хат жоқ. Өзіңіз жазып көріңіз алдымен.",
+  "empty_column.domain_blocks": "Бұғатталған домен жоқ.",
+  "empty_column.favourited_statuses": "Ешқандай жазба 'Таңдаулылар' тізіміне қосылмапты. Қосылғаннан кейін осында жинала бастайды.",
+  "empty_column.favourites": "Бұл постты әлі ешкім 'Таңдаулылар' тізіміне қоспапты. Біреу бастағаннан кейін осында көрінетін болады.",
+  "empty_column.follow_requests": "Әлі ешқандай жазылуға сұранымдар келмеді. Жаңа сұранымдар осында көрінетін болады.",
+  "empty_column.hashtag": "Бұндай хэштегпен әлі ешкім жазбапты.",
+  "empty_column.home": "Әлі ешкімге жазылмапсыз. Бәлкім {public} жазбаларын қарап немесе іздеуді қолданып көрерсіз.",
+  "empty_column.home.public_timeline": "ашық желі",
+  "empty_column.list": "Бұл тізімде ештеңе жоқ.",
+  "empty_column.lists": "Әзірше ешқандай тізіміңіз жоқ. Біреуін құрғаннан кейін осы жерде көрінетін болады.",
+  "empty_column.mutes": "Әзірше ешқандай үнсізге қойылған қолданушы жоқ.",
+  "empty_column.notifications": "Әзірше ешқандай ескертпе жоқ. Басқалармен араласуды бастаңыз және пікірталастарға қатысыңыз.",
+  "empty_column.public": "Ештеңе жоқ бұл жерде! Өзіңіз бастап жазып көріңіз немесе басқаларға жазылыңыз",
+  "follow_request.authorize": "Авторизация",
+  "follow_request.reject": "Қабылдамау",
+  "getting_started.developers": "Жасаушылар тобы",
+  "getting_started.directory": "Профильдер каталогы",
+  "getting_started.documentation": "Құжаттама",
+  "getting_started.heading": "Желіде",
+  "getting_started.invite": "Адам шақыру",
+  "getting_started.open_source_notice": "Mastodon - ашық кодты құрылым. Түзету енгізу немесе ұсыныстарды GitHub арқылы жасаңыз {github}.",
+  "getting_started.security": "Қауіпсіздік",
+  "getting_started.terms": "Қызмет көрсету шарттары",
+  "hashtag.column_header.tag_mode.all": "және {additional}",
+  "hashtag.column_header.tag_mode.any": "немесе {additional}",
+  "hashtag.column_header.tag_mode.none": "{additional} болмай",
+  "hashtag.column_settings.select.no_options_message": "Ұсыныстар табылмады",
+  "hashtag.column_settings.select.placeholder": "Хэштег жазыңыз…",
+  "hashtag.column_settings.tag_mode.all": "Осының барлығын",
+  "hashtag.column_settings.tag_mode.any": "Осылардың біреуін",
+  "hashtag.column_settings.tag_mode.none": "Бұлардың ешқайсысын",
+  "hashtag.column_settings.tag_toggle": "Осы бағанға қосымша тегтерді қосыңыз",
+  "home.column_settings.basic": "Негізгі",
+  "home.column_settings.show_reblogs": "Бөлісулерді көрсету",
+  "home.column_settings.show_replies": "Жауаптарды көрсету",
+  "intervals.full.days": "{number, plural, one {# күн} other {# күн}}",
+  "intervals.full.hours": "{number, plural, one {# сағат} other {# сағат}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
+  "introduction.federation.action": "Келесі",
+  "introduction.federation.federated.headline": "Жаһандық",
+  "introduction.federation.federated.text": "Жаһандық желідегі жазбалар осында көрінетін болады.",
+  "introduction.federation.home.headline": "Басты бет",
+  "introduction.federation.home.text": "Жазылған адамдарыңыздың жазбалары осында шығады. Кез келген серверден жазылуыңызға болады!",
+  "introduction.federation.local.headline": "Жергілікті",
+  "introduction.federation.local.text": "Жергілікті желіде жазылған жазбалар осында шығатын болады.",
+  "introduction.interactions.action": "Оқулық аяқталды!",
+  "introduction.interactions.favourite.headline": "Таңдаулы",
+  "introduction.interactions.favourite.text": "Жазбаларды таңдаулыға сақтауға болады, осылайша авторына ұнағанын білдіре аласыз.",
+  "introduction.interactions.reblog.headline": "Бөлісу",
+  "introduction.interactions.reblog.text": "Ұнаған жазбаларды өз оқырмандарыңызбен бөлісе аласыз.",
+  "introduction.interactions.reply.headline": "Жауап",
+  "introduction.interactions.reply.text": "Жазбаларға жауап жаза аласыз, осылайша пікірталас өрбітуіңізге болады.",
+  "introduction.welcome.action": "Кеттік!",
+  "introduction.welcome.headline": "Алғашқы қадамдар",
+  "introduction.welcome.text": "Желіге қош келдіңіз! Бірнеше минуттан кейін желіде жазба қалдырып, медиа бөлісіп, басқалармен пікірталасқа қатысып ортаға қосыла аласыз. . Бірақ бұл сервер {domain} - бұл ерекше, ол сіздің профиліңізді қояды, сондықтан оның есімін есіңізде сақтаңыз.",
+  "keyboard_shortcuts.back": "артқа қайту",
+  "keyboard_shortcuts.blocked": "бұғатталғандар тізімін ашу",
+  "keyboard_shortcuts.boost": "жазба бөлісу",
+  "keyboard_shortcuts.column": "бағандардағы жазбаны оқу",
+  "keyboard_shortcuts.compose": "пост жазу",
+  "keyboard_shortcuts.description": "Сипаттама",
+  "keyboard_shortcuts.direct": "жеке хаттар бағаны",
+  "keyboard_shortcuts.down": "тізімде төмен түсу",
+  "keyboard_shortcuts.enter": "жазбаны ашу",
+  "keyboard_shortcuts.favourite": "таңдаулыға қосу",
+  "keyboard_shortcuts.favourites": "таңдаулылар тізімін ашу",
+  "keyboard_shortcuts.federated": "жаңандық желіні ашу",
+  "keyboard_shortcuts.heading": "Қысқа кодтар тақтасы",
+  "keyboard_shortcuts.home": "жергілікті жазбаларды қарау",
+  "keyboard_shortcuts.hotkey": "Ыстық пернелер",
+  "keyboard_shortcuts.legend": "осы мазмұнды көрсету",
+  "keyboard_shortcuts.local": "жергілікті желіні ашу",
+  "keyboard_shortcuts.mention": "авторды атап өту",
+  "keyboard_shortcuts.muted": "үнсіздер тізімін ашу",
+  "keyboard_shortcuts.my_profile": "профиліңізді ашу",
+  "keyboard_shortcuts.notifications": "ескертпелер бағанын ашу",
+  "keyboard_shortcuts.pinned": "жабыстырылған жазбаларды көру",
+  "keyboard_shortcuts.profile": "автор профилін қарау",
+  "keyboard_shortcuts.reply": "жауап жазу",
+  "keyboard_shortcuts.requests": "жазылу сұранымдарын қарау",
+  "keyboard_shortcuts.search": "іздеу",
+  "keyboard_shortcuts.start": "бастапқы бағанға бару",
+  "keyboard_shortcuts.toggle_hidden": "жабық мәтінді CW ашу/жабу",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
+  "keyboard_shortcuts.toot": "жаңа жазба бастау",
+  "keyboard_shortcuts.unfocus": "жазба қалдыру алаңынан шығу",
+  "keyboard_shortcuts.up": "тізімде жоғары шығу",
+  "lightbox.close": "Жабу",
+  "lightbox.next": "Келесі",
+  "lightbox.previous": "Алдыңғы",
+  "lightbox.view_context": "View context",
+  "lists.account.add": "Тізімге қосу",
+  "lists.account.remove": "Тізімнен шығару",
+  "lists.delete": "Тізімді өшіру",
+  "lists.edit": "Тізімді өңдеу",
+  "lists.edit.submit": "Тақырыбын өзгерту",
+  "lists.new.create": "Тізім құру",
+  "lists.new.title_placeholder": "Жаңа тізім аты",
+  "lists.search": "Сіз іздеген адамдар арасында іздеу",
+  "lists.subheading": "Тізімдеріңіз",
+  "loading_indicator.label": "Жүктеу...",
+  "media_gallery.toggle_visible": "Көрінуді қосу",
+  "missing_indicator.label": "Табылмады",
+  "missing_indicator.sublabel": "Бұл ресурс табылмады",
+  "mute_modal.hide_notifications": "Бұл қолданушы ескертпелерін жасырамыз ба?",
+  "navigation_bar.apps": "Мобиль қосымшалар",
+  "navigation_bar.blocks": "Бұғатталғандар",
+  "navigation_bar.community_timeline": "Жергілікті желі",
+  "navigation_bar.compose": "Жаңа жазба бастау",
+  "navigation_bar.direct": "Жеке хаттар",
+  "navigation_bar.discover": "шарлау",
+  "navigation_bar.domain_blocks": "Жабық домендер",
+  "navigation_bar.edit_profile": "Профиль түзету",
+  "navigation_bar.favourites": "Таңдаулылар",
+  "navigation_bar.filters": "Үнсіз сөздер",
+  "navigation_bar.follow_requests": "Жазылуға сұранғандар",
+  "navigation_bar.follows_and_followers": "Follows and followers",
+  "navigation_bar.info": "Сервер туралы",
+  "navigation_bar.keyboard_shortcuts": "Ыстық пернелер",
+  "navigation_bar.lists": "Тізімдер",
+  "navigation_bar.logout": "Шығу",
+  "navigation_bar.mutes": "Үнсіз қолданушылар",
+  "navigation_bar.personal": "Жеке",
+  "navigation_bar.pins": "Жабыстырылғандар",
+  "navigation_bar.preferences": "Басымдықтар",
+  "navigation_bar.profile_directory": "Profile directory",
+  "navigation_bar.public_timeline": "Жаһандық желі",
+  "navigation_bar.security": "Қауіпсіздік",
+  "notification.favourite": "{name} жазбаңызды таңдаулыға қосты",
+  "notification.follow": "{name} сізге жазылды",
+  "notification.mention": "{name} сізді атап өтті",
+  "notification.poll": "Бұл сауалнаманың мерзімі аяқталыпты",
+  "notification.reblog": "{name} жазбаңызды бөлісті",
+  "notifications.clear": "Ескертпелерді тазарт",
+  "notifications.clear_confirmation": "Шынымен барлық ескертпелерді өшіресіз бе?",
+  "notifications.column_settings.alert": "Үстел ескертпелері",
+  "notifications.column_settings.favourite": "Таңдаулылар:",
+  "notifications.column_settings.filter_bar.advanced": "Барлық категорияны көрсет",
+  "notifications.column_settings.filter_bar.category": "Жедел сүзгі",
+  "notifications.column_settings.filter_bar.show": "Көрсету",
+  "notifications.column_settings.follow": "Жаңа оқырмандар:",
+  "notifications.column_settings.mention": "Аталымдар:",
+  "notifications.column_settings.poll": "Нәтижелері:",
+  "notifications.column_settings.push": "Push ескертпелер",
+  "notifications.column_settings.reblog": "Бөлісулер:",
+  "notifications.column_settings.show": "Бағанда көрсет",
+  "notifications.column_settings.sound": "Дыбысын қос",
+  "notifications.filter.all": "Барлығы",
+  "notifications.filter.boosts": "Бөлісулер",
+  "notifications.filter.favourites": "Таңдаулылар",
+  "notifications.filter.follows": "Жазылулар",
+  "notifications.filter.mentions": "Аталымдар",
+  "notifications.filter.polls": "Сауалнама нәтижелері",
+  "notifications.group": "{count} ескертпе",
+  "poll.closed": "Жабық",
+  "poll.refresh": "Жаңарту",
+  "poll.total_votes": "{count, plural, one {# дауыс} other {# дауыс}}",
+  "poll.vote": "Дауыс беру",
+  "poll_button.add_poll": "Сауалнама қосу",
+  "poll_button.remove_poll": "Сауалнаманы өшіру",
+  "privacy.change": "Құпиялылықты реттеу",
+  "privacy.direct.long": "Аталған адамдарға ғана көрінетін жазба",
+  "privacy.direct.short": "Тікелей",
+  "privacy.private.long": "Тек оқырмандарға арналған жазба",
+  "privacy.private.short": "Оқырмандарға ғана",
+  "privacy.public.long": "Ашық желіге жібер",
+  "privacy.public.short": "Ашық",
+  "privacy.unlisted.long": "Do not show in public timelines",
+  "privacy.unlisted.short": "Тізімсіз",
+  "regeneration_indicator.label": "Жүктеу…",
+  "regeneration_indicator.sublabel": "Жергілікті желі құрылуда!",
+  "relative_time.days": "{number}күн",
+  "relative_time.hours": "{number}сағ",
+  "relative_time.just_now": "жаңа",
+  "relative_time.minutes": "{number}мин",
+  "relative_time.seconds": "{number}s",
+  "reply_indicator.cancel": "Қайтып алу",
+  "report.forward": "Жіберу {target}",
+  "report.forward_hint": "Бұл аккаунт басқа серверден. Аноним шағым жібересіз бе?",
+  "report.hint": "Шағым сіздің модераторларға жіберіледі. Шағымның себептерін мына жерге жазуыңызға болады:",
+  "report.placeholder": "Қосымша пікірлер",
+  "report.submit": "Жіберу",
+  "report.target": "Шағымдану {target}",
+  "search.placeholder": "Іздеу",
+  "search_popout.search_format": "Кеңейтілген іздеу форматы",
+  "search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, bоosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
+  "search_popout.tips.hashtag": "хэштег",
+  "search_popout.tips.status": "статус",
+  "search_popout.tips.text": "Simple text returns matching display names, usernames аnd hashtags",
+  "search_popout.tips.user": "қолданушы",
+  "search_results.accounts": "Адамдар",
+  "search_results.hashtags": "Хэштегтер",
+  "search_results.statuses": "Жазбалар",
+  "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
+  "status.admin_account": "@{name} үшін модерация интерфейсін аш",
+  "status.admin_status": "Бұл жазбаны модерация интерфейсінде аш",
+  "status.block": "Бұғаттау @{name}",
+  "status.cancel_reblog_private": "Бөліспеу",
+  "status.cannot_reblog": "Бұл жазба бөлісілмейді",
+  "status.copy": "Жазба сілтемесін көшір",
+  "status.delete": "Өшіру",
+  "status.detailed_status": "Толық пікірталас көрінісі",
+  "status.direct": "Хат жіберу @{name}",
+  "status.embed": "Embеd",
+  "status.favourite": "Таңдаулы",
+  "status.filtered": "Фильтрленген",
+  "status.load_more": "Тағы әкел",
+  "status.media_hidden": "Жабық медиа",
+  "status.mention": "Аталым @{name}",
+  "status.more": "Тағы",
+  "status.mute": "Үнсіз @{name}",
+  "status.mute_conversation": "Пікірталасты үнсіз қылу",
+  "status.open": "Жазбаны ашу",
+  "status.pin": "Профильде жабыстыру",
+  "status.pinned": "Жабыстырылған жазба",
+  "status.read_more": "Әрі қарай",
+  "status.reblog": "Бөлісу",
+  "status.reblog_private": "Негізгі аудиторияға бөлісу",
+  "status.reblogged_by": "{name} бөлісті",
+  "status.reblogs.empty": "Бұл жазбаны әлі ешкім бөліспеді. Біреу бөліскен кезде осында көрінеді.",
+  "status.redraft": "Өшіру & қайта қарастыру",
+  "status.reply": "Жауап",
+  "status.replyAll": "Тақырыпқа жауап",
+  "status.report": "Шағым @{name}",
+  "status.sensitive_warning": "Нәзік контент",
+  "status.share": "Бөлісу",
+  "status.show_less": "Аздап көрсет",
+  "status.show_less_all": "Бәрін аздап көрсет",
+  "status.show_more": "Толығырақ",
+  "status.show_more_all": "Бәрін толығымен",
+  "status.show_thread": "Желіні көрсет",
+  "status.unmute_conversation": "Пікірталасты үнсіз қылмау",
+  "status.unpin": "Профильден алып тастау",
+  "suggestions.dismiss": "Өткізіп жіберу",
+  "suggestions.header": "Қызығуыңыз мүмкін…",
+  "tabs_bar.federated_timeline": "Жаһандық",
+  "tabs_bar.home": "Басты бет",
+  "tabs_bar.local_timeline": "Жергілікті",
+  "tabs_bar.notifications": "Ескертпелер",
+  "tabs_bar.search": "Іздеу",
+  "time_remaining.days": "{number, plural, one {# күн} other {# күн}}",
+  "time_remaining.hours": "{number, plural, one {# сағат} other {# сағат}}",
+  "time_remaining.minutes": "{number, plural, one {# минут} other {# минут}}",
+  "time_remaining.moments": "Қалған уақыт",
+  "time_remaining.seconds": "{number, plural, one {# секунд} other {# секунд}}",
+  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} жазған екен",
+  "ui.beforeunload": "Mastodon желісінен шықсаңыз, нобайыңыз сақталмайды.",
+  "upload_area.title": "Жүктеу үшін сүйреп әкеліңіз",
+  "upload_button.label": "Медиа қосу (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "Файл жүктеу лимитінен асып кеттіңіз.",
+  "upload_error.poll": "Сауалнамамен бірге файл жүктеуге болмайды.",
+  "upload_form.description": "Көру қабілеті нашар адамдар үшін сипаттаңыз",
+  "upload_form.focus": "Превьюді өзгерту",
+  "upload_form.undo": "Өшіру",
+  "upload_progress.label": "Жүктеп жатыр...",
+  "video.close": "Видеоны жабу",
+  "video.exit_fullscreen": "Толық экраннан шық",
+  "video.expand": "Видеоны аш",
+  "video.fullscreen": "Толық экран",
+  "video.hide": "Видеоны жасыр",
+  "video.mute": "Дыбысын бас",
+  "video.pause": "Пауза",
+  "video.play": "Қосу",
+  "video.unmute": "Дауысын аш"
+}
diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json
index ceb474a3e54974dd3941f0a912523b33f0d52c7d..656a36bce24f2826f2034c4352b4389ef038d271 100644
--- a/app/javascript/mastodon/locales/ko.json
+++ b/app/javascript/mastodon/locales/ko.json
@@ -5,7 +5,6 @@
   "account.block_domain": "{domain} 전체를 숨김",
   "account.blocked": "차단 됨",
   "account.direct": "@{name}으로부터의 다이렉트 메시지",
-  "account.disclaimer_full": "여기 있는 정보는 유저의 프로파일을 정확히 반영하지 못 할 수도 있습니다.",
   "account.domain_blocked": "도메인 숨겨짐",
   "account.edit_profile": "프로필 편집",
   "account.endorse": "프로필에 나타내기",
@@ -36,7 +35,6 @@
   "account.unfollow": "팔로우 해제",
   "account.unmute": "뮤트 해제",
   "account.unmute_notifications": "@{name}의 알림 뮤트 해제",
-  "account.view_full_profile": "전체 프로필 보기",
   "alert.unexpected.message": "예측하지 못한 에러가 발생했습니다.",
   "alert.unexpected.title": "ì•—!",
   "boost_modal.combo": "{combo}를 누르면 다음부터 이 과정을 건너뛸 수 있습니다",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "이 계정은 {locked}로 설정 되어 있지 않습니다. 누구나 이 계정을 팔로우 할 수 있으며, 팔로워 공개의 포스팅을 볼 수 있습니다.",
   "compose_form.lock_disclaimer.lock": "비공개",
   "compose_form.placeholder": "지금 무엇을 하고 있나요?",
+  "compose_form.poll.add_option": "항목 추가",
+  "compose_form.poll.duration": "투표 기간",
+  "compose_form.poll.option_placeholder": "{number}번 항목",
+  "compose_form.poll.remove_option": "이 항목 삭제",
   "compose_form.publish": "툿",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "미디어를 민감함으로 설정하기",
   "compose_form.sensitive.marked": "미디어가 열람주의로 설정되어 있습니다",
   "compose_form.sensitive.unmarked": "미디어가 열람주의로 설정 되어 있지 않습니다",
   "compose_form.spoiler.marked": "열람주의가 설정되어 있습니다",
   "compose_form.spoiler.unmarked": "열람주의가 설정 되어 있지 않습니다",
   "compose_form.spoiler_placeholder": "경고",
   "confirmation_modal.cancel": "취소",
+  "confirmations.block.block_and_report": "차단하고 신고하기",
   "confirmations.block.confirm": "차단",
   "confirmations.block.message": "정말로 {name}를 차단하시겠습니까?",
   "confirmations.delete.confirm": "삭제",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "기호",
   "emoji_button.travel": "여행과 장소",
   "empty_column.account_timeline": "여긴 툿이 없어요!",
+  "empty_column.account_unavailable": "프로필 사용 불가",
   "empty_column.blocks": "아직 아무도 차단하지 않았습니다.",
   "empty_column.community": "로컬 타임라인에 아무 것도 없습니다. 아무거나 적어 보세요!",
   "empty_column.direct": "아직 다이렉트 메시지가 없습니다. 다이렉트 메시지를 보내거나 받은 경우, 여기에 표시 됩니다.",
@@ -128,7 +133,7 @@
   "empty_column.lists": "아직 리스트가 없습니다. 리스트를 만들면 여기에 나타납니다.",
   "empty_column.mutes": "아직 아무도 뮤트하지 않았습니다.",
   "empty_column.notifications": "아직 알림이 없습니다. 다른 사람과 대화를 시작해 보세요.",
-  "empty_column.public": "여기엔 아직 아무 것도 없습니다! 공개적으로 무언가 포스팅하거나, 다른 인스턴스의 유저를 팔로우 해서 채워보세요",
+  "empty_column.public": "여기엔 아직 아무 것도 없습니다! 공개적으로 무언가 포스팅하거나, 다른 서버의 유저를 팔로우 해서 채워보세요",
   "follow_request.authorize": "허가",
   "follow_request.reject": "ê±°ë¶€",
   "getting_started.developers": "개발자",
@@ -142,19 +147,24 @@
   "hashtag.column_header.tag_mode.all": "그리고 {additional}",
   "hashtag.column_header.tag_mode.any": "또는 {additional}",
   "hashtag.column_header.tag_mode.none": "({additional}를 제외)",
+  "hashtag.column_settings.select.no_options_message": "추천 할 내용이 없습니다",
+  "hashtag.column_settings.select.placeholder": "해시태그를 입력하세요…",
   "hashtag.column_settings.tag_mode.all": "모두",
   "hashtag.column_settings.tag_mode.any": "아무것이든",
   "hashtag.column_settings.tag_mode.none": "이것들을 제외하고",
-  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "hashtag.column_settings.tag_toggle": "추가 해시태그를 이 컬럼에 추가합니다",
   "home.column_settings.basic": "기본 설정",
   "home.column_settings.show_reblogs": "부스트 표시",
   "home.column_settings.show_replies": "답글 표시",
+  "intervals.full.days": "{number} 일",
+  "intervals.full.hours": "{number} 시간",
+  "intervals.full.minutes": "{number} ë¶„",
   "introduction.federation.action": "다음",
-  "introduction.federation.federated.headline": "Federated",
+  "introduction.federation.federated.headline": "ì—°í•©",
   "introduction.federation.federated.text": "페디버스의 다른 서버의 공개 게시물이 연합 타임라인에 나타납니다.",
-  "introduction.federation.home.headline": "Home",
+  "introduction.federation.home.headline": "홈",
   "introduction.federation.home.text": "당신이 팔로우 하고 있는 사람의 게시물이 홈 타임라인에 나타납니다. 어느 서버에 있는 사람이라도 팔로우가 가능합니다!",
-  "introduction.federation.local.headline": "Local",
+  "introduction.federation.local.headline": "로컬",
   "introduction.federation.local.text": "같은 서버에 있는 공개 게시물은 로컬 타임라인에 나타납니다.",
   "introduction.interactions.action": "튜토리얼 마치기!",
   "introduction.interactions.favourite.headline": "즐겨찾기",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "검색창에 포커스",
   "keyboard_shortcuts.start": "\"시작하기\" 컬럼 열기",
   "keyboard_shortcuts.toggle_hidden": "CW로 가려진 텍스트를 표시/비표시",
+  "keyboard_shortcuts.toggle_sensitivity": "이미지 보이기/숨기기",
   "keyboard_shortcuts.toot": "새 툿 작성",
   "keyboard_shortcuts.unfocus": "작성창에서 포커스 해제",
   "keyboard_shortcuts.up": "리스트에서 위로 이동",
   "lightbox.close": "닫기",
   "lightbox.next": "다음",
   "lightbox.previous": "이전",
+  "lightbox.view_context": "게시물 보기",
   "lists.account.add": "리스트에 추가",
   "lists.account.remove": "리스트에서 제거",
   "lists.delete": "리스트 삭제",
   "lists.edit": "리스트 편집",
+  "lists.edit.submit": "제목 수정",
   "lists.new.create": "리스트 추가",
   "lists.new.title_placeholder": "새 리스트의 이름",
   "lists.search": "팔로우 중인 사람들 중에서 찾기",
@@ -224,7 +237,8 @@
   "navigation_bar.favourites": "즐겨찾기",
   "navigation_bar.filters": "뮤트",
   "navigation_bar.follow_requests": "팔로우 요청",
-  "navigation_bar.info": "이 인스턴스에 대해서",
+  "navigation_bar.follows_and_followers": "팔로우와 팔로워",
+  "navigation_bar.info": "이 서버에 대해서",
   "navigation_bar.keyboard_shortcuts": "단축키",
   "navigation_bar.lists": "리스트",
   "navigation_bar.logout": "로그아웃",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "개인용",
   "navigation_bar.pins": "고정된 툿",
   "navigation_bar.preferences": "사용자 설정",
+  "navigation_bar.profile_directory": "프로필 디렉토리",
   "navigation_bar.public_timeline": "연합 타임라인",
   "navigation_bar.security": "보안",
   "notification.favourite": "{name}님이 즐겨찾기 했습니다",
   "notification.follow": "{name}님이 나를 팔로우 했습니다",
   "notification.mention": "{name}님이 답글을 보냈습니다",
+  "notification.poll": "당신이 참여 한 투표가 종료되었습니다",
   "notification.reblog": "{name}님이 부스트 했습니다",
   "notifications.clear": "알림 지우기",
   "notifications.clear_confirmation": "정말로 알림을 삭제하시겠습니까?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "표시",
   "notifications.column_settings.follow": "새 팔로워:",
   "notifications.column_settings.mention": "답글:",
+  "notifications.column_settings.poll": "투표 결과:",
   "notifications.column_settings.push": "푸시 알림",
   "notifications.column_settings.reblog": "부스트:",
   "notifications.column_settings.show": "컬럼에 표시",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "즐겨찾기",
   "notifications.filter.follows": "팔로우",
   "notifications.filter.mentions": "멘션",
+  "notifications.filter.polls": "투표 결과",
   "notifications.group": "{count} 개의 알림",
+  "poll.closed": "마감됨",
+  "poll.refresh": "새로고침",
+  "poll.total_votes": "{count} 명 참여",
+  "poll.vote": "투표",
+  "poll_button.add_poll": "투표 추가",
+  "poll_button.remove_poll": "투표 삭제",
   "privacy.change": "포스트의 프라이버시 설정을 변경",
   "privacy.direct.long": "멘션한 사용자에게만 공개",
   "privacy.direct.short": "다이렉트",
@@ -291,12 +315,12 @@
   "search_results.hashtags": "해시태그",
   "search_results.statuses": "툿",
   "search_results.total": "{count, number}건의 결과",
-  "standalone.public_title": "지금 이런 이야기를 하고 있습니다…",
   "status.admin_account": "@{name}에 대한 모더레이션 인터페이스 열기",
   "status.admin_status": "모더레이션 인터페이스에서 이 게시물 열기",
   "status.block": "@{name} 차단",
   "status.cancel_reblog_private": "부스트 취소",
   "status.cannot_reblog": "이 포스트는 부스트 할 수 없습니다",
+  "status.copy": "게시물 링크 복사",
   "status.delete": "삭제",
   "status.detailed_status": "대화 자세히 보기",
   "status.direct": "@{name}에게 다이렉트 메시지",
@@ -321,14 +345,13 @@
   "status.reply": "답장",
   "status.replyAll": "전원에게 답장",
   "status.report": "ì‹ ê³ ",
-  "status.sensitive_toggle": "클릭해서 표시하기",
   "status.sensitive_warning": "민감한 미디어",
   "status.share": "공유",
   "status.show_less": "숨기기",
   "status.show_less_all": "모두 접기",
   "status.show_more": "더 보기",
   "status.show_more_all": "모두 펼치기",
-  "status.show_thread": "스레드 보기",
+  "status.show_thread": "글타래 보기",
   "status.unmute_conversation": "이 대화의 뮤트 해제하기",
   "status.unpin": "고정 해제",
   "suggestions.dismiss": "추천 지우기",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "로컬",
   "tabs_bar.notifications": "알림",
   "tabs_bar.search": "검색",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {명} other {명}} 의 사람들이 말하고 있습니다",
+  "time_remaining.days": "{number} 일 남음",
+  "time_remaining.hours": "{number} 시간 남음",
+  "time_remaining.minutes": "{number} 분 남음",
+  "time_remaining.moments": "남은 시간",
+  "time_remaining.seconds": "{number} 초 남음",
+  "trends.count_by_accounts": "{count} 명의 사람들이 말하고 있습니다",
   "ui.beforeunload": "지금 나가면 저장되지 않은 항목을 잃게 됩니다.",
   "upload_area.title": "드래그 & 드롭으로 업로드",
   "upload_button.label": "미디어 추가 (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "파일 업로드 제한에 도달했습니다.",
+  "upload_error.poll": "파일 업로드는 투표와 함께 첨부할 수 없습니다.",
   "upload_form.description": "시각장애인을 위한 설명",
   "upload_form.focus": "미리보기 변경",
   "upload_form.undo": "삭제",
diff --git a/app/javascript/mastodon/locales/lt.json b/app/javascript/mastodon/locales/lt.json
new file mode 100644
index 0000000000000000000000000000000000000000..ac58514d420791eebba0e8f7ce290ddf59340acd
--- /dev/null
+++ b/app/javascript/mastodon/locales/lt.json
@@ -0,0 +1,388 @@
+{
+  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.badges.bot": "Bot",
+  "account.block": "Block @{name}",
+  "account.block_domain": "Hide everything from {domain}",
+  "account.blocked": "Blocked",
+  "account.direct": "Direct message @{name}",
+  "account.domain_blocked": "Domain hidden",
+  "account.edit_profile": "Edit profile",
+  "account.endorse": "Feature on profile",
+  "account.follow": "Follow",
+  "account.followers": "Followers",
+  "account.followers.empty": "No one follows this user yet.",
+  "account.follows": "Follows",
+  "account.follows.empty": "This user doesn't follow anyone yet.",
+  "account.follows_you": "Follows you",
+  "account.hide_reblogs": "Hide boosts from @{name}",
+  "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
+  "account.media": "Media",
+  "account.mention": "Mention @{name}",
+  "account.moved_to": "{name} has moved to:",
+  "account.mute": "Mute @{name}",
+  "account.mute_notifications": "Mute notifications from @{name}",
+  "account.muted": "Muted",
+  "account.posts": "Toots",
+  "account.posts_with_replies": "Toots and replies",
+  "account.report": "Report @{name}",
+  "account.requested": "Awaiting approval. Click to cancel follow request",
+  "account.share": "Share @{name}'s profile",
+  "account.show_reblogs": "Show boosts from @{name}",
+  "account.unblock": "Unblock @{name}",
+  "account.unblock_domain": "Unhide {domain}",
+  "account.unendorse": "Don't feature on profile",
+  "account.unfollow": "Unfollow",
+  "account.unmute": "Unmute @{name}",
+  "account.unmute_notifications": "Unmute notifications from @{name}",
+  "alert.unexpected.message": "An unexpected error occurred.",
+  "alert.unexpected.title": "Oops!",
+  "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",
+  "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",
+  "column.community": "Local timeline",
+  "column.direct": "Direct messages",
+  "column.domain_blocks": "Hidden domains",
+  "column.favourites": "Favourites",
+  "column.follow_requests": "Follow requests",
+  "column.home": "Home",
+  "column.lists": "Lists",
+  "column.mutes": "Muted users",
+  "column.notifications": "Notifications",
+  "column.pins": "Pinned toot",
+  "column.public": "Federated timeline",
+  "column_back_button.label": "Back",
+  "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.settings": "Settings",
+  "community.column_settings.media_only": "Media Only",
+  "compose_form.direct_message_warning": "This toot will only be sent to all the mentioned users.",
+  "compose_form.direct_message_warning_learn_more": "Learn more",
+  "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",
+  "compose_form.placeholder": "What is on your mind?",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
+  "compose_form.publish": "Toot",
+  "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
+  "compose_form.sensitive.marked": "Media is marked as sensitive",
+  "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
+  "compose_form.spoiler.marked": "Text is hidden behind warning",
+  "compose_form.spoiler.unmarked": "Text is not hidden",
+  "compose_form.spoiler_placeholder": "Write your warning here",
+  "confirmation_modal.cancel": "Cancel",
+  "confirmations.block.block_and_report": "Block & Report",
+  "confirmations.block.confirm": "Block",
+  "confirmations.block.message": "Are you sure you want to block {name}?",
+  "confirmations.delete.confirm": "Delete",
+  "confirmations.delete.message": "Are you sure you want to delete this status?",
+  "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. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.",
+  "confirmations.mute.confirm": "Mute",
+  "confirmations.mute.message": "Are you sure you want to mute {name}?",
+  "confirmations.redraft.confirm": "Delete & redraft",
+  "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.",
+  "confirmations.reply.confirm": "Reply",
+  "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
+  "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.account_timeline": "No toots here!",
+  "empty_column.account_unavailable": "Profile unavailable",
+  "empty_column.blocks": "You haven't blocked any users yet.",
+  "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
+  "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
+  "empty_column.domain_blocks": "There are no hidden domains yet.",
+  "empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.",
+  "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.",
+  "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
+  "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. When members of this list post new statuses, they will appear here.",
+  "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
+  "empty_column.mutes": "You haven't muted any users 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 servers to fill it up",
+  "follow_request.authorize": "Authorize",
+  "follow_request.reject": "Reject",
+  "getting_started.developers": "Developers",
+  "getting_started.directory": "Profile directory",
+  "getting_started.documentation": "Documentation",
+  "getting_started.heading": "Getting started",
+  "getting_started.invite": "Invite people",
+  "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.",
+  "getting_started.security": "Security",
+  "getting_started.terms": "Terms of service",
+  "hashtag.column_header.tag_mode.all": "and {additional}",
+  "hashtag.column_header.tag_mode.any": "or {additional}",
+  "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
+  "hashtag.column_settings.tag_mode.all": "All of these",
+  "hashtag.column_settings.tag_mode.any": "Any of these",
+  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "home.column_settings.basic": "Basic",
+  "home.column_settings.show_reblogs": "Show boosts",
+  "home.column_settings.show_replies": "Show replies",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
+  "introduction.federation.action": "Next",
+  "introduction.federation.federated.headline": "Federated",
+  "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
+  "introduction.federation.home.headline": "Home",
+  "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
+  "introduction.federation.local.headline": "Local",
+  "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
+  "introduction.interactions.action": "Finish toot-orial!",
+  "introduction.interactions.favourite.headline": "Favourite",
+  "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
+  "introduction.interactions.reblog.headline": "Boost",
+  "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
+  "introduction.interactions.reply.headline": "Reply",
+  "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
+  "introduction.welcome.action": "Let's go!",
+  "introduction.welcome.headline": "First steps",
+  "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
+  "keyboard_shortcuts.back": "to navigate back",
+  "keyboard_shortcuts.blocked": "to open blocked users list",
+  "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",
+  "keyboard_shortcuts.description": "Description",
+  "keyboard_shortcuts.direct": "to open direct messages column",
+  "keyboard_shortcuts.down": "to move down in the list",
+  "keyboard_shortcuts.enter": "to open status",
+  "keyboard_shortcuts.favourite": "to favourite",
+  "keyboard_shortcuts.favourites": "to open favourites list",
+  "keyboard_shortcuts.federated": "to open federated timeline",
+  "keyboard_shortcuts.heading": "Keyboard Shortcuts",
+  "keyboard_shortcuts.home": "to open home timeline",
+  "keyboard_shortcuts.hotkey": "Hotkey",
+  "keyboard_shortcuts.legend": "to display this legend",
+  "keyboard_shortcuts.local": "to open local timeline",
+  "keyboard_shortcuts.mention": "to mention author",
+  "keyboard_shortcuts.muted": "to open muted users list",
+  "keyboard_shortcuts.my_profile": "to open your profile",
+  "keyboard_shortcuts.notifications": "to open notifications column",
+  "keyboard_shortcuts.pinned": "to open pinned toots list",
+  "keyboard_shortcuts.profile": "to open author's profile",
+  "keyboard_shortcuts.reply": "to reply",
+  "keyboard_shortcuts.requests": "to open follow requests list",
+  "keyboard_shortcuts.search": "to focus search",
+  "keyboard_shortcuts.start": "to open \"get started\" column",
+  "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
+  "keyboard_shortcuts.toot": "to start a brand new toot",
+  "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
+  "keyboard_shortcuts.up": "to move up in the list",
+  "lightbox.close": "Close",
+  "lightbox.next": "Next",
+  "lightbox.previous": "Previous",
+  "lightbox.view_context": "View context",
+  "lists.account.add": "Add to list",
+  "lists.account.remove": "Remove from list",
+  "lists.delete": "Delete list",
+  "lists.edit": "Edit list",
+  "lists.edit.submit": "Change title",
+  "lists.new.create": "Add list",
+  "lists.new.title_placeholder": "New list title",
+  "lists.search": "Search among people you follow",
+  "lists.subheading": "Your lists",
+  "loading_indicator.label": "Loading...",
+  "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.apps": "Mobile apps",
+  "navigation_bar.blocks": "Blocked users",
+  "navigation_bar.community_timeline": "Local timeline",
+  "navigation_bar.compose": "Compose new toot",
+  "navigation_bar.direct": "Direct messages",
+  "navigation_bar.discover": "Discover",
+  "navigation_bar.domain_blocks": "Hidden domains",
+  "navigation_bar.edit_profile": "Edit profile",
+  "navigation_bar.favourites": "Favourites",
+  "navigation_bar.filters": "Muted words",
+  "navigation_bar.follow_requests": "Follow requests",
+  "navigation_bar.follows_and_followers": "Follows and followers",
+  "navigation_bar.info": "About this server",
+  "navigation_bar.keyboard_shortcuts": "Hotkeys",
+  "navigation_bar.lists": "Lists",
+  "navigation_bar.logout": "Logout",
+  "navigation_bar.mutes": "Muted users",
+  "navigation_bar.personal": "Personal",
+  "navigation_bar.pins": "Pinned toots",
+  "navigation_bar.preferences": "Preferences",
+  "navigation_bar.profile_directory": "Profile directory",
+  "navigation_bar.public_timeline": "Federated timeline",
+  "navigation_bar.security": "Security",
+  "notification.favourite": "{name} favourited your status",
+  "notification.follow": "{name} followed you",
+  "notification.mention": "{name} mentioned you",
+  "notification.poll": "A poll you have voted in has ended",
+  "notification.reblog": "{name} boosted your status",
+  "notifications.clear": "Clear notifications",
+  "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
+  "notifications.column_settings.alert": "Desktop notifications",
+  "notifications.column_settings.favourite": "Favourites:",
+  "notifications.column_settings.filter_bar.advanced": "Display all categories",
+  "notifications.column_settings.filter_bar.category": "Quick filter bar",
+  "notifications.column_settings.filter_bar.show": "Show",
+  "notifications.column_settings.follow": "New followers:",
+  "notifications.column_settings.mention": "Mentions:",
+  "notifications.column_settings.poll": "Poll results:",
+  "notifications.column_settings.push": "Push notifications",
+  "notifications.column_settings.reblog": "Boosts:",
+  "notifications.column_settings.show": "Show in column",
+  "notifications.column_settings.sound": "Play sound",
+  "notifications.filter.all": "All",
+  "notifications.filter.boosts": "Boosts",
+  "notifications.filter.favourites": "Favourites",
+  "notifications.filter.follows": "Follows",
+  "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
+  "notifications.group": "{count} notifications",
+  "poll.closed": "Closed",
+  "poll.refresh": "Refresh",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
+  "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!",
+  "relative_time.days": "{number}d",
+  "relative_time.hours": "{number}h",
+  "relative_time.just_now": "now",
+  "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 server moderators. You can provide an explanation of why you are reporting this account below:",
+  "report.placeholder": "Additional comments",
+  "report.submit": "Submit",
+  "report.target": "Report {target}",
+  "search.placeholder": "Search",
+  "search_popout.search_format": "Advanced search format",
+  "search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
+  "search_popout.tips.hashtag": "hashtag",
+  "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}}",
+  "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_status": "Open this status in the moderation interface",
+  "status.block": "Block @{name}",
+  "status.cancel_reblog_private": "Unboost",
+  "status.cannot_reblog": "This post cannot be boosted",
+  "status.copy": "Copy link to status",
+  "status.delete": "Delete",
+  "status.detailed_status": "Detailed conversation view",
+  "status.direct": "Direct message @{name}",
+  "status.embed": "Embed",
+  "status.favourite": "Favourite",
+  "status.filtered": "Filtered",
+  "status.load_more": "Load more",
+  "status.media_hidden": "Media hidden",
+  "status.mention": "Mention @{name}",
+  "status.more": "More",
+  "status.mute": "Mute @{name}",
+  "status.mute_conversation": "Mute conversation",
+  "status.open": "Expand this status",
+  "status.pin": "Pin on profile",
+  "status.pinned": "Pinned toot",
+  "status.read_more": "Read more",
+  "status.reblog": "Boost",
+  "status.reblog_private": "Boost to original audience",
+  "status.reblogged_by": "{name} boosted",
+  "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
+  "status.redraft": "Delete & re-draft",
+  "status.reply": "Reply",
+  "status.replyAll": "Reply to thread",
+  "status.report": "Report @{name}",
+  "status.sensitive_warning": "Sensitive content",
+  "status.share": "Share",
+  "status.show_less": "Show less",
+  "status.show_less_all": "Show less for all",
+  "status.show_more": "Show more",
+  "status.show_more_all": "Show more for all",
+  "status.show_thread": "Show thread",
+  "status.unmute_conversation": "Unmute conversation",
+  "status.unpin": "Unpin from profile",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
+  "tabs_bar.federated_timeline": "Federated",
+  "tabs_bar.home": "Home",
+  "tabs_bar.local_timeline": "Local",
+  "tabs_bar.notifications": "Notifications",
+  "tabs_bar.search": "Search",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
+  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
+  "upload_area.title": "Drag & drop to upload",
+  "upload_button.label": "Add media (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
+  "upload_form.description": "Describe for the visually impaired",
+  "upload_form.focus": "Crop",
+  "upload_form.undo": "Delete",
+  "upload_progress.label": "Uploading...",
+  "video.close": "Close video",
+  "video.exit_fullscreen": "Exit full screen",
+  "video.expand": "Expand video",
+  "video.fullscreen": "Full screen",
+  "video.hide": "Hide video",
+  "video.mute": "Mute sound",
+  "video.pause": "Pause",
+  "video.play": "Play",
+  "video.unmute": "Unmute sound"
+}
diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json
index 0d510d011fd988fa03addb3c713686883efb4131..647e23a691652654a1039cd40783aed66d305092 100644
--- a/app/javascript/mastodon/locales/lv.json
+++ b/app/javascript/mastodon/locales/lv.json
@@ -1,136 +1,141 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
-  "account.badges.bot": "Bot",
-  "account.block": "Block @{name}",
-  "account.block_domain": "Hide everything from {domain}",
-  "account.blocked": "Blocked",
-  "account.direct": "Direct message @{name}",
-  "account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
-  "account.domain_blocked": "Domain hidden",
-  "account.edit_profile": "Edit profile",
-  "account.endorse": "Feature on profile",
-  "account.follow": "Follow",
-  "account.followers": "Followers",
-  "account.followers.empty": "No one follows this user yet.",
-  "account.follows": "Follows",
-  "account.follows.empty": "This user doesn't follow anyone yet.",
-  "account.follows_you": "Follows you",
-  "account.hide_reblogs": "Hide boosts from @{name}",
-  "account.link_verified_on": "Ownership of this link was checked on {date}",
-  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
-  "account.media": "Media",
-  "account.mention": "Mention @{name}",
-  "account.moved_to": "{name} has moved to:",
-  "account.mute": "Mute @{name}",
-  "account.mute_notifications": "Mute notifications from @{name}",
-  "account.muted": "Muted",
-  "account.posts": "Toots",
-  "account.posts_with_replies": "Toots and replies",
-  "account.report": "Report @{name}",
-  "account.requested": "Awaiting approval. Click to cancel follow request",
-  "account.share": "Share @{name}'s profile",
-  "account.show_reblogs": "Show boosts from @{name}",
-  "account.unblock": "Unblock @{name}",
-  "account.unblock_domain": "Unhide {domain}",
-  "account.unendorse": "Don't feature on profile",
-  "account.unfollow": "Unfollow",
-  "account.unmute": "Unmute @{name}",
-  "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account.view_full_profile": "View full profile",
-  "alert.unexpected.message": "An unexpected error occurred.",
-  "alert.unexpected.title": "Oops!",
-  "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",
-  "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",
-  "column.community": "Local timeline",
-  "column.direct": "Direct messages",
-  "column.domain_blocks": "Hidden domains",
-  "column.favourites": "Favourites",
-  "column.follow_requests": "Follow requests",
-  "column.home": "Home",
-  "column.lists": "Lists",
-  "column.mutes": "Muted users",
-  "column.notifications": "Notifications",
-  "column.pins": "Pinned toot",
-  "column.public": "Federated timeline",
-  "column_back_button.label": "Back",
-  "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.settings": "Settings",
-  "community.column_settings.media_only": "Media Only",
-  "compose_form.direct_message_warning": "This toot will only be sent to all the mentioned users.",
-  "compose_form.direct_message_warning_learn_more": "Learn more",
-  "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",
-  "compose_form.placeholder": "What is on your mind?",
-  "compose_form.publish": "Toot",
+  "account.add_or_remove_from_list": "Pievienot vai noņemt no saraksta",
+  "account.badges.bot": "Bots",
+  "account.block": "Bloķēt @{name}",
+  "account.block_domain": "Slēpt visu no {domain}",
+  "account.blocked": "Bloķēts",
+  "account.direct": "Privātā ziņa @{name}",
+  "account.domain_blocked": "Domēns ir paslēpts",
+  "account.edit_profile": "Labot profilu",
+  "account.endorse": "Izcelts profilā",
+  "account.follow": "Sekot",
+  "account.followers": "Sekotāji",
+  "account.followers.empty": "Šim lietotājam nav sekotāju.",
+  "account.follows": "Seko",
+  "account.follows.empty": "Šis lietotājs pagaidām nevienam neseko.",
+  "account.follows_you": "Seko tev",
+  "account.hide_reblogs": "Paslēpt paceltos ierakstus no lietotāja @{name}",
+  "account.link_verified_on": "Šīs saites piederība ir pārbaudīta {date}",
+  "account.locked_info": "Šī konta privātuma status ir iestatīts slēgts. Īpašnieks izskatīs un izvēlēsies kas viņam drīkst sekot.",
+  "account.media": "Mēdiji",
+  "account.mention": "Piemin @{name}",
+  "account.moved_to": "{name} ir pārvācies uz:",
+  "account.mute": "Apklusināt @{name}",
+  "account.mute_notifications": "Nerādīt paziņojumus no @{name}",
+  "account.muted": "Apklusināts",
+  "account.posts": "Ieraksti",
+  "account.posts_with_replies": "Ieraksti un atbildes",
+  "account.report": "Ziņot par lietotāju @{name}",
+  "account.requested": "Gaidām apstiprinājumu. Nospied lai atceltu sekošanas pieparasījumu",
+  "account.share": "Dalīties ar lietotāja @{name}'s profilu",
+  "account.show_reblogs": "Parādīt lietotāja @{name} paceltos ierakstus",
+  "account.unblock": "Atbloķēt lietotāju @{name}",
+  "account.unblock_domain": "Atbloķēt domēnu {domain}",
+  "account.unendorse": "Neizcelt profilā",
+  "account.unfollow": "Nesekot",
+  "account.unmute": "Noņemt apklusinājumu no lietotāja @{name}",
+  "account.unmute_notifications": "Rādīt paziņojumus no lietotāja @{name}",
+  "alert.unexpected.message": "Negaidīta kļūda.",
+  "alert.unexpected.title": "Ups!",
+  "boost_modal.combo": "Nospied {combo} lai izlaistu šo nākamreiz",
+  "bundle_column_error.body": "Kaut kas nogāja greizi ielādējot šo komponenti.",
+  "bundle_column_error.retry": "Mēģini vēlreiz",
+  "bundle_column_error.title": "Tīkla kļūda",
+  "bundle_modal_error.close": "Aizvērt",
+  "bundle_modal_error.message": "Kaut kas nogāja greizi ielādējot šo komponenti.",
+  "bundle_modal_error.retry": "Mēģini vēlreiz",
+  "column.blocks": "Bloķētie lietotāji",
+  "column.community": "Lokālā laika līnija",
+  "column.direct": "Privātās ziņas",
+  "column.domain_blocks": "Paslēptie domēni",
+  "column.favourites": "Favorīti",
+  "column.follow_requests": "Sekotāju pieprasījumi",
+  "column.home": "Sākums",
+  "column.lists": "Saraksti",
+  "column.mutes": "Apklusinātie lietotāji",
+  "column.notifications": "Paziņojumi",
+  "column.pins": "Piespraustie ziņojumi",
+  "column.public": "Federatīvā laika līnija",
+  "column_back_button.label": "Atpakaļ",
+  "column_header.hide_settings": "Paslēpt iestatījumus",
+  "column_header.moveLeft_settings": "Pārvietot kolonu pa kreisi",
+  "column_header.moveRight_settings": "Pārvietot kolonu pa labi",
+  "column_header.pin": "Piespraust",
+  "column_header.show_settings": "Rādīt iestatījumus",
+  "column_header.unpin": "Atspraust",
+  "column_subheading.settings": "Iestatījumi",
+  "community.column_settings.media_only": "Tikai mēdiji",
+  "compose_form.direct_message_warning": "Šis ziņojums tiks nosūtīts tikai pieminētajiem lietotājiem.",
+  "compose_form.direct_message_warning_learn_more": "Papildus informācija",
+  "compose_form.hashtag_warning": "Ziņojumu nebūs iespējams atrast zem haštagiem jo tas nav publisks. Tikai publiskos ziņojumus ir iespējams meklēt pēc tiem.",
+  "compose_form.lock_disclaimer": "Tavs konts nav {locked}. Ikviens var Tev sekot lai apskatītu tikai sekotājiem paredzētos ziņojumus.",
+  "compose_form.lock_disclaimer.lock": "slēgts",
+  "compose_form.placeholder": "Ko vēlies publicēt?",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
+  "compose_form.publish": "Publicēt",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive.marked": "Media is marked as sensitive",
-  "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
-  "compose_form.spoiler.marked": "Text is hidden behind warning",
-  "compose_form.spoiler.unmarked": "Text is not hidden",
-  "compose_form.spoiler_placeholder": "Write your warning here",
-  "confirmation_modal.cancel": "Cancel",
-  "confirmations.block.confirm": "Block",
-  "confirmations.block.message": "Are you sure you want to block {name}?",
-  "confirmations.delete.confirm": "Delete",
-  "confirmations.delete.message": "Are you sure you want to delete this status?",
-  "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. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.",
-  "confirmations.mute.confirm": "Mute",
-  "confirmations.mute.message": "Are you sure you want to mute {name}?",
-  "confirmations.redraft.confirm": "Delete & redraft",
-  "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.",
-  "confirmations.reply.confirm": "Reply",
-  "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
-  "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.account_timeline": "No toots here!",
-  "empty_column.blocks": "You haven't blocked any users yet.",
-  "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
-  "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
-  "empty_column.domain_blocks": "There are no hidden domains yet.",
-  "empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.",
-  "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.",
-  "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
-  "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. When members of this list post new statuses, they will appear here.",
-  "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
-  "empty_column.mutes": "You haven't muted any users 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",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
+  "compose_form.sensitive.marked": "Mēdijs ir atzīmēts kā sensitīvs",
+  "compose_form.sensitive.unmarked": "Mēdijs nav atzīmēts kā sensitīvs",
+  "compose_form.spoiler.marked": "Teksts ir paslēpts aiz brīdinājuma",
+  "compose_form.spoiler.unmarked": "Teksts nav paslēpts",
+  "compose_form.spoiler_placeholder": "Ieraksti Savu brīdinājuma tekstu šeit",
+  "confirmation_modal.cancel": "Atcelt",
+  "confirmations.block.block_and_report": "Block & Report",
+  "confirmations.block.confirm": "Bloķēt",
+  "confirmations.block.message": "Vai tiešām vēlies bloķēt lietotāju {name}?",
+  "confirmations.delete.confirm": "Dzēst",
+  "confirmations.delete.message": "Vai tiešām vēlies dzēst šo ierakstu?",
+  "confirmations.delete_list.confirm": "Dzēst",
+  "confirmations.delete_list.message": "Vai tiešam vēlies neatgriezeniski dzēst šo sarakstu?",
+  "confirmations.domain_block.confirm": "Paslēpt visu domēnu",
+  "confirmations.domain_block.message": "Vai tu tiešām, tiešam vēlies bloķēt visu domēnu {domain}? Lielākajā daļā gadījumu pietiek ja nobloķē vai apklusini kādu. Tu neredzēsi saturu vai paziņojumus no šī domēna nevienā laika līnijā. Tavi sekotāji no šī domēna tiks noņemti.",
+  "confirmations.mute.confirm": "Apklusināt",
+  "confirmations.mute.message": "Vai Tu tiešām velies apklusināt {name}?",
+  "confirmations.redraft.confirm": "Dzēst un pārrakstīt",
+  "confirmations.redraft.message": "Vai tiešām vēlies dzēst un pārrakstīt šo ierakstu? Favorīti un paceltie ieraksti tiks dzēsti, kā arī atbildes tiks atsaistītas no šī ieraksta.",
+  "confirmations.reply.confirm": "Atbildēt",
+  "confirmations.reply.message": "Atbildot tagad tava ziņa ko šobrīd raksti tiks pārrakstīta. Vai tiešām vēlies turpināt?",
+  "confirmations.unfollow.confirm": "Nesekot",
+  "confirmations.unfollow.message": "Vai tiešam vairs nevēlies sekot lietotājam {name}?",
+  "embed.instructions": "Iegul šo ziņojumu savā mājaslapā kopējot kodu zemāk.",
+  "embed.preview": "Tas izskatīsies šādi:",
+  "emoji_button.activity": "Aktivitāte",
+  "emoji_button.custom": "Pielāgots",
+  "emoji_button.flags": "Karogi",
+  "emoji_button.food": "Ēdieni un dzērieni",
+  "emoji_button.label": "Ielikt emoji smaidiņu",
+  "emoji_button.nature": "Daba",
+  "emoji_button.not_found": "Nekādu emodžīšu!! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.objects": "Objekti",
+  "emoji_button.people": "Cilvēki",
+  "emoji_button.recent": "Biežāk lietotie",
+  "emoji_button.search": "Meklēt...",
+  "emoji_button.search_results": "Meklēšanas rezultāti",
+  "emoji_button.symbols": "Simboli",
+  "emoji_button.travel": "Ceļošana & Vietas",
+  "empty_column.account_timeline": "Šeit ziņojumu nav!",
+  "empty_column.account_unavailable": "Profile unavailable",
+  "empty_column.blocks": "Tu neesi vēl nevienu bloķējis.",
+  "empty_column.community": "Lokālā laika līnija ir tukša. :/ Ieraksti kaut ko lai sākas rosība!",
+  "empty_column.direct": "Tev nav privāto ziņu. Tiklīdz saņemsi tās šeit parādīsies.",
+  "empty_column.domain_blocks": "Slēpto domēnu vēl nav.",
+  "empty_column.favourited_statuses": "Tev vēl nav iemīļoto ziņojumu. Kad Tev tādu būs tie šeit parādīsies.",
+  "empty_column.favourites": "Neviens šo ziņojumu nav pievienojis favorītiem. Kad tādu būs tie šeit parādīsies.",
+  "empty_column.follow_requests": "Šobrīd neviens nav pieteicies tev sekot. Kad kāds pieteiksies tas parādīsies šeit.",
+  "empty_column.hashtag": "Ar šo haštagu nekas nav atrodams.",
+  "empty_column.home": "Tava laika līnija ir tukša! Apmeklē federatīvo laika līniju vai uzmeklē kādu meklētājā lai satiktu citus.",
+  "empty_column.home.public_timeline": "publiskā laika līnija",
+  "empty_column.list": "Šis saraksts ir tukšs. Kad šī saraksta dalībnieki atjaunos statusu tas parādīsies šeit.",
+  "empty_column.lists": "Tev nav neviena saraksta. Kad tādu būs tie parādīsies šeit.",
+  "empty_column.mutes": "Tu neesi nevienu apklusinājis.",
+  "empty_column.notifications": "Tev nav paziņojumu. Iesaisties sarunās ar citiem.",
+  "empty_column.public": "Šeit nekā nav, tukšums! Ieraksti kaut ko publiski, vai uzmeklē un seko kādam no citas instances",
+  "follow_request.authorize": "Autorizēt",
+  "follow_request.reject": "Noraidīt",
   "getting_started.developers": "Developers",
   "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "and {additional}",
   "hashtag.column_header.tag_mode.any": "or {additional}",
   "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
   "hashtag.column_settings.tag_mode.all": "All of these",
   "hashtag.column_settings.tag_mode.any": "Any of these",
   "hashtag.column_settings.tag_mode.none": "None of these",
@@ -149,6 +156,9 @@
   "home.column_settings.basic": "Basic",
   "home.column_settings.show_reblogs": "Show boosts",
   "home.column_settings.show_replies": "Show replies",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
   "introduction.federation.action": "Next",
   "introduction.federation.federated.headline": "Federated",
   "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
@@ -156,7 +166,7 @@
   "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
   "introduction.federation.local.headline": "Local",
   "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
+  "introduction.interactions.action": "Finish toot-orial!",
   "introduction.interactions.favourite.headline": "Favourite",
   "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
   "introduction.interactions.reblog.headline": "Boost",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "to focus search",
   "keyboard_shortcuts.start": "to open \"get started\" column",
   "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "to start a brand new toot",
   "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
   "keyboard_shortcuts.up": "to move up in the list",
   "lightbox.close": "Close",
   "lightbox.next": "Next",
   "lightbox.previous": "Previous",
+  "lightbox.view_context": "View context",
   "lists.account.add": "Add to list",
   "lists.account.remove": "Remove from list",
   "lists.delete": "Delete list",
   "lists.edit": "Edit list",
+  "lists.edit.submit": "Change title",
   "lists.new.create": "Add list",
   "lists.new.title_placeholder": "New list title",
   "lists.search": "Search among people you follow",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "Favourites",
   "navigation_bar.filters": "Muted words",
   "navigation_bar.follow_requests": "Follow requests",
+  "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.info": "About this instance",
   "navigation_bar.keyboard_shortcuts": "Hotkeys",
   "navigation_bar.lists": "Lists",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Personal",
   "navigation_bar.pins": "Pinned toots",
   "navigation_bar.preferences": "Preferences",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "Federated timeline",
   "navigation_bar.security": "Security",
   "notification.favourite": "{name} favourited your status",
   "notification.follow": "{name} followed you",
   "notification.mention": "{name} mentioned you",
+  "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "{name} boosted your status",
   "notifications.clear": "Clear notifications",
   "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Show",
   "notifications.column_settings.follow": "New followers:",
   "notifications.column_settings.mention": "Mentions:",
+  "notifications.column_settings.poll": "Poll results:",
   "notifications.column_settings.push": "Push notifications",
   "notifications.column_settings.reblog": "Boosts:",
   "notifications.column_settings.show": "Show in column",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favourites",
   "notifications.filter.follows": "Follows",
   "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
   "notifications.group": "{count} notifications",
+  "poll.closed": "Closed",
+  "poll.refresh": "Refresh",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
   "privacy.change": "Adjust status privacy",
   "privacy.direct.long": "Post to mentioned users only",
   "privacy.direct.short": "Direct",
@@ -291,12 +315,12 @@
   "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.admin_account": "Open moderation interface for @{name}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "This post cannot be boosted",
+  "status.copy": "Copy link to status",
   "status.delete": "Delete",
   "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Reply",
   "status.replyAll": "Reply to thread",
   "status.report": "Report @{name}",
-  "status.sensitive_toggle": "Click to view",
   "status.sensitive_warning": "Sensitive content",
   "status.share": "Share",
   "status.show_less": "Show less",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Local",
   "tabs_bar.notifications": "Notifications",
   "tabs_bar.search": "Search",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
   "upload_area.title": "Drag & drop to upload",
   "upload_button.label": "Add media (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.focus": "Crop",
   "upload_form.undo": "Delete",
diff --git a/app/javascript/mastodon/locales/ms.json b/app/javascript/mastodon/locales/ms.json
index 0d510d011fd988fa03addb3c713686883efb4131..d7c50996360b029dcb8a0d630be45f063f924806 100644
--- a/app/javascript/mastodon/locales/ms.json
+++ b/app/javascript/mastodon/locales/ms.json
@@ -5,7 +5,6 @@
   "account.block_domain": "Hide everything from {domain}",
   "account.blocked": "Blocked",
   "account.direct": "Direct message @{name}",
-  "account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
   "account.domain_blocked": "Domain hidden",
   "account.edit_profile": "Edit profile",
   "account.endorse": "Feature on profile",
@@ -36,7 +35,6 @@
   "account.unfollow": "Unfollow",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account.view_full_profile": "View full profile",
   "alert.unexpected.message": "An unexpected error occurred.",
   "alert.unexpected.title": "Oops!",
   "boost_modal.combo": "You can press {combo} to skip this next time",
@@ -73,14 +71,20 @@
   "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",
   "compose_form.placeholder": "What is on your mind?",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
   "compose_form.sensitive.marked": "Media is marked as sensitive",
   "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
   "compose_form.spoiler.marked": "Text is hidden behind warning",
   "compose_form.spoiler.unmarked": "Text is not hidden",
   "compose_form.spoiler_placeholder": "Write your warning here",
   "confirmation_modal.cancel": "Cancel",
+  "confirmations.block.block_and_report": "Block & Report",
   "confirmations.block.confirm": "Block",
   "confirmations.block.message": "Are you sure you want to block {name}?",
   "confirmations.delete.confirm": "Delete",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Symbols",
   "emoji_button.travel": "Travel & Places",
   "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_unavailable": "Profile unavailable",
   "empty_column.blocks": "You haven't blocked any users yet.",
   "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
   "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "and {additional}",
   "hashtag.column_header.tag_mode.any": "or {additional}",
   "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
   "hashtag.column_settings.tag_mode.all": "All of these",
   "hashtag.column_settings.tag_mode.any": "Any of these",
   "hashtag.column_settings.tag_mode.none": "None of these",
@@ -149,6 +156,9 @@
   "home.column_settings.basic": "Basic",
   "home.column_settings.show_reblogs": "Show boosts",
   "home.column_settings.show_replies": "Show replies",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
   "introduction.federation.action": "Next",
   "introduction.federation.federated.headline": "Federated",
   "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
@@ -156,7 +166,7 @@
   "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
   "introduction.federation.local.headline": "Local",
   "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
+  "introduction.interactions.action": "Finish toot-orial!",
   "introduction.interactions.favourite.headline": "Favourite",
   "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
   "introduction.interactions.reblog.headline": "Boost",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "to focus search",
   "keyboard_shortcuts.start": "to open \"get started\" column",
   "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "to start a brand new toot",
   "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
   "keyboard_shortcuts.up": "to move up in the list",
   "lightbox.close": "Close",
   "lightbox.next": "Next",
   "lightbox.previous": "Previous",
+  "lightbox.view_context": "View context",
   "lists.account.add": "Add to list",
   "lists.account.remove": "Remove from list",
   "lists.delete": "Delete list",
   "lists.edit": "Edit list",
+  "lists.edit.submit": "Change title",
   "lists.new.create": "Add list",
   "lists.new.title_placeholder": "New list title",
   "lists.search": "Search among people you follow",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "Favourites",
   "navigation_bar.filters": "Muted words",
   "navigation_bar.follow_requests": "Follow requests",
+  "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.info": "About this instance",
   "navigation_bar.keyboard_shortcuts": "Hotkeys",
   "navigation_bar.lists": "Lists",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Personal",
   "navigation_bar.pins": "Pinned toots",
   "navigation_bar.preferences": "Preferences",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "Federated timeline",
   "navigation_bar.security": "Security",
   "notification.favourite": "{name} favourited your status",
   "notification.follow": "{name} followed you",
   "notification.mention": "{name} mentioned you",
+  "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "{name} boosted your status",
   "notifications.clear": "Clear notifications",
   "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Show",
   "notifications.column_settings.follow": "New followers:",
   "notifications.column_settings.mention": "Mentions:",
+  "notifications.column_settings.poll": "Poll results:",
   "notifications.column_settings.push": "Push notifications",
   "notifications.column_settings.reblog": "Boosts:",
   "notifications.column_settings.show": "Show in column",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favourites",
   "notifications.filter.follows": "Follows",
   "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
   "notifications.group": "{count} notifications",
+  "poll.closed": "Closed",
+  "poll.refresh": "Refresh",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
   "privacy.change": "Adjust status privacy",
   "privacy.direct.long": "Post to mentioned users only",
   "privacy.direct.short": "Direct",
@@ -291,12 +315,12 @@
   "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.admin_account": "Open moderation interface for @{name}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "This post cannot be boosted",
+  "status.copy": "Copy link to status",
   "status.delete": "Delete",
   "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Reply",
   "status.replyAll": "Reply to thread",
   "status.report": "Report @{name}",
-  "status.sensitive_toggle": "Click to view",
   "status.sensitive_warning": "Sensitive content",
   "status.share": "Share",
   "status.show_less": "Show less",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Local",
   "tabs_bar.notifications": "Notifications",
   "tabs_bar.search": "Search",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
   "upload_area.title": "Drag & drop to upload",
   "upload_button.label": "Add media (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.focus": "Crop",
   "upload_form.undo": "Delete",
diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json
index 871142195df56ca878bacca7c153c7080ed1663a..f6504f4bb80a925128b378a6832c691a8e0b6860 100644
--- a/app/javascript/mastodon/locales/nl.json
+++ b/app/javascript/mastodon/locales/nl.json
@@ -5,14 +5,13 @@
   "account.block_domain": "Verberg alles van {domain}",
   "account.blocked": "Geblokkeerd",
   "account.direct": "Direct Message @{name}",
-  "account.disclaimer_full": "De informatie hieronder kan mogelijk een incompleet beeld geven van dit gebruikersprofiel.",
   "account.domain_blocked": "Domein verborgen",
   "account.edit_profile": "Profiel bewerken",
   "account.endorse": "Op profiel weergeven",
   "account.follow": "Volgen",
   "account.followers": "Volgers",
   "account.followers.empty": "Niemand volgt nog deze gebruiker.",
-  "account.follows": "Volgt",
+  "account.follows": "Volgend",
   "account.follows.empty": "Deze gebruiker volgt nog niemand.",
   "account.follows_you": "Volgt jou",
   "account.hide_reblogs": "Verberg boosts van @{name}",
@@ -36,7 +35,6 @@
   "account.unfollow": "Ontvolgen",
   "account.unmute": "@{name} niet langer negeren",
   "account.unmute_notifications": "@{name} meldingen niet langer negeren",
-  "account.view_full_profile": "Volledig profiel tonen",
   "alert.unexpected.message": "Er deed zich een onverwachte fout voor",
   "alert.unexpected.title": "Oeps!",
   "boost_modal.combo": "Je kunt {combo} klikken om dit de volgende keer over te slaan",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "Jouw account is niet {locked}. Iedereen kan jou volgen en kan de toots zien die je alleen aan jouw volgers hebt gericht.",
   "compose_form.lock_disclaimer.lock": "besloten",
   "compose_form.placeholder": "Wat wil je kwijt?",
+  "compose_form.poll.add_option": "Keuze toevoegen",
+  "compose_form.poll.duration": "Duur van de poll",
+  "compose_form.poll.option_placeholder": "Keuze {number}",
+  "compose_form.poll.remove_option": "Deze keuze verwijderen",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Media als gevoelig markeren",
   "compose_form.sensitive.marked": "Media is als gevoelig gemarkeerd",
   "compose_form.sensitive.unmarked": "Media is niet als gevoelig gemarkeerd",
   "compose_form.spoiler.marked": "Tekst is achter een waarschuwing verborgen",
   "compose_form.spoiler.unmarked": "Tekst is niet verborgen",
   "compose_form.spoiler_placeholder": "Waarschuwingstekst",
   "confirmation_modal.cancel": "Annuleren",
+  "confirmations.block.block_and_report": "Blokkeren en rapporteren",
   "confirmations.block.confirm": "Blokkeren",
   "confirmations.block.message": "Weet je het zeker dat je {name} wilt blokkeren?",
   "confirmations.delete.confirm": "Verwijderen",
@@ -94,7 +98,7 @@
   "confirmations.redraft.confirm": "Verwijderen en herschrijven",
   "confirmations.redraft.message": "Weet je zeker dat je deze toot wilt verwijderen en herschrijven? Je verliest wel de boosts en favorieten, en reacties op de originele toot zitten niet meer aan de nieuwe toot vast.",
   "confirmations.reply.confirm": "Reageren",
-  "confirmations.reply.message": "Door nu  te reageren overschrijf je de toot die je op dit moment aan het schrijven bent. Weet je zeker dat je verder wil gaan?",
+  "confirmations.reply.message": "Door nu te reageren overschrijf je de toot die je op dit moment aan het schrijven bent. Weet je zeker dat je verder wil gaan?",
   "confirmations.unfollow.confirm": "Ontvolgen",
   "confirmations.unfollow.message": "Weet je het zeker dat je {name} wilt ontvolgen?",
   "embed.instructions": "Embed deze toot op jouw website, door de onderstaande code te kopiëren.",
@@ -114,10 +118,11 @@
   "emoji_button.symbols": "Symbolen",
   "emoji_button.travel": "Reizen en plekken",
   "empty_column.account_timeline": "Hier zijn geen toots!",
+  "empty_column.account_unavailable": "Profiel is niet beschikbaar",
   "empty_column.blocks": "Jij hebt nog geen enkele gebruiker geblokkeerd.",
   "empty_column.community": "De lokale tijdlijn is nog leeg. Toot iets in het openbaar om de bal aan het rollen te krijgen!",
   "empty_column.direct": "Je hebt nog geen directe berichten. Wanneer je er een verzend of ontvangt, zijn deze hier te zien.",
-  "empty_column.domain_blocks": "Er zijn nog geen genegeerde domeinen.",
+  "empty_column.domain_blocks": "Er zijn nog geen genegeerde servers.",
   "empty_column.favourited_statuses": "Jij hebt nog geen favoriete toots. Wanneer je er een aan jouw favorieten toevoegt, valt deze hier te zien.",
   "empty_column.favourites": "Niemand heeft deze toot nog aan hun favorieten toegevoegd. Wanneer iemand dit doet, valt dat hier te zien.",
   "empty_column.follow_requests": "Jij hebt nog enkel volgverzoek ontvangen. Wanneer je er eentje ontvangt, valt dat hier te zien.",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "en {additional}",
   "hashtag.column_header.tag_mode.any": "of {additional}",
   "hashtag.column_header.tag_mode.none": "zonder {additional}",
+  "hashtag.column_settings.select.no_options_message": "Geen voorstellen gevonden",
+  "hashtag.column_settings.select.placeholder": "Vul hashtags in…",
   "hashtag.column_settings.tag_mode.all": "Allemaal",
   "hashtag.column_settings.tag_mode.any": "Een van deze",
   "hashtag.column_settings.tag_mode.none": "Geen van deze",
@@ -149,17 +156,20 @@
   "home.column_settings.basic": "Algemeen",
   "home.column_settings.show_reblogs": "Boosts tonen",
   "home.column_settings.show_replies": "Reacties tonen",
+  "intervals.full.days": "{number, plural, one {# dag} other {# dagen}}",
+  "intervals.full.hours": "{number, plural, one {# uur} other {# uur}}",
+  "intervals.full.minutes": "{number, plural, one {# minuut} other {# minuten}}",
   "introduction.federation.action": "Volgende",
   "introduction.federation.federated.headline": "Globaal",
   "introduction.federation.federated.text": "Openbare toots van mensen op andere servers in de fediverse verschijnen op de globale tijdlijn.",
-  "introduction.federation.home.headline": "Home",
+  "introduction.federation.home.headline": "Start",
   "introduction.federation.home.text": "Toots van mensen die jij volgt verschijnen onder start. Je kunt iedereen op elke server volgen!",
-  "introduction.federation.local.headline": "Local",
+  "introduction.federation.local.headline": "Lokaal",
   "introduction.federation.local.text": "Openbare toots van mensen die ook op jouw server zitten verschijnen op de lokale tijdlijn.",
   "introduction.interactions.action": "Introductie beëindigen!",
   "introduction.interactions.favourite.headline": "Favorieten",
   "introduction.interactions.favourite.text": "Je kunt door een toot aan jouw favorieten toe te voegen, deze voor later bewaren en de auteur laten weten dat je de toot leuk vind.",
-  "introduction.interactions.reblog.headline": "Boost",
+  "introduction.interactions.reblog.headline": "Boosten",
   "introduction.interactions.reblog.text": "Je kunt toots van andere mensen met jouw volgers delen door deze te boosten.",
   "introduction.interactions.reply.headline": "Reageren",
   "introduction.interactions.reply.text": "Je kunt op toots van andere mensen en op die van jezelf reageren, waardoor er een gesprek ontstaat.",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "om het zoekvak te focussen",
   "keyboard_shortcuts.start": "om de \"Aan de slag\"-kolom te tonen",
   "keyboard_shortcuts.toggle_hidden": "om tekst achter een waarschuwing (CW) te tonen/verbergen",
+  "keyboard_shortcuts.toggle_sensitivity": "om media te tonen/verbergen",
   "keyboard_shortcuts.toot": "om een nieuwe toot te starten",
   "keyboard_shortcuts.unfocus": "om het tekst- en zoekvak te ontfocussen",
   "keyboard_shortcuts.up": "om omhoog te bewegen in de lijst",
   "lightbox.close": "Sluiten",
   "lightbox.next": "Volgende",
   "lightbox.previous": "Vorige",
+  "lightbox.view_context": "Context tonen",
   "lists.account.add": "Aan lijst toevoegen",
   "lists.account.remove": "Uit lijst verwijderen",
   "lists.delete": "Lijst verwijderen",
   "lists.edit": "Lijst bewerken",
+  "lists.edit.submit": "Titel veranderen",
   "lists.new.create": "Lijst toevoegen",
   "lists.new.title_placeholder": "Naam nieuwe lijst",
   "lists.search": "Zoek naar mensen die je volgt",
@@ -219,11 +232,12 @@
   "navigation_bar.compose": "Nieuw toot schrijven",
   "navigation_bar.direct": "Directe berichten",
   "navigation_bar.discover": "Ontdekken",
-  "navigation_bar.domain_blocks": "Genegeerde domeinen",
+  "navigation_bar.domain_blocks": "Genegeerde servers",
   "navigation_bar.edit_profile": "Profiel bewerken",
   "navigation_bar.favourites": "Favorieten",
   "navigation_bar.filters": "Filters",
   "navigation_bar.follow_requests": "Volgverzoeken",
+  "navigation_bar.follows_and_followers": "Volgers en gevolgden",
   "navigation_bar.info": "Over deze server",
   "navigation_bar.keyboard_shortcuts": "Sneltoetsen",
   "navigation_bar.lists": "Lijsten",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Persoonlijk",
   "navigation_bar.pins": "Vastgezette toots",
   "navigation_bar.preferences": "Instellingen",
+  "navigation_bar.profile_directory": "Gebruikersgids",
   "navigation_bar.public_timeline": "Globale tijdlijn",
   "navigation_bar.security": "Beveiliging",
   "notification.favourite": "{name} voegde jouw toot als favoriet toe",
   "notification.follow": "{name} volgt jou nu",
   "notification.mention": "{name} vermeldde jou",
+  "notification.poll": "Een poll waaraan jij hebt meegedaan is beëindigd",
   "notification.reblog": "{name} boostte jouw toot",
   "notifications.clear": "Meldingen verwijderen",
   "notifications.clear_confirmation": "Weet je het zeker dat je al jouw meldingen wilt verwijderen?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Tonen",
   "notifications.column_settings.follow": "Nieuwe volgers:",
   "notifications.column_settings.mention": "Vermeldingen:",
+  "notifications.column_settings.poll": "Pollresultaten:",
   "notifications.column_settings.push": "Pushmeldingen",
   "notifications.column_settings.reblog": "Boosts:",
   "notifications.column_settings.show": "In kolom tonen",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favorieten",
   "notifications.filter.follows": "Die jij volgt",
   "notifications.filter.mentions": "Vermeldingen",
+  "notifications.filter.polls": "Pollresultaten",
   "notifications.group": "{count} meldingen",
+  "poll.closed": "Gesloten",
+  "poll.refresh": "Vernieuwen",
+  "poll.total_votes": "{count, plural, one {# stem} other {# stemmen}}",
+  "poll.vote": "Stemmen",
+  "poll_button.add_poll": "Poll toevoegen",
+  "poll_button.remove_poll": "Poll verwijderen",
   "privacy.change": "Zichtbaarheid toot aanpassen",
   "privacy.direct.long": "Alleen aan vermelde gebruikers tonen",
   "privacy.direct.short": "Direct",
@@ -269,7 +293,7 @@
   "regeneration_indicator.label": "Aan het laden…",
   "regeneration_indicator.sublabel": "Jouw tijdlijn wordt aangemaakt!",
   "relative_time.days": "{number}d",
-  "relative_time.hours": "{number}h",
+  "relative_time.hours": "{number}u",
   "relative_time.just_now": "nu",
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
@@ -291,16 +315,16 @@
   "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.admin_account": "Moderatie-omgeving van @{name} openen",
   "status.admin_status": "Deze toot in de moderatie-omgeving openen",
   "status.block": "Blokkeer @{name}",
   "status.cancel_reblog_private": "Niet langer boosten",
   "status.cannot_reblog": "Deze toot kan niet geboost worden",
+  "status.copy": "Link naar toot kopiëren",
   "status.delete": "Verwijderen",
   "status.detailed_status": "Uitgebreide gespreksweergave",
   "status.direct": "Directe toot @{name}",
-  "status.embed": "Embed",
+  "status.embed": "Insluiten",
   "status.favourite": "Favoriet",
   "status.filtered": "Gefilterd",
   "status.load_more": "Meer laden",
@@ -313,7 +337,7 @@
   "status.pin": "Aan profielpagina vastmaken",
   "status.pinned": "Vastgemaakte toot",
   "status.read_more": "Meer lezen",
-  "status.reblog": "Boost",
+  "status.reblog": "Boosten",
   "status.reblog_private": "Boost naar oorspronkelijke ontvangers",
   "status.reblogged_by": "{name} boostte",
   "status.reblogs.empty": "Niemand heeft deze toot nog geboost. Wanneer iemand dit doet, valt dat hier te zien.",
@@ -321,7 +345,6 @@
   "status.reply": "Reageren",
   "status.replyAll": "Reageer op iedereen",
   "status.report": "Rapporteer @{name}",
-  "status.sensitive_toggle": "Klik om te bekijken",
   "status.sensitive_warning": "Gevoelige inhoud",
   "status.share": "Delen",
   "status.show_less": "Minder tonen",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Lokaal",
   "tabs_bar.notifications": "Meldingen",
   "tabs_bar.search": "Zoeken",
+  "time_remaining.days": "{number, plural, one {# dag} other {# dagen}} te gaan",
+  "time_remaining.hours": "{number, plural, one {# uur} other {# uur}} te gaan",
+  "time_remaining.minutes": "{number, plural, one {# minuut} other {# minuten}} te gaan",
+  "time_remaining.moments": "Nog enkele ogenblikken resterend",
+  "time_remaining.seconds": "{number, plural, one {# seconde} other {# seconden}} te gaan",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {persoon praat} other {mensen praten}} hierover",
   "ui.beforeunload": "Je concept zal verloren gaan als je Mastodon verlaat.",
-  "upload_area.title": "Hierin slepen om te uploaden",
-  "upload_button.label": "Media toevoegen (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_area.title": "Hiernaar toe slepen om te uploaden",
+  "upload_button.label": "Media toevoegen ({formats})",
+  "upload_error.limit": "Uploadlimiet van bestand overschreden.",
+  "upload_error.poll": "Het uploaden van bestanden is in polls niet toegestaan.",
   "upload_form.description": "Omschrijf dit voor mensen met een visuele beperking",
   "upload_form.focus": "Voorvertoning aanpassen",
   "upload_form.undo": "Verwijderen",
diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json
index fa08e8d73b486da5f1ae4351367f40ec175b1277..2ba8236e27058cd6cf2f67afd9c4de23457906a3 100644
--- a/app/javascript/mastodon/locales/no.json
+++ b/app/javascript/mastodon/locales/no.json
@@ -5,7 +5,6 @@
   "account.block_domain": "Skjul alt fra {domain}",
   "account.blocked": "Blocked",
   "account.direct": "Direct Message @{name}",
-  "account.disclaimer_full": "Informasjonen nedenfor kan gi et ufullstendig bilde av brukerens profil.",
   "account.domain_blocked": "Domain hidden",
   "account.edit_profile": "Rediger profil",
   "account.endorse": "Feature on profile",
@@ -36,7 +35,6 @@
   "account.unfollow": "Avfølg",
   "account.unmute": "Avdemp @{name}",
   "account.unmute_notifications": "Vis varsler fra @{name}",
-  "account.view_full_profile": "Vis hele profilen",
   "alert.unexpected.message": "An unexpected error occurred.",
   "alert.unexpected.title": "Oops!",
   "boost_modal.combo": "You kan trykke {combo} for å hoppe over dette neste gang",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "Din konto er ikke {locked}. Hvem som helst kan følge deg og se dine private poster.",
   "compose_form.lock_disclaimer.lock": "låst",
   "compose_form.placeholder": "Hva har du på hjertet?",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
   "compose_form.publish": "Tut",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
   "compose_form.sensitive.marked": "Media is marked as sensitive",
   "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
   "compose_form.spoiler.marked": "Text is hidden behind warning",
   "compose_form.spoiler.unmarked": "Text is not hidden",
   "compose_form.spoiler_placeholder": "Innholdsadvarsel",
   "confirmation_modal.cancel": "Avbryt",
+  "confirmations.block.block_and_report": "Block & Report",
   "confirmations.block.confirm": "Blokkèr",
   "confirmations.block.message": "Er du sikker på at du vil blokkere {name}?",
   "confirmations.delete.confirm": "Slett",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Symboler",
   "emoji_button.travel": "Reise & steder",
   "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_unavailable": "Profile unavailable",
   "empty_column.blocks": "You haven't blocked any users yet.",
   "empty_column.community": "Den lokale tidslinjen er tom. Skriv noe offentlig for å få snøballen til å rulle!",
   "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "and {additional}",
   "hashtag.column_header.tag_mode.any": "or {additional}",
   "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
   "hashtag.column_settings.tag_mode.all": "All of these",
   "hashtag.column_settings.tag_mode.any": "Any of these",
   "hashtag.column_settings.tag_mode.none": "None of these",
@@ -149,6 +156,9 @@
   "home.column_settings.basic": "Enkel",
   "home.column_settings.show_reblogs": "Vis fremhevinger",
   "home.column_settings.show_replies": "Vis svar",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
   "introduction.federation.action": "Next",
   "introduction.federation.federated.headline": "Federated",
   "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
@@ -156,7 +166,7 @@
   "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
   "introduction.federation.local.headline": "Local",
   "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
+  "introduction.interactions.action": "Finish toot-orial!",
   "introduction.interactions.favourite.headline": "Favourite",
   "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
   "introduction.interactions.reblog.headline": "Boost",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "å fokusere søk",
   "keyboard_shortcuts.start": "to open \"get started\" column",
   "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "Ã¥ starte en helt ny tut",
   "keyboard_shortcuts.unfocus": "å ufokusere komponerings-/søkefeltet",
   "keyboard_shortcuts.up": "Ã¥ flytte opp i listen",
   "lightbox.close": "Lukk",
   "lightbox.next": "Neste",
   "lightbox.previous": "Forrige",
+  "lightbox.view_context": "View context",
   "lists.account.add": "Legg til i listen",
   "lists.account.remove": "Fjern fra listen",
   "lists.delete": "Slett listen",
   "lists.edit": "Rediger listen",
+  "lists.edit.submit": "Change title",
   "lists.new.create": "Ligg til liste",
   "lists.new.title_placeholder": "Ny listetittel",
   "lists.search": "Søk blant personer du følger",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "Favoritter",
   "navigation_bar.filters": "Muted words",
   "navigation_bar.follow_requests": "Følgeforespørsler",
+  "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.info": "Utvidet informasjon",
   "navigation_bar.keyboard_shortcuts": "Tastatursnarveier",
   "navigation_bar.lists": "Lister",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Personal",
   "navigation_bar.pins": "Festa tuter",
   "navigation_bar.preferences": "Preferanser",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "Felles tidslinje",
   "navigation_bar.security": "Security",
   "notification.favourite": "{name} likte din status",
   "notification.follow": "{name} fulgte deg",
   "notification.mention": "{name} nevnte deg",
+  "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "{name} fremhevde din status",
   "notifications.clear": "Fjern varsler",
   "notifications.clear_confirmation": "Er du sikker på at du vil fjerne alle dine varsler permanent?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Show",
   "notifications.column_settings.follow": "Nye følgere:",
   "notifications.column_settings.mention": "Nevnt:",
+  "notifications.column_settings.poll": "Poll results:",
   "notifications.column_settings.push": "Push varsler",
   "notifications.column_settings.reblog": "Fremhevet:",
   "notifications.column_settings.show": "Vis i kolonne",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favourites",
   "notifications.filter.follows": "Follows",
   "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
   "notifications.group": "{count} notifications",
+  "poll.closed": "Closed",
+  "poll.refresh": "Refresh",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
   "privacy.change": "Justér synlighet",
   "privacy.direct.long": "Post kun til nevnte brukere",
   "privacy.direct.short": "Direkte",
@@ -291,12 +315,12 @@
   "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.admin_account": "Open moderation interface for @{name}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "Denne posten kan ikke fremheves",
+  "status.copy": "Copy link to status",
   "status.delete": "Slett",
   "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Svar",
   "status.replyAll": "Svar til samtale",
   "status.report": "Rapporter @{name}",
-  "status.sensitive_toggle": "Klikk for å vise",
   "status.sensitive_warning": "Følsomt innhold",
   "status.share": "Del",
   "status.show_less": "Vis mindre",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Lokal",
   "tabs_bar.notifications": "Varslinger",
   "tabs_bar.search": "Search",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
   "ui.beforeunload": "Din kladd vil bli forkastet om du forlater Mastodon.",
   "upload_area.title": "Dra og slipp for å laste opp",
   "upload_button.label": "Legg til media",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "upload_form.description": "Beskriv for synshemmede",
   "upload_form.focus": "Crop",
   "upload_form.undo": "Angre",
diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json
index c28e9f5b8344f3582f4821737e71ce84460b16ba..3178f200deb12e2e64f1250cf71186d67c5ee5e8 100644
--- a/app/javascript/mastodon/locales/oc.json
+++ b/app/javascript/mastodon/locales/oc.json
@@ -5,7 +5,6 @@
   "account.block_domain": "Tot amagar del domeni {domain}",
   "account.blocked": "Blocat",
   "account.direct": "Escriure un MP a @{name}",
-  "account.disclaimer_full": "Aquelas informacions de perfil pòdon èsser incomplètas.",
   "account.domain_blocked": "Domeni amagat",
   "account.edit_profile": "Modificar lo perfil",
   "account.endorse": "Mostrar pel perfil",
@@ -36,7 +35,6 @@
   "account.unfollow": "Quitar de sègre",
   "account.unmute": "Quitar de rescondre @{name}",
   "account.unmute_notifications": "Mostrar las notificacions de @{name}",
-  "account.view_full_profile": "Veire lo perfil complèt",
   "alert.unexpected.message": "Una error s’es producha.",
   "alert.unexpected.title": "Ops !",
   "boost_modal.combo": "Podètz botar {combo} per passar aquò lo còp que ven",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "Vòstre compte es pas {locked}. Tot lo monde pòt vos sègre e veire los estatuts reservats als seguidors.",
   "compose_form.lock_disclaimer.lock": "clavat",
   "compose_form.placeholder": "A de qué pensatz ?",
+  "compose_form.poll.add_option": "Ajustar una causida",
+  "compose_form.poll.duration": "Durada del sondatge",
+  "compose_form.poll.option_placeholder": "Opcion {number}",
+  "compose_form.poll.remove_option": "Levar aquesta opcion",
   "compose_form.publish": "Tut",
   "compose_form.publish_loud": "{publish} !",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
   "compose_form.sensitive.marked": "Lo mèdia es marcat coma sensible",
   "compose_form.sensitive.unmarked": "Lo mèdia es pas marcat coma sensible",
   "compose_form.spoiler.marked": "Lo tèxte es rescondut jos l’avertiment",
   "compose_form.spoiler.unmarked": "Lo tèxte es pas rescondut",
   "compose_form.spoiler_placeholder": "Escrivètz l’avertiment aquí",
   "confirmation_modal.cancel": "Anullar",
+  "confirmations.block.block_and_report": "Blocar e senhalar",
   "confirmations.block.confirm": "Blocar",
   "confirmations.block.message": "Volètz vertadièrament blocar {name} ?",
   "confirmations.delete.confirm": "Escafar",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Simbòls",
   "emoji_button.travel": "Viatges & lòcs",
   "empty_column.account_timeline": "Cap de tuts aquí !",
+  "empty_column.account_unavailable": "Perfil pas disponible",
   "empty_column.blocks": "Avètz pas blocat degun pel moment.",
   "empty_column.community": "Lo flux public local es void. Escrivètz quicòm per lo garnir !",
   "empty_column.direct": "Avètz pas encara cap de messatges. Quand ne mandatz un o que ne recebètz un, serà mostrat aquí.",
@@ -128,7 +133,7 @@
   "empty_column.lists": "Encara avètz pas cap de lista. Quand ne creetz una, apareisserà aquí.",
   "empty_column.mutes": "Encara avètz pas mes en silenci degun.",
   "empty_column.notifications": "Avètz pas encara de notificacions. Respondètz a qualqu’un per començar una conversacion.",
-  "empty_column.public": "I a pas res aquí ! Escrivètz quicòm de public, o seguètz de personas d’autras instàncias per garnir lo flux public",
+  "empty_column.public": "I a pas res aquí ! Escrivètz quicòm de public, o seguètz de personas d’autres servidors per garnir lo flux public",
   "follow_request.authorize": "Acceptar",
   "follow_request.reject": "Regetar",
   "getting_started.developers": "Desvelopaires",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "e {additional}",
   "hashtag.column_header.tag_mode.any": "o {additional}",
   "hashtag.column_header.tag_mode.none": "sens {additional}",
+  "hashtag.column_settings.select.no_options_message": "Cap de suggestion pas trobada",
+  "hashtag.column_settings.select.placeholder": "Picatz d’etiquetas…",
   "hashtag.column_settings.tag_mode.all": "Totes aquestes",
   "hashtag.column_settings.tag_mode.any": "Un d’aquestes",
   "hashtag.column_settings.tag_mode.none": "Cap d’aquestes",
@@ -149,6 +156,9 @@
   "home.column_settings.basic": "Basic",
   "home.column_settings.show_reblogs": "Mostrar los partatges",
   "home.column_settings.show_replies": "Mostrar las responsas",
+  "intervals.full.days": "{number, plural, one {# jorn} other {# jorns}}",
+  "intervals.full.hours": "{number, plural, one {# ora} other {# oras}}",
+  "intervals.full.minutes": "{number, plural, one {# minuta} other {# minutas}}",
   "introduction.federation.action": "Seguent",
   "introduction.federation.federated.headline": "Federat",
   "introduction.federation.federated.text": "Los tuts publics d’autres servidors del fediverse apareisseràn dins lo flux d’actualitats.",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "anar a la recèrca",
   "keyboard_shortcuts.start": "dobrir la colomna « Per començar »",
   "keyboard_shortcuts.toggle_hidden": "mostrar/amagar lo tèxte dels avertiments",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "començar un estatut tot novèl",
   "keyboard_shortcuts.unfocus": "quitar lo camp tèxte/de recèrca",
   "keyboard_shortcuts.up": "far montar dins la lista",
   "lightbox.close": "Tampar",
   "lightbox.next": "Seguent",
   "lightbox.previous": "Precedent",
+  "lightbox.view_context": "View context",
   "lists.account.add": "Ajustar a la lista",
   "lists.account.remove": "Levar de la lista",
   "lists.delete": "Suprimir la lista",
   "lists.edit": "Modificar la lista",
+  "lists.edit.submit": "Cambiar lo títol",
   "lists.new.create": "Ajustar una lista",
   "lists.new.title_placeholder": "Títol de la nòva lista",
   "lists.search": "Cercar demest lo monde que seguètz",
@@ -224,7 +237,8 @@
   "navigation_bar.favourites": "Favorits",
   "navigation_bar.filters": "Mots ignorats",
   "navigation_bar.follow_requests": "Demandas d’abonament",
-  "navigation_bar.info": "Mai informacions",
+  "navigation_bar.follows_and_followers": "Follows and followers",
+  "navigation_bar.info": "Tocant aqueste servidor",
   "navigation_bar.keyboard_shortcuts": "Acorchis clavièr",
   "navigation_bar.lists": "Listas",
   "navigation_bar.logout": "Desconnexion",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Personal",
   "navigation_bar.pins": "Tuts penjats",
   "navigation_bar.preferences": "Preferéncias",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "Flux public global",
   "navigation_bar.security": "Seguretat",
   "notification.favourite": "{name} a ajustat a sos favorits",
   "notification.follow": "{name} vos sèc",
   "notification.mention": "{name} vos a mencionat",
+  "notification.poll": "Avètz participat a un sondatge que ven de s’acabar",
   "notification.reblog": "{name} a partejat vòstre estatut",
   "notifications.clear": "Escafar",
   "notifications.clear_confirmation": "Volètz vertadièrament escafar totas vòstras las notificacions ?",
@@ -247,16 +263,24 @@
   "notifications.column_settings.filter_bar.show": "Mostrar",
   "notifications.column_settings.follow": "Nòus seguidors :",
   "notifications.column_settings.mention": "Mencions :",
+  "notifications.column_settings.poll": "Resultats del sondatge :",
   "notifications.column_settings.push": "Notificacions",
   "notifications.column_settings.reblog": "Partatges :",
   "notifications.column_settings.show": "Mostrar dins la colomna",
   "notifications.column_settings.sound": "Emetre un son",
-  "notifications.filter.all": "Totes",
+  "notifications.filter.all": "Totas",
   "notifications.filter.boosts": "Partages",
   "notifications.filter.favourites": "Favorits",
   "notifications.filter.follows": "Seguiments",
   "notifications.filter.mentions": "Mencions",
+  "notifications.filter.polls": "Resultats del sondatge",
   "notifications.group": "{count} notificacions",
+  "poll.closed": "Tampat",
+  "poll.refresh": "Actualizar",
+  "poll.total_votes": "{count, plural, one {# vòte} other {# vòtes}}",
+  "poll.vote": "Votar",
+  "poll_button.add_poll": "Ajustar un sondatge",
+  "poll_button.remove_poll": "Levar lo sondatge",
   "privacy.change": "Ajustar la confidencialitat del messatge",
   "privacy.direct.long": "Mostrar pas qu’a las personas mencionadas",
   "privacy.direct.short": "Dirècte",
@@ -276,7 +300,7 @@
   "reply_indicator.cancel": "Anullar",
   "report.forward": "Far sègre a {target}",
   "report.forward_hint": "Lo compte ven d’un autre servidor. Volètz mandar una còpia anonima del rapòrt enlai tanben ?",
-  "report.hint": "Lo moderator de l’instància aurà lo rapòrt. Podètz fornir una explicacion de vòstre senhalament aquí dejós :",
+  "report.hint": "Lo moderator del servidor aurà lo rapòrt. Podètz fornir una explicacion de vòstre senhalament aquí dejós  :",
   "report.placeholder": "Comentaris addicionals",
   "report.submit": "Mandar",
   "report.target": "Senhalar {target}",
@@ -291,12 +315,12 @@
   "search_results.hashtags": "Etiquetas",
   "search_results.statuses": "Tuts",
   "search_results.total": "{count, number} {count, plural, one {resultat} other {resultats}}",
-  "standalone.public_title": "Una ulhada dedins…",
   "status.admin_account": "Dobrir l’interfàcia de moderacion per @{name}",
   "status.admin_status": "Dobrir aqueste estatut dins l’interfàcia de moderacion",
   "status.block": "Blocar @{name}",
   "status.cancel_reblog_private": "Quitar de partejar",
   "status.cannot_reblog": "Aqueste estatut pòt pas èsser partejat",
+  "status.copy": "Copiar lo ligam de l’estatut",
   "status.delete": "Escafar",
   "status.detailed_status": "Vista detalhada de la convèrsa",
   "status.direct": "Messatge per @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Respondre",
   "status.replyAll": "Respondre a la conversacion",
   "status.report": "Senhalar @{name}",
-  "status.sensitive_toggle": "Clicar per mostrar",
   "status.sensitive_warning": "Contengut sensible",
   "status.share": "Partejar",
   "status.show_less": "Tornar plegar",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Flux public local",
   "tabs_bar.notifications": "Notificacions",
   "tabs_bar.search": "Recèrcas",
+  "time_remaining.days": "demòra{number, plural, one  { # jorn} other {n # jorns}}",
+  "time_remaining.hours": "demòra{number, plural, one { # ora} other {n # oras}}",
+  "time_remaining.minutes": "demòra{number, plural, one { # minuta} other {n # minutas}}",
+  "time_remaining.moments": "Moments restants",
+  "time_remaining.seconds": "demòra{number, plural, one { # segonda} other {n # segondas}}",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} ne charra other {people}} ne charran",
   "ui.beforeunload": "Vòstre brolhon serà perdut se quitatz Mastodon.",
   "upload_area.title": "Lisatz e depausatz per mandar",
   "upload_button.label": "Ajustar un mèdia (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "Talha maximum pels mandadís subrepassada.",
+  "upload_error.poll": "Lo mandadís de fichièr es pas autorizat pels sondatges.",
   "upload_form.description": "Descripcion pels mal vesents",
   "upload_form.focus": "Modificar l’apercebut",
   "upload_form.undo": "Suprimir",
diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json
index 0d16f7cfc0554f80289c85dcc12ba683bd68e240..44edf6e3dd3c9cc3f7078c4c5170b6303ec039d8 100644
--- a/app/javascript/mastodon/locales/pl.json
+++ b/app/javascript/mastodon/locales/pl.json
@@ -5,7 +5,6 @@
   "account.block_domain": "Blokuj wszystko z {domain}",
   "account.blocked": "Zablokowany(-a)",
   "account.direct": "Wyślij wiadomość bezpośrednią do @{name}",
-  "account.disclaimer_full": "Poniższe informacje mogą nie odwzorowywać bezbłędnie profilu użytkownika.",
   "account.domain_blocked": "Ukryto domenÄ™",
   "account.edit_profile": "Edytuj profil",
   "account.endorse": "Polecaj na profilu",
@@ -36,7 +35,6 @@
   "account.unfollow": "Przestań śledzić",
   "account.unmute": "Cofnij wyciszenie @{name}",
   "account.unmute_notifications": "Cofnij wyciszenie powiadomień od @{name}",
-  "account.view_full_profile": "Wyświetl pełny profil",
   "alert.unexpected.message": "Wystąpił nieoczekiwany błąd.",
   "alert.unexpected.title": "O nie!",
   "boost_modal.combo": "Naciśnij {combo}, aby pominąć to następnym razem",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "Twoje konto nie jest {locked}. Każdy, kto Cię śledzi, może wyświetlać Twoje wpisy przeznaczone tylko dla śledzących.",
   "compose_form.lock_disclaimer.lock": "zablokowane",
   "compose_form.placeholder": "Co Ci chodzi po głowie?",
+  "compose_form.poll.add_option": "Dodaj opcjÄ™",
+  "compose_form.poll.duration": "Czas trwania głosowania",
+  "compose_form.poll.option_placeholder": "Opcja {number}",
+  "compose_form.poll.remove_option": "Usuń tę opcję",
   "compose_form.publish": "Wyślij",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Oznacz multimedia jako wrażliwe",
   "compose_form.sensitive.marked": "Zawartość multimedia jest oznaczona jako wrażliwa",
   "compose_form.sensitive.unmarked": "Zawartość multimedialna nie jest oznaczona jako wrażliwa",
   "compose_form.spoiler.marked": "Tekst jest ukryty za ostrzeżeniem",
   "compose_form.spoiler.unmarked": "Tekst nie jest ukryty",
   "compose_form.spoiler_placeholder": "Wprowadź swoje ostrzeżenie o zawartości",
   "confirmation_modal.cancel": "Anuluj",
+  "confirmations.block.block_and_report": "Zablokuj i zgłoś",
   "confirmations.block.confirm": "Zablokuj",
   "confirmations.block.message": "Czy na pewno chcesz zablokować {name}?",
   "confirmations.delete.confirm": "Usuń",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Symbole",
   "emoji_button.travel": "Podróże i miejsca",
   "empty_column.account_timeline": "Brak wpisów tutaj!",
+  "empty_column.account_unavailable": "Profil niedostępny",
   "empty_column.blocks": "Nie zablokowałeś(-aś) jeszcze żadnego użytkownika.",
   "empty_column.community": "Lokalna oś czasu jest pusta. Napisz coś publicznie, aby zagaić!",
   "empty_column.direct": "Nie masz żadnych wiadomości bezpośrednich. Kiedy dostaniesz lub wyślesz jakąś, pojawi się ona tutaj.",
@@ -128,7 +133,7 @@
   "empty_column.lists": "Nie masz żadnych list. Kiedy utworzysz jedną, pojawi się tutaj.",
   "empty_column.mutes": "Nie wyciszyłeś(-aś) jeszcze żadnego użytkownika.",
   "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 serwerów, aby to wyświetlić",
   "follow_request.authorize": "Autoryzuj",
   "follow_request.reject": "Odrzuć",
   "getting_started.developers": "Dla programistów",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "i {additional}",
   "hashtag.column_header.tag_mode.any": "lub {additional}",
   "hashtag.column_header.tag_mode.none": "bez {additional}",
+  "hashtag.column_settings.select.no_options_message": "Nie odnaleziono sugestii",
+  "hashtag.column_settings.select.placeholder": "Wprowadź hashtagi…",
   "hashtag.column_settings.tag_mode.all": "Wszystkie",
   "hashtag.column_settings.tag_mode.any": "Dowolne",
   "hashtag.column_settings.tag_mode.none": "Żadne",
@@ -149,6 +156,9 @@
   "home.column_settings.basic": "Podstawowe",
   "home.column_settings.show_reblogs": "Pokazuj podbicia",
   "home.column_settings.show_replies": "Pokazuj odpowiedzi",
+  "intervals.full.days": "{number, plural, one {# dzień} few {# dni} many {# dni} other {# dni}}",
+  "intervals.full.hours": "{number, plural, one {# godzina} few {# godziny} many {# godzin} other {# godzin}}",
+  "intervals.full.minutes": "{number, plural, one {# minuta} few {# minuty} many {# minut} other {# minut}}",
   "introduction.federation.action": "Dalej",
   "introduction.federation.federated.headline": "OÅ› czasu federacji",
   "introduction.federation.federated.text": "Publiczne wpisy osób z tego całego Fediwersum pojawiają się na lokalnej osi czasu.",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "aby przejść do pola wyszukiwania",
   "keyboard_shortcuts.start": "aby otworzyć kolumnę „Rozpocznij”",
   "keyboard_shortcuts.toggle_hidden": "aby wyświetlić lub ukryć wpis spod CW",
+  "keyboard_shortcuts.toggle_sensitivity": "by pokazać/ukryć multimedia",
   "keyboard_shortcuts.toot": "aby utworzyć nowy wpis",
   "keyboard_shortcuts.unfocus": "aby opuścić pole wyszukiwania/pisania",
   "keyboard_shortcuts.up": "aby przejść na górę listy",
   "lightbox.close": "Zamknij",
   "lightbox.next": "Następne",
   "lightbox.previous": "Poprzednie",
+  "lightbox.view_context": "Pokaż kontekst",
   "lists.account.add": "Dodaj do listy",
   "lists.account.remove": "Usunąć z listy",
   "lists.delete": "Usuń listę",
   "lists.edit": "Edytuj listÄ™",
+  "lists.edit.submit": "Zmień tytuł",
   "lists.new.create": "Utwórz listę",
   "lists.new.title_placeholder": "Wprowadź tytuł listy",
   "lists.search": "Szukaj wśród osób które śledzisz",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "Ulubione",
   "navigation_bar.filters": "Wyciszone słowa",
   "navigation_bar.follow_requests": "Prośby o śledzenie",
+  "navigation_bar.follows_and_followers": "Śledzeni i śledzący",
   "navigation_bar.info": "Szczegółowe informacje",
   "navigation_bar.keyboard_shortcuts": "Skróty klawiszowe",
   "navigation_bar.lists": "Listy",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Osobiste",
   "navigation_bar.pins": "Przypięte wpisy",
   "navigation_bar.preferences": "Preferencje",
+  "navigation_bar.profile_directory": "Katalog profilów",
   "navigation_bar.public_timeline": "Globalna oÅ› czasu",
   "navigation_bar.security": "Bezpieczeństwo",
   "notification.favourite": "{name} dodał(a) Twój wpis do ulubionych",
   "notification.follow": "{name} zaczął(-ęła) Cię śledzić",
   "notification.mention": "{name} wspomniał(a) o tobie",
+  "notification.poll": "Głosowanie w którym brałeś(-aś) udział zakończyła się",
   "notification.reblog": "{name} podbił(a) Twój wpis",
   "notifications.clear": "Wyczyść powiadomienia",
   "notifications.clear_confirmation": "Czy na pewno chcesz bezpowrotnie usunąć wszystkie powiadomienia?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Pokaż",
   "notifications.column_settings.follow": "Nowi śledzący:",
   "notifications.column_settings.mention": "Wspomnienia:",
+  "notifications.column_settings.poll": "Wyniki głosowania:",
   "notifications.column_settings.push": "Powiadomienia push",
   "notifications.column_settings.reblog": "Podbicia:",
   "notifications.column_settings.show": "Pokaż w kolumnie",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Ulubione",
   "notifications.filter.follows": "Åšledzenia",
   "notifications.filter.mentions": "Wspomienia",
+  "notifications.filter.polls": "Wyniki głosowania",
   "notifications.group": "{count, number} {count, plural, one {powiadomienie} few {powiadomienia} many {powiadomień} more {powiadomień}}",
+  "poll.closed": "Zamknięte",
+  "poll.refresh": "Odśwież",
+  "poll.total_votes": "{count, plural, one {# głos} few {# głosy} many {# głosów} other {# głosów}}",
+  "poll.vote": "Zagłosuj",
+  "poll_button.add_poll": "Dodaj głosowanie",
+  "poll_button.remove_poll": "Usuń głosowanie",
   "privacy.change": "Dostosuj widoczność wpisów",
   "privacy.direct.long": "Widoczny tylko dla wspomnianych",
   "privacy.direct.short": "Bezpośrednio",
@@ -276,14 +300,14 @@
   "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śnienie dlaczego zgłaszasz to konto:",
+  "report.hint": "Zgłoszenie zostanie wysłane moderatorom Twojego serwera. Poniżej możesz też umieścić wyjaśnienie dlaczego zgłaszasz to konto:",
   "report.placeholder": "Dodatkowe komentarze",
   "report.submit": "Wyślij",
   "report.target": "Zgłaszanie {target}",
   "search.placeholder": "Szukaj",
   "search_popout.search_format": "Zaawansowane wyszukiwanie",
   "search_popout.tips.full_text": "Pozwala na wyszukiwanie wpisów które napisałeś(-aś), dodałeś(-aś) do ulubionych lub podbiłeś(-aś), w których o Tobie wspomniano, oraz pasujące nazwy użytkowników, pełne nazwy i hashtagi.",
-  "search_popout.tips.hashtag": "hashtag",
+  "search_popout.tips.hashtag": "hasztag",
   "search_popout.tips.status": "wpis",
   "search_popout.tips.text": "Proste wyszukiwanie pasujących pseudonimów, nazw użytkowników i hashtagów",
   "search_popout.tips.user": "użytkownik",
@@ -291,12 +315,12 @@
   "search_results.hashtags": "Hashtagi",
   "search_results.statuses": "Wpisy",
   "search_results.total": "{count, number} {count, plural, one {wynik} few {wyniki} many {wyników} more {wyników}}",
-  "standalone.public_title": "Spojrzenie w głąb…",
   "status.admin_account": "Otwórz interfejs moderacyjny dla @{name}",
   "status.admin_status": "Otwórz ten wpis w interfejsie moderacyjnym",
   "status.block": "Zablokuj @{name}",
   "status.cancel_reblog_private": "Cofnij podbicie",
   "status.cannot_reblog": "Ten wpis nie może zostać podbity",
+  "status.copy": "Skopiuj odnośnik do wpisu",
   "status.delete": "Usuń",
   "status.detailed_status": "Szczegółowy widok konwersacji",
   "status.direct": "Wyślij wiadomość bezpośrednią do @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Odpowiedz",
   "status.replyAll": "Odpowiedz na wÄ…tek",
   "status.report": "Zgłoś @{name}",
-  "status.sensitive_toggle": "Naciśnij aby wyświetlić",
   "status.sensitive_warning": "Wrażliwa zawartość",
   "status.share": "Udostępnij",
   "status.show_less": "Zwiń",
@@ -338,14 +361,21 @@
   "tabs_bar.local_timeline": "Lokalne",
   "tabs_bar.notifications": "Powiadomienia",
   "tabs_bar.search": "Szukaj",
+  "time_remaining.days": "{number, plural, one {Pozostał # dzień} few {Pozostały # dni} many {Pozostało # dni} other {Pozostało # dni}}",
+  "time_remaining.hours": "{number, plural, one {Pozostała # godzina} few {Pozostały # godziny} many {Pozostało # godzin} other {Pozostało # godzin}}",
+  "time_remaining.minutes": "{number, plural, one {Pozostała # minuta} few {Pozostały # minuty} many {Pozostało # minut} other {Pozostało # minut}}",
+  "time_remaining.moments": "Pozostała chwila",
+  "time_remaining.seconds": "{number, plural, one {Pozostała # sekunda} few {Pozostały # sekundy} many {Pozostało # sekund} other {Pozostało # sekund}}",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {osoba rozmawia} few {osoby rozmawiają} other {osób rozmawia}} o tym",
   "ui.beforeunload": "Utracisz tworzony wpis, jeżeli opuścisz Mastodona.",
   "upload_area.title": "Przeciągnij i upuść aby wysłać",
   "upload_button.label": "Dodaj zawartość multimedialną (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "Przekroczono limit plików do wysłania.",
+  "upload_error.poll": "Dołączanie plików nie dozwolone z głosowaniami.",
   "upload_form.description": "Wprowadź opis dla niewidomych i niedowidzących",
   "upload_form.focus": "Dopasuj podglÄ…d",
   "upload_form.undo": "Usuń",
-  "upload_progress.label": "Wysyłanie...",
+  "upload_progress.label": "Wysyłanie…",
   "video.close": "Zamknij film",
   "video.exit_fullscreen": "Opuść tryb pełnoekranowy",
   "video.expand": "Rozszerz film",
diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json
index 392e7f485d2483091d1fa5a52e2e3a83f24b6a21..dca087af9572bbf1e1c9ccf8a28f3462242bcc9d 100644
--- a/app/javascript/mastodon/locales/pt-BR.json
+++ b/app/javascript/mastodon/locales/pt-BR.json
@@ -5,7 +5,6 @@
   "account.block_domain": "Esconder tudo de {domain}",
   "account.blocked": "Bloqueado",
   "account.direct": "Direct Message @{name}",
-  "account.disclaimer_full": "As informações abaixo podem refletir o perfil do usuário de maneira incompleta.",
   "account.domain_blocked": "Domínio escondido",
   "account.edit_profile": "Editar perfil",
   "account.endorse": "Destacar no perfil",
@@ -36,7 +35,6 @@
   "account.unfollow": "Deixar de seguir",
   "account.unmute": "Não silenciar @{name}",
   "account.unmute_notifications": "Retirar silêncio das notificações vindas de @{name}",
-  "account.view_full_profile": "Ver perfil completo",
   "alert.unexpected.message": "Um erro inesperado ocorreu.",
   "alert.unexpected.title": "Oops!",
   "boost_modal.combo": "Você pode pressionar {combo} para ignorar este diálogo na próxima vez",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "A sua conta não está {locked}. Qualquer pessoa pode te seguir e visualizar postagens direcionadas a apenas seguidores.",
   "compose_form.lock_disclaimer.lock": "trancada",
   "compose_form.placeholder": "No que você está pensando?",
+  "compose_form.poll.add_option": "Adicionar uma opção",
+  "compose_form.poll.duration": "Duração da enquete",
+  "compose_form.poll.option_placeholder": "Opção {number}",
+  "compose_form.poll.remove_option": "Remover essa opção",
   "compose_form.publish": "Publicar",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
   "compose_form.sensitive.marked": "Mídia está marcada como sensível",
   "compose_form.sensitive.unmarked": "Mídia não está marcada como sensível",
   "compose_form.spoiler.marked": "O texto está escondido por um aviso de conteúdo",
   "compose_form.spoiler.unmarked": "O texto não está escondido",
   "compose_form.spoiler_placeholder": "Aviso de conteúdo",
   "confirmation_modal.cancel": "Cancelar",
+  "confirmations.block.block_and_report": "Bloquear e denunciar",
   "confirmations.block.confirm": "Bloquear",
   "confirmations.block.message": "Você tem certeza de que quer bloquear {name}?",
   "confirmations.delete.confirm": "Excluir",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Símbolos",
   "emoji_button.travel": "Viagens & Lugares",
   "empty_column.account_timeline": "Não há toots aqui!",
+  "empty_column.account_unavailable": "Perfil indisponível",
   "empty_column.blocks": "Você ainda não bloqueou nenhum usuário.",
   "empty_column.community": "A timeline local está vazia. Escreva algo publicamente para começar!",
   "empty_column.direct": "Você não tem nenhuma mensagem direta ainda. Quando você enviar ou receber uma, as mensagens aparecerão por aqui.",
@@ -142,13 +147,18 @@
   "hashtag.column_header.tag_mode.all": "e {additional}",
   "hashtag.column_header.tag_mode.any": "ou {additional}",
   "hashtag.column_header.tag_mode.none": "sem {additional}",
+  "hashtag.column_settings.select.no_options_message": "Nenhuma sugestão encontrada",
+  "hashtag.column_settings.select.placeholder": "Adicione as hashtags…",
   "hashtag.column_settings.tag_mode.all": "Todas essas",
   "hashtag.column_settings.tag_mode.any": "Qualquer uma dessas",
   "hashtag.column_settings.tag_mode.none": "Nenhuma dessas",
-  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "hashtag.column_settings.tag_toggle": "Incluir outras hashtags nessa coluna",
   "home.column_settings.basic": "Básico",
   "home.column_settings.show_reblogs": "Mostrar compartilhamentos",
   "home.column_settings.show_replies": "Mostrar as respostas",
+  "intervals.full.days": "{number, plural, one {# dia} other {# dias}}",
+  "intervals.full.hours": "{number, plural, one {# hora} other {# horas}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
   "introduction.federation.action": "Próximo",
   "introduction.federation.federated.headline": "Federated",
   "introduction.federation.federated.text": "Posts públicos de outros servidores do fediverso vão aparecer na timeline global.",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "para focar a pesquisa",
   "keyboard_shortcuts.start": "para abrir a coluna \"primeiros passos\"",
   "keyboard_shortcuts.toggle_hidden": "mostrar/esconder o texto com aviso de conteúdo",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "para compor um novo toot",
   "keyboard_shortcuts.unfocus": "para remover o foco da área de composição/pesquisa",
   "keyboard_shortcuts.up": "para mover para cima na lista",
   "lightbox.close": "Fechar",
   "lightbox.next": "Próximo",
   "lightbox.previous": "Anterior",
+  "lightbox.view_context": "View context",
   "lists.account.add": "Adicionar a listas",
   "lists.account.remove": "Remover da lista",
   "lists.delete": "Delete list",
   "lists.edit": "Editar lista",
+  "lists.edit.submit": "Mudar o título",
   "lists.new.create": "Adicionar lista",
   "lists.new.title_placeholder": "Novo título da lista",
   "lists.search": "Procurar entre as pessoas que você segue",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "Favoritos",
   "navigation_bar.filters": "Palavras silenciadas",
   "navigation_bar.follow_requests": "Seguidores pendentes",
+  "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.info": "Mais informações",
   "navigation_bar.keyboard_shortcuts": "Atalhos de teclado",
   "navigation_bar.lists": "Listas",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Pessoal",
   "navigation_bar.pins": "Postagens fixadas",
   "navigation_bar.preferences": "Preferências",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "Global",
   "navigation_bar.security": "Segurança",
   "notification.favourite": "{name} adicionou a sua postagem aos favoritos",
   "notification.follow": "{name} te seguiu",
   "notification.mention": "{name} te mencionou",
+  "notification.poll": "Uma enquete em que você votou chegou ao fim",
   "notification.reblog": "{name} compartilhou a sua postagem",
   "notifications.clear": "Limpar notificações",
   "notifications.clear_confirmation": "Você tem certeza de que quer limpar todas as suas notificações permanentemente?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Mostrar",
   "notifications.column_settings.follow": "Novos seguidores:",
   "notifications.column_settings.mention": "Menções:",
+  "notifications.column_settings.poll": "Resultados da enquete:",
   "notifications.column_settings.push": "Enviar notificações",
   "notifications.column_settings.reblog": "Compartilhamento:",
   "notifications.column_settings.show": "Mostrar nas colunas",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favoritos",
   "notifications.filter.follows": "Seguidores",
   "notifications.filter.mentions": "Menções",
+  "notifications.filter.polls": "Resultados da enquete",
   "notifications.group": "{count} notificações",
+  "poll.closed": "Fechada",
+  "poll.refresh": "Atualizar",
+  "poll.total_votes": "{count, plural, one {# voto} other {# votos}}",
+  "poll.vote": "Votar",
+  "poll_button.add_poll": "Adicionar uma enquete",
+  "poll_button.remove_poll": "Remover enquete",
   "privacy.change": "Ajustar a privacidade da mensagem",
   "privacy.direct.long": "Apenas para usuários mencionados",
   "privacy.direct.short": "Direta",
@@ -291,12 +315,12 @@
   "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.admin_account": "Abrir interface de moderação para @{name}",
   "status.admin_status": "Abrir esse status na interface de moderação",
   "status.block": "Block @{name}",
   "status.cancel_reblog_private": "Desfazer compartilhamento",
   "status.cannot_reblog": "Esta postagem não pode ser compartilhada",
+  "status.copy": "Copiar o link para o status",
   "status.delete": "Excluir",
   "status.detailed_status": "Visão detalhada da conversa",
   "status.direct": "Enviar mensagem direta a @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Responder",
   "status.replyAll": "Responder à sequência",
   "status.report": "Denunciar @{name}",
-  "status.sensitive_toggle": "Clique para ver",
   "status.sensitive_warning": "Conteúdo sensível",
   "status.share": "Compartilhar",
   "status.show_less": "Mostrar menos",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Local",
   "tabs_bar.notifications": "Notificações",
   "tabs_bar.search": "Buscar",
+  "time_remaining.days": "{number, plural, one {# dia restante} other {# dias restantes}}",
+  "time_remaining.hours": "{number, plural, one {# hora restante} other {# horas restantes}}",
+  "time_remaining.minutes": "{number, plural, one {# minuto restante} other {# minutos restantes}}",
+  "time_remaining.moments": "Momentos restantes",
+  "time_remaining.seconds": "{number, plural, one {# segundo restante} other {# segundos restantes}}",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {pessoa} other {pessoas}} falando sobre",
   "ui.beforeunload": "Seu rascunho será perdido se você sair do Mastodon.",
   "upload_area.title": "Arraste e solte para enviar",
   "upload_button.label": "Adicionar mídia (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "Limite de envio de arquivos excedido.",
+  "upload_error.poll": "Envio de arquivos não é permitido com enquetes.",
   "upload_form.description": "Descreva a imagem para deficientes visuais",
   "upload_form.focus": "Ajustar foco",
   "upload_form.undo": "Remover",
diff --git a/app/javascript/mastodon/locales/pt.json b/app/javascript/mastodon/locales/pt.json
index d4126704a2fcff0179efac7d5c2b45e080fadb1c..157090c55fdd12e49fbdd7e889bd71259ebc354b 100644
--- a/app/javascript/mastodon/locales/pt.json
+++ b/app/javascript/mastodon/locales/pt.json
@@ -1,44 +1,42 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
-  "account.badges.bot": "Bot",
+  "account.add_or_remove_from_list": "Adicionar ou remover das listas",
+  "account.badges.bot": "Robô",
   "account.block": "Bloquear @{name}",
   "account.block_domain": "Esconder tudo do domínio {domain}",
-  "account.blocked": "Blocked",
-  "account.direct": "Direct Message @{name}",
-  "account.disclaimer_full": "As informações abaixo podem refletir o perfil do usuário de forma incompleta.",
-  "account.domain_blocked": "Domain hidden",
+  "account.blocked": "Bloqueado",
+  "account.direct": "Mensagem directa @{name}",
+  "account.domain_blocked": "Domínio escondido",
   "account.edit_profile": "Editar perfil",
-  "account.endorse": "Feature on profile",
+  "account.endorse": "Atributo no perfil",
   "account.follow": "Seguir",
   "account.followers": "Seguidores",
-  "account.followers.empty": "No one follows this user yet.",
+  "account.followers.empty": "Ainda ninguém segue este utilizador.",
   "account.follows": "Segue",
-  "account.follows.empty": "This user doesn't follow anyone yet.",
+  "account.follows.empty": "Este utilizador ainda não segue alguém.",
   "account.follows_you": "É teu seguidor",
   "account.hide_reblogs": "Esconder partilhas de @{name}",
-  "account.link_verified_on": "Ownership of this link was checked on {date}",
-  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
+  "account.link_verified_on": "A posse deste link foi verificada em {date}",
+  "account.locked_info": "O estatuto de privacidade desta conta é fechado. O dono revê manualmente que a pode seguir.",
   "account.media": "Media",
   "account.mention": "Mencionar @{name}",
   "account.moved_to": "{name} mudou a sua conta para:",
   "account.mute": "Silenciar @{name}",
   "account.mute_notifications": "Silenciar notificações de @{name}",
-  "account.muted": "Muted",
-  "account.posts": "Posts",
-  "account.posts_with_replies": "Toots with replies",
+  "account.muted": "Silenciada",
+  "account.posts": "Publicações",
+  "account.posts_with_replies": "Publicações e respostas",
   "account.report": "Denunciar @{name}",
-  "account.requested": "A aguardar aprovação",
+  "account.requested": "A aguardar aprovação. Clique para cancelar o pedido de seguimento",
   "account.share": "Partilhar o perfil @{name}",
   "account.show_reblogs": "Mostrar partilhas de @{name}",
-  "account.unblock": "Não bloquear @{name}",
+  "account.unblock": "Desbloquear @{name}",
   "account.unblock_domain": "Mostrar {domain}",
-  "account.unendorse": "Don't feature on profile",
+  "account.unendorse": "Não mostrar no perfil",
   "account.unfollow": "Deixar de seguir",
   "account.unmute": "Não silenciar @{name}",
   "account.unmute_notifications": "Deixar de silenciar @{name}",
-  "account.view_full_profile": "Ver perfil completo",
-  "alert.unexpected.message": "An unexpected error occurred.",
-  "alert.unexpected.title": "Oops!",
+  "alert.unexpected.message": "Ocorreu um erro inesperado.",
+  "alert.unexpected.title": "Bolas!",
   "boost_modal.combo": "Pode clicar {combo} para não voltar a ver",
   "bundle_column_error.body": "Algo de errado aconteceu enquanto este componente era carregado.",
   "bundle_column_error.retry": "Tente de novo",
@@ -47,17 +45,17 @@
   "bundle_modal_error.message": "Algo de errado aconteceu enquanto este componente era carregado.",
   "bundle_modal_error.retry": "Tente de novo",
   "column.blocks": "Utilizadores Bloqueados",
-  "column.community": "Local",
-  "column.direct": "Direct messages",
-  "column.domain_blocks": "Hidden domains",
+  "column.community": "Cronologia local",
+  "column.direct": "Mensagens directas",
+  "column.domain_blocks": "Domínios escondidos",
   "column.favourites": "Favoritos",
   "column.follow_requests": "Seguidores Pendentes",
   "column.home": "Início",
   "column.lists": "Listas",
   "column.mutes": "Utilizadores silenciados",
   "column.notifications": "Notificações",
-  "column.pins": "Posts fixos",
-  "column.public": "Global",
+  "column.pins": "Publicações fixas",
+  "column.public": "Cronologia federativa",
   "column_back_button.label": "Voltar",
   "column_header.hide_settings": "Esconder preferências",
   "column_header.moveLeft_settings": "Mover coluna para a esquerda",
@@ -66,41 +64,47 @@
   "column_header.show_settings": "Mostrar preferências",
   "column_header.unpin": "Desafixar",
   "column_subheading.settings": "Preferências",
-  "community.column_settings.media_only": "Media Only",
-  "compose_form.direct_message_warning": "This toot will only be visible to all the mentioned users.",
-  "compose_form.direct_message_warning_learn_more": "Learn more",
+  "community.column_settings.media_only": "Somente media",
+  "compose_form.direct_message_warning": "Esta publicação só  será enviada para os utilizadores mencionados.",
+  "compose_form.direct_message_warning_learn_more": "Aprender mais",
   "compose_form.hashtag_warning": "Esta pulbicacção não será listada em nenhuma hashtag por ser não listada. Somente publicações públicas podem ser pesquisadas por hashtag.",
   "compose_form.lock_disclaimer": "A tua conta não está {locked}. Qualquer pessoa pode seguir-te e ver as publicações direcionadas apenas a seguidores.",
-  "compose_form.lock_disclaimer.lock": "bloqueada",
+  "compose_form.lock_disclaimer.lock": "fechada",
   "compose_form.placeholder": "Em que estás a pensar?",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
   "compose_form.publish": "Publicar",
-  "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive.marked": "Media is marked as sensitive",
-  "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
-  "compose_form.spoiler.marked": "Text is hidden behind warning",
-  "compose_form.spoiler.unmarked": "Text is not hidden",
-  "compose_form.spoiler_placeholder": "Aviso de conteúdo",
+  "compose_form.publish_loud": "{publicar}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
+  "compose_form.sensitive.marked": "Media marcado como sensível",
+  "compose_form.sensitive.unmarked": "Media não está marcado como sensível",
+  "compose_form.spoiler.marked": "Texto escondido atrás de aviso",
+  "compose_form.spoiler.unmarked": "O texto não está escondido",
+  "compose_form.spoiler_placeholder": "Escreve o teu aviso aqui",
   "confirmation_modal.cancel": "Cancelar",
-  "confirmations.block.confirm": "Block",
+  "confirmations.block.block_and_report": "Block & Report",
+  "confirmations.block.confirm": "Bloquear",
   "confirmations.block.message": "De certeza que queres bloquear {name}?",
   "confirmations.delete.confirm": "Eliminar",
   "confirmations.delete.message": "De certeza que queres eliminar esta publicação?",
-  "confirmations.delete_list.confirm": "Delete",
+  "confirmations.delete_list.confirm": "Apagar",
   "confirmations.delete_list.message": "Tens a certeza de que desejas apagar permanentemente esta lista?",
   "confirmations.domain_block.confirm": "Esconder tudo deste domínio",
-  "confirmations.domain_block.message": "De certeza que queres bloquear por completo o domínio {domain}? Na maioria dos casos, silenciar ou bloquear alguns utilizadores é o suficiente e o recomendado.",
+  "confirmations.domain_block.message": "De certeza que queres bloquear completamente o domínio {domain}? Na maioria dos casos, silenciar ou bloquear alguns utilizadores é o suficiente e o recomendado. Não irás ver conteúdo daquele domínio em cronologia alguma, nem nas tuas notificações. Os teus seguidores daquele domínio serão removidos.",
   "confirmations.mute.confirm": "Silenciar",
   "confirmations.mute.message": "De certeza que queres silenciar {name}?",
-  "confirmations.redraft.confirm": "Delete & redraft",
-  "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.",
-  "confirmations.reply.confirm": "Reply",
-  "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
+  "confirmations.redraft.confirm": "Apagar & redigir",
+  "confirmations.redraft.message": "Tens a certeza que queres apagar e redigir esta publicação?  Os favoritos e as partilhas perder-se-ão e as respostas à publicação original ficarão órfãs.",
+  "confirmations.reply.confirm": "Responder",
+  "confirmations.reply.message": "Responder agora irá reescrever a mensagem que estás a compor actualmente. Tens a certeza que queres continuar?",
   "confirmations.unfollow.confirm": "Deixar de seguir",
   "confirmations.unfollow.message": "De certeza que queres deixar de seguir {name}?",
-  "embed.instructions": "Publicar este post num outro site copiando o código abaixo.",
+  "embed.instructions": "Publica esta publicação no teu site copiando o código abaixo.",
   "embed.preview": "Podes ver aqui como irá ficar:",
   "emoji_button.activity": "Actividade",
-  "emoji_button.custom": "Especiais",
+  "emoji_button.custom": "Personalizar",
   "emoji_button.flags": "Bandeiras",
   "emoji_button.food": "Comida & Bebida",
   "emoji_button.label": "Inserir Emoji",
@@ -113,97 +117,106 @@
   "emoji_button.search_results": "Resultados da pesquisa",
   "emoji_button.symbols": "Símbolos",
   "emoji_button.travel": "Viagens & Lugares",
-  "empty_column.account_timeline": "No toots here!",
-  "empty_column.blocks": "You haven't blocked any users yet.",
+  "empty_column.account_timeline": "Sem publicações!",
+  "empty_column.account_unavailable": "Profile unavailable",
+  "empty_column.blocks": "Ainda não bloqueaste qualquer utilizador.",
   "empty_column.community": "Ainda não existe conteúdo local para mostrar!",
-  "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
-  "empty_column.domain_blocks": "There are no hidden domains yet.",
-  "empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.",
-  "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.",
-  "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
+  "empty_column.direct": "Ainda não tens qualquer mensagem directa. Quando enviares ou receberes alguma, ela irá aparecer aqui.",
+  "empty_column.domain_blocks": "Ainda não há qualquer domínio escondido.",
+  "empty_column.favourited_statuses": "Ainda não tens quaisquer publicações favoritas. Quando tiveres alguma, ela irá aparecer aqui.",
+  "empty_column.favourites": "Ainda ninguém favorizou esta publicação. Quando alguém o fizer, ela irá aparecer aqui.",
+  "empty_column.follow_requests": "Ainda não tens pedido de seguimento algum. Quando receberes algum, ele irá aparecer aqui.",
   "empty_column.hashtag": "Não foram encontradas publicações com essa hashtag.",
   "empty_column.home": "Ainda não segues qualquer utilizador. Visita {public} ou utiliza a pesquisa para procurar outros utilizadores.",
-  "empty_column.home.public_timeline": "global",
+  "empty_column.home.public_timeline": "Cronologia pública",
   "empty_column.list": "Ainda não existem publicações nesta lista. Quando membros desta lista fizerem novas publicações, elas aparecerão aqui.",
-  "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
-  "empty_column.mutes": "You haven't muted any users yet.",
+  "empty_column.lists": "Ainda não tens qualquer lista. Quando criares uma, ela irá aparecer aqui.",
+  "empty_column.mutes": "Ainda não silenciaste qualquer utilizador.",
   "empty_column.notifications": "Não tens notificações. Interage com outros utilizadores para iniciar uma conversa.",
-  "empty_column.public": "Não há nada aqui! Escreve algo publicamente ou segue outros utilizadores para ver aqui os conteúdos públicos",
+  "empty_column.public": "Não há nada aqui! Escreve algo publicamente ou segue outros utilizadores para veres aqui os conteúdos públicos",
   "follow_request.authorize": "Autorizar",
   "follow_request.reject": "Rejeitar",
-  "getting_started.developers": "Developers",
-  "getting_started.directory": "Profile directory",
+  "getting_started.developers": "Responsáveis pelo desenvolvimento",
+  "getting_started.directory": "Directório de perfil",
   "getting_started.documentation": "Documentation",
   "getting_started.heading": "Primeiros passos",
-  "getting_started.invite": "Invite people",
+  "getting_started.invite": "Convidar pessoas",
   "getting_started.open_source_notice": "Mastodon é software de fonte aberta. Podes contribuir ou repostar problemas no GitHub do projecto: {github}.",
-  "getting_started.security": "Security",
-  "getting_started.terms": "Terms of service",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
-  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "getting_started.security": "Segurança",
+  "getting_started.terms": "Termos de serviço",
+  "hashtag.column_header.tag_mode.all": "e {additional}",
+  "hashtag.column_header.tag_mode.any": "ou {additional}",
+  "hashtag.column_header.tag_mode.none": "sem {additional}",
+  "hashtag.column_settings.select.no_options_message": "Não foram encontradas sugestões",
+  "hashtag.column_settings.select.placeholder": "Introduzir as hashtags…",
+  "hashtag.column_settings.tag_mode.all": "Todos estes",
+  "hashtag.column_settings.tag_mode.any": "Qualquer destes",
+  "hashtag.column_settings.tag_mode.none": "Nenhum destes",
+  "hashtag.column_settings.tag_toggle": "Incluir etiquetas adicionais para esta coluna",
   "home.column_settings.basic": "Básico",
   "home.column_settings.show_reblogs": "Mostrar as partilhas",
   "home.column_settings.show_replies": "Mostrar as respostas",
-  "introduction.federation.action": "Next",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
+  "introduction.federation.action": "Seguinte",
   "introduction.federation.federated.headline": "Federated",
-  "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
+  "introduction.federation.federated.text": "Publicações públicas de outros servidores do fediverse aparecerão na cronologia federativa.",
   "introduction.federation.home.headline": "Home",
-  "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
+  "introduction.federation.home.text": "As publicações das pessoas que tu segues aparecerão na tua coluna inicial. Tu podes seguir qualquer pessoa em qualquer servidor!",
   "introduction.federation.local.headline": "Local",
-  "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
-  "introduction.interactions.favourite.headline": "Favourite",
-  "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
-  "introduction.interactions.reblog.headline": "Boost",
-  "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
-  "introduction.interactions.reply.headline": "Reply",
-  "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
-  "introduction.welcome.action": "Let's go!",
-  "introduction.welcome.headline": "First steps",
-  "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
+  "introduction.federation.local.text": "Publicações públicas de pessoas que tu segues no teu servidor aparecerão na coluna local.",
+  "introduction.interactions.action": "Terminar o tutorial!",
+  "introduction.interactions.favourite.headline": "Favorito",
+  "introduction.interactions.favourite.text": "Tu podes guardar um toot para depois e deixar o autor saber que gostaste dele, favoritando-o.",
+  "introduction.interactions.reblog.headline": "Partilhar",
+  "introduction.interactions.reblog.text": "Podes partilhar os toots de outras pessoas com os teus seguidores partilhando-os.",
+  "introduction.interactions.reply.headline": "Responder",
+  "introduction.interactions.reply.text": "Tu podes responder a toots de outras pessoas e aos teus, o que os irá juntar numa conversa.",
+  "introduction.welcome.action": "Vamos!",
+  "introduction.welcome.headline": "Primeiros passos",
+  "introduction.welcome.text": "Bem-vindo ao fediverse! Em pouco tempo poderás enviar mensagens e falar com os teus amigos numa grande variedade de servidores. Mas este servidor, {domain}, é especial—ele alberga o teu perfil. Por isso, lembra-te do seu nome.",
   "keyboard_shortcuts.back": "para voltar",
-  "keyboard_shortcuts.blocked": "to open blocked users list",
+  "keyboard_shortcuts.blocked": "para abrir a lista de utilizadores bloqueados",
   "keyboard_shortcuts.boost": "para partilhar",
   "keyboard_shortcuts.column": "para focar uma publicação numa das colunas",
   "keyboard_shortcuts.compose": "para focar na área de publicação",
   "keyboard_shortcuts.description": "Descrição",
-  "keyboard_shortcuts.direct": "to open direct messages column",
+  "keyboard_shortcuts.direct": "para abrir a coluna das mensagens directas",
   "keyboard_shortcuts.down": "para mover para baixo na lista",
   "keyboard_shortcuts.enter": "para expandir uma publicação",
   "keyboard_shortcuts.favourite": "para adicionar aos favoritos",
-  "keyboard_shortcuts.favourites": "to open favourites list",
-  "keyboard_shortcuts.federated": "to open federated timeline",
+  "keyboard_shortcuts.favourites": "para abrir a lista dos favoritos",
+  "keyboard_shortcuts.federated": "para abrir a cronologia federativa",
   "keyboard_shortcuts.heading": "Atalhos do teclado",
-  "keyboard_shortcuts.home": "to open home timeline",
+  "keyboard_shortcuts.home": "para abrir a cronologia inicial",
   "keyboard_shortcuts.hotkey": "Atalho",
   "keyboard_shortcuts.legend": "para mostrar esta legenda",
-  "keyboard_shortcuts.local": "to open local timeline",
+  "keyboard_shortcuts.local": "para abrir a cronologia local",
   "keyboard_shortcuts.mention": "para mencionar o autor",
-  "keyboard_shortcuts.muted": "to open muted users list",
-  "keyboard_shortcuts.my_profile": "to open your profile",
-  "keyboard_shortcuts.notifications": "to open notifications column",
-  "keyboard_shortcuts.pinned": "to open pinned toots list",
-  "keyboard_shortcuts.profile": "to open author's profile",
+  "keyboard_shortcuts.muted": "para abrir a lista dos utilizadores silenciados",
+  "keyboard_shortcuts.my_profile": "para abrir o teu perfil",
+  "keyboard_shortcuts.notifications": "para abrir a coluna das notificações",
+  "keyboard_shortcuts.pinned": "para abrir a lista dos toots fixados",
+  "keyboard_shortcuts.profile": "para abrir o perfil do autor",
   "keyboard_shortcuts.reply": "para responder",
-  "keyboard_shortcuts.requests": "to open follow requests list",
+  "keyboard_shortcuts.requests": "para abrir a lista dos pedidos de seguimento",
   "keyboard_shortcuts.search": "para focar na pesquisa",
-  "keyboard_shortcuts.start": "to open \"get started\" column",
-  "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
+  "keyboard_shortcuts.start": "para abrir a coluna dos \"primeiros passos\"",
+  "keyboard_shortcuts.toggle_hidden": "para mostrar/esconder texto atrás de CW",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "para compor um novo post",
   "keyboard_shortcuts.unfocus": "para remover o foco da área de publicação/pesquisa",
   "keyboard_shortcuts.up": "para mover para cima na lista",
   "lightbox.close": "Fechar",
   "lightbox.next": "Próximo",
   "lightbox.previous": "Anterior",
+  "lightbox.view_context": "View context",
   "lists.account.add": "Adicionar à lista",
   "lists.account.remove": "Remover da lista",
   "lists.delete": "Delete list",
   "lists.edit": "Editar lista",
+  "lists.edit.submit": "Mudar o título",
   "lists.new.create": "Adicionar lista",
   "lists.new.title_placeholder": "Novo título da lista",
   "lists.search": "Pesquisa entre as pessoas que segues",
@@ -213,18 +226,19 @@
   "missing_indicator.label": "Não encontrado",
   "missing_indicator.sublabel": "Este recurso não foi encontrado",
   "mute_modal.hide_notifications": "Esconder notificações deste utilizador?",
-  "navigation_bar.apps": "Mobile apps",
+  "navigation_bar.apps": "Aplicações móveis",
   "navigation_bar.blocks": "Utilizadores bloqueados",
   "navigation_bar.community_timeline": "Local",
-  "navigation_bar.compose": "Compose new toot",
-  "navigation_bar.direct": "Direct messages",
-  "navigation_bar.discover": "Discover",
-  "navigation_bar.domain_blocks": "Hidden domains",
+  "navigation_bar.compose": "Escrever novo toot",
+  "navigation_bar.direct": "Mensagens directas",
+  "navigation_bar.discover": "Descobrir",
+  "navigation_bar.domain_blocks": "Domínios escondidos",
   "navigation_bar.edit_profile": "Editar perfil",
   "navigation_bar.favourites": "Favoritos",
-  "navigation_bar.filters": "Muted words",
+  "navigation_bar.filters": "Palavras silenciadas",
   "navigation_bar.follow_requests": "Seguidores pendentes",
-  "navigation_bar.info": "Mais informações",
+  "navigation_bar.follows_and_followers": "Follows and followers",
+  "navigation_bar.info": "Sobre este servidor",
   "navigation_bar.keyboard_shortcuts": "Atalhos de teclado",
   "navigation_bar.lists": "Listas",
   "navigation_bar.logout": "Sair",
@@ -232,31 +246,41 @@
   "navigation_bar.personal": "Personal",
   "navigation_bar.pins": "Posts fixos",
   "navigation_bar.preferences": "Preferências",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "Global",
-  "navigation_bar.security": "Security",
+  "navigation_bar.security": "Segurança",
   "notification.favourite": "{name} adicionou o teu post aos favoritos",
   "notification.follow": "{name} seguiu-te",
   "notification.mention": "{name} mencionou-te",
+  "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "{name} partilhou o teu post",
   "notifications.clear": "Limpar notificações",
   "notifications.clear_confirmation": "Queres mesmo limpar todas as notificações?",
   "notifications.column_settings.alert": "Notificações no computador",
   "notifications.column_settings.favourite": "Favoritos:",
-  "notifications.column_settings.filter_bar.advanced": "Display all categories",
-  "notifications.column_settings.filter_bar.category": "Quick filter bar",
-  "notifications.column_settings.filter_bar.show": "Show",
+  "notifications.column_settings.filter_bar.advanced": "Mostrar todas as categorias",
+  "notifications.column_settings.filter_bar.category": "Barra de filtros rápidos",
+  "notifications.column_settings.filter_bar.show": "Mostrar",
   "notifications.column_settings.follow": "Novos seguidores:",
   "notifications.column_settings.mention": "Menções:",
+  "notifications.column_settings.poll": "Poll results:",
   "notifications.column_settings.push": "Notificações Push",
   "notifications.column_settings.reblog": "Partilhas:",
   "notifications.column_settings.show": "Mostrar nas colunas",
   "notifications.column_settings.sound": "Reproduzir som",
-  "notifications.filter.all": "All",
-  "notifications.filter.boosts": "Boosts",
-  "notifications.filter.favourites": "Favourites",
-  "notifications.filter.follows": "Follows",
-  "notifications.filter.mentions": "Mentions",
-  "notifications.group": "{count} notifications",
+  "notifications.filter.all": "Todas",
+  "notifications.filter.boosts": "Partilhas",
+  "notifications.filter.favourites": "Favoritas",
+  "notifications.filter.follows": "Seguimento",
+  "notifications.filter.mentions": "Referências",
+  "notifications.filter.polls": "Poll results",
+  "notifications.group": "{count} notificações",
+  "poll.closed": "Fechado",
+  "poll.refresh": "Recarregar",
+  "poll.total_votes": "{contar, plural, um {# vote} outro {# votes}}",
+  "poll.vote": "Votar",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
   "privacy.change": "Ajustar a privacidade da mensagem",
   "privacy.direct.long": "Apenas para utilizadores mencionados",
   "privacy.direct.short": "Directo",
@@ -274,35 +298,35 @@
   "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.forward": "Reenviar para {target}",
+  "report.forward_hint": "A conta é de outro servidor. Enviar uma cópia anónima do relatório para lá também?",
+  "report.hint": "O relatório será enviado para os moderadores do teu servidor. Podes fornecer, em baixo, uma explicação do motivo pelo qual estás a relatar esta conta:",
   "report.placeholder": "Comentários adicionais",
   "report.submit": "Enviar",
   "report.target": "Denunciar",
   "search.placeholder": "Pesquisar",
   "search_popout.search_format": "Formato avançado de pesquisa",
-  "search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
+  "search_popout.tips.full_text": "Texto simples devolve publicações que tu escreveste, favoritaste, partilhaste ou em que foste mencionado, tal como nomes de utilizador correspondentes, alcunhas e hashtags.",
   "search_popout.tips.hashtag": "hashtag",
-  "search_popout.tips.status": "status",
+  "search_popout.tips.status": "estado",
   "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.accounts": "Pessoas",
   "search_results.hashtags": "Hashtags",
-  "search_results.statuses": "Toots",
+  "search_results.statuses": "Publicações",
   "search_results.total": "{count, number} {count, plural, one {resultado} other {resultados}}",
-  "standalone.public_title": "Espreitar lá dentro...",
-  "status.admin_account": "Open moderation interface for @{name}",
-  "status.admin_status": "Open this status in the moderation interface",
+  "status.admin_account": "Abrir a interface de moderação para @{name}",
+  "status.admin_status": "Abrir esta publicação na interface de moderação",
   "status.block": "Block @{name}",
-  "status.cancel_reblog_private": "Unboost",
+  "status.cancel_reblog_private": "Não partilhar",
   "status.cannot_reblog": "Este post não pode ser partilhado",
+  "status.copy": "Copiar o link para a publicação",
   "status.delete": "Eliminar",
-  "status.detailed_status": "Detailed conversation view",
-  "status.direct": "Direct message @{name}",
+  "status.detailed_status": "Vista de conversação detalhada",
+  "status.direct": "Mensagem directa @{name}",
   "status.embed": "Incorporar",
   "status.favourite": "Adicionar aos favoritos",
-  "status.filtered": "Filtered",
+  "status.filtered": "Filtrada",
   "status.load_more": "Carregar mais",
   "status.media_hidden": "Media escondida",
   "status.mention": "Mencionar @{name}",
@@ -311,41 +335,47 @@
   "status.mute_conversation": "Silenciar conversa",
   "status.open": "Expandir",
   "status.pin": "Fixar no perfil",
-  "status.pinned": "Pinned toot",
-  "status.read_more": "Read more",
+  "status.pinned": "Publicação fixa",
+  "status.read_more": "Ler mais",
   "status.reblog": "Partilhar",
-  "status.reblog_private": "Boost to original audience",
+  "status.reblog_private": "Partilhar com a audiência original",
   "status.reblogged_by": "{name} partilhou",
-  "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
-  "status.redraft": "Delete & re-draft",
+  "status.reblogs.empty": "Ainda ninguém partilhou esta publicação. Quando alguém o fizer, ela irá aparecer aqui.",
+  "status.redraft": "Apagar & reescrever",
   "status.reply": "Responder",
   "status.replyAll": "Responder à conversa",
   "status.report": "Denunciar @{name}",
-  "status.sensitive_toggle": "Clique para ver",
   "status.sensitive_warning": "Conteúdo sensível",
   "status.share": "Compartilhar",
   "status.show_less": "Mostrar menos",
-  "status.show_less_all": "Show less for all",
+  "status.show_less_all": "Mostrar menos para todas",
   "status.show_more": "Mostrar mais",
-  "status.show_more_all": "Show more for all",
-  "status.show_thread": "Show thread",
+  "status.show_more_all": "Mostrar mais para todas",
+  "status.show_thread": "Mostrar conversa",
   "status.unmute_conversation": "Deixar de silenciar esta conversa",
   "status.unpin": "Não fixar no perfil",
-  "suggestions.dismiss": "Dismiss suggestion",
-  "suggestions.header": "You might be interested in…",
+  "suggestions.dismiss": "Dispensar a sugestão",
+  "suggestions.header": "Tu podes estar interessado em…",
   "tabs_bar.federated_timeline": "Global",
   "tabs_bar.home": "Home",
   "tabs_bar.local_timeline": "Local",
   "tabs_bar.notifications": "Notificações",
-  "tabs_bar.search": "Search",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "tabs_bar.search": "Pesquisar",
+  "time_remaining.days": "{número, plural, um {# day} outro {# days}} faltam",
+  "time_remaining.hours": "{número, plural, um {# hour} outro {# hours}} faltam",
+  "time_remaining.minutes": "{número, plural, um {# minute} outro {# minutes}} faltam",
+  "time_remaining.moments": "Momentos em falta",
+  "time_remaining.seconds": "{número, plural, um {# second} outro {# seconds}} faltam",
+  "trends.count_by_accounts": "{count} {rawCount, plural, uma {person} outra {people}} a falar",
   "ui.beforeunload": "O teu rascunho vai ser perdido se abandonares o Mastodon.",
   "upload_area.title": "Arraste e solte para enviar",
   "upload_button.label": "Adicionar media",
+  "upload_error.limit": "Limite máximo do ficheiro a carregar excedido.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "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...",
+  "upload_form.focus": "Alterar previsualização",
+  "upload_form.undo": "Apagar",
+  "upload_progress.label": "A enviar...",
   "video.close": "Fechar vídeo",
   "video.exit_fullscreen": "Sair de full screen",
   "video.expand": "Expandir vídeo",
diff --git a/app/javascript/mastodon/locales/ro.json b/app/javascript/mastodon/locales/ro.json
index a1a514f4948b5f2878b561fbdf039f51b68c9492..dcb7a088dfe0dbe4de8bff048c63f27118d37aa0 100644
--- a/app/javascript/mastodon/locales/ro.json
+++ b/app/javascript/mastodon/locales/ro.json
@@ -5,7 +5,6 @@
   "account.block_domain": "Ascunde tot de la {domain}",
   "account.blocked": "Blocat",
   "account.direct": "Mesaj direct @{name}",
-  "account.disclaimer_full": "Informațiile de mai jos pot reflecta profilul utilizatorului incomplet.",
   "account.domain_blocked": "Domeniu ascuns",
   "account.edit_profile": "Editează profilul",
   "account.endorse": "Redistribuie pe profil",
@@ -36,7 +35,6 @@
   "account.unfollow": "Nu mai urmări",
   "account.unmute": "Activează notificările de la @{name}",
   "account.unmute_notifications": "Activează notificările de la @{name}",
-  "account.view_full_profile": "Vezi profilul complet",
   "alert.unexpected.message": "A apărut o eroare neașteptată.",
   "alert.unexpected.title": "Hopa!",
   "boost_modal.combo": "Poți apăsa {combo} pentru a omite asta data viitoare",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "Contul tău nu este {locked}. Oricine te poate urmări fără aprobarea ta și vedea toate postările tale.",
   "compose_form.lock_disclaimer.lock": "privat",
   "compose_form.placeholder": "La ce te gândești?",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
   "compose_form.publish": "Postează",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
   "compose_form.sensitive.marked": "Conținutul media este marcat ca sensibil",
   "compose_form.sensitive.unmarked": "Conținutul media nu este marcat ca sensibil",
   "compose_form.spoiler.marked": "Textul este ascuns sub o avertizare",
   "compose_form.spoiler.unmarked": "Textul nu este ascuns",
   "compose_form.spoiler_placeholder": "Scrie averitzarea aici",
   "confirmation_modal.cancel": "Anulează",
+  "confirmations.block.block_and_report": "Block & Report",
   "confirmations.block.confirm": "Blochează",
   "confirmations.block.message": "Ești sigur că vrei să blochezi {name}?",
   "confirmations.delete.confirm": "Șterge",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Simboluri",
   "emoji_button.travel": "Călătorii si Locuri",
   "empty_column.account_timeline": "Nici o postare aici!",
+  "empty_column.account_unavailable": "Profile unavailable",
   "empty_column.blocks": "Nu ai blocat nici un utilizator incă.",
   "empty_column.community": "Fluxul local este gol. Scrie ceva public pentru a împinge bila la vale!",
   "empty_column.direct": "Nu ai nici un mesaj direct incă. Când trimiți sau primești unul, va fi afișat aici.",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "și {additional}",
   "hashtag.column_header.tag_mode.any": "sau {additional}",
   "hashtag.column_header.tag_mode.none": "fără {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
   "hashtag.column_settings.tag_mode.all": "Toate acestea",
   "hashtag.column_settings.tag_mode.any": "Oricare din acestea",
   "hashtag.column_settings.tag_mode.none": "Niciuna din aceastea",
@@ -149,6 +156,9 @@
   "home.column_settings.basic": "De bază",
   "home.column_settings.show_reblogs": "Arată redistribuirile",
   "home.column_settings.show_replies": "Arată răspunsurile",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
   "introduction.federation.action": "Următorul",
   "introduction.federation.federated.headline": "Federalizat",
   "introduction.federation.federated.text": "Postările publice de pe alte servere din rețea vor apărea in fluxul global.",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "să focuseze căutarea",
   "keyboard_shortcuts.start": "să deschidă coloana \"Începere\"",
   "keyboard_shortcuts.toggle_hidden": "să arate/ascundă textul in spatele CW",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "să înceapă o postare nouă",
   "keyboard_shortcuts.unfocus": "să dezactiveze zona de compunere/căutare",
   "keyboard_shortcuts.up": "să mute mai sus în listă",
   "lightbox.close": "ÃŽnchide",
   "lightbox.next": "Următorul",
   "lightbox.previous": "Precedentul",
+  "lightbox.view_context": "View context",
   "lists.account.add": "Adaugă în listă",
   "lists.account.remove": "Elimină din listă",
   "lists.delete": "Șterge lista",
   "lists.edit": "Editează lista",
+  "lists.edit.submit": "Change title",
   "lists.new.create": "Adaugă listă",
   "lists.new.title_placeholder": "Titlu pentru noua listă",
   "lists.search": "Caută printre persoanale pe care le urmărești",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "Favorite",
   "navigation_bar.filters": "Cuvinte oprite",
   "navigation_bar.follow_requests": "Cereri de urmărire",
+  "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.info": "Despre această instanță",
   "navigation_bar.keyboard_shortcuts": "Prescurtări",
   "navigation_bar.lists": "Liste",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Personal",
   "navigation_bar.pins": "Postări fixate",
   "navigation_bar.preferences": "Preferințe",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "Flux global",
   "navigation_bar.security": "Securitate",
   "notification.favourite": "{name} a adăugat statusul tău la favorite",
   "notification.follow": "{name} te urmărește",
   "notification.mention": "{name} te-a menționat",
+  "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "{name} a redistribuit postarea ta",
   "notifications.clear": "Șterge notificările",
   "notifications.clear_confirmation": "Ești sigur că vrei să ștergi toate notificările?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Arată",
   "notifications.column_settings.follow": "Noi urmăritori:",
   "notifications.column_settings.mention": "Mențiuni:",
+  "notifications.column_settings.poll": "Poll results:",
   "notifications.column_settings.push": "Notificări push",
   "notifications.column_settings.reblog": "Redistribuite:",
   "notifications.column_settings.show": "Arată în coloană",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favorite",
   "notifications.filter.follows": "Urmărește",
   "notifications.filter.mentions": "Menționări",
+  "notifications.filter.polls": "Poll results",
   "notifications.group": "{count} notificări",
+  "poll.closed": "Closed",
+  "poll.refresh": "Refresh",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
   "privacy.change": "Cine vede asta",
   "privacy.direct.long": "Postează doar pentru utilizatorii menționați",
   "privacy.direct.short": "Direct",
@@ -291,12 +315,12 @@
   "search_results.hashtags": "Hashtaguri",
   "search_results.statuses": "Postări",
   "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
-  "standalone.public_title": "Se întâmplă acum...",
   "status.admin_account": "Open moderation interface for @{name}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Blochează @{name}",
   "status.cancel_reblog_private": "Nedistribuit",
   "status.cannot_reblog": "Această postare nu poate fi redistribuită",
+  "status.copy": "Copy link to status",
   "status.delete": "Șterge",
   "status.detailed_status": "Conversația detailată",
   "status.direct": "Mesaj direct @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Răspunde",
   "status.replyAll": "Răspunde la topic",
   "status.report": "Raportează @{name}",
-  "status.sensitive_toggle": "Afișează",
   "status.sensitive_warning": "Conținut sensibil",
   "status.share": "Distribuie",
   "status.show_less": "Arată mai puțin",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Local",
   "tabs_bar.notifications": "Notificări",
   "tabs_bar.search": "Căutare",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} vorbesc",
   "ui.beforeunload": "Postarea se va pierde dacă părăsești pagina.",
   "upload_area.title": "Trage și eliberează pentru a încărca",
   "upload_button.label": "Adaugă media (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "upload_form.description": "Adaugă o descriere pentru persoanele cu deficiențe de vedere",
   "upload_form.focus": "Schimbă previzualizarea",
   "upload_form.undo": "Șterge",
diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json
index cb601089865c47fde78230d86cb292164bf5b611..d720b62729d22f494adea0b4464791c7816b33aa 100644
--- a/app/javascript/mastodon/locales/ru.json
+++ b/app/javascript/mastodon/locales/ru.json
@@ -1,11 +1,10 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "Добавить или удалить из списков",
   "account.badges.bot": "Бот",
   "account.block": "Блокировать",
   "account.block_domain": "Блокировать все с {domain}",
   "account.blocked": "Заблокирован(а)",
   "account.direct": "Написать @{name}",
-  "account.disclaimer_full": "Нижеуказанная информация может не полностью отражать профиль пользователя.",
   "account.domain_blocked": "Домен скрыт",
   "account.edit_profile": "Изменить профиль",
   "account.endorse": "Рекомендовать в профиле",
@@ -15,9 +14,9 @@
   "account.follows": "Подписки",
   "account.follows.empty": "Этот пользователь ни на кого не подписан.",
   "account.follows_you": "Подписан(а) на Вас",
-  "account.hide_reblogs": "Скрыть продвижения от @{name}",
-  "account.link_verified_on": "Ownership of this link was checked on {date}",
-  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
+  "account.hide_reblogs": "Скрыть реблоги от @{name}",
+  "account.link_verified_on": "Владение этой ссылкой было проверено {date}",
+  "account.locked_info": "Это закрытый аккаунт. Его владелец вручную одобряет подписчиков.",
   "account.media": "Медиа",
   "account.mention": "Упомянуть",
   "account.moved_to": "Ищите {name} здесь:",
@@ -36,7 +35,6 @@
   "account.unfollow": "Отписаться",
   "account.unmute": "Снять глушение",
   "account.unmute_notifications": "Показывать уведомления от @{name}",
-  "account.view_full_profile": "Показать полный профиль",
   "alert.unexpected.message": "Что-то пошло не так.",
   "alert.unexpected.title": "Ой!",
   "boost_modal.combo": "Нажмите {combo}, чтобы пропустить это в следующий раз",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "Ваш аккаунт не {locked}. Любой человек может подписаться на Вас и просматривать посты для подписчиков.",
   "compose_form.lock_disclaimer.lock": "закрыт",
   "compose_form.placeholder": "О чем Вы думаете?",
+  "compose_form.poll.add_option": "Добавить",
+  "compose_form.poll.duration": "Длительность опроса",
+  "compose_form.poll.option_placeholder": "Вариант {number}",
+  "compose_form.poll.remove_option": "Удалить этот вариант",
   "compose_form.publish": "Трубить",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Пометить медиафайл как чувствительный",
   "compose_form.sensitive.marked": "Медиафайлы не отмечены как чувствительные",
   "compose_form.sensitive.unmarked": "Медиафайлы не отмечены как чувствительные",
   "compose_form.spoiler.marked": "Текст скрыт за предупреждением",
   "compose_form.spoiler.unmarked": "Текст не скрыт",
   "compose_form.spoiler_placeholder": "Текст предупреждения",
   "confirmation_modal.cancel": "Отмена",
+  "confirmations.block.block_and_report": "Заблокировать и пожаловаться",
   "confirmations.block.confirm": "Заблокировать",
   "confirmations.block.message": "Вы уверены, что хотите заблокировать {name}?",
   "confirmations.delete.confirm": "Удалить",
@@ -93,8 +97,8 @@
   "confirmations.mute.message": "Вы уверены, что хотите заглушить {name}?",
   "confirmations.redraft.confirm": "Удалить и исправить",
   "confirmations.redraft.message": "Вы уверены, что хотите удалить этот статус и превратить в черновик? Вы потеряете все ответы, продвижения и отметки 'нравится' к нему.",
-  "confirmations.reply.confirm": "Reply",
-  "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
+  "confirmations.reply.confirm": "Ответить",
+  "confirmations.reply.message": "При ответе текст набираемого сообщения будет перезаписан. Продолжить?",
   "confirmations.unfollow.confirm": "Отписаться",
   "confirmations.unfollow.message": "Вы уверены, что хотите отписаться от {name}?",
   "embed.instructions": "Встройте этот статус на Вашем сайте, скопировав код внизу.",
@@ -113,7 +117,8 @@
   "emoji_button.search_results": "Результаты поиска",
   "emoji_button.symbols": "Символы",
   "emoji_button.travel": "Путешествия",
-  "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_timeline": "Статусов нет!",
+  "empty_column.account_unavailable": "Профиль недоступен",
   "empty_column.blocks": "Вы ещё никого не заблокировали.",
   "empty_column.community": "Локальная лента пуста. Напишите что-нибудь, чтобы разогреть народ!",
   "empty_column.direct": "У Вас пока нет личных сообщений. Когда Вы начнёте их отправлять или получать, они появятся здесь.",
@@ -132,40 +137,45 @@
   "follow_request.authorize": "Авторизовать",
   "follow_request.reject": "Отказать",
   "getting_started.developers": "Для разработчиков",
-  "getting_started.directory": "Profile directory",
+  "getting_started.directory": "Каталог профилей",
   "getting_started.documentation": "Документация",
   "getting_started.heading": "Добро пожаловать",
   "getting_started.invite": "Пригласить людей",
   "getting_started.open_source_notice": "Mastodon - сервис с открытым исходным кодом. Вы можете помочь проекту или сообщить о проблемах на GitHub по адресу {github}.",
   "getting_started.security": "Безопасность",
   "getting_started.terms": "Условия использования",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
-  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "hashtag.column_header.tag_mode.all": "и {additional}",
+  "hashtag.column_header.tag_mode.any": "или {additional}",
+  "hashtag.column_header.tag_mode.none": "без {additional}",
+  "hashtag.column_settings.select.no_options_message": "Предложений не найдено",
+  "hashtag.column_settings.select.placeholder": "Введите хэштеги…",
+  "hashtag.column_settings.tag_mode.all": "Все из списка",
+  "hashtag.column_settings.tag_mode.any": "Любой из списка",
+  "hashtag.column_settings.tag_mode.none": "Ни один из списка",
+  "hashtag.column_settings.tag_toggle": "Включая дополнительные хэштеге из этой колонки",
   "home.column_settings.basic": "Основные",
   "home.column_settings.show_reblogs": "Показывать продвижения",
   "home.column_settings.show_replies": "Показывать ответы",
-  "introduction.federation.action": "Next",
-  "introduction.federation.federated.headline": "Federated",
-  "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
-  "introduction.federation.home.headline": "Home",
-  "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
-  "introduction.federation.local.headline": "Local",
-  "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
-  "introduction.interactions.favourite.headline": "Favourite",
-  "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
-  "introduction.interactions.reblog.headline": "Boost",
-  "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
-  "introduction.interactions.reply.headline": "Reply",
-  "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
-  "introduction.welcome.action": "Let's go!",
-  "introduction.welcome.headline": "First steps",
-  "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
+  "intervals.full.days": "{number, plural, one {# день} few {# дня} many {# дней} other {# дней}}",
+  "intervals.full.hours": "{number, plural, one {# час} few {# часа} many {# часов} other {# часов}}",
+  "intervals.full.minutes": "{number, plural, one {# минута} few {# минуты} many {# минут} other {# минут}}",
+  "introduction.federation.action": "Далее",
+  "introduction.federation.federated.headline": "Глобальная лента",
+  "introduction.federation.federated.text": "Публичные статусы с других серверов федеративной сети расположатся в глобальной ленте.",
+  "introduction.federation.home.headline": "Домашняя лента",
+  "introduction.federation.home.text": "Статусы от тех, на кого вы подписаны, появятся в вашей домашней ленте. Вы можете подписаться на кого угодно с любого сервера!",
+  "introduction.federation.local.headline": "Локальная лента",
+  "introduction.federation.local.text": "Публичные статусы от людей с того же сервера, что и вы, будут отображены в локальной ленте.",
+  "introduction.interactions.action": "Завершить обучение",
+  "introduction.interactions.favourite.headline": "Отметки \"нравится\"",
+  "introduction.interactions.favourite.text": "Вы можете отметить статус, чтобы вернуться к нему позже и дать знать автору, что запись вам понравилась, поставив отметку \"нравится\".",
+  "introduction.interactions.reblog.headline": "Продвижения",
+  "introduction.interactions.reblog.text": "Вы можете делиться статусами других людей, продвигая их в своём аккаунте.",
+  "introduction.interactions.reply.headline": "Ответы",
+  "introduction.interactions.reply.text": "Вы можете отвечать свои и чужие посты, образуя цепочки сообщений (обсуждения).",
+  "introduction.welcome.action": "Поехали!",
+  "introduction.welcome.headline": "Первые шаги",
+  "introduction.welcome.text": "Добро пожаловать в федеративную сеть! Уже через мгновение вы сможете отправлять сообщения и общаться со своими друзьями на любом сервере. Но этот сервер — {domain} — особенный: на нём располагается ваш профиль. Запомните его название.",
   "keyboard_shortcuts.back": "перейти назад",
   "keyboard_shortcuts.blocked": "чтобы открыть список заблокированных",
   "keyboard_shortcuts.boost": "продвинуть пост",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "перейти к поиску",
   "keyboard_shortcuts.start": "перейти к разделу \"добро пожаловать\"",
   "keyboard_shortcuts.toggle_hidden": "показать/скрыть текст за предупреждением",
+  "keyboard_shortcuts.toggle_sensitivity": "показать/скрыть медиафайлы",
   "keyboard_shortcuts.toot": "начать писать новый пост",
   "keyboard_shortcuts.unfocus": "убрать фокус с поля ввода/поиска",
   "keyboard_shortcuts.up": "вверх по списку",
   "lightbox.close": "Закрыть",
   "lightbox.next": "Далее",
   "lightbox.previous": "Назад",
+  "lightbox.view_context": "Контекст",
   "lists.account.add": "Добавить в список",
   "lists.account.remove": "Убрать из списка",
   "lists.delete": "Удалить список",
   "lists.edit": "Изменить список",
+  "lists.edit.submit": "Изменить название",
   "lists.new.create": "Новый список",
   "lists.new.title_placeholder": "Заголовок списка",
   "lists.search": "Искать из ваших подписок",
@@ -213,7 +226,7 @@
   "missing_indicator.label": "Не найдено",
   "missing_indicator.sublabel": "Запрашиваемый ресурс не найден",
   "mute_modal.hide_notifications": "Убрать уведомления от этого пользователя?",
-  "navigation_bar.apps": "Mobile apps",
+  "navigation_bar.apps": "Мобильные приложения",
   "navigation_bar.blocks": "Список блокировки",
   "navigation_bar.community_timeline": "Локальная лента",
   "navigation_bar.compose": "Создать новый статус",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "Понравившееся",
   "navigation_bar.filters": "Заглушенные слова",
   "navigation_bar.follow_requests": "Запросы на подписку",
+  "navigation_bar.follows_and_followers": "Подписки и подписчики",
   "navigation_bar.info": "Об узле",
   "navigation_bar.keyboard_shortcuts": "Сочетания клавиш",
   "navigation_bar.lists": "Списки",
@@ -232,31 +246,41 @@
   "navigation_bar.personal": "Личное",
   "navigation_bar.pins": "Закреплённые посты",
   "navigation_bar.preferences": "Опции",
+  "navigation_bar.profile_directory": "Каталог профилей",
   "navigation_bar.public_timeline": "Глобальная лента",
   "navigation_bar.security": "Безопасность",
   "notification.favourite": "{name} понравился Ваш статус",
   "notification.follow": "{name} подписался(-лась) на Вас",
   "notification.mention": "{name} упомянул(а) Вас",
+  "notification.poll": "Опрос, в котором вы приняли участие, завершился",
   "notification.reblog": "{name} продвинул(а) Ваш статус",
   "notifications.clear": "Очистить уведомления",
   "notifications.clear_confirmation": "Вы уверены, что хотите очистить все уведомления?",
   "notifications.column_settings.alert": "Десктопные уведомления",
   "notifications.column_settings.favourite": "Нравится:",
-  "notifications.column_settings.filter_bar.advanced": "Display all categories",
-  "notifications.column_settings.filter_bar.category": "Quick filter bar",
-  "notifications.column_settings.filter_bar.show": "Show",
+  "notifications.column_settings.filter_bar.advanced": "Отображать все категории",
+  "notifications.column_settings.filter_bar.category": "Фильтры по категориям",
+  "notifications.column_settings.filter_bar.show": "Показывать",
   "notifications.column_settings.follow": "Новые подписчики:",
   "notifications.column_settings.mention": "Упоминания:",
+  "notifications.column_settings.poll": "Результаты опроса:",
   "notifications.column_settings.push": "Push-уведомления",
   "notifications.column_settings.reblog": "Продвижения:",
   "notifications.column_settings.show": "Показывать в колонке",
   "notifications.column_settings.sound": "Проигрывать звук",
-  "notifications.filter.all": "All",
-  "notifications.filter.boosts": "Boosts",
-  "notifications.filter.favourites": "Favourites",
-  "notifications.filter.follows": "Follows",
-  "notifications.filter.mentions": "Mentions",
+  "notifications.filter.all": "Все",
+  "notifications.filter.boosts": "Продвижения",
+  "notifications.filter.favourites": "Отметки \"нравится\"",
+  "notifications.filter.follows": "Новые подписчики",
+  "notifications.filter.mentions": "Упоминания",
+  "notifications.filter.polls": "Результаты опросов",
   "notifications.group": "{count} уведомл.",
+  "poll.closed": "Завершён",
+  "poll.refresh": "Обновить",
+  "poll.total_votes": "{count, plural, one {# голос} few {# голоса} many {# голосов} other {# голосов}}",
+  "poll.vote": "Голосовать",
+  "poll_button.add_poll": "Добавить опрос",
+  "poll_button.remove_poll": "Удалить опрос",
   "privacy.change": "Изменить видимость статуса",
   "privacy.direct.long": "Показать только упомянутым",
   "privacy.direct.short": "Направленный",
@@ -274,12 +298,12 @@
   "relative_time.minutes": "{number}м",
   "relative_time.seconds": "{number}с",
   "reply_indicator.cancel": "Отмена",
-  "report.forward": "Переслать для {target}",
+  "report.forward": "Переслать в {target}",
   "report.forward_hint": "Этот аккаунт расположен на другом сервере. Отправить туда анонимную копию Вашей жалобы?",
   "report.hint": "Жалоба будет отправлена модераторам Вашего сервера. Вы также можете указать подробную причину жалобы ниже:",
   "report.placeholder": "Комментарий",
   "report.submit": "Отправить",
-  "report.target": "Жалуемся на {target}",
+  "report.target": "Жалоба на {target}",
   "search.placeholder": "Поиск",
   "search_popout.search_format": "Продвинутый формат поиска",
   "search_popout.tips.full_text": "Возвращает посты, которые Вы написали, отметили как 'избранное', продвинули или в которых были упомянуты, а также содержащие юзернейм, имя и хэштеги.",
@@ -291,12 +315,12 @@
   "search_results.hashtags": "Хэштеги",
   "search_results.statuses": "Посты",
   "search_results.total": "{count, number} {count, plural, one {результат} few {результата} many {результатов} other {результатов}}",
-  "standalone.public_title": "Прямо сейчас",
-  "status.admin_account": "Open moderation interface for @{name}",
-  "status.admin_status": "Open this status in the moderation interface",
+  "status.admin_account": "Открыть интерфейс модератора для @{name}",
+  "status.admin_status": "Открыть этот статус в интерфейсе модератора",
   "status.block": "Заблокировать @{name}",
   "status.cancel_reblog_private": "Не продвигать",
   "status.cannot_reblog": "Этот статус не может быть продвинут",
+  "status.copy": "Копировать ссылку на запись",
   "status.delete": "Удалить",
   "status.detailed_status": "Подробный просмотр обсуждения",
   "status.direct": "Написать @{name}",
@@ -308,11 +332,11 @@
   "status.mention": "Упомянуть @{name}",
   "status.more": "Больше",
   "status.mute": "Заглушить @{name}",
-  "status.mute_conversation": "Заглушить всю цепочку",
+  "status.mute_conversation": "Заглушить всё обсуждение",
   "status.open": "Развернуть статус",
   "status.pin": "Закрепить в профиле",
   "status.pinned": "Закреплённый статус",
-  "status.read_more": "Read more",
+  "status.read_more": "Ещё",
   "status.reblog": "Продвинуть",
   "status.reblog_private": "Продвинуть для своей аудитории",
   "status.reblogged_by": "{name} продвинул(а)",
@@ -321,27 +345,33 @@
   "status.reply": "Ответить",
   "status.replyAll": "Ответить всем",
   "status.report": "Пожаловаться",
-  "status.sensitive_toggle": "Нажмите для просмотра",
   "status.sensitive_warning": "Чувствительный контент",
   "status.share": "Поделиться",
   "status.show_less": "Свернуть",
   "status.show_less_all": "Свернуть для всех",
   "status.show_more": "Развернуть",
   "status.show_more_all": "Развернуть для всех",
-  "status.show_thread": "Show thread",
-  "status.unmute_conversation": "Снять глушение с треда",
+  "status.show_thread": "Показать обсуждение",
+  "status.unmute_conversation": "Снять глушение с обсуждения",
   "status.unpin": "Открепить от профиля",
-  "suggestions.dismiss": "Dismiss suggestion",
-  "suggestions.header": "You might be interested in…",
+  "suggestions.dismiss": "Удалить предложение",
+  "suggestions.header": "Вам может быть интересно…",
   "tabs_bar.federated_timeline": "Глобальная",
   "tabs_bar.home": "Главная",
   "tabs_bar.local_timeline": "Локальная",
   "tabs_bar.notifications": "Уведомления",
   "tabs_bar.search": "Поиск",
+  "time_remaining.days": "{number, plural, one {остался # день} few {осталось # дня} many {осталось # дней} other {осталось # дней}}",
+  "time_remaining.hours": "{number, plural, one {остался # час} few {осталось # часа} many {осталось # часов} other {осталось # часов}}",
+  "time_remaining.minutes": "{number, plural, one {осталась # минута} few {осталось # минуты} many {осталось # минут} other {осталось # минут}}",
+  "time_remaining.moments": "остались считанные мгновения",
+  "time_remaining.seconds": "{number, plural, one {осталась # секунду} few {осталось # секунды} many {осталось # секунд} other {осталось # секунд}}",
   "trends.count_by_accounts": "Популярно у {count} {rawCount, plural, one {человека} few {человек} many {человек} other {человек}}",
   "ui.beforeunload": "Ваш черновик будет утерян, если вы покинете Mastodon.",
   "upload_area.title": "Перетащите сюда, чтобы загрузить",
   "upload_button.label": "Добавить медиаконтент",
+  "upload_error.limit": "Достигнут лимит загруженных файлов.",
+  "upload_error.poll": "К опросам нельзя прикреплять файлы.",
   "upload_form.description": "Описать для людей с нарушениями зрения",
   "upload_form.focus": "Обрезать",
   "upload_form.undo": "Отменить",
diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json
index a3467785a434af2e084ef62365ac6718c23615ca..18993af97014a1d8ccac142e0d17c0b76be56508 100644
--- a/app/javascript/mastodon/locales/sk.json
+++ b/app/javascript/mastodon/locales/sk.json
@@ -1,53 +1,51 @@
 {
-  "account.add_or_remove_from_list": "Pridaj, alebo odstráň zo zoznamov",
+  "account.add_or_remove_from_list": "Pridaj do, alebo odober zo zoznamov",
   "account.badges.bot": "Bot",
   "account.block": "Blokuj @{name}",
   "account.block_domain": "Ukry všetko z {domain}",
   "account.blocked": "Blokovaný/á",
   "account.direct": "Súkromná správa pre @{name}",
-  "account.disclaimer_full": "Inofrmácie uvedené nižšie nemusia byť úplným odrazom uživateľovho účtu.",
   "account.domain_blocked": "Doména ukrytá",
-  "account.edit_profile": "Upraviť profil",
+  "account.edit_profile": "Uprav profil",
   "account.endorse": "Zobrazuj na profile",
   "account.follow": "Následuj",
   "account.followers": "Sledujúci",
   "account.followers.empty": "Tohto užívateľa ešte nikto nenásleduje.",
   "account.follows": "Následuje",
-  "account.follows.empty": "Tento užívateľ tu ešte nikoho nenásleduje.",
+  "account.follows.empty": "Tento užívateľ ešte nikoho nenásleduje.",
   "account.follows_you": "Následuje ťa",
-  "account.hide_reblogs": "Skryť povýšenia od @{name}",
+  "account.hide_reblogs": "Skry vyzdvihnutia od @{name}",
   "account.link_verified_on": "Vlastníctvo tohto odkazu bolo skontrolované {date}",
   "account.locked_info": "Stav súkromia pre tento účet je nastavený na zamknutý. Jeho vlastník sám prehodnocuje, kto ho môže sledovať.",
   "account.media": "Médiá",
   "account.mention": "Spomeň @{name}",
   "account.moved_to": "{name} sa presunul/a na:",
   "account.mute": "Ignorovať @{name}",
-  "account.mute_notifications": "Stĺmiť oboznámenia od @{name}",
+  "account.mute_notifications": "Stĺm oboznámenia od @{name}",
   "account.muted": "Utíšený/á",
   "account.posts": "Príspevky",
   "account.posts_with_replies": "Príspevky aj s odpoveďami",
   "account.report": "Nahlás @{name}",
-  "account.requested": "Čaká na schválenie. Kliknite pre zrušenie žiadosti",
-  "account.share": "Zdieľať @{name} profil",
+  "account.requested": "Čaká na schválenie. Klikni pre zrušenie žiadosti",
+  "account.share": "Zdieľaj @{name} profil",
   "account.show_reblogs": "Ukáž vyzdvihnutia od @{name}",
   "account.unblock": "Odblokuj @{name}",
   "account.unblock_domain": "Prestaň skrývať {domain}",
   "account.unendorse": "Nezobrazuj na profile",
   "account.unfollow": "Prestaň následovať",
   "account.unmute": "Prestaň ignorovať @{name}",
-  "account.unmute_notifications": "Odtĺm oboznámenia od @{name}",
-  "account.view_full_profile": "Pozri celý profil",
+  "account.unmute_notifications": "Zruš stĺmenie oboznámení od @{name}",
   "alert.unexpected.message": "Vyskytla sa nečakaná chyba.",
-  "alert.unexpected.title": "Oops!",
+  "alert.unexpected.title": "Ups!",
   "boost_modal.combo": "Nabudúce môžeš kliknúť {combo} pre preskočenie",
   "bundle_column_error.body": "Pri načítaní tohto prvku nastala nejaká chyba.",
   "bundle_column_error.retry": "Skús to znova",
   "bundle_column_error.title": "Chyba siete",
-  "bundle_modal_error.close": "Zatvoriť",
+  "bundle_modal_error.close": "Zatvor",
   "bundle_modal_error.message": "Nastala chyba pri načítaní tohto komponentu.",
   "bundle_modal_error.retry": "Skúsiť znova",
   "column.blocks": "Blokovaní užívatelia",
-  "column.community": "Lokálna časová os",
+  "column.community": "Miestna časová os",
   "column.direct": "Súkromné správy",
   "column.domain_blocks": "Skryté domény",
   "column.favourites": "Obľúbené",
@@ -60,60 +58,67 @@
   "column.public": "Federovaná časová os",
   "column_back_button.label": "Späť",
   "column_header.hide_settings": "Skryť nastavenia",
-  "column_header.moveLeft_settings": "Presunúť stĺpec doľava",
-  "column_header.moveRight_settings": "Presunúť stĺpec doprava",
-  "column_header.pin": "Pripnúť",
+  "column_header.moveLeft_settings": "Presuň stĺpec doľava",
+  "column_header.moveRight_settings": "Presuň stĺpec doprava",
+  "column_header.pin": "Pripni",
   "column_header.show_settings": "Ukáž nastavenia",
   "column_header.unpin": "Odopnúť",
   "column_subheading.settings": "Nastavenia",
-  "community.column_settings.media_only": "Iba media",
+  "community.column_settings.media_only": "Iba médiá",
   "compose_form.direct_message_warning": "Tento príspevok bude videný výhradne iba spomenutými užívateľmi. Ber ale na vedomie že správci tvojej a všetkých iných zahrnutých instancií majú možnosť skontrolovať túto správu.",
   "compose_form.direct_message_warning_learn_more": "Zistiť viac",
   "compose_form.hashtag_warning": "Tento toot nebude zobrazený pod žiadným haštagom lebo nieje listovaný. Iba verejné tooty môžu byť nájdené podľa haštagu.",
-  "compose_form.lock_disclaimer": "Váš účet nie je {locked}. Ktokoľvek ťa môže nasledovať a vidieť tvoje správy pre sledujúcich.",
+  "compose_form.lock_disclaimer": "Tvoj účet nie je {locked}. Ktokoľvek ťa môže nasledovať a vidieť tvoje správy pre sledujúcich.",
   "compose_form.lock_disclaimer.lock": "zamknutý",
   "compose_form.placeholder": "Čo máš na mysli?",
+  "compose_form.poll.add_option": "Pridaj voľbu",
+  "compose_form.poll.duration": "Trvanie ankety",
+  "compose_form.poll.option_placeholder": "Voľba {number}",
+  "compose_form.poll.remove_option": "Odstráň túto voľbu",
   "compose_form.publish": "Pošli",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Označ médiá ako chúlostivé",
   "compose_form.sensitive.marked": "Médiálny obsah je označený ako chúlostivý",
   "compose_form.sensitive.unmarked": "Médiálny obsah nieje označený ako chúlostivý",
   "compose_form.spoiler.marked": "Text je ukrytý za varovaním",
   "compose_form.spoiler.unmarked": "Text nieje ukrytý",
-  "compose_form.spoiler_placeholder": "Sem napíšte vaše varovanie",
-  "confirmation_modal.cancel": "Zrušiť",
-  "confirmations.block.confirm": "Blokovať",
-  "confirmations.block.message": "Si si istý, že chcete blokovať {name}?",
-  "confirmations.delete.confirm": "Zmazať",
-  "confirmations.delete.message": "Si si naozaj istá/ý, že chceš vymazať túto správu?",
-  "confirmations.delete_list.confirm": "Vymazať",
-  "confirmations.delete_list.message": "Si si istý/á, že chceš navždy vymazať tento zoznam?",
-  "confirmations.domain_block.confirm": "Skryť celú doménu",
-  "confirmations.domain_block.message": "Si si naozaj istý, že chceš blokovať celú {domain}? Vo väčšine prípadov stačí blokovať alebo ignorovať pár konkrétnych užívateľov, čo sa doporučuje. Neuvidíš obsah z tejto domény v žiadnej verejnej časovej osi, ani v oznámeniach. Tvoji následovníci pochádzajúci z tejto domény budú odstránení.",
+  "compose_form.spoiler_placeholder": "Sem napíš tvoje varovanie",
+  "confirmation_modal.cancel": "Zruš",
+  "confirmations.block.block_and_report": "Zablokuj a nahlás",
+  "confirmations.block.confirm": "Blokuj",
+  "confirmations.block.message": "Si si istý/á, že chceš blokovať {name}?",
+  "confirmations.delete.confirm": "Vymaž",
+  "confirmations.delete.message": "Si si istý/á, že chceš vymazať túto správu?",
+  "confirmations.delete_list.confirm": "Vymaž",
+  "confirmations.delete_list.message": "Si si istý/á, že chceš natrvalo vymazať tento zoznam?",
+  "confirmations.domain_block.confirm": "Skry celú doménu",
+  "confirmations.domain_block.message": "Si si naozaj istý/á, že chceš blokovať celú doménu {domain}? Vo väčšine prípadov stačí blokovať alebo ignorovať pár konkrétnych užívateľov, čo sa doporučuje. Neuvidíš obsah z tejto domény v žiadnej verejnej časovej osi, ani v oznámeniach. Tvoji následovníci pochádzajúci z tejto domény budú odstránení.",
   "confirmations.mute.confirm": "Ignoruj",
-  "confirmations.mute.message": "Naozaj chcete ignorovať {name}?",
-  "confirmations.redraft.confirm": "Vyčistiť a prepísať",
+  "confirmations.mute.message": "Naozaj chceš ignorovať {name}?",
+  "confirmations.redraft.confirm": "Vyčisti a prepíš",
   "confirmations.redraft.message": "Si si istý/á, že chceš premazať a prepísať tento príspevok? Jeho nadobudnuté vyzdvihnutia a obľúbenia, ale i odpovede na pôvodný príspevok budú odlúčené.",
   "confirmations.reply.confirm": "Odpovedz",
   "confirmations.reply.message": "Odpovedaním akurát teraz prepíšeš správu, ktorú máš práve rozpísanú. Si si istý/á, že chceš pokračovať?",
-  "confirmations.unfollow.confirm": "Nesledovať",
-  "confirmations.unfollow.message": "Naozaj chcete prestať sledovať {name}?",
+  "confirmations.unfollow.confirm": "Nesleduj",
+  "confirmations.unfollow.message": "Naozaj chceš prestať sledovať {name}?",
   "embed.instructions": "Umiestni kód uvedený nižšie pre pridanie tohto statusu na tvoju web stránku.",
   "embed.preview": "Tu je ako to bude vyzerať:",
   "emoji_button.activity": "Aktivita",
   "emoji_button.custom": "Vlastné",
   "emoji_button.flags": "Vlajky",
   "emoji_button.food": "Jedlá a nápoje",
-  "emoji_button.label": "Vložiť emotikony",
+  "emoji_button.label": "Vlož emotikony",
   "emoji_button.nature": "Prírodné",
   "emoji_button.not_found": "Nie emotikony!! (╯°□°)╯︵ ┻━┻",
   "emoji_button.objects": "Predmety",
   "emoji_button.people": "Ľudia",
   "emoji_button.recent": "Často používané",
-  "emoji_button.search": "Hľadať...",
+  "emoji_button.search": "Hľadaj...",
   "emoji_button.search_results": "Nájdené",
   "emoji_button.symbols": "Symboly",
   "emoji_button.travel": "Cestovanie a miesta",
   "empty_column.account_timeline": "Niesú tu žiadne príspevky!",
+  "empty_column.account_unavailable": "Profil nedostupný",
   "empty_column.blocks": "Ešte si nikoho nezablokoval/a.",
   "empty_column.community": "Lokálna časová os je prázdna. Napíšte niečo, aby sa to tu začalo hýbať!",
   "empty_column.direct": "Ešte nemáš žiadne súkromné správy. Keď nejakú pošleš, alebo dostaneš, ukáže sa tu.",
@@ -128,7 +133,7 @@
   "empty_column.lists": "Nemáš ešte žiadne zoznamy. Keď nejaký vytvoríš, bude zobrazený práve tu.",
   "empty_column.mutes": "Ešte si nestĺmil žiadných užívateľov.",
   "empty_column.notifications": "Ešte nemáš žiadne oznámenia. Začni komunikovať s ostatnými, aby diskusia mohla začať.",
-  "empty_column.public": "Ešte tu nič nie je. Napíš niečo verejne, alebo začni sledovať užívateľov z iných Mastodon serverov, aby tu niečo pribudlo",
+  "empty_column.public": "Ešte tu nič nie je. Napíš niečo verejne, alebo začni sledovať užívateľov z iných serverov, aby tu niečo pribudlo",
   "follow_request.authorize": "Povoľ prístup",
   "follow_request.reject": "Odmietni",
   "getting_started.developers": "Vývojári",
@@ -142,161 +147,180 @@
   "hashtag.column_header.tag_mode.all": "a {additional}",
   "hashtag.column_header.tag_mode.any": "alebo {additional}",
   "hashtag.column_header.tag_mode.none": "bez {additional}",
+  "hashtag.column_settings.select.no_options_message": "Žiadne návrhy neboli nájdené",
+  "hashtag.column_settings.select.placeholder": "Zadaj haštagy…",
   "hashtag.column_settings.tag_mode.all": "Všetky tieto",
   "hashtag.column_settings.tag_mode.any": "Hociktorý z týchto",
   "hashtag.column_settings.tag_mode.none": "Žiaden z týchto",
-  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "hashtag.column_settings.tag_toggle": "Vlož dodatočné haštagy pre tento stĺpec",
   "home.column_settings.basic": "Základné",
   "home.column_settings.show_reblogs": "Zobraziť povýšené",
   "home.column_settings.show_replies": "Ukázať odpovede",
+  "intervals.full.days": "{number, plural, one {# deň} few {# dní} many {# dní} other {# dni}}",
+  "intervals.full.hours": "{number, plural, one {# hodina} few {# hodín} many {# hodín} other {# hodiny}}",
+  "intervals.full.minutes": "{number, plural, one {# minúta} few {# minút} many {# minút} other {# minúty}}",
   "introduction.federation.action": "ÄŽalej",
-  "introduction.federation.federated.headline": "Federated",
-  "introduction.federation.federated.text": "Verejné príspevky z ostatných serverov vo fediverse budú zobrazenie vo federovanej časovej osi.",
-  "introduction.federation.home.headline": "Home",
+  "introduction.federation.federated.headline": "Federovaná",
+  "introduction.federation.federated.text": "Verejné príspevky z ostatných serverov vo fediverse budú zobrazené vo federovanej časovej osi.",
+  "introduction.federation.home.headline": "Domovská",
   "introduction.federation.home.text": "Príspevky od ľudí ktorých následuješ sa zobrazia na tvojej domovskej nástenke. Môžeš následovať hocikoho na ktoromkoľvek serveri!",
-  "introduction.federation.local.headline": "Local",
+  "introduction.federation.local.headline": "Miestna",
   "introduction.federation.local.text": "Verejné príspevky od ľudí v rámci toho istého serveru na akom si aj ty, budú zobrazované na miestnej časovej osi.",
   "introduction.interactions.action": "Ukonči návod!",
   "introduction.interactions.favourite.headline": "Obľúbené",
   "introduction.interactions.favourite.text": "Obľúbením si môžeš príspevok uložiť na neskôr, a zároveň dať jeho autorovi vedieť, že sa ti páčil.",
-  "introduction.interactions.reblog.headline": "Povýš",
+  "introduction.interactions.reblog.headline": "Vyzdvihni",
   "introduction.interactions.reblog.text": "Môžeš zdieľať príspevky iných ľudí s vašimi následovateľmi tým, že ich povýšiš.",
   "introduction.interactions.reply.headline": "Odpovedz",
-  "introduction.interactions.reply.text": "Odpovedať môžeš na príspevky iných ľudí, aj na svoje vlastné, čím sa sspolu prepoja do konverzácie.",
+  "introduction.interactions.reply.text": "Odpovedať môžeš na príspevky iných ľudí, aj na svoje vlastné, čím sa spolu prepoja do konverzácie.",
   "introduction.welcome.action": "Poďme do toho!",
   "introduction.welcome.headline": "Prvé kroky",
   "introduction.welcome.text": "Vitaj vo fediverse! Za malú chvíľu budeš môcť posielať správy a rozpovedať sa so svojími priateľmi cez širokú škálu rôznorodých serverov. Ale tento server, {domain}, je špeciálny v tom, že ukladá tvoj profil, takže si jeho názov zapametaj.",
   "keyboard_shortcuts.back": "dostať sa naspäť",
   "keyboard_shortcuts.blocked": "otvor zoznam blokovaných užívateľov",
   "keyboard_shortcuts.boost": "vyzdvihnúť",
-  "keyboard_shortcuts.column": "zamerať sa na status v jednom zo stĺpcov",
-  "keyboard_shortcuts.compose": "zamerať sa na písaciu plochu",
+  "keyboard_shortcuts.column": "zameraj sa na príspevok v jednom zo stĺpcov",
+  "keyboard_shortcuts.compose": "zameraj sa na písaciu plochu",
   "keyboard_shortcuts.description": "Popis",
   "keyboard_shortcuts.direct": "otvor panel súkromných správ",
   "keyboard_shortcuts.down": "posunúť sa dole v zozname",
   "keyboard_shortcuts.enter": "otvoriť správu",
-  "keyboard_shortcuts.favourite": "pridať do obľúbených",
+  "keyboard_shortcuts.favourite": "pridaj do obľúbených",
   "keyboard_shortcuts.favourites": "otvor zoznam obľúbených",
   "keyboard_shortcuts.federated": "otvor federovanú časovú os",
   "keyboard_shortcuts.heading": "Klávesové skratky",
   "keyboard_shortcuts.home": "otvor domácu časovú os",
   "keyboard_shortcuts.hotkey": "Klávesa",
-  "keyboard_shortcuts.legend": "zobraziť túto legendu",
+  "keyboard_shortcuts.legend": "zobraz túto legendu",
   "keyboard_shortcuts.local": "otvor miestnu časovú os",
-  "keyboard_shortcuts.mention": "spomenúť autora",
+  "keyboard_shortcuts.mention": "spomeň autora",
   "keyboard_shortcuts.muted": "otvor zoznam stíšených užívateľov",
   "keyboard_shortcuts.my_profile": "otvor svoj profil",
   "keyboard_shortcuts.notifications": "otvor panel oboznámení",
   "keyboard_shortcuts.pinned": "otvor zoznam pripnutých príspevkov",
   "keyboard_shortcuts.profile": "otvor autorov profil",
   "keyboard_shortcuts.reply": "odpovedať",
-  "keyboard_shortcuts.requests": "otvor zoznam požiadavok k následovaniu",
-  "keyboard_shortcuts.search": "zamerať sa na vyhľadávanie",
+  "keyboard_shortcuts.requests": "otvor zoznam žiadostí o sledovanie",
+  "keyboard_shortcuts.search": "zameraj sa na vyhľadávanie",
   "keyboard_shortcuts.start": "otvor panel ''začíname''",
   "keyboard_shortcuts.toggle_hidden": "ukáž/skry text za CW",
-  "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ť",
+  "keyboard_shortcuts.toggle_sensitivity": "pre zobrazenie/skrytie médií",
+  "keyboard_shortcuts.toot": "začni úplne nový príspevok",
+  "keyboard_shortcuts.unfocus": "nesústreď sa na písaciu plochu, alebo hľadanie",
+  "keyboard_shortcuts.up": "posuň sa vyššie v zozname",
+  "lightbox.close": "Zatvor",
   "lightbox.next": "Ďalšie",
   "lightbox.previous": "Predchádzajúci",
-  "lists.account.add": "Pridať do zoznamu",
-  "lists.account.remove": "Odobrať zo zoznamu",
-  "lists.delete": "Vymazať list",
+  "lightbox.view_context": "Ukáž kontext",
+  "lists.account.add": "Pridaj do zoznamu",
+  "lists.account.remove": "Odober zo zoznamu",
+  "lists.delete": "Vymaž list",
   "lists.edit": "Uprav zoznam",
+  "lists.edit.submit": "Zmeň názov",
   "lists.new.create": "Pridaj zoznam",
   "lists.new.title_placeholder": "Názov nového zoznamu",
-  "lists.search": "Vyhľadávajte medzi užívateľmi ktorých sledujete",
+  "lists.search": "Vyhľadávaj medzi užívateľmi, ktorých sleduješ",
   "lists.subheading": "Tvoje zoznamy",
   "loading_indicator.label": "Načítam...",
-  "media_gallery.toggle_visible": "Zapnúť/Vypnúť viditeľnosť",
+  "media_gallery.toggle_visible": "Zapni/Vypni viditeľnosť",
   "missing_indicator.label": "Nenájdené",
   "missing_indicator.sublabel": "Tento zdroj sa ešte nepodarilo nájsť",
-  "mute_modal.hide_notifications": "Skryť oboznámenia od tohoto užívateľa?",
-  "navigation_bar.apps": "Mobilné aplikácie",
+  "mute_modal.hide_notifications": "Skry oznámenia od tohto používateľa?",
+  "navigation_bar.apps": "Aplikácie",
   "navigation_bar.blocks": "Blokovaní užívatelia",
-  "navigation_bar.community_timeline": "Lokálna časová os",
+  "navigation_bar.community_timeline": "Miestna časová os",
   "navigation_bar.compose": "Napíš nový príspevok",
   "navigation_bar.direct": "Súkromné správy",
   "navigation_bar.discover": "Objavuj",
   "navigation_bar.domain_blocks": "Skryté domény",
   "navigation_bar.edit_profile": "Uprav profil",
   "navigation_bar.favourites": "Obľúbené",
-  "navigation_bar.filters": "Utĺmené slová",
+  "navigation_bar.filters": "Filtrované slová",
   "navigation_bar.follow_requests": "Žiadosti o sledovanie",
-  "navigation_bar.info": "O tomto Mastodon serveri",
+  "navigation_bar.follows_and_followers": "Následovaní a sledovatelia",
+  "navigation_bar.info": "O tomto serveri",
   "navigation_bar.keyboard_shortcuts": "Klávesové skratky",
   "navigation_bar.lists": "Zoznamy",
   "navigation_bar.logout": "Odhlás sa",
   "navigation_bar.mutes": "Ignorovaní užívatelia",
   "navigation_bar.personal": "Osobné",
-  "navigation_bar.pins": "Pripnuté tooty",
+  "navigation_bar.pins": "Pripnuté príspevky",
   "navigation_bar.preferences": "Voľby",
+  "navigation_bar.profile_directory": "Katalóg profilov",
   "navigation_bar.public_timeline": "Federovaná časová os",
   "navigation_bar.security": "Zabezbečenie",
-  "notification.favourite": "{name} sa páči tvoj status",
+  "notification.favourite": "{name} si obľúbil/a tvoj príspevok",
   "notification.follow": "{name} ťa začal/a následovať",
   "notification.mention": "{name} ťa spomenul/a",
-  "notification.reblog": "{name} zdieľal/a tvoj status",
-  "notifications.clear": "Vyčistiť zoznam notifikácii",
-  "notifications.clear_confirmation": "Naozaj chcete nenávratne prečistiť všetky vaše notifikácie?",
-  "notifications.column_settings.alert": "Notifikácie na ploche",
+  "notification.poll": "Anketa v ktorej si hlasoval/a sa skončila",
+  "notification.reblog": "{name} zdieľal/a tvoj príspevok",
+  "notifications.clear": "Vyčistiť zoznam oboznámení",
+  "notifications.clear_confirmation": "Naozaj chceš nenávratne prečistiť všetky tvoje oboznámenia?",
+  "notifications.column_settings.alert": "Oboznámenia na ploche",
   "notifications.column_settings.favourite": "Obľúbené:",
   "notifications.column_settings.filter_bar.advanced": "Zobraz všetky kategórie",
   "notifications.column_settings.filter_bar.category": "Rýchle triedenie",
   "notifications.column_settings.filter_bar.show": "Ukáž",
-  "notifications.column_settings.follow": "Noví následujúci:",
+  "notifications.column_settings.follow": "Noví sledujúci:",
   "notifications.column_settings.mention": "Zmienenia:",
+  "notifications.column_settings.poll": "Výsledky ankiet:",
   "notifications.column_settings.push": "Push notifikácie",
-  "notifications.column_settings.reblog": "Boosty:",
-  "notifications.column_settings.show": "Zobraziť v stĺpci",
-  "notifications.column_settings.sound": "Prehrať zvuk",
+  "notifications.column_settings.reblog": "Vyzdvihnutia:",
+  "notifications.column_settings.show": "Zobraz v stĺpci",
+  "notifications.column_settings.sound": "Prehraj zvuk",
   "notifications.filter.all": "Všetky",
   "notifications.filter.boosts": "Vyzdvihnutia",
   "notifications.filter.favourites": "Obľúbené",
   "notifications.filter.follows": "Sledovania",
-  "notifications.filter.mentions": "Spomenutia",
-  "notifications.group": "{count} oznámenia",
-  "privacy.change": "Zmeňiť viditeľnosť statusu",
-  "privacy.direct.long": "Poslať priamo iba spomenutým používateľom",
+  "notifications.filter.mentions": "Iba spomenutia",
+  "notifications.filter.polls": "Výsledky ankiet",
+  "notifications.group": "{count} oboznámení",
+  "poll.closed": "Uzatvorená",
+  "poll.refresh": "Aktualizuj",
+  "poll.total_votes": "{count, plural, one {# hlas} few {# hlasov} many {# hlasov} other {# hlasy}}",
+  "poll.vote": "Hlasuj",
+  "poll_button.add_poll": "Pridaj anketu",
+  "poll_button.remove_poll": "Odstráň anketu",
+  "privacy.change": "Uprav súkromie príspevku",
+  "privacy.direct.long": "Pošli iba spomenutým užívateľom",
   "privacy.direct.short": "Súkromne",
-  "privacy.private.long": "Poslať iba následovateľom",
+  "privacy.private.long": "Pošli iba následovateľom",
   "privacy.private.short": "Iba pre sledujúcich",
-  "privacy.public.long": "Poslať všetkým verejne",
+  "privacy.public.long": "Pošli všetkým verejne",
   "privacy.public.short": "Verejné",
-  "privacy.unlisted.long": "Neposielať do verejných časových osí",
+  "privacy.unlisted.long": "Neposielaj do verejných časových osí",
   "privacy.unlisted.short": "Verejne, ale nezobraziť v osi",
   "regeneration_indicator.label": "Načítava sa…",
   "regeneration_indicator.sublabel": "Vaša domovská nástenka sa pripravuje!",
-  "relative_time.days": "{number}d",
-  "relative_time.hours": "{number}h",
+  "relative_time.days": "{number}dní",
+  "relative_time.hours": "{number}hod",
   "relative_time.just_now": "teraz",
-  "relative_time.minutes": "{number}m",
-  "relative_time.seconds": "{number}s",
+  "relative_time.minutes": "{number}min",
+  "relative_time.seconds": "{number}sek",
   "reply_indicator.cancel": "Zrušiť",
   "report.forward": "Posuň ku {target}",
-  "report.forward_hint": "Tento účet je z iného serveru. Chceš poslať anonymnú kópiu reportu aj tam?",
-  "report.hint": "Toto nahlásenie bude zaslané správcom servera. Môžeš napísať odvôvodnenie prečo si nahlásil/a tento účet:",
+  "report.forward_hint": "Tento účet je z iného serveru. Chceš poslať anonymnú kópiu hlásenia aj tam?",
+  "report.hint": "Toto nahlásenie bude zaslané správcom tvojho servera. Môžeš napísať odvôvodnenie, prečo nahlasuješ tento účet:",
   "report.placeholder": "Ďalšie komentáre",
-  "report.submit": "Poslať",
-  "report.target": "Nahlásenie {target}",
+  "report.submit": "Odošli",
+  "report.target": "Nahlás {target}",
   "search.placeholder": "Hľadaj",
   "search_popout.search_format": "Pokročilé vyhľadávanie",
-  "search_popout.tips.full_text": "Jednoduchý textový výpis statusov ktoré si napísal/a, ktoré si obľúbil/a, povýšil/a, alebo aj tých, v ktorých si bol/a spomenutý/á, a potom všetky zadaniu odpovedajúce prezívky, mená a haštagy.",
+  "search_popout.tips.full_text": "Vráti jednoduchý textový výpis príspevkov ktoré si napísal/a, ktoré si obľúbil/a, povýšil/a, alebo aj tých, v ktorých si bol/a spomenutý/á, a potom všetky zadaniu odpovedajúce prezívky, mená a haštagy.",
   "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_popout.tips.status": "príspevok",
+  "search_popout.tips.text": "Vráti jednoduchý textový výpis zhodujúcich sa mien, prezývok a haštagov",
+  "search_popout.tips.user": "užívateľ",
   "search_results.accounts": "Ľudia",
   "search_results.hashtags": "Haštagy",
   "search_results.statuses": "Príspevky",
   "search_results.total": "{count, number} {count, plural, one {výsledok} many {výsledkov} other {výsledky}}",
-  "standalone.public_title": "Náhľad dovnútra...",
   "status.admin_account": "Otvor moderovacie rozhranie užívateľa @{name}",
   "status.admin_status": "Otvor tento príspevok v moderovacom rozhraní",
-  "status.block": "Blokovať @{name}",
+  "status.block": "Blokuj @{name}",
   "status.cancel_reblog_private": "Nezdieľaj",
-  "status.cannot_reblog": "Tento príspevok nemôže byť re-tootnutý",
+  "status.cannot_reblog": "Tento príspevok nemôže byť zdieľaný",
+  "status.copy": "Skopíruj odkaz na príspevok",
   "status.delete": "Zmazať",
   "status.detailed_status": "Podrobný náhľad celej konverzácie",
   "status.direct": "Súkromná správa @{name}",
@@ -307,23 +331,22 @@
   "status.media_hidden": "Skryté médiá",
   "status.mention": "Spomeň @{name}",
   "status.more": "Viac",
-  "status.mute": "Utíšiť @{name}",
-  "status.mute_conversation": "Ignorovať konverzáciu",
-  "status.open": "Otvoriť tento status",
+  "status.mute": "Utíš @{name}",
+  "status.mute_conversation": "Ignoruj konverzáciu",
+  "status.open": "Otvor tento príspevok",
   "status.pin": "Pripni na profil",
   "status.pinned": "Pripnutý príspevok",
   "status.read_more": "Čítaj ďalej",
-  "status.reblog": "Povýšiť",
-  "status.reblog_private": "Povýš k pôvodnému publiku",
+  "status.reblog": "Vyzdvihni",
+  "status.reblog_private": "Vyzdvihni k pôvodnému publiku",
   "status.reblogged_by": "{name} povýšil/a",
-  "status.reblogs.empty": "Nikto ešte nepovýšil tento príspevok. Keď tak niekto urobí, bude to zobrazené práve tu.",
+  "status.reblogs.empty": "Nikto ešte nevyzdvihol tento príspevok. Keď tak niekto urobí, bude to zobrazené práve tu.",
   "status.redraft": "Vymaž a prepíš",
   "status.reply": "Odpovedať",
-  "status.replyAll": "Odpovedať na diskusiu",
-  "status.report": "Nahlásiť @{name}",
-  "status.sensitive_toggle": "Klikni pre zobrazenie",
+  "status.replyAll": "Odpovedz na diskusiu",
+  "status.report": "Nahlás @{name}",
   "status.sensitive_warning": "Chúlostivý obsah",
-  "status.share": "Zdieľať",
+  "status.share": "Zdieľaj",
   "status.show_less": "Zobraz menej",
   "status.show_less_all": "Všetkým ukáž menej",
   "status.show_more": "Ukáž viac",
@@ -334,25 +357,32 @@
   "suggestions.dismiss": "Zavrhni návrh",
   "suggestions.header": "Mohlo by ťa zaujímať…",
   "tabs_bar.federated_timeline": "Federovaná",
-  "tabs_bar.home": "Domov",
-  "tabs_bar.local_timeline": "Lokálna",
-  "tabs_bar.notifications": "Notifikácie",
+  "tabs_bar.home": "Domovská",
+  "tabs_bar.local_timeline": "Miestna",
+  "tabs_bar.notifications": "Oboznámenia",
   "tabs_bar.search": "Hľadaj",
+  "time_remaining.days": "Ostáva {number, plural, one {# deň} few {# dní} many {# dní} other {# dni}}",
+  "time_remaining.hours": "Ostáva {number, plural, one {# hodina} few {# hodín} many {# hodín} other {# hodiny}}",
+  "time_remaining.minutes": "Ostáva {number, plural, one {# minúta} few {# minút} many {# minút} other {# minúty}}",
+  "time_remaining.moments": "Ostáva už iba chviľka",
+  "time_remaining.seconds": "Ostáva {number, plural, one {# sekunda} few {# sekúnd} many {# sekúnd} other {# sekundy}}",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {človek vraví} other {ľudia vravia}}",
   "ui.beforeunload": "Čo máš rozpísané sa stratí, ak opustíš Mastodon.",
   "upload_area.title": "Pretiahni a pusť pre nahratie",
-  "upload_button.label": "Pridať médiálny súbor (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_button.label": "Pridaj médiálny súbor (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "Limit pre nahrávanie súborov bol prekročený.",
+  "upload_error.poll": "Nahrávanie súborov pri anketách nieje možné.",
   "upload_form.description": "Opis pre slabo vidiacich",
   "upload_form.focus": "Pozmeň náhľad",
   "upload_form.undo": "Vymaž",
   "upload_progress.label": "Nahráva sa...",
-  "video.close": "Zavrieť video",
-  "video.exit_fullscreen": "Vpnúť zobrazenie na celú obrazovku",
-  "video.expand": "Zväčšiť video",
-  "video.fullscreen": "Zobraziť na celú obrazovku",
-  "video.hide": "Skryť video",
-  "video.mute": "Vypnúť zvuk",
+  "video.close": "Zavri video",
+  "video.exit_fullscreen": "Vypni zobrazenie na celú obrazovku",
+  "video.expand": "Zväčši video",
+  "video.fullscreen": "Zobraz na celú obrazovku",
+  "video.hide": "Skry video",
+  "video.mute": "Vypni zvuk",
   "video.pause": "Pauza",
-  "video.play": "Prehrať",
-  "video.unmute": "Zapnúť zvuk"
+  "video.play": "Prehraj",
+  "video.unmute": "Zapni zvuk"
 }
diff --git a/app/javascript/mastodon/locales/sl.json b/app/javascript/mastodon/locales/sl.json
index cabad737d65871292ed0e92032a208c08f6377d6..51794a862502b3227b5cdd6a6956880d2b291336 100644
--- a/app/javascript/mastodon/locales/sl.json
+++ b/app/javascript/mastodon/locales/sl.json
@@ -1,11 +1,10 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "Dodaj ali odstrani iz seznama",
   "account.badges.bot": "Robot",
   "account.block": "Blokiraj @{name}",
   "account.block_domain": "Skrij vse iz {domain}",
   "account.blocked": "Blokirano",
   "account.direct": "Neposredno sporočilo @{name}",
-  "account.disclaimer_full": "Spodnje informacije lahko nepopolno prikazujejo profil uporabnika.",
   "account.domain_blocked": "Skrita domena",
   "account.edit_profile": "Uredi profil",
   "account.endorse": "Zmožnost profila",
@@ -14,10 +13,10 @@
   "account.followers.empty": "Nihče ne sledi temu uporabniku.",
   "account.follows": "Sledi",
   "account.follows.empty": "Ta uporabnik še ne sledi nikomur.",
-  "account.follows_you": "Ti sledi",
-  "account.hide_reblogs": "Skrij sunke od @{name}",
+  "account.follows_you": "Sledi tebi",
+  "account.hide_reblogs": "Skrij spodbude od @{name}",
   "account.link_verified_on": "Lastništvo te povezave je bilo preverjeno {date}",
-  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
+  "account.locked_info": "Stanje zasebnosti računa je nastavljeno na zaklenjeno. Lastnik ročno pregleda, kdo ga lahko spremlja.",
   "account.media": "Mediji",
   "account.mention": "Omeni @{name}",
   "account.moved_to": "{name} se je premaknil na:",
@@ -29,17 +28,16 @@
   "account.report": "Prijavi @{name}",
   "account.requested": "Čakanje na odobritev. Kliknite, da prekličete prošnjo za sledenje",
   "account.share": "Delite profil osebe @{name}",
-  "account.show_reblogs": "Pokaži delitve osebe @{name}",
+  "account.show_reblogs": "Pokaži spodbude osebe @{name}",
   "account.unblock": "Odblokiraj @{name}",
   "account.unblock_domain": "Razkrij {domain}",
-  "account.unendorse": "Don't feature on profile",
+  "account.unendorse": "Ne vključi v profil",
   "account.unfollow": "Prenehaj slediti",
   "account.unmute": "Odtišaj @{name}",
   "account.unmute_notifications": "Vklopi obvestila od @{name}",
-  "account.view_full_profile": "Ogled celotnega profila",
   "alert.unexpected.message": "Zgodila se je nepričakovana napaka.",
   "alert.unexpected.title": "Uups!",
-  "boost_modal.combo": "Če želite naslednjič preskočiti to, lahko pritisnete {combo}",
+  "boost_modal.combo": "Če želite preskočiti to, lahko pritisnete {combo}",
   "bundle_column_error.body": "Med nalaganjem te komponente je prišlo do napake.",
   "bundle_column_error.retry": "Poskusi ponovno",
   "bundle_column_error.title": "Napaka omrežja",
@@ -69,43 +67,49 @@
   "community.column_settings.media_only": "Samo mediji",
   "compose_form.direct_message_warning": "Ta tut bo viden le vsem omenjenim uporabnikom.",
   "compose_form.direct_message_warning_learn_more": "Nauči se več",
-  "compose_form.hashtag_warning": "Ta tut ne bo naveden pod nobenim hashtagom, ker ni dodan hashtag. Samo javne tute lahko iščete pod hashtagom.",
+  "compose_form.hashtag_warning": "Ta tut ne bo naveden pod nobenim ključnikom, ker ni javen. Samo javne tute lahko iščete s ključniki.",
   "compose_form.lock_disclaimer": "Vaš račun ni {locked}. Vsakdo vam lahko sledi in si ogleda objave, ki so namenjene samo sledilcem.",
   "compose_form.lock_disclaimer.lock": "zaklenjen",
   "compose_form.placeholder": "O čem razmišljaš?",
+  "compose_form.poll.add_option": "Dodaj izbiro",
+  "compose_form.poll.duration": "Trajanje ankete",
+  "compose_form.poll.option_placeholder": "Izbira {number}",
+  "compose_form.poll.remove_option": "Odstrani to izbiro",
   "compose_form.publish": "Tutni",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Označi medij kot občutljiv",
   "compose_form.sensitive.marked": "Medij je označen kot občutljiv",
   "compose_form.sensitive.unmarked": "Medij ni označen kot občutljiv",
   "compose_form.spoiler.marked": "Besedilo je skrito za opozorilom",
   "compose_form.spoiler.unmarked": "Besedilo ni skrito",
-  "compose_form.spoiler_placeholder": "Napišite opozorilo tukaj",
+  "compose_form.spoiler_placeholder": "Tukaj napišite opozorilo",
   "confirmation_modal.cancel": "Prekliči",
-  "confirmations.block.confirm": "Block",
+  "confirmations.block.block_and_report": "Blokiraj in Prijavi",
+  "confirmations.block.confirm": "Blokiraj",
   "confirmations.block.message": "Ali ste prepričani, da želite blokirati {name}?",
-  "confirmations.delete.confirm": "Delete",
+  "confirmations.delete.confirm": "Izbriši",
   "confirmations.delete.message": "Ali ste prepričani, da želite izbrisati to stanje?",
-  "confirmations.delete_list.confirm": "Delete",
+  "confirmations.delete_list.confirm": "Izbriši",
   "confirmations.delete_list.message": "Ali ste prepričani, da želite trajno izbrisati ta seznam?",
   "confirmations.domain_block.confirm": "Skrij celotno domeno",
-  "confirmations.domain_block.message": "Ali ste res, res prepričani, da želite blokirati celotno {domain}? V večini primerov je nekaj ciljnih blokiranj ali utišanj dovolj in boljše.",
+  "confirmations.domain_block.message": "Ali ste res, res prepričani, da želite blokirati celotno {domain}? V večini primerov je nekaj ciljnih blokiranj ali utišanj dovolj in boljše. Vsebino iz te domene ne boste videli v javnih časovnicah ali obvestilih. Vaši sledilci iz te domene bodo odstranjeni.",
   "confirmations.mute.confirm": "Utišanje",
   "confirmations.mute.message": "Ali ste prepričani, da želite utišati {name}?",
   "confirmations.redraft.confirm": "Izbriši in preoblikuj",
-  "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.",
-  "confirmations.reply.confirm": "Reply",
+  "confirmations.redraft.message": "Ali ste prepričani, da želite izbrisati ta status in ga preoblikovati? Vzljubi in spodbude bodo izgubljeni, odgovori na izvirno objavo pa bodo osiroteli.",
+  "confirmations.reply.confirm": "Odgovori",
   "confirmations.reply.message": "Odgovarjanje bo prepisalo sporočilo, ki ga trenutno sestavljate. Ali ste prepričani, da želite nadaljevati?",
   "confirmations.unfollow.confirm": "Prenehaj slediti",
   "confirmations.unfollow.message": "Ali ste prepričani, da ne želite več slediti {name}?",
   "embed.instructions": "Vstavi ta status na svojo spletno stran tako, da kopirate spodnjo kodo.",
-  "embed.preview": "Tukaj je, kako bo izgledalo:",
+  "embed.preview": "Tako bo izgledalo:",
   "emoji_button.activity": "Dejavnost",
   "emoji_button.custom": "Po meri",
   "emoji_button.flags": "Zastave",
   "emoji_button.food": "Hrana in Pijača",
-  "emoji_button.label": "Vstavi emojija",
+  "emoji_button.label": "Vstavi emotikon",
   "emoji_button.nature": "Narava",
-  "emoji_button.not_found": "Ni emojijev!! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.not_found": "Ni emotikonov!! (╯°□°)╯︵ ┻━┻",
   "emoji_button.objects": "Predmeti",
   "emoji_button.people": "Ljudje",
   "emoji_button.recent": "Pogosto uporabljeni",
@@ -113,215 +117,234 @@
   "emoji_button.search_results": "Rezultati iskanja",
   "emoji_button.symbols": "Simboli",
   "emoji_button.travel": "Potovanja in Kraji",
-  "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_timeline": "Tukaj ni tutov!",
+  "empty_column.account_unavailable": "Profil ni na voljo",
   "empty_column.blocks": "Niste še blokirali nobenega uporabnika.",
   "empty_column.community": "Lokalna časovnica je prazna. Napišite nekaj javnega, da se bo žoga zakotalila!",
-  "empty_column.direct": "Nimate še nobenih neposrednih sporočil. Ko ga pošljete ali prejmete, se prikaže tukaj.",
+  "empty_column.direct": "Nimate še nobenih neposrednih sporočil. Ko ga boste poslali ali prejeli, se bo prikazal tukaj.",
   "empty_column.domain_blocks": "Å e vedno ni skritih domen.",
-  "empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.",
-  "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.",
-  "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
-  "empty_column.hashtag": "V tem hashtagu še ni nič.",
+  "empty_column.favourited_statuses": "Nimate priljubljenih tutov. Ko boste vzljubili kakšnega, se bo prikazal tukaj.",
+  "empty_column.favourites": "Nihče še ni vzljubil tega tuta. Ko ga bo nekdo, se bo pojavil tukaj.",
+  "empty_column.follow_requests": "Nimate prošenj za sledenje. Ko boste prejeli kakšno, se bo prikazala tukaj.",
+  "empty_column.hashtag": "V tem ključniku še ni nič.",
   "empty_column.home": "Vaša domača časovnica je prazna! Obiščite {public} ali uporabite iskanje, da se boste srečali druge uporabnike.",
   "empty_column.home.public_timeline": "javna časovnica",
   "empty_column.list": "Na tem seznamu ni ničesar. Ko bodo člani tega seznama objavili nove statuse, se bodo pojavili tukaj.",
-  "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
-  "empty_column.mutes": "You haven't muted any users yet.",
+  "empty_column.lists": "Nimate seznamov. Ko ga boste ustvarili, se bo prikazal tukaj.",
+  "empty_column.mutes": "Niste utišali še nobenega uporabnika.",
   "empty_column.notifications": "Nimate še nobenih obvestil. Poveži se z drugimi, da začnete pogovor.",
-  "empty_column.public": "Tukaj ni ničesar! Da ga napolnite, napišite nekaj javnega ali pa ročno sledite uporabnikom iz drugih vozlišč",
-  "follow_request.authorize": "Odobri",
+  "empty_column.public": "Tukaj ni ničesar! Da ga napolnite, napišite nekaj javnega ali pa ročno sledite uporabnikom iz drugih strežnikov",
+  "follow_request.authorize": "Overi",
   "follow_request.reject": "Zavrni",
-  "getting_started.developers": "Developers",
-  "getting_started.directory": "Profile directory",
-  "getting_started.documentation": "Documentation",
-  "getting_started.heading": "Prvi koraki",
-  "getting_started.invite": "Invite people",
-  "getting_started.open_source_notice": "Mastodon je odprtokodna programska oprema. V GitHubu na {github} lahko prispevate ali poročate o napakah.",
-  "getting_started.security": "Security",
-  "getting_started.terms": "Terms of service",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
-  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "getting_started.developers": "Razvijalci",
+  "getting_started.directory": "Imenik profilov",
+  "getting_started.documentation": "Dokumentacija",
+  "getting_started.heading": "Kako začeti",
+  "getting_started.invite": "Povabite osebe",
+  "getting_started.open_source_notice": "Mastodon je odprtokodna programska oprema. Na GitHubu na {github} lahko prispevate ali poročate o napakah.",
+  "getting_started.security": "Varnost",
+  "getting_started.terms": "Pogoji uporabe",
+  "hashtag.column_header.tag_mode.all": "in {additional}",
+  "hashtag.column_header.tag_mode.any": "ali {additional}",
+  "hashtag.column_header.tag_mode.none": "brez {additional}",
+  "hashtag.column_settings.select.no_options_message": "Ni najdenih predlogov",
+  "hashtag.column_settings.select.placeholder": "Vpiši ključnik…",
+  "hashtag.column_settings.tag_mode.all": "Vse od naštetega",
+  "hashtag.column_settings.tag_mode.any": "Karkoli od naštetega",
+  "hashtag.column_settings.tag_mode.none": "Nič od naštetega",
+  "hashtag.column_settings.tag_toggle": "Za ta stolpec vključi dodatne oznake",
   "home.column_settings.basic": "Osnovno",
-  "home.column_settings.show_reblogs": "Pokaži sunke",
+  "home.column_settings.show_reblogs": "Pokaži spodbude",
   "home.column_settings.show_replies": "Pokaži odgovore",
-  "introduction.federation.action": "Next",
-  "introduction.federation.federated.headline": "Federated",
-  "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
-  "introduction.federation.home.headline": "Home",
-  "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
-  "introduction.federation.local.headline": "Local",
-  "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
-  "introduction.interactions.favourite.headline": "Favourite",
-  "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
-  "introduction.interactions.reblog.headline": "Boost",
-  "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
-  "introduction.interactions.reply.headline": "Reply",
-  "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
-  "introduction.welcome.action": "Let's go!",
-  "introduction.welcome.headline": "First steps",
-  "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
-  "keyboard_shortcuts.back": "za krmarjenje nazaj",
-  "keyboard_shortcuts.blocked": "to open blocked users list",
-  "keyboard_shortcuts.boost": "suniti",
-  "keyboard_shortcuts.column": "osredotočiti status v enega od stolpcev",
-  "keyboard_shortcuts.compose": "osredotočiti na sestavljanje besedila",
+  "intervals.full.days": "{number, plural, one {# dan} two {# dni} few {# dni} other {# dni}}",
+  "intervals.full.hours": "{number, plural, one {# ura} two {# uri} few {# ure} other {# ur}}",
+  "intervals.full.minutes": "{number, plural, one {# minuta} two {# minuti} few {# minute} other {# minut}}",
+  "introduction.federation.action": "Naprej",
+  "introduction.federation.federated.headline": "Združeno",
+  "introduction.federation.federated.text": "Javne objave iz drugih strežnikov fediverse-a bodo prikazane v združeni časovnici.",
+  "introduction.federation.home.headline": "Domov",
+  "introduction.federation.home.text": "Objave oseb, ki jim sledite, bodo prikazane v vaši domači časovnici. Lahko sledite vsakomur na katerem koli strežniku!",
+  "introduction.federation.local.headline": "Lokalno",
+  "introduction.federation.local.text": "Javne objave ljudi na istem strežniku, se bodo prikazale na lokalni časovnici.",
+  "introduction.interactions.action": "Zaključi vadnico!",
+  "introduction.interactions.favourite.headline": "Priljubljeni",
+  "introduction.interactions.favourite.text": "Tut lahko shranite za pozneje in ga vzljubite ter s tem pokažete avtorju, da vam je ta tut priljubljen.",
+  "introduction.interactions.reblog.headline": "Spodbudi",
+  "introduction.interactions.reblog.text": "Tute drugih ljudi lahko delite z vašimi sledilci, tako da spodbudite tute.",
+  "introduction.interactions.reply.headline": "Odgovori",
+  "introduction.interactions.reply.text": "Lahko odgovarjate na tuje in vaše tute, kar bo odgovore povezalo v pogovor.",
+  "introduction.welcome.action": "Gremo!",
+  "introduction.welcome.headline": "Prvi koraki",
+  "introduction.welcome.text": "Dobrodošli v fediverse-u! Čez nekaj trenutkov boste lahko oddajali sporočila in se pogovarjali s prijatelji prek različnih strežnikov. Vendar je ta strežnik {domain} poseben - gosti vaš profil, zato si zapomnite njegovo ime.",
+  "keyboard_shortcuts.back": "pojdi nazaj",
+  "keyboard_shortcuts.blocked": "odpri seznam blokiranih uporabnikov",
+  "keyboard_shortcuts.boost": "spodbudi",
+  "keyboard_shortcuts.column": "fokusiraj na status v enemu od stolpcev",
+  "keyboard_shortcuts.compose": "fokusiraj na območje za sestavljanje besedila",
   "keyboard_shortcuts.description": "Opis",
-  "keyboard_shortcuts.direct": "to open direct messages column",
-  "keyboard_shortcuts.down": "premakniti navzdol po seznamu",
-  "keyboard_shortcuts.enter": "odpreti status",
-  "keyboard_shortcuts.favourite": "to favourite",
-  "keyboard_shortcuts.favourites": "to open favourites list",
-  "keyboard_shortcuts.federated": "to open federated timeline",
+  "keyboard_shortcuts.direct": "odpri stolpec za neposredna sporočila",
+  "keyboard_shortcuts.down": "premakni se navzdol po seznamu",
+  "keyboard_shortcuts.enter": "odpri status",
+  "keyboard_shortcuts.favourite": "vzljubi",
+  "keyboard_shortcuts.favourites": "odpri seznam priljubljenih",
+  "keyboard_shortcuts.federated": "odpri združeno časovnico",
   "keyboard_shortcuts.heading": "Tipkovne bližnjice",
-  "keyboard_shortcuts.home": "to open home timeline",
+  "keyboard_shortcuts.home": "odpri domačo časovnico",
   "keyboard_shortcuts.hotkey": "Hitra tipka",
-  "keyboard_shortcuts.legend": "to display this legend",
-  "keyboard_shortcuts.local": "to open local timeline",
-  "keyboard_shortcuts.mention": "to mention author",
-  "keyboard_shortcuts.muted": "to open muted users list",
-  "keyboard_shortcuts.my_profile": "to open your profile",
-  "keyboard_shortcuts.notifications": "to open notifications column",
-  "keyboard_shortcuts.pinned": "to open pinned toots list",
-  "keyboard_shortcuts.profile": "to open author's profile",
-  "keyboard_shortcuts.reply": "to reply",
-  "keyboard_shortcuts.requests": "to open follow requests list",
-  "keyboard_shortcuts.search": "to focus search",
-  "keyboard_shortcuts.start": "to open \"get started\" column",
-  "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
-  "keyboard_shortcuts.toot": "da začnete povsem nov tut",
-  "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
-  "keyboard_shortcuts.up": "to move up in the list",
-  "lightbox.close": "Close",
-  "lightbox.next": "Next",
-  "lightbox.previous": "Previous",
-  "lists.account.add": "Add to list",
-  "lists.account.remove": "Remove from list",
-  "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",
-  "loading_indicator.label": "Loading...",
-  "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.apps": "Mobile apps",
-  "navigation_bar.blocks": "Blocked users",
-  "navigation_bar.community_timeline": "Local timeline",
-  "navigation_bar.compose": "Compose new toot",
-  "navigation_bar.direct": "Direct messages",
-  "navigation_bar.discover": "Discover",
-  "navigation_bar.domain_blocks": "Hidden domains",
-  "navigation_bar.edit_profile": "Edit profile",
-  "navigation_bar.favourites": "Favourites",
-  "navigation_bar.filters": "Muted words",
-  "navigation_bar.follow_requests": "Follow requests",
-  "navigation_bar.info": "O tem vozlišču",
-  "navigation_bar.keyboard_shortcuts": "Keyboard shortcuts",
-  "navigation_bar.lists": "Lists",
-  "navigation_bar.logout": "Logout",
-  "navigation_bar.mutes": "Muted users",
-  "navigation_bar.personal": "Personal",
+  "keyboard_shortcuts.legend": "pokaži to legendo",
+  "keyboard_shortcuts.local": "odpri lokalno časovnico",
+  "keyboard_shortcuts.mention": "omeni avtorja",
+  "keyboard_shortcuts.muted": "odpri seznam utišanih uporabnikov",
+  "keyboard_shortcuts.my_profile": "odpri svoj profil",
+  "keyboard_shortcuts.notifications": "odpri stolpec z obvestili",
+  "keyboard_shortcuts.pinned": "odpri seznam pripetih tutov",
+  "keyboard_shortcuts.profile": "odpri avtorjev profil",
+  "keyboard_shortcuts.reply": "odgovori",
+  "keyboard_shortcuts.requests": "odpri seznam s prošnjami za sledenje",
+  "keyboard_shortcuts.search": "fokusiraj na iskanje",
+  "keyboard_shortcuts.start": "odpri stolpec \"začni\"",
+  "keyboard_shortcuts.toggle_hidden": "prikaži/skrij besedilo za CW",
+  "keyboard_shortcuts.toggle_sensitivity": "prikaži/skrij medije",
+  "keyboard_shortcuts.toot": "začni povsem nov tut",
+  "keyboard_shortcuts.unfocus": "odfokusiraj območje za sestavljanje besedila/iskanje",
+  "keyboard_shortcuts.up": "premakni se navzgor po seznamu",
+  "lightbox.close": "Zapri",
+  "lightbox.next": "Naslednji",
+  "lightbox.previous": "Prejšnji",
+  "lightbox.view_context": "Poglej kontekst",
+  "lists.account.add": "Dodaj na seznam",
+  "lists.account.remove": "Odstrani s seznama",
+  "lists.delete": "Izbriši seznam",
+  "lists.edit": "Uredi seznam",
+  "lists.edit.submit": "Spremeni naslov",
+  "lists.new.create": "Dodaj seznam",
+  "lists.new.title_placeholder": "Nov naslov seznama",
+  "lists.search": "Išči med ljudmi, katerim sledite",
+  "lists.subheading": "Vaši seznami",
+  "loading_indicator.label": "Nalaganje...",
+  "media_gallery.toggle_visible": "Preklopi vidljivost",
+  "missing_indicator.label": "Ni najdeno",
+  "missing_indicator.sublabel": "Tega vira ni bilo mogoče najti",
+  "mute_modal.hide_notifications": "Skrij obvestila tega uporabnika?",
+  "navigation_bar.apps": "Mobilne aplikacije",
+  "navigation_bar.blocks": "Blokirani uporabniki",
+  "navigation_bar.community_timeline": "Lokalna časovnica",
+  "navigation_bar.compose": "Sestavi nov tut",
+  "navigation_bar.direct": "Neposredna sporočila",
+  "navigation_bar.discover": "Odkrijte",
+  "navigation_bar.domain_blocks": "Skrite domene",
+  "navigation_bar.edit_profile": "Uredi profil",
+  "navigation_bar.favourites": "Priljubljeni",
+  "navigation_bar.filters": "Utišane besede",
+  "navigation_bar.follow_requests": "Prošnje za sledenje",
+  "navigation_bar.follows_and_followers": "Sledenja in sledilci",
+  "navigation_bar.info": "O tem strežniku",
+  "navigation_bar.keyboard_shortcuts": "Hitre tipke",
+  "navigation_bar.lists": "Seznami",
+  "navigation_bar.logout": "Odjava",
+  "navigation_bar.mutes": "Utišani uporabniki",
+  "navigation_bar.personal": "Osebno",
   "navigation_bar.pins": "Pripeti tuti",
-  "navigation_bar.preferences": "Preferences",
-  "navigation_bar.public_timeline": "Federated timeline",
-  "navigation_bar.security": "Security",
-  "notification.favourite": "{name} favourited your status",
-  "notification.follow": "{name} followed you",
-  "notification.mention": "{name} mentioned you",
-  "notification.reblog": "{name} boosted your status",
-  "notifications.clear": "Clear notifications",
-  "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
-  "notifications.column_settings.alert": "Desktop notifications",
-  "notifications.column_settings.favourite": "Favourites:",
-  "notifications.column_settings.filter_bar.advanced": "Display all categories",
-  "notifications.column_settings.filter_bar.category": "Quick filter bar",
-  "notifications.column_settings.filter_bar.show": "Show",
-  "notifications.column_settings.follow": "New followers:",
-  "notifications.column_settings.mention": "Mentions:",
-  "notifications.column_settings.push": "Push notifications",
-  "notifications.column_settings.reblog": "Boosts:",
-  "notifications.column_settings.show": "Show in column",
-  "notifications.column_settings.sound": "Play sound",
-  "notifications.filter.all": "All",
-  "notifications.filter.boosts": "Boosts",
-  "notifications.filter.favourites": "Favourites",
-  "notifications.filter.follows": "Follows",
-  "notifications.filter.mentions": "Mentions",
-  "notifications.group": "{count} notifications",
-  "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!",
+  "navigation_bar.preferences": "Nastavitve",
+  "navigation_bar.profile_directory": "Imenik profilov",
+  "navigation_bar.public_timeline": "Združena časovnica",
+  "navigation_bar.security": "Varnost",
+  "notification.favourite": "{name} je vzljubil/a vaš status",
+  "notification.follow": "{name} vam sledi",
+  "notification.mention": "{name} vas je omenil/a",
+  "notification.poll": "Glasovanje, v katerem ste sodelovali, se je končalo",
+  "notification.reblog": "{name} je spodbudil/a vaš status",
+  "notifications.clear": "Počisti obvestila",
+  "notifications.clear_confirmation": "Ali ste prepričani, da želite trajno izbrisati vsa vaša obvestila?",
+  "notifications.column_settings.alert": "Namizna obvestila",
+  "notifications.column_settings.favourite": "Priljubljeni:",
+  "notifications.column_settings.filter_bar.advanced": "Prikaži vse kategorije",
+  "notifications.column_settings.filter_bar.category": "Vrstica za hitro filtriranje",
+  "notifications.column_settings.filter_bar.show": "Pokaži",
+  "notifications.column_settings.follow": "Novi sledilci:",
+  "notifications.column_settings.mention": "Omembe:",
+  "notifications.column_settings.poll": "Rezultati glasovanja:",
+  "notifications.column_settings.push": "Potisna obvestila",
+  "notifications.column_settings.reblog": "Spodbude:",
+  "notifications.column_settings.show": "Prikaži v stolpcu",
+  "notifications.column_settings.sound": "Predvajaj zvok",
+  "notifications.filter.all": "Vse",
+  "notifications.filter.boosts": "Spodbude",
+  "notifications.filter.favourites": "Priljubljeni",
+  "notifications.filter.follows": "Sledi",
+  "notifications.filter.mentions": "Omembe",
+  "notifications.filter.polls": "Rezultati glasovanj",
+  "notifications.group": "{count} obvestil",
+  "poll.closed": "Zaprto",
+  "poll.refresh": "Osveži",
+  "poll.total_votes": "{count, plural,one {# glas} other {# glasov}}",
+  "poll.vote": "Glasuj",
+  "poll_button.add_poll": "Dodaj anketo",
+  "poll_button.remove_poll": "Odstrani anketo",
+  "privacy.change": "Prilagodi zasebnost statusa",
+  "privacy.direct.long": "Objavi samo omenjenim uporabnikom",
+  "privacy.direct.short": "Neposredno",
+  "privacy.private.long": "Objavi samo sledilcem",
+  "privacy.private.short": "Samo sledilci",
+  "privacy.public.long": "Objavi na javne časovnice",
+  "privacy.public.short": "Javno",
+  "privacy.unlisted.long": "Ne objavi na javne časovnice",
+  "privacy.unlisted.short": "Ni prikazano",
+  "regeneration_indicator.label": "Nalaganje…",
+  "regeneration_indicator.sublabel": "Vaš domači vir se pripravlja!",
   "relative_time.days": "{number}d",
   "relative_time.hours": "{number}h",
-  "relative_time.just_now": "now",
+  "relative_time.just_now": "zdaj",
   "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": "Report {target}",
-  "search.placeholder": "Search",
-  "search_popout.search_format": "Advanced search format",
-  "search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
-  "search_popout.tips.hashtag": "hashtag",
-  "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",
+  "reply_indicator.cancel": "Prekliči",
+  "report.forward": "Posreduj do {target}",
+  "report.forward_hint": "Račun je iz drugega strežnika. Pošljem anonimno kopijo poročila tudi na drugi strežnik?",
+  "report.hint": "Poročilo bo poslano moderatorjem vašega vozlišča. Spodaj lahko navedete, zakaj prijavljate ta račun:",
+  "report.placeholder": "Dodatni komentarji",
+  "report.submit": "Pošlji",
+  "report.target": "Prijavi {target}",
+  "search.placeholder": "Iskanje",
+  "search_popout.search_format": "Napredna oblika iskanja",
+  "search_popout.tips.full_text": "Enostavno besedilo vrne statuse, ki ste jih napisali, vzljubili, spodbudili ali ste bili v njih omenjeni, kot tudi ujemajoča se uporabniška imena, prikazna imena in ključnike.",
+  "search_popout.tips.hashtag": "ključnik",
+  "search_popout.tips.status": "stanje",
+  "search_popout.tips.text": "Enostavno besedilo vrne ujemajoča se prikazna imena, uporabniška imena in ključnike",
+  "search_popout.tips.user": "uporabnik",
+  "search_results.accounts": "Ljudje",
+  "search_results.hashtags": "Ključniki",
   "search_results.statuses": "Tuti",
-  "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
-  "standalone.public_title": "A look inside...",
-  "status.admin_account": "Open moderation interface for @{name}",
-  "status.admin_status": "Open this status in the moderation interface",
-  "status.block": "Block @{name}",
-  "status.cancel_reblog_private": "Unboost",
-  "status.cannot_reblog": "This post cannot be boosted",
-  "status.delete": "Delete",
-  "status.detailed_status": "Detailed conversation view",
-  "status.direct": "Direct message @{name}",
-  "status.embed": "Embed",
-  "status.favourite": "Favourite",
-  "status.filtered": "Filtered",
-  "status.load_more": "Load more",
-  "status.media_hidden": "Media hidden",
-  "status.mention": "Mention @{name}",
-  "status.more": "More",
-  "status.mute": "Mute @{name}",
-  "status.mute_conversation": "Mute conversation",
-  "status.open": "Expand this status",
-  "status.pin": "Pin on profile",
+  "search_results.total": "{count, number} {count, plural, one {rezultat} other {rezultatov}}",
+  "status.admin_account": "Odpri vmesnik za moderiranje za @{name}",
+  "status.admin_status": "Odpri status v vmesniku za moderiranje",
+  "status.block": "Blokiraj @{name}",
+  "status.cancel_reblog_private": "Prekini spodbudo",
+  "status.cannot_reblog": "Te objave ni mogoče spodbuditi",
+  "status.copy": "Kopiraj povezavo do statusa",
+  "status.delete": "Izbriši",
+  "status.detailed_status": "Podroben pogled pogovora",
+  "status.direct": "Neposredno sporočilo @{name}",
+  "status.embed": "Vgradi",
+  "status.favourite": "Priljubljen",
+  "status.filtered": "Filtrirano",
+  "status.load_more": "Naloži več",
+  "status.media_hidden": "Mediji so skriti",
+  "status.mention": "Omeni @{name}",
+  "status.more": "Več",
+  "status.mute": "Utišaj @{name}",
+  "status.mute_conversation": "Utišaj pogovor",
+  "status.open": "Razširi ta status",
+  "status.pin": "Pripni na profil",
   "status.pinned": "Pripeti tut",
-  "status.read_more": "Read more",
-  "status.reblog": "Suni",
-  "status.reblog_private": "Suni v prvotno občinstvo",
-  "status.reblogged_by": "{name} sunjen",
-  "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
-  "status.redraft": "Delete & re-draft",
+  "status.read_more": "Preberi več",
+  "status.reblog": "Spodbudi",
+  "status.reblog_private": "Spodbudi izvirnemu občinstvu",
+  "status.reblogged_by": "{name} spodbujen",
+  "status.reblogs.empty": "Nihče še ni spodbudil tega tuta. Ko se bo to zgodilo, se bodo pojavili tukaj.",
+  "status.redraft": "Izbriši in preoblikuj",
   "status.reply": "Odgovori",
   "status.replyAll": "Odgovori na objavo",
   "status.report": "Prijavi @{name}",
-  "status.sensitive_toggle": "Kliknite za ogled",
   "status.sensitive_warning": "Občutljiva vsebina",
   "status.share": "Deli",
   "status.show_less": "Prikaži manj",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Lokalno",
   "tabs_bar.notifications": "Obvestila",
   "tabs_bar.search": "Poišči",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
   "ui.beforeunload": "Vaš osnutek bo izgubljen, če zapustite Mastodona.",
   "upload_area.title": "Povlecite in spustite za pošiljanje",
   "upload_button.label": "Dodaj medij",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "upload_form.description": "Opišite za slabovidne",
   "upload_form.focus": "Obreži",
   "upload_form.undo": "Izbriši",
diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json
new file mode 100644
index 0000000000000000000000000000000000000000..13ce4e97891c2f753214a13f5122362ee6418e18
--- /dev/null
+++ b/app/javascript/mastodon/locales/sq.json
@@ -0,0 +1,388 @@
+{
+  "account.add_or_remove_from_list": "Shtoni ose Hiqni prej listash",
+  "account.badges.bot": "Robot",
+  "account.block": "Blloko @{name}",
+  "account.block_domain": "Fshih gjithçka prej {domain}",
+  "account.blocked": "E bllokuar",
+  "account.direct": "Mesazh i drejtpërdrejt për @{name}",
+  "account.domain_blocked": "Përkatësi e fshehur",
+  "account.edit_profile": "Përpunoni profilin",
+  "account.endorse": "Pasqyrojeni në profil",
+  "account.follow": "Ndiqeni",
+  "account.followers": "Ndjekës",
+  "account.followers.empty": "Këtë përdorues ende s’e ndjek njeri.",
+  "account.follows": "Ndjekje",
+  "account.follows.empty": "Ky përdorues ende s’ndjek njeri.",
+  "account.follows_you": "Ju ndjek",
+  "account.hide_reblogs": "Fshih përforcime nga @{name}",
+  "account.link_verified_on": "Pronësia e kësaj lidhjeje qe kontrolluar më {date}",
+  "account.locked_info": "Gjendja e privatësisë së kësaj llogarie është caktuar si e kyçur. I zoti merr dorazi në shqyrtim cilët mund ta ndjekin.",
+  "account.media": "Media",
+  "account.mention": "Përmendni @{name}",
+  "account.moved_to": "{name} ka kaluar te:",
+  "account.mute": "Heshtoni @{name}",
+  "account.mute_notifications": "Heshtoji njoftimet prej @{name}",
+  "account.muted": "Heshtuar",
+  "account.posts": "Mesazhe",
+  "account.posts_with_replies": "Mesazhe dhe përgjigje",
+  "account.report": "Raportojeni @{name}",
+  "account.requested": "Në pritje të miratimit. Klikoni që të anulohet kërkesa për ndjekje",
+  "account.share": "Ndajeni profilin e @{name} me të tjerët",
+  "account.show_reblogs": "Shfaq përforcime nga @{name}",
+  "account.unblock": "Zhbllokoje @{name}",
+  "account.unblock_domain": "Shfshihe {domain}",
+  "account.unendorse": "Mos e përfshi në profil",
+  "account.unfollow": "Resht së ndjekuri",
+  "account.unmute": "Ktheji zërin @{name}",
+  "account.unmute_notifications": "Hiqua ndalimin e shfaqjes njoftimeve nga @{name}",
+  "alert.unexpected.message": "Ndodhi një gabim të papritur.",
+  "alert.unexpected.title": "Hëm!",
+  "boost_modal.combo": "Mund të shtypni {combo}, që të anashkalohet kjo herës tjetër",
+  "bundle_column_error.body": "Diç shkoi ters teksa ngarkohej ky përbërës.",
+  "bundle_column_error.retry": "Riprovoni",
+  "bundle_column_error.title": "Gabim rrjeti",
+  "bundle_modal_error.close": "Mbylle",
+  "bundle_modal_error.message": "Diç shkoi ters teksa ngarkohej ky përbërës.",
+  "bundle_modal_error.retry": "Riprovoni",
+  "column.blocks": "Përdorues të bllokuar",
+  "column.community": "Rrjedhë kohore vendore",
+  "column.direct": "Mesazhe të drejtpërdrejta",
+  "column.domain_blocks": "Përkatësi të fshehura",
+  "column.favourites": "Të parapëlqyer",
+  "column.follow_requests": "Kërkesa për ndjekje",
+  "column.home": "Kreu",
+  "column.lists": "Lista",
+  "column.mutes": "Përdorues të heshtuar",
+  "column.notifications": "Njoftime",
+  "column.pins": "Mesazhe të fiksuar",
+  "column.public": "Rrjedhë kohore e federuar",
+  "column_back_button.label": "Mbrapsht",
+  "column_header.hide_settings": "Fshihi rregullimet",
+  "column_header.moveLeft_settings": "Shpjere shtyllën majtas",
+  "column_header.moveRight_settings": "Shpjere shtyllën djathtas",
+  "column_header.pin": "Fiksoje",
+  "column_header.show_settings": "Shfaq rregullime",
+  "column_header.unpin": "Shfiksoje",
+  "column_subheading.settings": "Rregullime",
+  "community.column_settings.media_only": "Vetëm Media",
+  "compose_form.direct_message_warning": "Ky mesazh do t’u dërgohet përdoruesve të përmendur.",
+  "compose_form.direct_message_warning_learn_more": "Mësoni më tepër",
+  "compose_form.hashtag_warning": "Ky mesazh s’do të paraqitet nën ndonjë hashtag, ngaqë s’i është caktuar ndonjë. Vetëm mesazhet publike mund të kërkohen sipas hashtagësh.",
+  "compose_form.lock_disclaimer": "Llogaria juaj s’është {locked}. Mund ta ndjekë cilido, për të parë postimet tuaja vetëm për ndjekësit.",
+  "compose_form.lock_disclaimer.lock": "e bllokuar",
+  "compose_form.placeholder": "Ç’bluani në mendje?",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
+  "compose_form.publish": "Mesazh",
+  "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
+  "compose_form.sensitive.marked": "Media është shënuar si rezervat",
+  "compose_form.sensitive.unmarked": "Media s’është shënuar si rezervat",
+  "compose_form.spoiler.marked": "Teksti është fshehur pas sinjalizimit",
+  "compose_form.spoiler.unmarked": "Teksti s’është i fshehur",
+  "compose_form.spoiler_placeholder": "Shkruani këtu sinjalizimin tuaj",
+  "confirmation_modal.cancel": "Anuloje",
+  "confirmations.block.block_and_report": "Block & Report",
+  "confirmations.block.confirm": "Bllokoje",
+  "confirmations.block.message": "Jeni i sigurt se doni të bllokohet {name}?",
+  "confirmations.delete.confirm": "Fshije",
+  "confirmations.delete.message": "Jeni i sigurt se doni të fshihet kjo gjendje?",
+  "confirmations.delete_list.confirm": "Fshije",
+  "confirmations.delete_list.message": "Jeni i sigurt që doni të fshihet përgjithmonë kjo listë?",
+  "confirmations.domain_block.confirm": "Fshih krejt përkatësinë",
+  "confirmations.domain_block.message": "Jeni i sigurt, shumë i sigurt se doni të bllokohet krejt {domain}? Në shumicën e rasteve, ndoca bllokime ose heshtime me synim të caktuar janë të mjaftueshme dhe të parapëlqyera. S’keni për të parë lëndë nga kjo përkatësi në ndonjë rrjedhë kohore publike, apo te njoftimet tuaja. Ndjekësit tuaj prej asaj përkatësie do të hiqen.",
+  "confirmations.mute.confirm": "Heshtoje",
+  "confirmations.mute.message": "Jeni i sigurt se doni të heshtohet {name}?",
+  "confirmations.redraft.confirm": "Fshijeni & rihartojeni",
+  "confirmations.redraft.message": "Jeni i sigurt se doni të fshihet kjo gjendje dhe të rihartohet? Parapëlqimet dhe boosts do të humbin, ndërsa përgjigjet te postimi origjinal do të bëhen jetime.",
+  "confirmations.reply.confirm": "Përgjigjuni",
+  "confirmations.reply.message": "Përgjigja tani do të shkaktojë mbishkrimin e mesazhit që po hartoni. Jeni i sigurt se doni të vazhdohet më tej?",
+  "confirmations.unfollow.confirm": "Resht së ndjekuri",
+  "confirmations.unfollow.message": "Jeni i sigurt se doni të mos ndiqet më {name}?",
+  "embed.instructions": "Trupëzojeni këtë gjendje në sajtin tuaj duke kopjuar kodin më poshtë.",
+  "embed.preview": "Ja si do të duket:",
+  "emoji_button.activity": "Veprimtari",
+  "emoji_button.custom": "Vetjak",
+  "emoji_button.flags": "Flamuj",
+  "emoji_button.food": "Ushqim & Pije",
+  "emoji_button.label": "Futni emoji",
+  "emoji_button.nature": "Natyrë",
+  "emoji_button.not_found": "No emojos!!! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.objects": "Objekte",
+  "emoji_button.people": "Persona",
+  "emoji_button.recent": "Të përdorur shpesh",
+  "emoji_button.search": "Kërkoni…",
+  "emoji_button.search_results": "Përfundime kërkimi",
+  "emoji_button.symbols": "Simbole",
+  "emoji_button.travel": "Udhëtime & Vende",
+  "empty_column.account_timeline": "S’ka mesazhe këtu!",
+  "empty_column.account_unavailable": "Profile unavailable",
+  "empty_column.blocks": "S’keni bllokuar ende ndonjë përdorues.",
+  "empty_column.community": "Rrjedha kohore vendore është e zbrazët. Shkruani diçka publikisht që t’i hyhet valles!",
+  "empty_column.direct": "S’keni ende ndonjë mesazh të drejtpërdrejt. Kur dërgoni ose merrni një të tillë, ai do të shfaqet këtu.",
+  "empty_column.domain_blocks": "Ende s’ka përkatësi të fshehura.",
+  "empty_column.favourited_statuses": "S’keni ende ndonjë mesazh të parapëlqyer. Kur parapëlqeni një të tillë, ai do të shfaqet këtu.",
+  "empty_column.favourites": "Askush s’e ka parapëlqyer ende këtë mesazh. Kur e bën dikush, ai do të shfaqet këtu.",
+  "empty_column.follow_requests": "Ende s’keni ndonjë kërkesë ndjekjeje. Kur të merrni një të tillë, do të shfaqet këtu.",
+  "empty_column.hashtag": "Ende s’ka gjë nën këtë hashtag.",
+  "empty_column.home": "Rrjedha juaj kohore është e zbrazët! Vizitoni {public} ose përdorni kërkimin që t’ia filloni dhe të takoni përdorues të tjerë.",
+  "empty_column.home.public_timeline": "rrjedha kohore publike",
+  "empty_column.list": "Në këtë listë ende s’ka gjë. Kur anëtarë të kësaj liste postojnë gjendje të reja, ato do të shfaqen këtu.",
+  "empty_column.lists": "Ende s’keni ndonjë listë. Kur të krijoni një të tillë, do të duket këtu.",
+  "empty_column.mutes": "S’keni heshtuar ende ndonjë përdorues.",
+  "empty_column.notifications": "Ende s’keni ndonjë njoftim. Ndërveproni me të tjerët që të nisë biseda.",
+  "empty_column.public": "S’ka gjë këtu! Shkruani diçka publikisht, ose ndiqni dorazi përdorues prej instancash të tjera, që ta mbushni këtë zonë",
+  "follow_request.authorize": "Autorizoje",
+  "follow_request.reject": "Hidhe tej",
+  "getting_started.developers": "Zhvillues",
+  "getting_started.directory": "Drejtori profilesh",
+  "getting_started.documentation": "Dokumentim",
+  "getting_started.heading": "Si t’ia fillohet",
+  "getting_started.invite": "Ftoni njerëz",
+  "getting_started.open_source_notice": "Mastodon-i është software me burim të hapur. Mund të jepni ndihmesë ose të njoftoni probleme në GitHub, te {github}.",
+  "getting_started.security": "Siguri",
+  "getting_started.terms": "Kushte shërbimi",
+  "hashtag.column_header.tag_mode.all": "dhe {additional}",
+  "hashtag.column_header.tag_mode.any": "ose {additional}",
+  "hashtag.column_header.tag_mode.none": "pa {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
+  "hashtag.column_settings.tag_mode.all": "Krejt këto",
+  "hashtag.column_settings.tag_mode.any": "Cilëndo prej këtyre",
+  "hashtag.column_settings.tag_mode.none": "Asnjë prej këtyre",
+  "hashtag.column_settings.tag_toggle": "Përfshi etiketa shtesë për këtë shtyllë",
+  "home.column_settings.basic": "Bazë",
+  "home.column_settings.show_reblogs": "Shfaq përforcime",
+  "home.column_settings.show_replies": "Shfaq përgjigje",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
+  "introduction.federation.action": "Pasuesi",
+  "introduction.federation.federated.headline": "Të federuara",
+  "introduction.federation.federated.text": "Postimet publike nga shërbyes të tjerë të fediversit do të shfaqen te rrjedha kohore e të federuarve.",
+  "introduction.federation.home.headline": "Vatër",
+  "introduction.federation.home.text": "Postime prej personash që ndiqni do të shfaqen te prurja juaj vatër. Mund të ndiqni këdo, në çfarëdo shërbyesi!",
+  "introduction.federation.local.headline": "Vendore",
+  "introduction.federation.local.text": "Postimet publike prej personash në të njëjtin shërbyes me ju do të shfaqen te rrjedha kohore vendore.",
+  "introduction.interactions.action": "Përfundojeni përkujdesoren!",
+  "introduction.interactions.favourite.headline": "Parapëlqejeni",
+  "introduction.interactions.favourite.text": "Duke e parapëlqyer, një mesazh mund ta ruani për më vonë dhe t’i bëni të ditur autorit se e pëlqyet.",
+  "introduction.interactions.reblog.headline": "Përforcime",
+  "introduction.interactions.reblog.text": "Mesazhet e të tjerëve mund t’i ndani me ndjekësit tuaj duke i përforcuar.",
+  "introduction.interactions.reply.headline": "Përgjigjuni",
+  "introduction.interactions.reply.text": "Mund t'u përgjigjeni mesazheve tuaja dhe atyre të personave të tjerë, çka do t’i lidhë ato tok në një bisedë.",
+  "introduction.welcome.action": "Shkojmë!",
+  "introduction.welcome.headline": "Hapat e parë",
+  "introduction.welcome.text": "Mirë se vini në fedivers! Brenda pak çastesh do të jeni në gjendje të transmetoni mesazhe dhe të bisedoni me miqtë tuaj nëpër një larmi të madhe shërbyesish. Po ky shërbyes, {domain}, është i veçantë—strehon profilin tuaj, ndaj mbajeni mend emrin e tij.",
+  "keyboard_shortcuts.back": "për shkuarje mbrapsht",
+  "keyboard_shortcuts.blocked": "për hapje liste përdoruesish të bllokuar",
+  "keyboard_shortcuts.boost": "për përfocim",
+  "keyboard_shortcuts.column": "për kalim fokusi mbi një gjendje te një nga shtyllat",
+  "keyboard_shortcuts.compose": "për kalim fokusi te fusha e hartimit të mesazheve",
+  "keyboard_shortcuts.description": "Përshkrim",
+  "keyboard_shortcuts.direct": "për hapje shtylle mesazhesh të drejtpërdrejtë",
+  "keyboard_shortcuts.down": "për zbritje poshtë nëpër listë",
+  "keyboard_shortcuts.enter": "për hapje gjendjeje",
+  "keyboard_shortcuts.favourite": "për t’i vënë shenjë si të parapëlqyer",
+  "keyboard_shortcuts.favourites": "për hapje liste të parapëlqyerish",
+  "keyboard_shortcuts.federated": "për hapje rrjedhe kohore të të federuarve",
+  "keyboard_shortcuts.heading": "Shkurtore tastiere",
+  "keyboard_shortcuts.home": "për hapje rrjedhe kohore vetjake",
+  "keyboard_shortcuts.hotkey": "Tast përkatës",
+  "keyboard_shortcuts.legend": "për shfaqje të kësaj legjende",
+  "keyboard_shortcuts.local": "për hapje rrjedhe kohore vendore",
+  "keyboard_shortcuts.mention": "për përmendje të autorit",
+  "keyboard_shortcuts.muted": "për hapje liste përdoruesish të heshtuar",
+  "keyboard_shortcuts.my_profile": "për hapjen e profilit tuaj",
+  "keyboard_shortcuts.notifications": "për hapje shtylle njoftimesh",
+  "keyboard_shortcuts.pinned": "për hapje liste mesazhesh të fiksuar",
+  "keyboard_shortcuts.profile": "për hapje të profilit të autorit",
+  "keyboard_shortcuts.reply": "për t’u përgjigjur",
+  "keyboard_shortcuts.requests": "për hapje liste kërkesash për ndjekje",
+  "keyboard_shortcuts.search": "për kalim fokusi te kërkimi",
+  "keyboard_shortcuts.start": "për hapjen e shtyllës \"fillojani\"",
+  "keyboard_shortcuts.toggle_hidden": "për shfaqje/fshehje teksti pas CW",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
+  "keyboard_shortcuts.toot": "për të filluar një mesazh fringo të ri",
+  "keyboard_shortcuts.unfocus": "për heqjen e fokusit nga fusha e hartimit të mesazheve apo kërkimeve",
+  "keyboard_shortcuts.up": "për ngjitje sipër nëpër listë",
+  "lightbox.close": "Mbylle",
+  "lightbox.next": "Pasuesja",
+  "lightbox.previous": "E mëparshmja",
+  "lightbox.view_context": "View context",
+  "lists.account.add": "Shto në listë",
+  "lists.account.remove": "Hiqe nga lista",
+  "lists.delete": "Fshije listën",
+  "lists.edit": "Përpunoni listën",
+  "lists.edit.submit": "Change title",
+  "lists.new.create": "Shtoni listë",
+  "lists.new.title_placeholder": "Titull liste të re",
+  "lists.search": "Kërkoni mes personash që ndiqni",
+  "lists.subheading": "Listat tuaja",
+  "loading_indicator.label": "Po ngarkohet…",
+  "media_gallery.toggle_visible": "Ndërroni dukshmërinë",
+  "missing_indicator.label": "S’u gjet",
+  "missing_indicator.sublabel": "Ky burim s’u gjet dot",
+  "mute_modal.hide_notifications": "Të fshihen njoftimet prej këtij përdoruesi?",
+  "navigation_bar.apps": "Aplikacione për celular",
+  "navigation_bar.blocks": "Përdorues të bllokuar",
+  "navigation_bar.community_timeline": "Rrjedhë kohore vendore",
+  "navigation_bar.compose": "Hartoni mesazh të ri",
+  "navigation_bar.direct": "Mesazhe të drejtpërdrejta",
+  "navigation_bar.discover": "Zbuloni",
+  "navigation_bar.domain_blocks": "Përkatësi të fshehura",
+  "navigation_bar.edit_profile": "Përpunoni profilin",
+  "navigation_bar.favourites": "Të parapëlqyer",
+  "navigation_bar.filters": "Fjalë të heshtuara",
+  "navigation_bar.follow_requests": "Kërkesa për ndjekje",
+  "navigation_bar.follows_and_followers": "Follows and followers",
+  "navigation_bar.info": "Mbi këtë shërbyes",
+  "navigation_bar.keyboard_shortcuts": "Taste përkatës",
+  "navigation_bar.lists": "Lista",
+  "navigation_bar.logout": "Dalje",
+  "navigation_bar.mutes": "Përdorues të heshtuar",
+  "navigation_bar.personal": "Personale",
+  "navigation_bar.pins": "Mesazhe të fiksuar",
+  "navigation_bar.preferences": "Parapëlqime",
+  "navigation_bar.profile_directory": "Profile directory",
+  "navigation_bar.public_timeline": "Rrjedhë kohore të federuarish",
+  "navigation_bar.security": "Siguri",
+  "notification.favourite": "{name} parapëlqeu gjendjen tuaj",
+  "notification.follow": "{name} zuri t’ju ndjekë",
+  "notification.mention": "{name} ju ka përmendur",
+  "notification.poll": "A poll you have voted in has ended",
+  "notification.reblog": "{name} përforcoi gjendjen tuaj",
+  "notifications.clear": "Pastroji njoftimet",
+  "notifications.clear_confirmation": "Jeni i sigurt se doni të pastrohen përgjithmonë krejt njoftimet tuaja?",
+  "notifications.column_settings.alert": "Njoftime desktopi",
+  "notifications.column_settings.favourite": "Të parapëlqyer:",
+  "notifications.column_settings.filter_bar.advanced": "Shfaq krejt kategoritë",
+  "notifications.column_settings.filter_bar.category": "Shtyllë filtrimesh të shpejta",
+  "notifications.column_settings.filter_bar.show": "Shfaq",
+  "notifications.column_settings.follow": "Ndjekës të rinj:",
+  "notifications.column_settings.mention": "Përmendje:",
+  "notifications.column_settings.poll": "Poll results:",
+  "notifications.column_settings.push": "Njoftime Push",
+  "notifications.column_settings.reblog": "Përforcime:",
+  "notifications.column_settings.show": "Shfaq në shtylla",
+  "notifications.column_settings.sound": "Luaj një tingull",
+  "notifications.filter.all": "Krejt",
+  "notifications.filter.boosts": "Përforcime",
+  "notifications.filter.favourites": "Të parapëlqyer",
+  "notifications.filter.follows": "Ndjekje",
+  "notifications.filter.mentions": "Përmendje",
+  "notifications.filter.polls": "Poll results",
+  "notifications.group": "{count}s njoftime",
+  "poll.closed": "Closed",
+  "poll.refresh": "Refresh",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
+  "privacy.change": "Rregulloni privatësi gjendje",
+  "privacy.direct.long": "Postoja vetëm përdoruesve të përmendur",
+  "privacy.direct.short": "I drejtpërdrejtë",
+  "privacy.private.long": "Postojuani vetëm ndjekësve",
+  "privacy.private.short": "Vetëm ndjekësve",
+  "privacy.public.long": "Postojeni në rrjedha publike kohore",
+  "privacy.public.short": "Publike",
+  "privacy.unlisted.long": "Mos e postoni në rrjedha publike kohore",
+  "privacy.unlisted.short": "Jo në lista",
+  "regeneration_indicator.label": "Po ngarkohet…",
+  "regeneration_indicator.sublabel": "Prurja juaj vetjake po përgatiteet!",
+  "relative_time.days": "{number}d",
+  "relative_time.hours": "{number}h",
+  "relative_time.just_now": "tani",
+  "relative_time.minutes": "{number}m",
+  "relative_time.seconds": "{number}s",
+  "reply_indicator.cancel": "Anuloje",
+  "report.forward": "Përcillja {target}",
+  "report.forward_hint": "Llogaria është nga një shërbyes tjetër. Të dërgohet edhe një kopje e anonimizuar e raportimit?",
+  "report.hint": "Raportimi do t’u dërgohet moderatorëve të shërbyesit tuaj. Më poshtë mund të jepni një shpjegim se pse po e raportoni këtë llogari:",
+  "report.placeholder": "Komente shtesë",
+  "report.submit": "Parashtroje",
+  "report.target": "Raportim i {target}",
+  "search.placeholder": "Kërkoni",
+  "search_popout.search_format": "Format kërkimi të përparuar",
+  "search_popout.tips.full_text": "Kërkimi për tekst të thjeshtë përgjigjet me gjendje që keni shkruar, parapëlqyer, përforcuar, ose ku jeni përmendur, si dhe emra përdoruesish, emra ekrani dhe hashtagë që kanë përputhje me termin e kërkimit.",
+  "search_popout.tips.hashtag": "hashtag",
+  "search_popout.tips.status": "gjendje",
+  "search_popout.tips.text": "Kërkim për tekst të thjeshtë përgjigjet me emra, emra përdoruesish dhe hashtagë që kanë përputhje me termin e kërkimit",
+  "search_popout.tips.user": "përdorues",
+  "search_results.accounts": "Persona",
+  "search_results.hashtags": "Hashtagë",
+  "search_results.statuses": "Mesazhe",
+  "search_results.total": "{count, number} {count, plural, një {result} {results} të tjera}",
+  "status.admin_account": "Hap ndërfaqe moderimi për @{name}",
+  "status.admin_status": "Hape këtë gjendje te ndërfaqja e moderimit",
+  "status.block": "Blloko @{name}",
+  "status.cancel_reblog_private": "Shpërforcojeni",
+  "status.cannot_reblog": "Ky postim s’mund të përforcohet",
+  "status.copy": "Kopjoje lidhjen te gjendje",
+  "status.delete": "Fshije",
+  "status.detailed_status": "Pamje e hollësishme bisede",
+  "status.direct": "Mesazh i drejtpërdrejt për @{name}",
+  "status.embed": "Trupëzim",
+  "status.favourite": "I parapëlqyer",
+  "status.filtered": "I filtruar",
+  "status.load_more": "Ngarko më tepër",
+  "status.media_hidden": "Me media të fshehur",
+  "status.mention": "Përmendni @{name}",
+  "status.more": "Më tepër",
+  "status.mute": "Heshtoni @{name}",
+  "status.mute_conversation": "Heshtojeni bisedën",
+  "status.open": "Zgjeroje këtë gjendje",
+  "status.pin": "Fiksoje në profil",
+  "status.pinned": "Mesazh i fiksuar",
+  "status.read_more": "Lexoni më tepër",
+  "status.reblog": "Përforcojeni",
+  "status.reblog_private": "Përforcim për publikun origjinal",
+  "status.reblogged_by": "{name} përforcoi",
+  "status.reblogs.empty": "Këtë mesazh s’e ka përforcuar njeri deri tani. Kur ta bëjë dikush, kjo do të duket këtu.",
+  "status.redraft": "Fshijeni & rihartojeni",
+  "status.reply": "Përgjigjuni",
+  "status.replyAll": "Përgjigjuni rrjedhës",
+  "status.report": "Raportojeni @{name}",
+  "status.sensitive_warning": "Lëndë me spec",
+  "status.share": "Ndajeni me të tjerët",
+  "status.show_less": "Shfaq më pak",
+  "status.show_less_all": "Shfaq më pak për të tërë",
+  "status.show_more": "Shfaq më tepër",
+  "status.show_more_all": "Shfaq më tepër për të tërë",
+  "status.show_thread": "Shfaq rrjedhën",
+  "status.unmute_conversation": "Ktheji zërin bisedës",
+  "status.unpin": "Shfiksoje nga profili",
+  "suggestions.dismiss": "Mos e merr parasysh sugjerimin",
+  "suggestions.header": "Mund t’ju interesonte…",
+  "tabs_bar.federated_timeline": "E federuar",
+  "tabs_bar.home": "Kreu",
+  "tabs_bar.local_timeline": "Vendore",
+  "tabs_bar.notifications": "Njoftime",
+  "tabs_bar.search": "Kërkim",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
+  "trends.count_by_accounts": "{count} {rawCount, plural, një {person} {people} të tjerë} po flasin",
+  "ui.beforeunload": "Skica juaj do të humbë nëse dilni nga Mastodon-i.",
+  "upload_area.title": "Merreni & vëreni që të ngarkohet",
+  "upload_button.label": "Shtoni media (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "U tejkalua kufi ngarkimi kartelash.",
+  "upload_error.poll": "File upload not allowed with polls.",
+  "upload_form.description": "Përshkruajeni për persona me probleme shikimi",
+  "upload_form.focus": "Ndryshoni parapamjen",
+  "upload_form.undo": "Fshije",
+  "upload_progress.label": "Po ngarkohet…",
+  "video.close": "Mbylle videon",
+  "video.exit_fullscreen": "Dil nga mënyra Sa Krejt Ekrani",
+  "video.expand": "Zgjeroje videon",
+  "video.fullscreen": "Sa krejt ekrani",
+  "video.hide": "Fshihe videon",
+  "video.mute": "Hiqi zërin",
+  "video.pause": "Ndalesë",
+  "video.play": "Luaje",
+  "video.unmute": "Riktheji zërin"
+}
diff --git a/app/javascript/mastodon/locales/sr-Latn.json b/app/javascript/mastodon/locales/sr-Latn.json
index c8513dbe1809c75cbb002d186e6500051fd27bf1..8f8ca7c303fb209accc04b2e180d5f3dbf679cd0 100644
--- a/app/javascript/mastodon/locales/sr-Latn.json
+++ b/app/javascript/mastodon/locales/sr-Latn.json
@@ -5,7 +5,6 @@
   "account.block_domain": "Sakrij sve sa domena {domain}",
   "account.blocked": "Blocked",
   "account.direct": "Direct Message @{name}",
-  "account.disclaimer_full": "Navedene informacije možda ne odslikavaju korisnički profil u potpunosti.",
   "account.domain_blocked": "Domain hidden",
   "account.edit_profile": "Izmeni profil",
   "account.endorse": "Feature on profile",
@@ -36,7 +35,6 @@
   "account.unfollow": "Otprati",
   "account.unmute": "Ukloni ućutkavanje korisniku @{name}",
   "account.unmute_notifications": "Uključi nazad obaveštenja od korisnika @{name}",
-  "account.view_full_profile": "Vidi ceo profil",
   "alert.unexpected.message": "An unexpected error occurred.",
   "alert.unexpected.title": "Oops!",
   "boost_modal.combo": "Možete pritisnuti {combo} da preskočite ovo sledeći put",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "Vaš nalog nije {locked}. Svako može da Vas zaprati i da vidi objave namenjene samo Vašim pratiocima.",
   "compose_form.lock_disclaimer.lock": "zaključan",
   "compose_form.placeholder": "Å ta Vam je na umu?",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
   "compose_form.publish": "Tutni",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
   "compose_form.sensitive.marked": "Media is marked as sensitive",
   "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
   "compose_form.spoiler.marked": "Text is hidden behind warning",
   "compose_form.spoiler.unmarked": "Text is not hidden",
   "compose_form.spoiler_placeholder": "Ovde upišite upozorenje",
   "confirmation_modal.cancel": "Poništi",
+  "confirmations.block.block_and_report": "Block & Report",
   "confirmations.block.confirm": "Blokiraj",
   "confirmations.block.message": "Da li ste sigurni da želite da blokirate korisnika {name}?",
   "confirmations.delete.confirm": "Obriši",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Simboli",
   "emoji_button.travel": "Putovanja & mesta",
   "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_unavailable": "Profile unavailable",
   "empty_column.blocks": "You haven't blocked any users yet.",
   "empty_column.community": "Lokalna lajna je prazna. Napišite nešto javno da lajna produva!",
   "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "and {additional}",
   "hashtag.column_header.tag_mode.any": "or {additional}",
   "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
   "hashtag.column_settings.tag_mode.all": "All of these",
   "hashtag.column_settings.tag_mode.any": "Any of these",
   "hashtag.column_settings.tag_mode.none": "None of these",
@@ -149,6 +156,9 @@
   "home.column_settings.basic": "Osnovno",
   "home.column_settings.show_reblogs": "Prikaži i podržavanja",
   "home.column_settings.show_replies": "Prikaži odgovore",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
   "introduction.federation.action": "Next",
   "introduction.federation.federated.headline": "Federated",
   "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
@@ -156,7 +166,7 @@
   "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
   "introduction.federation.local.headline": "Local",
   "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
+  "introduction.interactions.action": "Finish toot-orial!",
   "introduction.interactions.favourite.headline": "Favourite",
   "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
   "introduction.interactions.reblog.headline": "Boost",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "da se prebacite na pretragu",
   "keyboard_shortcuts.start": "to open \"get started\" column",
   "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "da započnete skroz novi tut",
   "keyboard_shortcuts.unfocus": "da ne budete više na pretrazi/pravljenju novog tuta",
   "keyboard_shortcuts.up": "da se pomerite na gore u listi",
   "lightbox.close": "Zatvori",
   "lightbox.next": "Sledeći",
   "lightbox.previous": "Prethodni",
+  "lightbox.view_context": "View context",
   "lists.account.add": "Dodaj na listu",
   "lists.account.remove": "Ukloni sa liste",
   "lists.delete": "Obriši listu",
   "lists.edit": "Izmeni listu",
+  "lists.edit.submit": "Change title",
   "lists.new.create": "Dodaj listu",
   "lists.new.title_placeholder": "Naslov nove liste",
   "lists.search": "Pretraži među ljudima koje pratite",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "Omiljeni",
   "navigation_bar.filters": "Muted words",
   "navigation_bar.follow_requests": "Zahtevi za praćenje",
+  "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.info": "O ovoj instanci",
   "navigation_bar.keyboard_shortcuts": "Prečice na tastaturi",
   "navigation_bar.lists": "Liste",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Personal",
   "navigation_bar.pins": "Prikačeni tutovi",
   "navigation_bar.preferences": "Podešavanja",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "Federisana lajna",
   "navigation_bar.security": "Security",
   "notification.favourite": "{name} je stavio Vaš status kao omiljeni",
   "notification.follow": "{name} Vas je zapratio",
   "notification.mention": "{name} Vas je pomenuo",
+  "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "{name} je podržao(la) Vaš status",
   "notifications.clear": "Očisti obaveštenja",
   "notifications.clear_confirmation": "Da li ste sigurno da trajno želite da očistite Vaša obaveštenja?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Show",
   "notifications.column_settings.follow": "Novi pratioci:",
   "notifications.column_settings.mention": "Pominjanja:",
+  "notifications.column_settings.poll": "Poll results:",
   "notifications.column_settings.push": "Guraj obaveštenja",
   "notifications.column_settings.reblog": "Podrški:",
   "notifications.column_settings.show": "Prikaži u koloni",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favourites",
   "notifications.filter.follows": "Follows",
   "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
   "notifications.group": "{count} notifications",
+  "poll.closed": "Closed",
+  "poll.refresh": "Refresh",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
   "privacy.change": "Podesi status privatnosti",
   "privacy.direct.long": "Objavi samo korisnicima koji su pomenuti",
   "privacy.direct.short": "Direktno",
@@ -291,12 +315,12 @@
   "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.admin_account": "Open moderation interface for @{name}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "Ovaj status ne može da se podrži",
+  "status.copy": "Copy link to status",
   "status.delete": "Obriši",
   "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Odgovori",
   "status.replyAll": "Odgovori na diskusiju",
   "status.report": "Prijavi korisnika @{name}",
-  "status.sensitive_toggle": "Kliknite da vidite",
   "status.sensitive_warning": "Osetljiv sadržaj",
   "status.share": "Podeli",
   "status.show_less": "Prikaži manje",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Lokalno",
   "tabs_bar.notifications": "Obaveštenja",
   "tabs_bar.search": "Search",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
   "ui.beforeunload": "Ako napustite Mastodont, izgubićete napisani nacrt.",
   "upload_area.title": "Prevucite ovde da otpremite",
   "upload_button.label": "Dodaj multimediju",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "upload_form.description": "Opiši za slabovide osobe",
   "upload_form.focus": "Crop",
   "upload_form.undo": "Opozovi",
diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json
index 6e0ac6eca7c3f1b9d398feff379d20fc3d9cd185..8ef18a7743423d88e13f185f91ec42889d44594e 100644
--- a/app/javascript/mastodon/locales/sr.json
+++ b/app/javascript/mastodon/locales/sr.json
@@ -5,7 +5,6 @@
   "account.block_domain": "Сакриј све са домена {domain}",
   "account.blocked": "Блокиран",
   "account.direct": "Директна порука @{name}",
-  "account.disclaimer_full": "Наведене информације можда не одсликавају кориснички профил у потпуности.",
   "account.domain_blocked": "Домен сакривен",
   "account.edit_profile": "Измени профил",
   "account.endorse": "Приказати на профилу",
@@ -36,7 +35,6 @@
   "account.unfollow": "Отпрати",
   "account.unmute": "Уклони ућуткавање кориснику @{name}",
   "account.unmute_notifications": "Укључи назад обавештења од корисника @{name}",
-  "account.view_full_profile": "Види цео профил",
   "alert.unexpected.message": "Појавила се неочекивана грешка.",
   "alert.unexpected.title": "Упс!",
   "boost_modal.combo": "Можете притиснути {combo} да прескочите ово следећи пут",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "Ваш налог није {locked}. Свако може да Вас запрати и да види објаве намењене само Вашим пратиоцима.",
   "compose_form.lock_disclaimer.lock": "закључан",
   "compose_form.placeholder": "Шта Вам је на уму?",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
   "compose_form.publish": "Труби",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
   "compose_form.sensitive.marked": "Медији су означени као осетљиви",
   "compose_form.sensitive.unmarked": "Медији су означени као не-осетљиви",
   "compose_form.spoiler.marked": "Текст је сакривен иза упозорења",
   "compose_form.spoiler.unmarked": "Текст није сакривен",
   "compose_form.spoiler_placeholder": "Овде упишите упозорење",
   "confirmation_modal.cancel": "Поништи",
+  "confirmations.block.block_and_report": "Block & Report",
   "confirmations.block.confirm": "Блокирај",
   "confirmations.block.message": "Да ли сте сигурни да желите да блокирате корисника {name}?",
   "confirmations.delete.confirm": "Обриши",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Симболи",
   "emoji_button.travel": "Путовања и места",
   "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_unavailable": "Profile unavailable",
   "empty_column.blocks": "Још увек немате блокираних корисника.",
   "empty_column.community": "Локална временска линија је празна. Напишите нешто јавно да започнете!",
   "empty_column.direct": "Још увек немате директних порука. Када пошаљете или примите једну, појавиће се овде.",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "and {additional}",
   "hashtag.column_header.tag_mode.any": "or {additional}",
   "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
   "hashtag.column_settings.tag_mode.all": "All of these",
   "hashtag.column_settings.tag_mode.any": "Any of these",
   "hashtag.column_settings.tag_mode.none": "None of these",
@@ -149,6 +156,9 @@
   "home.column_settings.basic": "Основно",
   "home.column_settings.show_reblogs": "Прикажи и подржавања",
   "home.column_settings.show_replies": "Прикажи одговоре",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
   "introduction.federation.action": "Next",
   "introduction.federation.federated.headline": "Federated",
   "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
@@ -156,7 +166,7 @@
   "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
   "introduction.federation.local.headline": "Local",
   "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
+  "introduction.interactions.action": "Finish toot-orial!",
   "introduction.interactions.favourite.headline": "Favourite",
   "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
   "introduction.interactions.reblog.headline": "Boost",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "да се пребаците на претрагу",
   "keyboard_shortcuts.start": "да отворите колону \"почнимо\"",
   "keyboard_shortcuts.toggle_hidden": "да прикажете/сакријте текст иза CW-а",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "да започнете скроз нову трубу",
   "keyboard_shortcuts.unfocus": "да одфокусирате/не будете више на претрази/прављењу нове трубе",
   "keyboard_shortcuts.up": "да се померите на горе у листи",
   "lightbox.close": "Затвори",
   "lightbox.next": "Следећи",
   "lightbox.previous": "Претходни",
+  "lightbox.view_context": "View context",
   "lists.account.add": "Додај на листу",
   "lists.account.remove": "Уклони са листе",
   "lists.delete": "Обриши листу",
   "lists.edit": "Измени листу",
+  "lists.edit.submit": "Change title",
   "lists.new.create": "Додај листу",
   "lists.new.title_placeholder": "Наслов нове листе",
   "lists.search": "Претражи међу људима које пратите",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "Омиљене",
   "navigation_bar.filters": "Пригушене речи",
   "navigation_bar.follow_requests": "Захтеви за праћење",
+  "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.info": "О овој инстанци",
   "navigation_bar.keyboard_shortcuts": "Пречице на тастатури",
   "navigation_bar.lists": "Листе",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Personal",
   "navigation_bar.pins": "Прикачене трубе",
   "navigation_bar.preferences": "Подешавања",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "Здружена временска линија",
   "navigation_bar.security": "Безбедност",
   "notification.favourite": "{name} је ставио/ла Ваш статус као омиљени",
   "notification.follow": "{name} Вас је запратио/ла",
   "notification.mention": "{name} Вас је поменуо/ла",
+  "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "{name} је подржао/ла Ваш статус",
   "notifications.clear": "Очисти обавештења",
   "notifications.clear_confirmation": "Да ли сте сигурно да трајно желите да очистите Ваша обавештења?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Show",
   "notifications.column_settings.follow": "Нови пратиоци:",
   "notifications.column_settings.mention": "Помињања:",
+  "notifications.column_settings.poll": "Poll results:",
   "notifications.column_settings.push": "Гурај обавештења",
   "notifications.column_settings.reblog": "Подршки:",
   "notifications.column_settings.show": "Прикажи у колони",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favourites",
   "notifications.filter.follows": "Follows",
   "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
   "notifications.group": "{count} обавештења",
+  "poll.closed": "Closed",
+  "poll.refresh": "Refresh",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
   "privacy.change": "Подеси статус приватности",
   "privacy.direct.long": "Објави само корисницима који су поменути",
   "privacy.direct.short": "Директно",
@@ -291,12 +315,12 @@
   "search_results.hashtags": "Тарабе",
   "search_results.statuses": "Трубе",
   "search_results.total": "{count, number} {count, plural, one {резултат} few {резултата} other {резултата}}",
-  "standalone.public_title": "Поглед изнутра...",
   "status.admin_account": "Open moderation interface for @{name}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Блокирај @{name}",
   "status.cancel_reblog_private": "Уклони подршку",
   "status.cannot_reblog": "Овај статус не може да се подржи",
+  "status.copy": "Copy link to status",
   "status.delete": "Обриши",
   "status.detailed_status": "Детаљни преглед разговора",
   "status.direct": "Директна порука @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Одговори",
   "status.replyAll": "Одговори на дискусију",
   "status.report": "Пријави корисника @{name}",
-  "status.sensitive_toggle": "Кликните да видите",
   "status.sensitive_warning": "Осетљив садржај",
   "status.share": "Подели",
   "status.show_less": "Прикажи мање",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Локално",
   "tabs_bar.notifications": "Обавештења",
   "tabs_bar.search": "Претрага",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {човек} other {људи}} прича",
   "ui.beforeunload": "Ако напустите Мастодонт, изгубићете написани нацрт.",
   "upload_area.title": "Превуците овде да отпремите",
   "upload_button.label": "Додај мултимедију (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "upload_form.description": "Опишите за особе са оштећеним видом",
   "upload_form.focus": "Подесите",
   "upload_form.undo": "Обриши",
diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json
index 47ce8497a65b624616d257c41a7caa3d60ea9f84..ab12be885f14d6067dc64c8a4e4801f8eb93ff25 100644
--- a/app/javascript/mastodon/locales/sv.json
+++ b/app/javascript/mastodon/locales/sv.json
@@ -1,17 +1,16 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "Lägg till eller ta bort från listor",
   "account.badges.bot": "Robot",
   "account.block": "Blockera @{name}",
   "account.block_domain": "Dölj allt från {domain}",
   "account.blocked": "Blockerad",
   "account.direct": "Direktmeddelande @{name}",
-  "account.disclaimer_full": "Informationen nedan kan spegla användarens profil ofullständigt.",
   "account.domain_blocked": "Domän dold",
   "account.edit_profile": "Redigera profil",
   "account.endorse": "Feature on profile",
   "account.follow": "Följ",
   "account.followers": "Följare",
-  "account.followers.empty": "No one follows this user yet.",
+  "account.followers.empty": "Ingen följer denna användaren än.",
   "account.follows": "Följer",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Följer dig",
@@ -36,9 +35,8 @@
   "account.unfollow": "Sluta följa",
   "account.unmute": "Ta bort tystad @{name}",
   "account.unmute_notifications": "Återaktivera notifikationer från @{name}",
-  "account.view_full_profile": "Visa hela profilen",
   "alert.unexpected.message": "Ett oväntat fel uppstod.",
-  "alert.unexpected.title": "Oops!",
+  "alert.unexpected.title": "Whups!",
   "boost_modal.combo": "Du kan trycka {combo} för att slippa denna nästa gång",
   "bundle_column_error.body": "Något gick fel när du laddade denna komponent.",
   "bundle_column_error.retry": "Försök igen",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "Ditt konto är inte {locked}. Vemsomhelst kan följa dig och även se dina inlägg skrivna för endast dina följare.",
   "compose_form.lock_disclaimer.lock": "låst",
   "compose_form.placeholder": "Vad funderar du på?",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
   "compose_form.sensitive.marked": "Media har markerats som känsligt",
   "compose_form.sensitive.unmarked": "Media har inte markerats som känsligt",
   "compose_form.spoiler.marked": "Texten har dolts bakom en varning",
   "compose_form.spoiler.unmarked": "Texten är inte dold",
   "compose_form.spoiler_placeholder": "Skriv din varning här",
   "confirmation_modal.cancel": "Ã…ngra",
+  "confirmations.block.block_and_report": "Block & Report",
   "confirmations.block.confirm": "Blockera",
   "confirmations.block.message": "Är du säker att du vill blockera {name}?",
   "confirmations.delete.confirm": "Ta bort",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Symboler",
   "emoji_button.travel": "Resor & Platser",
   "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_unavailable": "Profile unavailable",
   "empty_column.blocks": "You haven't blocked any users yet.",
   "empty_column.community": "Den lokala tidslinjen är tom. Skriv något offentligt för att få bollen att rulla!",
   "empty_column.direct": "Du har inga direktmeddelanden än. När du skickar eller tar emot kommer den att dyka upp här.",
@@ -142,21 +147,26 @@
   "hashtag.column_header.tag_mode.all": "and {additional}",
   "hashtag.column_header.tag_mode.any": "or {additional}",
   "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
   "hashtag.column_settings.tag_mode.all": "All of these",
   "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_settings.tag_mode.none": "Ingen av dessa",
   "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
   "home.column_settings.basic": "Grundläggande",
   "home.column_settings.show_reblogs": "Visa knuffar",
   "home.column_settings.show_replies": "Visa svar",
-  "introduction.federation.action": "Next",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
+  "introduction.federation.action": "Nästa",
   "introduction.federation.federated.headline": "Federated",
   "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
   "introduction.federation.home.headline": "Home",
   "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
   "introduction.federation.local.headline": "Local",
   "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
+  "introduction.interactions.action": "Finish toot-orial!",
   "introduction.interactions.favourite.headline": "Favourite",
   "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
   "introduction.interactions.reblog.headline": "Boost",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "att fokusera sökfältet",
   "keyboard_shortcuts.start": "to open \"get started\" column",
   "keyboard_shortcuts.toggle_hidden": "att visa/gömma text bakom CW",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "att börja en helt ny toot",
   "keyboard_shortcuts.unfocus": "att avfokusera komponera text fält / sökfält",
   "keyboard_shortcuts.up": "att flytta upp i listan",
   "lightbox.close": "Stäng",
   "lightbox.next": "Nästa",
   "lightbox.previous": "Tidigare",
+  "lightbox.view_context": "View context",
   "lists.account.add": "Lägg till i lista",
   "lists.account.remove": "Ta bort från lista",
   "lists.delete": "Radera lista",
   "lists.edit": "Redigera lista",
+  "lists.edit.submit": "Ändra titel",
   "lists.new.create": "Lägg till lista",
   "lists.new.title_placeholder": "Ny listrubrik",
   "lists.search": "Sök bland personer du följer",
@@ -213,7 +226,7 @@
   "missing_indicator.label": "Hittades inte",
   "missing_indicator.sublabel": "Den här resursen kunde inte hittas",
   "mute_modal.hide_notifications": "Dölj notifikationer från denna användare?",
-  "navigation_bar.apps": "Mobile apps",
+  "navigation_bar.apps": "Mobilappar",
   "navigation_bar.blocks": "Blockerade användare",
   "navigation_bar.community_timeline": "Lokal tidslinje",
   "navigation_bar.compose": "Compose new toot",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "Favoriter",
   "navigation_bar.filters": "Muted words",
   "navigation_bar.follow_requests": "Följförfrågningar",
+  "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.info": "Om denna instans",
   "navigation_bar.keyboard_shortcuts": "Tangentbordsgenvägar",
   "navigation_bar.lists": "Listor",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Personal",
   "navigation_bar.pins": "Nålade inlägg (toots)",
   "navigation_bar.preferences": "Inställningar",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "Förenad tidslinje",
   "navigation_bar.security": "Säkerhet",
   "notification.favourite": "{name} favoriserade din status",
   "notification.follow": "{name} följer dig",
   "notification.mention": "{name} nämnde dig",
+  "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "{name} knuffade din status",
   "notifications.clear": "Rensa meddelanden",
   "notifications.clear_confirmation": "Är du säker på att du vill radera alla dina meddelanden permanent?",
@@ -247,16 +263,24 @@
   "notifications.column_settings.filter_bar.show": "Show",
   "notifications.column_settings.follow": "Nya följare:",
   "notifications.column_settings.mention": "Omnämningar:",
+  "notifications.column_settings.poll": "Poll results:",
   "notifications.column_settings.push": "Push meddelanden",
   "notifications.column_settings.reblog": "Knuffar:",
   "notifications.column_settings.show": "Visa i kolumnen",
   "notifications.column_settings.sound": "Spela upp ljud",
   "notifications.filter.all": "All",
   "notifications.filter.boosts": "Boosts",
-  "notifications.filter.favourites": "Favourites",
+  "notifications.filter.favourites": "Favoriter",
   "notifications.filter.follows": "Follows",
   "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
   "notifications.group": "{count} aviseringar",
+  "poll.closed": "Closed",
+  "poll.refresh": "Ladda om",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Rösta",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
   "privacy.change": "Justera sekretess",
   "privacy.direct.long": "Skicka endast till nämnda användare",
   "privacy.direct.short": "Direkt",
@@ -291,12 +315,12 @@
   "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.admin_account": "Open moderation interface for @{name}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.cancel_reblog_private": "Ta bort knuff",
   "status.cannot_reblog": "Detta inlägg kan inte knuffas",
+  "status.copy": "Copy link to status",
   "status.delete": "Ta bort",
   "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direktmeddela @{name}",
@@ -312,7 +336,7 @@
   "status.open": "Utvidga denna status",
   "status.pin": "Fäst i profil",
   "status.pinned": "Fäst toot",
-  "status.read_more": "Read more",
+  "status.read_more": "Läs mer",
   "status.reblog": "Knuff",
   "status.reblog_private": "Knuffa till de ursprungliga åhörarna",
   "status.reblogged_by": "{name} knuffade",
@@ -321,14 +345,13 @@
   "status.reply": "Svara",
   "status.replyAll": "Svara på tråden",
   "status.report": "Rapportera @{name}",
-  "status.sensitive_toggle": "Klicka för att se",
   "status.sensitive_warning": "Känsligt innehåll",
   "status.share": "Dela",
   "status.show_less": "Visa mindre",
   "status.show_less_all": "Visa mindre för alla",
   "status.show_more": "Visa mer",
   "status.show_more_all": "Visa mer för alla",
-  "status.show_thread": "Show thread",
+  "status.show_thread": "Visa tråd",
   "status.unmute_conversation": "Öppna konversation",
   "status.unpin": "Ångra fäst i profil",
   "suggestions.dismiss": "Dismiss suggestion",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Lokal",
   "tabs_bar.notifications": "Meddelanden",
   "tabs_bar.search": "Sök",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, en {person} andra {people}} pratar",
   "ui.beforeunload": "Ditt utkast kommer att förloras om du lämnar Mastodon.",
   "upload_area.title": "Dra & släpp för att ladda upp",
   "upload_button.label": "Lägg till media",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "upload_form.description": "Beskriv för synskadade",
   "upload_form.focus": "Beskär",
   "upload_form.undo": "Ta bort",
diff --git a/app/javascript/mastodon/locales/ta.json b/app/javascript/mastodon/locales/ta.json
index 0d510d011fd988fa03addb3c713686883efb4131..637ca884a3298bbfb89a8197cfa4fa3b5bb35f0b 100644
--- a/app/javascript/mastodon/locales/ta.json
+++ b/app/javascript/mastodon/locales/ta.json
@@ -1,358 +1,388 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
-  "account.badges.bot": "Bot",
+  "account.add_or_remove_from_list": "பட்டியல்களில் இருந்து சேர் அல்லது நீக்குக",
+  "account.badges.bot": "பாட்",
   "account.block": "Block @{name}",
-  "account.block_domain": "Hide everything from {domain}",
-  "account.blocked": "Blocked",
-  "account.direct": "Direct message @{name}",
-  "account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
-  "account.domain_blocked": "Domain hidden",
-  "account.edit_profile": "Edit profile",
-  "account.endorse": "Feature on profile",
-  "account.follow": "Follow",
-  "account.followers": "Followers",
-  "account.followers.empty": "No one follows this user yet.",
-  "account.follows": "Follows",
-  "account.follows.empty": "This user doesn't follow anyone yet.",
-  "account.follows_you": "Follows you",
-  "account.hide_reblogs": "Hide boosts from @{name}",
-  "account.link_verified_on": "Ownership of this link was checked on {date}",
-  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
+  "account.block_domain": "எல்லாவற்றையும் மறைக்க {domain}",
+  "account.blocked": "தடைமுட்டுகள்",
+  "account.direct": "நேரடி செய்தி @{name}",
+  "account.domain_blocked": "டொமைன் மறைக்கப்பட்டது",
+  "account.edit_profile": "சுயவிவரத்தைத் திருத்தவும்",
+  "account.endorse": "சுயவிவரத்தில் அம்சம்",
+  "account.follow": "பின்பற்று",
+  "account.followers": "பின்பற்றுபவர்கள்",
+  "account.followers.empty": "இதுவரை யாரும் இந்த பயனரைப் பின்தொடரவில்லை.",
+  "account.follows": "பின்பற்று",
+  "account.follows.empty": "இந்த பயனர் இதுவரை யாரையும் பின்தொடரவில்லை.",
+  "account.follows_you": "நீ பின் தொடர்கிறாய்",
+  "account.hide_reblogs": "இருந்து ஊக்கியாக மறை @{name}",
+  "account.link_verified_on": "இந்த இணைப்பை உரிமையாளர் சரிபார்க்கப்பட்டது {date}",
+  "account.locked_info": "இந்தக் கணக்கு தனியுரிமை நிலை பூட்டப்பட்டுள்ளது. அவர்களைப் பின்தொடர்பவர் யார் என்பதை உரிமையாளர் கைமுறையாக மதிப்பாய்வு செய்கிறார்.",
   "account.media": "Media",
-  "account.mention": "Mention @{name}",
-  "account.moved_to": "{name} has moved to:",
-  "account.mute": "Mute @{name}",
-  "account.mute_notifications": "Mute notifications from @{name}",
-  "account.muted": "Muted",
+  "account.mention": "குறிப்பிடு @{name}",
+  "account.moved_to": "{name} நகர்த்தப்பட்டது:",
+  "account.mute": "ஊமையான @{name}",
+  "account.mute_notifications": "அறிவிப்புகளை முடக்கு @{name}",
+  "account.muted": "முடக்கியது",
   "account.posts": "Toots",
-  "account.posts_with_replies": "Toots and replies",
+  "account.posts_with_replies": "Toots மற்றும் பதில்கள்",
   "account.report": "Report @{name}",
-  "account.requested": "Awaiting approval. Click to cancel follow request",
-  "account.share": "Share @{name}'s profile",
-  "account.show_reblogs": "Show boosts from @{name}",
-  "account.unblock": "Unblock @{name}",
-  "account.unblock_domain": "Unhide {domain}",
-  "account.unendorse": "Don't feature on profile",
-  "account.unfollow": "Unfollow",
-  "account.unmute": "Unmute @{name}",
-  "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account.view_full_profile": "View full profile",
-  "alert.unexpected.message": "An unexpected error occurred.",
-  "alert.unexpected.title": "Oops!",
-  "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.requested": "ஒப்புதலுக்காக காத்திருக்கிறது. கோரிக்கையை ரத்துசெய்ய கிளிக் செய்க",
+  "account.share": "பங்கிடு @{name}'s மனித முகத்தின்",
+  "account.show_reblogs": "காட்டு boosts இருந்து @{name}",
+  "account.unblock": "விடுவி @{name}",
+  "account.unblock_domain": "காண்பி {domain}",
+  "account.unendorse": "சுயவிவரத்தில் அம்சம் இல்லை",
+  "account.unfollow": "பின்தொடராட்",
+  "account.unmute": "தடுப்புநீக்கு @{name}",
+  "account.unmute_notifications": "அறிவிப்புகளை அகற்றவும் @{name}",
+  "alert.unexpected.message": "எதிர் பாராத பிழை ஏற்பட்டு விட்டது.",
+  "alert.unexpected.title": "அச்சச்சோ!",
+  "boost_modal.combo": "நீங்கள் அழுத்தவும் {combo} அடுத்த முறை தவிர்க்கவும்",
+  "bundle_column_error.body": "இந்த கூறுகளை ஏற்றும்போது ஏதோ தவறு ஏற்பட்டது.",
+  "bundle_column_error.retry": "மீண்டும் முயற்சி செய்",
   "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",
-  "column.community": "Local timeline",
-  "column.direct": "Direct messages",
-  "column.domain_blocks": "Hidden domains",
-  "column.favourites": "Favourites",
-  "column.follow_requests": "Follow requests",
+  "bundle_modal_error.close": "நெருக்கமாக",
+  "bundle_modal_error.message": "இந்த கூறுகளை ஏற்றும்போது ஏதோ தவறு ஏற்பட்டது.",
+  "bundle_modal_error.retry": "மீண்டும் முயற்சி செய்",
+  "column.blocks": "தடுக்கப்பட்ட பயனர்கள்",
+  "column.community": "உள்ளூர் காலக்கெடு",
+  "column.direct": "நேரடி செய்திகள்",
+  "column.domain_blocks": "மறைந்த களங்கள்",
+  "column.favourites": "விருப்பத்துக்குகந்த",
+  "column.follow_requests": "கோரிக்கைகளை பின்பற்றவும்",
   "column.home": "Home",
-  "column.lists": "Lists",
-  "column.mutes": "Muted users",
+  "column.lists": "குதிரை வீர்ர்கள்",
+  "column.mutes": "முடக்கப்பட்ட பயனர்கள்",
   "column.notifications": "Notifications",
   "column.pins": "Pinned toot",
-  "column.public": "Federated timeline",
-  "column_back_button.label": "Back",
-  "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.settings": "Settings",
-  "community.column_settings.media_only": "Media Only",
+  "column.public": "கூட்டாட்சி காலக்கெடு",
+  "column_back_button.label": "ஆதரி",
+  "column_header.hide_settings": "அமைப்புகளை மறை",
+  "column_header.moveLeft_settings": "நெடுவரிசையை இடதுபுறமாக நகர்த்தவும்",
+  "column_header.moveRight_settings": "நெடுவரிசை வலது புறமாக நகர்த்து",
+  "column_header.pin": "குண்டூசி",
+  "column_header.show_settings": "அமைப்புகளைக் காட்டு",
+  "column_header.unpin": "பொருத்தப்படாத",
+  "column_subheading.settings": "அமைப்புகள்",
+  "community.column_settings.media_only": "மீடியா மட்டுமே",
   "compose_form.direct_message_warning": "This toot will only be sent to all the mentioned users.",
-  "compose_form.direct_message_warning_learn_more": "Learn more",
-  "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",
+  "compose_form.direct_message_warning_learn_more": "மேலும் அறிக",
+  "compose_form.hashtag_warning": "இந்த toot பட்டியலிடப்படாதது போல எந்த ஹேஸ்டேக்கின் கீழ் பட்டியலிடப்படாது. ஹேஸ்டேக் மூலம் பொது டோட்டல்கள் மட்டுமே தேட முடியும்.",
+  "compose_form.lock_disclaimer": "உங்கள் கணக்கு அல்ல {locked}. உங்களுடைய பின்தொடர்பவர் மட்டும் இடுகைகளை யாராவது காணலாம்.",
+  "compose_form.lock_disclaimer.lock": "தாழிடு",
   "compose_form.placeholder": "What is on your mind?",
+  "compose_form.poll.add_option": "ஒரு விருப்பத்தைச் சேர்க்கவும்",
+  "compose_form.poll.duration": "வாக்கெடுப்பு காலம்",
+  "compose_form.poll.option_placeholder": "தேர்ந்தெடுப்ப {number}",
+  "compose_form.poll.remove_option": "இந்த விருப்பத்தை அகற்றவும்",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive.marked": "Media is marked as sensitive",
-  "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
-  "compose_form.spoiler.marked": "Text is hidden behind warning",
-  "compose_form.spoiler.unmarked": "Text is not hidden",
-  "compose_form.spoiler_placeholder": "Write your warning here",
-  "confirmation_modal.cancel": "Cancel",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
+  "compose_form.sensitive.marked": "ஊடகம் உணர்திறன் என குறிக்கப்பட்டுள்ளது",
+  "compose_form.sensitive.unmarked": "ஊடகம் உணர்திறன் என குறிக்கப்படவில்லை",
+  "compose_form.spoiler.marked": "எச்சரிக்கை பின்னால் உரை மறைக்கப்பட்டுள்ளது",
+  "compose_form.spoiler.unmarked": "உரை மறைக்கப்படவில்லை",
+  "compose_form.spoiler_placeholder": "இங்கே உங்கள் எச்சரிக்கையை எழுதுங்கள்",
+  "confirmation_modal.cancel": "எதிராணை",
+  "confirmations.block.block_and_report": "Block & Report",
   "confirmations.block.confirm": "Block",
-  "confirmations.block.message": "Are you sure you want to block {name}?",
+  "confirmations.block.message": "நீங்கள் நிச்சயமாக தடைசெய்ய விரும்புகிறீர்களா {name}?",
   "confirmations.delete.confirm": "Delete",
-  "confirmations.delete.message": "Are you sure you want to delete this status?",
+  "confirmations.delete.message": "இந்த நிலையை நிச்சயமாக நீக்க விரும்புகிறீர்களா?",
   "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. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.",
-  "confirmations.mute.confirm": "Mute",
-  "confirmations.mute.message": "Are you sure you want to mute {name}?",
-  "confirmations.redraft.confirm": "Delete & redraft",
-  "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.",
-  "confirmations.reply.confirm": "Reply",
-  "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
-  "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",
+  "confirmations.delete_list.message": "இந்த பட்டியலில் நிரந்தரமாக நீக்க விரும்புகிறீர்களா?",
+  "confirmations.domain_block.confirm": "முழு டொமைனை மறை",
+  "confirmations.domain_block.message": "நீங்கள் உண்மையில், நிச்சயமாக நீங்கள் முழு தடுக்க வேண்டும் நிச்சயமாக {domain}? பெரும்பாலான சந்தர்ப்பங்களில் ஒரு சில இலக்குகள் அல்லது மியூட்கள் போதுமானவை மற்றும் சிறந்தவை. எந்த பொது நேரத்திலும் அல்லது உங்கள் அறிவிப்புகளிலும் அந்தக் களத்திலிருந்து உள்ளடக்கத்தை நீங்கள் பார்க்க மாட்டீர்கள். அந்த களத்தில் இருந்து உங்கள் ஆதரவாளர்கள் அகற்றப்படுவார்கள்.",
+  "confirmations.mute.confirm": "ஊமையான",
+  "confirmations.mute.message": "நிச்சயமாக நீங்கள் முடக்க விரும்புகிறீர்களா {name}?",
+  "confirmations.redraft.confirm": "நீக்கு & redraft",
+  "confirmations.redraft.message": "நிச்சயமாக இந்த நிலையை நீக்கி, அதை மறுபடியும் உருவாக்க வேண்டுமா? பிடித்தவை மற்றும் ஊக்கங்கள் இழக்கப்படும், மற்றும் அசல் இடுகையில் பதில்கள் அனாதையான இருக்கும்.",
+  "confirmations.reply.confirm": "பதில்",
+  "confirmations.reply.message": "இப்போது பதில், தற்போது நீங்கள் உருவாக்கும் செய்தி மேலெழுதப்படும். நீங்கள் தொடர விரும்புகிறீர்களா?",
+  "confirmations.unfollow.confirm": "பின்தொடராட்",
+  "confirmations.unfollow.message": "நிச்சயமாக நீங்கள் பின்தொடர விரும்புகிறீர்களா {name}?",
+  "embed.instructions": "கீழே உள்ள குறியீட்டை நகலெடுப்பதன் மூலம் உங்கள் இணையதளத்தில் இந்த நிலையை உட்பொதிக்கவும்.",
+  "embed.preview": "இது போன்ற தோற்றத்தை இங்கு காணலாம்:",
+  "emoji_button.activity": "நடவடிக்கை",
+  "emoji_button.custom": "வழக்கம்",
+  "emoji_button.flags": "கொடி",
+  "emoji_button.food": "உணவு மற்றும் பானம்",
   "emoji_button.label": "Insert emoji",
-  "emoji_button.nature": "Nature",
-  "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻",
-  "emoji_button.objects": "Objects",
+  "emoji_button.nature": "இயற்கை",
+  "emoji_button.not_found": "எமோஜோஸ் இல்லை! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.objects": "மறுப்ப கூறு",
   "emoji_button.people": "People",
-  "emoji_button.recent": "Frequently used",
-  "emoji_button.search": "Search...",
-  "emoji_button.search_results": "Search results",
+  "emoji_button.recent": "அடிக்கடி பயன்படுத்தப்படும்",
+  "emoji_button.search": "தேடல்...",
+  "emoji_button.search_results": "தேடல் முடிவுகள்",
   "emoji_button.symbols": "Symbols",
-  "emoji_button.travel": "Travel & Places",
-  "empty_column.account_timeline": "No toots here!",
-  "empty_column.blocks": "You haven't blocked any users yet.",
-  "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
-  "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
-  "empty_column.domain_blocks": "There are no hidden domains yet.",
-  "empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.",
-  "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.",
-  "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
-  "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. When members of this list post new statuses, they will appear here.",
-  "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
-  "empty_column.mutes": "You haven't muted any users 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.developers": "Developers",
-  "getting_started.directory": "Profile directory",
+  "emoji_button.travel": "சுற்றுலா மற்றும் இடங்கள்",
+  "empty_column.account_timeline": "இல்லை toots இங்கே!",
+  "empty_column.account_unavailable": "சுயவிவரம் கிடைக்கவில்லை",
+  "empty_column.blocks": "இதுவரை எந்த பயனர்களும் தடுக்கவில்லை.",
+  "empty_column.community": "உள்ளூர் காலக்கெடு காலியாக உள்ளது. பந்தை உருட்டிக்கொள்வதற்கு பகிரங்கமாக ஒன்றை எழுதுங்கள்!",
+  "empty_column.direct": "உங்களிடம் நேரடியான செய்திகள் எதுவும் இல்லை. நீங்கள் ஒன்றை அனுப்பி அல்லது பெறும் போது, அது இங்கே காண்பிக்கும்.",
+  "empty_column.domain_blocks": "இன்னும் மறைந்த களங்கள் இல்லை.",
+  "empty_column.favourited_statuses": "இதுவரை உங்களுக்கு பிடித்த டோட்டுகள் இல்லை. உங்களுக்கு பிடித்த ஒரு போது, அது இங்கே காண்பிக்கும்.",
+  "empty_column.favourites": "இதுவரை யாரும் இந்தத் தட்டுக்கு ஆதரவில்லை. யாராவது செய்தால், அவர்கள் இங்கே காண்பார்கள்.",
+  "empty_column.follow_requests": "உங்களுக்கு இன்னும் எந்தவொரு கோரிக்கைகளும் இல்லை. நீங்கள் ஒன்றைப் பெற்றுக்கொண்டால், அது இங்கே காண்பிக்கும்.",
+  "empty_column.hashtag": "இன்னும் இந்த ஹேஸ்டேக்கில் எதுவும் இல்லை.",
+  "empty_column.home": "உங்கள் வீட்டுக் காலம் காலியாக உள்ளது! வருகை {public} அல்லது தொடங்குவதற்கு தேடலைப் பயன்படுத்தலாம் மற்றும் பிற பயனர்களை சந்திக்கவும்.",
+  "empty_column.home.public_timeline": "பொது காலக்கெடு",
+  "empty_column.list": "இந்த பட்டியலில் இதுவரை எதுவும் இல்லை. இந்த பட்டியலின் உறுப்பினர்கள் புதிய நிலைகளை இடுகையிடுகையில், அவை இங்கே தோன்றும்.",
+  "empty_column.lists": "உங்களுக்கு இதுவரை எந்த பட்டியலும் இல்லை. நீங்கள் ஒன்றை உருவாக்கினால், அது இங்கே காண்பிக்கும்.",
+  "empty_column.mutes": "நீங்கள் இதுவரை எந்த பயனர்களையும் முடக்கியிருக்கவில்லை.",
+  "empty_column.notifications": "உங்களிடம் எந்த அறிவிப்புகளும் இல்லை. உரையாடலைத் தொடங்க பிறருடன் தொடர்புகொள்ளவும்.",
+  "empty_column.public": "இங்கே எதுவும் இல்லை! பகிரங்கமாக ஒன்றை எழுதவும் அல்லது மற்ற நிகழ்வுகளிலிருந்து பயனர்களை அதை நிரப்புவதற்கு கைமுறையாக பின்பற்றவும்",
+  "follow_request.authorize": "அதிகாரமளி",
+  "follow_request.reject": "விலக்கு",
+  "getting_started.developers": "உருவாக்குநர்கள்",
+  "getting_started.directory": "சுயவிவர அடைவு",
   "getting_started.documentation": "Documentation",
-  "getting_started.heading": "Getting started",
-  "getting_started.invite": "Invite people",
-  "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.",
-  "getting_started.security": "Security",
-  "getting_started.terms": "Terms of service",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
-  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
-  "home.column_settings.basic": "Basic",
-  "home.column_settings.show_reblogs": "Show boosts",
-  "home.column_settings.show_replies": "Show replies",
-  "introduction.federation.action": "Next",
+  "getting_started.heading": "தொடங்குதல்",
+  "getting_started.invite": "நபர்களை அழைக்கவும்",
+  "getting_started.open_source_notice": "Mastodon திறந்த மூல மென்பொருள். GitHub இல் நீங்கள் பங்களிக்கவோ அல்லது புகார் அளிக்கவோ முடியும் {github}.",
+  "getting_started.security": "பத்திரம்",
+  "getting_started.terms": "சேவை விதிமுறைகள்",
+  "hashtag.column_header.tag_mode.all": "மற்றும் {additional}",
+  "hashtag.column_header.tag_mode.any": "அல்லது {additional}",
+  "hashtag.column_header.tag_mode.none": "இல்லாமல் {additional}",
+  "hashtag.column_settings.select.no_options_message": "பரிந்துரைகள் எதுவும் இல்லை",
+  "hashtag.column_settings.select.placeholder": "ஹாஷ்டேகுகளை உள்ளிடவும் …",
+  "hashtag.column_settings.tag_mode.all": "இவை அனைத்தும்",
+  "hashtag.column_settings.tag_mode.any": "இவை எதையும்",
+  "hashtag.column_settings.tag_mode.none": "இவற்றில் ஏதுமில்லை",
+  "hashtag.column_settings.tag_toggle": "இந்த நெடுவரிசையில் கூடுதல் குறிச்சொற்களை சேர்க்கவும்",
+  "home.column_settings.basic": "அடிப்படையான",
+  "home.column_settings.show_reblogs": "காட்டு boosts",
+  "home.column_settings.show_replies": "பதில்களைக் காண்பி",
+  "intervals.full.days": "{number, plural, one {# day} மற்ற {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} மற்ற {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} மற்ற {# minutes}}",
+  "introduction.federation.action": "அடுத்த",
   "introduction.federation.federated.headline": "Federated",
-  "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
+  "introduction.federation.federated.text": "கூட்டமைப்பின் பிற சேவையகங்களிலிருந்து பொது பதிவுகள் கூட்டப்பட்ட காலக்கெடுவில் தோன்றும்.",
   "introduction.federation.home.headline": "Home",
-  "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
+  "introduction.federation.home.text": "நீங்கள் பின்பற்றும் நபர்களின் இடுகைகள் உங்கள் வீட்டு ஊட்டத்தில் தோன்றும். நீங்கள் எந்த சர்வரில் யாரையும் பின்பற்ற முடியும்!",
   "introduction.federation.local.headline": "Local",
-  "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
-  "introduction.interactions.favourite.headline": "Favourite",
-  "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
-  "introduction.interactions.reblog.headline": "Boost",
-  "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
-  "introduction.interactions.reply.headline": "Reply",
-  "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
-  "introduction.welcome.action": "Let's go!",
-  "introduction.welcome.headline": "First steps",
-  "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
-  "keyboard_shortcuts.back": "to navigate back",
-  "keyboard_shortcuts.blocked": "to open blocked users list",
-  "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",
+  "introduction.federation.local.text": "உள்ளூர் சேவையகத்தில் தோன்றும் அதே சர்வரில் உள்ளவர்களின் பொது இடுகைகள்.",
+  "introduction.interactions.action": "பயிற்சி முடிக்க!",
+  "introduction.interactions.favourite.headline": "விருப்பத்துக்குகந்த",
+  "introduction.interactions.favourite.text": "நீங்கள் ஒரு காப்பாற்ற முடியும் toot பின்னர், மற்றும் ஆசிரியர் அதை நீங்கள் பிடித்திருக்கிறது என்று, அதை பிடித்திருக்கிறது என்று தெரியப்படுத்துங்கள்.",
+  "introduction.interactions.reblog.headline": "மதிப்பை உயர்த்து",
+  "introduction.interactions.reblog.text": "மற்றவர்களின் பகிர்ந்து கொள்ளலாம் toots உங்கள் ஆதரவாளர்களுடன் அவர்களை அதிகரிக்கும்.",
+  "introduction.interactions.reply.headline": "மறுமொழி கூறு",
+  "introduction.interactions.reply.text": "நீங்கள் மற்றவர்களுக்கும் உங்கள் சொந்த டோட்ட்களிற்கும் பதிலளிப்பீர்கள், இது ஒரு உரையாடலில் சங்கிலி ஒன்றாகச் சேரும்.",
+  "introduction.welcome.action": "போகலாம்!",
+  "introduction.welcome.headline": "முதல் படிகள்",
+  "introduction.welcome.text": "கூட்டாளிக்கு வருக! ஒரு சில நிமிடங்களில், பலவிதமான சேவையகங்களில் செய்திகளை உரையாட மற்றும் உங்கள் நண்பர்களிடம் பேச முடியும். ஆனால் இந்த சர்வர், {domain}, சிறப்பு - இது உங்கள் சுயவிவரத்தை வழங்குகிறது, எனவே அதன் பெயரை நினைவில் கொள்ளுங்கள்.",
+  "keyboard_shortcuts.back": "மீண்டும் செல்லவும்",
+  "keyboard_shortcuts.blocked": "தடுக்கப்பட்ட பயனர்களின் பட்டியலைத் திறக்க",
+  "keyboard_shortcuts.boost": "அதிகரிக்கும்",
+  "keyboard_shortcuts.column": "நெடுவரிசைகளில் ஒன்றில் நிலைக்கு கவனம் செலுத்த வேண்டும்",
+  "keyboard_shortcuts.compose": "தொகு உரைப்பகுதியை கவனத்தில் கொள்ளவும்",
   "keyboard_shortcuts.description": "Description",
-  "keyboard_shortcuts.direct": "to open direct messages column",
-  "keyboard_shortcuts.down": "to move down in the list",
+  "keyboard_shortcuts.direct": "நேரடி செய்திகள் பத்தி திறக்க",
+  "keyboard_shortcuts.down": "பட்டியலில் கீழே நகர்த்த",
   "keyboard_shortcuts.enter": "to open status",
-  "keyboard_shortcuts.favourite": "to favourite",
-  "keyboard_shortcuts.favourites": "to open favourites list",
-  "keyboard_shortcuts.federated": "to open federated timeline",
+  "keyboard_shortcuts.favourite": "பிடித்தது",
+  "keyboard_shortcuts.favourites": "பிடித்தவை பட்டியலை திறக்க",
+  "keyboard_shortcuts.federated": "ஒருங்கிணைந்த நேரத்தை திறக்க",
   "keyboard_shortcuts.heading": "Keyboard Shortcuts",
-  "keyboard_shortcuts.home": "to open home timeline",
-  "keyboard_shortcuts.hotkey": "Hotkey",
-  "keyboard_shortcuts.legend": "to display this legend",
-  "keyboard_shortcuts.local": "to open local timeline",
-  "keyboard_shortcuts.mention": "to mention author",
-  "keyboard_shortcuts.muted": "to open muted users list",
-  "keyboard_shortcuts.my_profile": "to open your profile",
-  "keyboard_shortcuts.notifications": "to open notifications column",
-  "keyboard_shortcuts.pinned": "to open pinned toots list",
-  "keyboard_shortcuts.profile": "to open author's profile",
-  "keyboard_shortcuts.reply": "to reply",
-  "keyboard_shortcuts.requests": "to open follow requests list",
-  "keyboard_shortcuts.search": "to focus search",
-  "keyboard_shortcuts.start": "to open \"get started\" column",
-  "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
-  "keyboard_shortcuts.toot": "to start a brand new toot",
-  "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
-  "keyboard_shortcuts.up": "to move up in the list",
-  "lightbox.close": "Close",
-  "lightbox.next": "Next",
-  "lightbox.previous": "Previous",
-  "lists.account.add": "Add to list",
-  "lists.account.remove": "Remove from list",
+  "keyboard_shortcuts.home": "வீட்டு நேரத்தை திறக்க",
+  "keyboard_shortcuts.hotkey": "ஹாட் கீ",
+  "keyboard_shortcuts.legend": "இந்த புராணத்தை காட்சிப்படுத்த",
+  "keyboard_shortcuts.local": "உள்ளூர் காலவரிசை திறக்க",
+  "keyboard_shortcuts.mention": "எழுத்தாளர் குறிப்பிட வேண்டும்",
+  "keyboard_shortcuts.muted": "முடக்கப்பட்ட பயனர்களின் பட்டியலைத் திறக்க",
+  "keyboard_shortcuts.my_profile": "உங்கள் சுயவிவரத்தை திறக்க",
+  "keyboard_shortcuts.notifications": "அறிவிப்பு நெடுவரிசையைத் திறக்க",
+  "keyboard_shortcuts.pinned": "திறக்க பொருத்தப்பட்டன toots பட்டியல்",
+  "keyboard_shortcuts.profile": "ஆசிரியரின் சுயவிவரத்தைத் திறக்க",
+  "keyboard_shortcuts.reply": "பதிலளிக்க",
+  "keyboard_shortcuts.requests": "கோரிக்கைகள் பட்டியலைத் திறக்க",
+  "keyboard_shortcuts.search": "தேடல் கவனம் செலுத்த",
+  "keyboard_shortcuts.start": "'தொடங்குவதற்கு' நெடுவரிசை திறக்க",
+  "keyboard_shortcuts.toggle_hidden": "CW க்கு பின்னால் உரையை மறைக்க / மறைக்க",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
+  "keyboard_shortcuts.toot": "தொடங்க ஒரு புதிய toot",
+  "keyboard_shortcuts.unfocus": "உரை பகுதியை / தேடலை கவனம் செலுத்த வேண்டும்",
+  "keyboard_shortcuts.up": "பட்டியலில் மேலே செல்ல",
+  "lightbox.close": "நெருக்கமாக",
+  "lightbox.next": "அடுத்த",
+  "lightbox.previous": "சென்ற",
+  "lightbox.view_context": "View context",
+  "lists.account.add": "பட்டியலில் சேர்",
+  "lists.account.remove": "பட்டியலில் இருந்து அகற்று",
   "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",
-  "loading_indicator.label": "Loading...",
-  "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.apps": "Mobile apps",
-  "navigation_bar.blocks": "Blocked users",
-  "navigation_bar.community_timeline": "Local timeline",
-  "navigation_bar.compose": "Compose new toot",
-  "navigation_bar.direct": "Direct messages",
-  "navigation_bar.discover": "Discover",
-  "navigation_bar.domain_blocks": "Hidden domains",
-  "navigation_bar.edit_profile": "Edit profile",
-  "navigation_bar.favourites": "Favourites",
-  "navigation_bar.filters": "Muted words",
-  "navigation_bar.follow_requests": "Follow requests",
-  "navigation_bar.info": "About this instance",
-  "navigation_bar.keyboard_shortcuts": "Hotkeys",
-  "navigation_bar.lists": "Lists",
-  "navigation_bar.logout": "Logout",
-  "navigation_bar.mutes": "Muted users",
+  "lists.edit": "பட்டியலை திருத்து",
+  "lists.edit.submit": "தலைப்பு மாற்றவும்",
+  "lists.new.create": "பட்டியலில் சேர்",
+  "lists.new.title_placeholder": "புதிய பட்டியல் தலைப்பு",
+  "lists.search": "நீங்கள் பின்தொடரும் நபர்கள் மத்தியில் தேடுதல்",
+  "lists.subheading": "உங்கள் பட்டியல்கள்",
+  "loading_indicator.label": "ஏற்றுதல்...",
+  "media_gallery.toggle_visible": "நிலைமாற்று தெரியும்",
+  "missing_indicator.label": "கிடைக்கவில்லை",
+  "missing_indicator.sublabel": "இந்த ஆதாரத்தை காண முடியவில்லை",
+  "mute_modal.hide_notifications": "இந்த பயனரின் அறிவிப்புகளை மறைக்கவா?",
+  "navigation_bar.apps": "மொபைல் பயன்பாடுகள்",
+  "navigation_bar.blocks": "தடுக்கப்பட்ட பயனர்கள்",
+  "navigation_bar.community_timeline": "உள்ளூர் காலக்கெடு",
+  "navigation_bar.compose": "புதியவற்றை எழுதுக toot",
+  "navigation_bar.direct": "நேரடி செய்திகள்",
+  "navigation_bar.discover": "கண்டு பிடி",
+  "navigation_bar.domain_blocks": "மறைந்த களங்கள்",
+  "navigation_bar.edit_profile": "சுயவிவரத்தைத் திருத்தவும்",
+  "navigation_bar.favourites": "விருப்பத்துக்குகந்த",
+  "navigation_bar.filters": "முடக்கப்பட்ட வார்த்தைகள்",
+  "navigation_bar.follow_requests": "கோரிக்கைகளை பின்பற்றவும்",
+  "navigation_bar.follows_and_followers": "Follows and followers",
+  "navigation_bar.info": "இந்த நிகழ்வு பற்றி",
+  "navigation_bar.keyboard_shortcuts": "சுருக்குவிசைகள்",
+  "navigation_bar.lists": "குதிரை வீர்ர்கள்",
+  "navigation_bar.logout": "விடு பதிகை",
+  "navigation_bar.mutes": "முடக்கப்பட்ட பயனர்கள்",
   "navigation_bar.personal": "Personal",
-  "navigation_bar.pins": "Pinned toots",
-  "navigation_bar.preferences": "Preferences",
-  "navigation_bar.public_timeline": "Federated timeline",
-  "navigation_bar.security": "Security",
-  "notification.favourite": "{name} favourited your status",
-  "notification.follow": "{name} followed you",
-  "notification.mention": "{name} mentioned you",
-  "notification.reblog": "{name} boosted your status",
-  "notifications.clear": "Clear notifications",
-  "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
-  "notifications.column_settings.alert": "Desktop notifications",
-  "notifications.column_settings.favourite": "Favourites:",
-  "notifications.column_settings.filter_bar.advanced": "Display all categories",
-  "notifications.column_settings.filter_bar.category": "Quick filter bar",
-  "notifications.column_settings.filter_bar.show": "Show",
-  "notifications.column_settings.follow": "New followers:",
-  "notifications.column_settings.mention": "Mentions:",
+  "navigation_bar.pins": "பொருத்தப்பட்டன toots",
+  "navigation_bar.preferences": "விருப்பங்கள்",
+  "navigation_bar.profile_directory": "Profile directory",
+  "navigation_bar.public_timeline": "கூட்டாட்சி காலக்கெடு",
+  "navigation_bar.security": "பத்திரம்",
+  "notification.favourite": "{name} ஆர்வம் கொண்டவர், உங்கள் நிலை",
+  "notification.follow": "{name} நீங்கள் தொடர்ந்து வந்தீர்கள்",
+  "notification.mention": "{name} நீங்கள் குறிப்பிட்டுள்ளீர்கள்",
+  "notification.poll": "நீங்கள் வாக்களித்த வாக்கெடுப்பு முடிவடைந்தது",
+  "notification.reblog": "{name} உங்கள் நிலை அதிகரித்தது",
+  "notifications.clear": "அறிவிப்புகளை அழிக்கவும்",
+  "notifications.clear_confirmation": "உங்கள் எல்லா அறிவிப்புகளையும் நிரந்தரமாக அழிக்க விரும்புகிறீர்களா?",
+  "notifications.column_settings.alert": "டெஸ்க்டாப் அறிவிப்புகள்",
+  "notifications.column_settings.favourite": "பிடித்தவை:",
+  "notifications.column_settings.filter_bar.advanced": "எல்லா வகைகளையும் காட்டு",
+  "notifications.column_settings.filter_bar.category": "விரைவு வடிகட்டி பட்டை",
+  "notifications.column_settings.filter_bar.show": "காட்டு",
+  "notifications.column_settings.follow": "புதிய பின்பற்றுபவர்கள்:",
+  "notifications.column_settings.mention": "குறிப்பிடுகிறது:",
+  "notifications.column_settings.poll": "கருத்துக்கணிப்பு முடிவுகள்:",
   "notifications.column_settings.push": "Push notifications",
-  "notifications.column_settings.reblog": "Boosts:",
-  "notifications.column_settings.show": "Show in column",
-  "notifications.column_settings.sound": "Play sound",
-  "notifications.filter.all": "All",
-  "notifications.filter.boosts": "Boosts",
-  "notifications.filter.favourites": "Favourites",
-  "notifications.filter.follows": "Follows",
-  "notifications.filter.mentions": "Mentions",
+  "notifications.column_settings.reblog": "மதிப்பை உயர்த்து:",
+  "notifications.column_settings.show": "பத்தியில் காண்பி",
+  "notifications.column_settings.sound": "ஒலி விளையாட",
+  "notifications.filter.all": "எல்லா",
+  "notifications.filter.boosts": "மதிப்பை உயர்த்து",
+  "notifications.filter.favourites": "விருப்பத்துக்குகந்த",
+  "notifications.filter.follows": "பின்பற்று",
+  "notifications.filter.mentions": "குறிப்பிடுகிறார்",
+  "notifications.filter.polls": "கருத்துக்கணிப்பு முடிவுகள்",
   "notifications.group": "{count} notifications",
-  "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",
+  "poll.closed": "மூடிய",
+  "poll.refresh": "பத்துயிர்ப்ப?ட்டு",
+  "poll.total_votes": "{count, plural, one {# vote} மற்ற {# votes}}",
+  "poll.vote": "வாக்களி",
+  "poll_button.add_poll": "வாக்கெடுப்பைச் சேர்க்கவும்",
+  "poll_button.remove_poll": "வாக்கெடுப்பை அகற்று",
+  "privacy.change": "நிலை தனியுரிமை",
+  "privacy.direct.long": "குறிப்பிடப்பட்ட பயனர்களுக்கு மட்டுமே இடுகையிடவும்",
+  "privacy.direct.short": "நடத்து",
+  "privacy.private.long": "பின்தொடர்பவர்களுக்கு மட்டுமே இடுகை",
+  "privacy.private.short": "பின்பற்றுபவர்கள் மட்டும்",
+  "privacy.public.long": "பொது நேரங்களுக்கான இடுகை",
   "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!",
+  "privacy.unlisted.short": "பட்டியலிடப்படாத",
+  "regeneration_indicator.label": "சுமையேற்றம்…",
+  "regeneration_indicator.sublabel": "உங்கள் வீட்டு ஊட்டம் தயார் செய்யப்படுகிறது!",
   "relative_time.days": "{number}d",
   "relative_time.hours": "{number}h",
-  "relative_time.just_now": "now",
+  "relative_time.just_now": "இப்பொழுது",
   "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",
+  "reply_indicator.cancel": "எதிராணை",
+  "report.forward": "முன்னோக்கி {target}",
+  "report.forward_hint": "கணக்கு மற்றொரு சேவையகத்திலிருந்து வருகிறது. அறிக்கையின் அநாமதேய பிரதி ஒன்றை அனுப்பவும்.?",
+  "report.hint": "அறிக்கை உங்கள் மாதிரியாக மாற்றியமைக்கப்படும். கீழே உள்ள கணக்கை நீங்கள் ஏன் புகாரளிக்கிறீர்கள் என்பதற்கான விளக்கத்தை வழங்கலாம்:",
+  "report.placeholder": "கூடுதல் கருத்துரைகள்",
   "report.submit": "Submit",
   "report.target": "Report {target}",
-  "search.placeholder": "Search",
-  "search_popout.search_format": "Advanced search format",
-  "search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
-  "search_popout.tips.hashtag": "hashtag",
+  "search.placeholder": "தேடு",
+  "search_popout.search_format": "மேம்பட்ட தேடல் வடிவம்",
+  "search_popout.tips.full_text": "எளிமையான உரை நீங்கள் எழுதப்பட்ட, புகழ், அதிகரித்தது, அல்லது குறிப்பிட்டுள்ள, அதே போல் பயனர் பெயர்கள், காட்சி பெயர்கள், மற்றும் ஹேஸ்டேகைகளை கொண்டுள்ளது என்று நிலைகளை கொடுக்கிறது.",
+  "search_popout.tips.hashtag": "ஹேஸ்டேக்",
   "search_popout.tips.status": "status",
-  "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
+  "search_popout.tips.text": "எளிய உரை காட்சி பெயர்கள், பயனர்பெயர்கள் மற்றும் ஹாஷ்டேட்களுடன் பொருந்துகிறது",
   "search_popout.tips.user": "user",
   "search_results.accounts": "People",
-  "search_results.hashtags": "Hashtags",
+  "search_results.hashtags": "ஹாஷ்டேக்குகளைச்",
   "search_results.statuses": "Toots",
-  "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
-  "standalone.public_title": "A look inside...",
-  "status.admin_account": "Open moderation interface for @{name}",
-  "status.admin_status": "Open this status in the moderation interface",
+  "search_results.total": "{count, number} {count, plural, one {result} மற்ற {results}}",
+  "status.admin_account": "மிதமான இடைமுகத்தை திறக்க @{name}",
+  "status.admin_status": "மிதமான இடைமுகத்தில் இந்த நிலையை திறக்கவும்",
   "status.block": "Block @{name}",
-  "status.cancel_reblog_private": "Unboost",
-  "status.cannot_reblog": "This post cannot be boosted",
+  "status.cancel_reblog_private": "இல்லை பூஸ்ட்",
+  "status.cannot_reblog": "இந்த இடுகை அதிகரிக்க முடியாது",
+  "status.copy": "நிலைக்கு இணைப்பை நகலெடு",
   "status.delete": "Delete",
-  "status.detailed_status": "Detailed conversation view",
-  "status.direct": "Direct message @{name}",
-  "status.embed": "Embed",
-  "status.favourite": "Favourite",
-  "status.filtered": "Filtered",
-  "status.load_more": "Load more",
-  "status.media_hidden": "Media hidden",
-  "status.mention": "Mention @{name}",
-  "status.more": "More",
-  "status.mute": "Mute @{name}",
-  "status.mute_conversation": "Mute conversation",
-  "status.open": "Expand this status",
-  "status.pin": "Pin on profile",
-  "status.pinned": "Pinned toot",
-  "status.read_more": "Read more",
-  "status.reblog": "Boost",
-  "status.reblog_private": "Boost to original audience",
-  "status.reblogged_by": "{name} boosted",
-  "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
-  "status.redraft": "Delete & re-draft",
-  "status.reply": "Reply",
-  "status.replyAll": "Reply to thread",
+  "status.detailed_status": "விரிவான உரையாடல் காட்சி",
+  "status.direct": "நேரடி செய்தி @{name}",
+  "status.embed": "கிடத்து",
+  "status.favourite": "விருப்பத்துக்குகந்த",
+  "status.filtered": "வடிகட்டு",
+  "status.load_more": "அதிகமாய் ஏற்று",
+  "status.media_hidden": "மீடியா மறைக்கப்பட்டது",
+  "status.mention": "குறிப்பிடு @{name}",
+  "status.more": "அதிக",
+  "status.mute": "ஊமையான @{name}",
+  "status.mute_conversation": "ஒலிதடு உரையாடல்",
+  "status.open": "இந்த நிலையை விரிவாக்கு",
+  "status.pin": "சுயவிவரத்தில் முள்",
+  "status.pinned": "பொருத்தப்பட்டன toot",
+  "status.read_more": "மேலும் வாசிக்க",
+  "status.reblog": "மதிப்பை உயர்த்து",
+  "status.reblog_private": "Boost அசல் பார்வையாளர்களுக்கு",
+  "status.reblogged_by": "{name} மதிப்பை உயர்த்து",
+  "status.reblogs.empty": "இதுவரை யாரும் இந்த மோதலை அதிகரிக்கவில்லை. யாராவது செய்தால், அவர்கள் இங்கே காண்பார்கள்.",
+  "status.redraft": "நீக்கு மற்றும் மீண்டும் வரைவு",
+  "status.reply": "பதில்",
+  "status.replyAll": "நூலுக்கு பதிலளிக்கவும்",
   "status.report": "Report @{name}",
-  "status.sensitive_toggle": "Click to view",
-  "status.sensitive_warning": "Sensitive content",
-  "status.share": "Share",
-  "status.show_less": "Show less",
-  "status.show_less_all": "Show less for all",
-  "status.show_more": "Show more",
-  "status.show_more_all": "Show more for all",
-  "status.show_thread": "Show thread",
-  "status.unmute_conversation": "Unmute conversation",
-  "status.unpin": "Unpin from profile",
-  "suggestions.dismiss": "Dismiss suggestion",
-  "suggestions.header": "You might be interested in…",
+  "status.sensitive_warning": "உணர்திறன் உள்ளடக்கம்",
+  "status.share": "பங்கிடு",
+  "status.show_less": "குறைவாகக் காண்பி",
+  "status.show_less_all": "அனைத்தையும் குறைவாக காட்டு",
+  "status.show_more": "மேலும் காட்ட",
+  "status.show_more_all": "அனைவருக்கும் மேலும் காட்டு",
+  "status.show_thread": "நூல் காட்டு",
+  "status.unmute_conversation": "ஊமையாக உரையாடல் இல்லை",
+  "status.unpin": "சுயவிவரத்திலிருந்து நீக்கவும்",
+  "suggestions.dismiss": "பரிந்துரை விலக்க",
+  "suggestions.header": "நீங்கள் ஆர்வமாக இருக்கலாம் …",
   "tabs_bar.federated_timeline": "Federated",
   "tabs_bar.home": "Home",
   "tabs_bar.local_timeline": "Local",
   "tabs_bar.notifications": "Notifications",
-  "tabs_bar.search": "Search",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
-  "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
-  "upload_area.title": "Drag & drop to upload",
-  "upload_button.label": "Add media (JPEG, PNG, GIF, WebM, MP4, MOV)",
-  "upload_form.description": "Describe for the visually impaired",
-  "upload_form.focus": "Crop",
+  "tabs_bar.search": "தேடு",
+  "time_remaining.days": "{number, plural, one {# day} மற்ற {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} மற்ற {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} மற்ற {# minutes}} left",
+  "time_remaining.moments": "தருணங்கள் மீதமுள்ளன",
+  "time_remaining.seconds": "{number, plural, one {# second} மற்ற {# seconds}} left",
+  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} மற்ற {people}} உரையாடு",
+  "ui.beforeunload": "நீங்கள் வெளியே சென்றால் உங்கள் வரைவு இழக்கப்படும் மஸ்தோடோன்.",
+  "upload_area.title": "பதிவேற்ற & இழுக்கவும்",
+  "upload_button.label": "மீடியாவைச் சேர்க்கவும் (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "கோப்பு பதிவேற்ற வரம்பு மீறப்பட்டது.",
+  "upload_error.poll": "கோப்பு பதிவேற்றம் அனுமதிக்கப்படவில்லை.",
+  "upload_form.description": "பார்வையற்ற விவரிக்கவும்",
+  "upload_form.focus": "மாற்றம் முன்னோட்டம்",
   "upload_form.undo": "Delete",
-  "upload_progress.label": "Uploading...",
-  "video.close": "Close video",
-  "video.exit_fullscreen": "Exit full screen",
-  "video.expand": "Expand video",
+  "upload_progress.label": "ஏற்றுகிறது ...",
+  "video.close": "வீடியோவை மூடு",
+  "video.exit_fullscreen": "முழு திரையில் இருந்து வெளியேறவும்",
+  "video.expand": "வீடியோவை விரிவாக்கு",
   "video.fullscreen": "Full screen",
-  "video.hide": "Hide video",
-  "video.mute": "Mute sound",
+  "video.hide": "வீடியோவை மறை",
+  "video.mute": "ஒலி முடக்கவும்",
   "video.pause": "Pause",
-  "video.play": "Play",
-  "video.unmute": "Unmute sound"
+  "video.play": "விளையாடு",
+  "video.unmute": "ஒலி மெளனமாக இல்லை"
 }
diff --git a/app/javascript/mastodon/locales/te.json b/app/javascript/mastodon/locales/te.json
index 7306ec00194d2a5ee59790186792b5e8d9a7a761..269ea45c3b4e2ebd3e2e78d4cdb3c0f407ccb8f3 100644
--- a/app/javascript/mastodon/locales/te.json
+++ b/app/javascript/mastodon/locales/te.json
@@ -5,7 +5,6 @@
   "account.block_domain": "{domain} నుంచి అన్నీ దాచిపెట్టు",
   "account.blocked": "బ్లాక్ అయినవి",
   "account.direct": "@{name}కు నేరుగా సందేశం పంపు",
-  "account.disclaimer_full": "క్రింది సమాచారం వాడుకరి యొక్క ప్రొఫైల్ను అసంపూర్తిగా ప్రతిబింబించవచ్చు.",
   "account.domain_blocked": "డొమైన్ దాచిపెట్టబడినది",
   "account.edit_profile": "ప్రొఫైల్ని సవరించండి",
   "account.endorse": "ప్రొఫైల్లో చూపించు",
@@ -36,7 +35,6 @@
   "account.unfollow": "అనుసరించవద్దు",
   "account.unmute": "@{name}పై మ్యూట్ ని తొలగించు",
   "account.unmute_notifications": "@{name} నుంచి ప్రకటనలపై మ్యూట్ ని తొలగించు",
-  "account.view_full_profile": "పూర్తి ప్రొఫైల్ను చూడండి",
   "alert.unexpected.message": "అనుకోని తప్పు జరిగినది.",
   "alert.unexpected.title": "అయ్యో!",
   "boost_modal.combo": "మీరు తదుపరిసారి దీనిని దాటవేయడానికి {combo} నొక్కవచ్చు",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "మీ ఖాతా {locked} చేయబడలేదు. ఎవరైనా మిమ్మల్ని అనుసరించి మీ అనుచరులకు-మాత్రమే పోస్ట్లను వీక్షించవచ్చు.",
   "compose_form.lock_disclaimer.lock": "బిగించబడినది",
   "compose_form.placeholder": "మీ మనస్సులో ఏముంది?",
+  "compose_form.poll.add_option": "ఒక ఎంపికను చేర్చండి",
+  "compose_form.poll.duration": "ఎన్నిక వ్యవధి",
+  "compose_form.poll.option_placeholder": "ఎంపిక {number}",
+  "compose_form.poll.remove_option": "ఈ ఎంపికను తొలగించు",
   "compose_form.publish": "టూట్",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
   "compose_form.sensitive.marked": "మీడియా సున్నితమైనదిగా గుర్తించబడింది",
   "compose_form.sensitive.unmarked": "మీడియా సున్నితమైనదిగా గుర్తించబడలేదు",
   "compose_form.spoiler.marked": "హెచ్చరిక వెనుక పాఠ్యం దాచబడింది",
   "compose_form.spoiler.unmarked": "పాఠ్యం దాచబడలేదు",
   "compose_form.spoiler_placeholder": "ఇక్కడ మీ హెచ్చరికను రాయండి",
   "confirmation_modal.cancel": "రద్దు చెయ్యి",
+  "confirmations.block.block_and_report": "Block & Report",
   "confirmations.block.confirm": "బ్లాక్ చేయి",
   "confirmations.block.message": "మీరు ఖచ్చితంగా {name}ని బ్లాక్ చేయాలనుకుంటున్నారా?",
   "confirmations.delete.confirm": "తొలగించు",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "చిహ్నాలు",
   "emoji_button.travel": "ప్రయాణం & ప్రదేశాలు",
   "empty_column.account_timeline": "ఇక్కడ ఏ టూట్లూ లేవు!No toots here!",
+  "empty_column.account_unavailable": "Profile unavailable",
   "empty_column.blocks": "మీరు ఇంకా ఏ వినియోగదారులనూ బ్లాక్ చేయలేదు.",
   "empty_column.community": "స్థానిక కాలక్రమం ఖాళీగా ఉంది. మొదలుపెట్టడానికి బహిరంగంగా ఏదో ఒకటి వ్రాయండి!",
   "empty_column.direct": "మీకు ఇంకా ఏ ప్రత్యక్ష సందేశాలు లేవు. మీరు ఒకదాన్ని పంపినప్పుడు లేదా స్వీకరించినప్పుడు, అది ఇక్కడ చూపబడుతుంది.",
@@ -128,11 +133,11 @@
   "empty_column.lists": "మీకు ఇంకా జాబితాలు ఏమీ లేవు. మీరు ఒకటి సృష్టించగానే, అది ఇక్కడ కనబడుతుంది.",
   "empty_column.mutes": "మీరు ఇంకా ఏ వినియోగదారులనూ మ్యూట్ చేయలేదు.",
   "empty_column.notifications": "మీకు ఇంకా ఏ నోటిఫికేషన్లు లేవు. సంభాషణను ప్రారంభించడానికి ఇతరులతో ప్రతిస్పందించండి.",
-  "empty_column.public": "ఇక్కడ ఏమీ లేదు! దీన్ని నింపడానికి బహిరంగంగా ఏదైనా వ్రాయండి, లేదా ఇతర దృష్టాంతాల్లోని వినియోగదారులను అనుసరించండి",
+  "empty_column.public": "ఇక్కడ ఏమీ లేదు! దీన్ని నింపడానికి బహిరంగంగా ఏదైనా వ్రాయండి, లేదా ఇతర సేవికల నుండి వినియోగదారులను అనుసరించండి",
   "follow_request.authorize": "అనుమతించు",
   "follow_request.reject": "తిరస్కరించు",
   "getting_started.developers": "డెవలపర్లు",
-  "getting_started.directory": "ప్రొఫైల్ డైరెక్టరీProfile directory",
+  "getting_started.directory": "ప్రొఫైల్ డైరెక్టరీ",
   "getting_started.documentation": "డాక్యుమెంటేషన్",
   "getting_started.heading": "మొదలుపెడదాం",
   "getting_started.invite": "వ్యక్తులను ఆహ్వానించండి",
@@ -142,13 +147,18 @@
   "hashtag.column_header.tag_mode.all": "మరియు {additional}",
   "hashtag.column_header.tag_mode.any": "లేదా {additional}",
   "hashtag.column_header.tag_mode.none": "{additional} లేకుండా",
-  "hashtag.column_settings.tag_mode.all": "ఇవన్నీAll of these",
+  "hashtag.column_settings.select.no_options_message": "ఎటువంటి సూచనలూ దొరకలేదు",
+  "hashtag.column_settings.select.placeholder": "హ్యాష్ టాగులు నింపండి…",
+  "hashtag.column_settings.tag_mode.all": "ఇవన్నీ",
   "hashtag.column_settings.tag_mode.any": "వీటిలో ఏవైనా",
   "hashtag.column_settings.tag_mode.none": "ఇవేవీ కావు",
-  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "hashtag.column_settings.tag_toggle": "ఈ నిలువు వరుసలో మరికొన్ని ట్యాగులను చేర్చండి",
   "home.column_settings.basic": "ప్రాథమిక",
   "home.column_settings.show_reblogs": "బూస్ట్ లను చూపించు",
   "home.column_settings.show_replies": "ప్రత్యుత్తరాలను చూపించు",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
   "introduction.federation.action": "తరువాత",
   "introduction.federation.federated.headline": "Federated",
   "introduction.federation.federated.text": "ఫెడివర్స్ లోని ఇతర సర్వర్లకు చెందిన పబ్లిక్ టూట్లు ఫెడరేటెడ్ టైంలైన్ లో కనిపిస్తాయి.",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "శోధనపై దృష్టి పెట్టండి",
   "keyboard_shortcuts.start": "\"ఇక్కడ ప్రారంభించండి\" నిలువు వరుసను తెరవడానికి",
   "keyboard_shortcuts.toggle_hidden": "CW వెనుక ఉన్న పాఠ్యాన్ని చూపడానికి / దాచడానికి",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "ఒక సరికొత్త టూట్ను ప్రారంభించడానికి",
   "keyboard_shortcuts.unfocus": "పాఠ్యం వ్రాసే ఏరియా/శోధన పట్టిక నుండి బయటకు రావడానికి",
   "keyboard_shortcuts.up": "జాబితాలో పైకి తరలించడానికి",
   "lightbox.close": "మూసివేయు",
   "lightbox.next": "తరువాత",
   "lightbox.previous": "మునుపటి",
+  "lightbox.view_context": "View context",
   "lists.account.add": "జాబితాకు జోడించు",
   "lists.account.remove": "జాబితా నుండి తొలగించు",
   "lists.delete": "జాబితాను తొలగించు",
   "lists.edit": "జాబితాను సవరించు",
+  "lists.edit.submit": "శీర్షిక మార్చు",
   "lists.new.create": "జాబితాను జోడించు",
   "lists.new.title_placeholder": "కొత్త జాబితా శీర్షిక",
   "lists.search": "మీరు అనుసరించే వ్యక్తులలో శోధించండి",
@@ -224,7 +237,8 @@
   "navigation_bar.favourites": "ఇష్టపడినవి",
   "navigation_bar.filters": "మ్యూట్ చేయబడిన పదాలు",
   "navigation_bar.follow_requests": "అనుసరించడానికి అభ్యర్ధనలు",
-  "navigation_bar.info": "ఈ దృష్టాంతం గురించి",
+  "navigation_bar.follows_and_followers": "Follows and followers",
+  "navigation_bar.info": "ఈ సేవిక గురించి",
   "navigation_bar.keyboard_shortcuts": "హాట్ కీలు",
   "navigation_bar.lists": "జాబితాలు",
   "navigation_bar.logout": "లాగ్ అవుట్ చేయండి",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "వ్యక్తిగతం",
   "navigation_bar.pins": "అతికించిన టూట్లు",
   "navigation_bar.preferences": "ప్రాధాన్యతలు",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "సమాఖ్య కాలక్రమం",
   "navigation_bar.security": "భద్రత",
   "notification.favourite": "{name} మీ స్టేటస్ ను ఇష్టపడ్డారు",
   "notification.follow": "{name} మిమ్మల్ని అనుసరిస్తున్నారు",
   "notification.mention": "{name} మిమ్మల్ని ప్రస్తావించారు",
+  "notification.poll": "మీరు పాల్గొనిన ఎన్సిక ముగిసినది",
   "notification.reblog": "{name} మీ స్టేటస్ ను బూస్ట్ చేసారు",
   "notifications.clear": "ప్రకటనలను తుడిచివేయు",
   "notifications.clear_confirmation": "మీరు మీ అన్ని నోటిఫికేషన్లను శాశ్వతంగా తొలగించాలనుకుంటున్నారా?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "చూపించు",
   "notifications.column_settings.follow": "క్రొత్త అనుచరులు:",
   "notifications.column_settings.mention": "ప్రస్తావనలు:",
+  "notifications.column_settings.poll": "ఎన్నిక ఫలితాలు:",
   "notifications.column_settings.push": "పుష్ ప్రకటనలు",
   "notifications.column_settings.reblog": "బూస్ట్ లు:",
   "notifications.column_settings.show": "నిలువు వరుసలో చూపు",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "ఇష్టాలు",
   "notifications.filter.follows": "అనుసరిస్తున్నవి",
   "notifications.filter.mentions": "పేర్కొన్నవి",
+  "notifications.filter.polls": "ఎన్నిక ఫలితాలు",
   "notifications.group": "{count} ప్రకటనలు",
+  "poll.closed": "మూసివేయబడినవి",
+  "poll.refresh": "నవీకరించు",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "ఎన్నుకోండి",
+  "poll_button.add_poll": "ఒక ఎన్నికను చేర్చు",
+  "poll_button.remove_poll": "ఎన్నికను తొలగించు",
   "privacy.change": "స్టేటస్ గోప్యతను సర్దుబాటు చేయండి",
   "privacy.direct.long": "పేర్కొన్న వినియోగదారులకు మాత్రమే పోస్ట్ చేయి",
   "privacy.direct.short": "ప్రత్యక్ష",
@@ -276,7 +300,7 @@
   "reply_indicator.cancel": "రద్దు చెయ్యి",
   "report.forward": "{target}కి ఫార్వార్డ్ చేయండి",
   "report.forward_hint": "ఖాతా మరొక సర్వర్లో ఉంది. నివేదిక యొక్క ఒక అనామకంగా ఉన్న కాపీని అక్కడికి కూడా పంపించమంటారా?",
-  "report.hint": "మీ దుష్టాంత మోడరేటర్లకు నివేదిక పంపబడుతుంది. దిగువ ఈ ఖాతాను ఎందుకు నివేదిస్తున్నారనేదాని వివరణను మీరు అందించవచ్చు:",
+  "report.hint": "మీ సేవిక మోడరేటర్లకు నివేదిక పంపబడుతుంది. ఈ ఖాతాను ఎందుకు నివేదిస్తున్నారనేదాని వివరణను మీరు దిగువన అందించవచ్చు:",
   "report.placeholder": "అదనపు వ్యాఖ్యలు",
   "report.submit": "సమర్పించండి",
   "report.target": "{target}పై ఫిర్యాదు చేయండి",
@@ -291,12 +315,12 @@
   "search_results.hashtags": "హాష్ ట్యాగ్లు",
   "search_results.statuses": "టూట్లు",
   "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
-  "standalone.public_title": "లోపలికి ఒక చూపు...",
-  "status.admin_account": "Open moderation interface for @{name}",
-  "status.admin_status": "Open this status in the moderation interface",
+  "status.admin_account": "@{name} కొరకు సమన్వయ వినిమయసీమను తెరువు",
+  "status.admin_status": "సమన్వయ వినిమయసీమలో ఈ స్టేటస్ ను తెరవండి",
   "status.block": "@{name} ను బ్లాక్ చేయి",
   "status.cancel_reblog_private": "బూస్ట్ను తొలగించు",
   "status.cannot_reblog": "ఈ పోస్ట్ను బూస్ట్ చేయడం సాధ్యం కాదు",
+  "status.copy": "లంకెను స్టేటస్కు కాపీ చేయి",
   "status.delete": "తొలగించు",
   "status.detailed_status": "వివరణాత్మక సంభాషణ వీక్షణ",
   "status.direct": "@{name}కు నేరుగా సందేశం పంపు",
@@ -321,7 +345,6 @@
   "status.reply": "ప్రత్యుత్తరం",
   "status.replyAll": "సంభాషణకు ప్రత్యుత్తరం ఇవ్వండి",
   "status.report": "@{name}పై ఫిర్యాదుచేయు",
-  "status.sensitive_toggle": "వీక్షించడానికి క్లిక్ చేయండి",
   "status.sensitive_warning": "సున్నితమైన కంటెంట్",
   "status.share": "పంచుకోండి",
   "status.show_less": "తక్కువ చూపించు",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "స్థానిక",
   "tabs_bar.notifications": "ప్రకటనలు",
   "tabs_bar.search": "శోధన",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "కొన్ని క్షణాలు మాత్రమే మిగిలి ఉన్నాయి",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} మాట్లాడుతున్నారు",
   "ui.beforeunload": "మీరు మాస్టొడొన్ను వదిలివేస్తే మీ డ్రాఫ్ట్లు పోతాయి.",
   "upload_area.title": "అప్లోడ్ చేయడానికి డ్రాగ్ & డ్రాప్ చేయండి",
   "upload_button.label": "మీడియాను జోడించండి (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "upload_form.description": "దృష్టి లోపమున్న వారి కోసం వివరించండి",
   "upload_form.focus": "ప్రివ్యూను మార్చు",
   "upload_form.undo": "తొలగించు",
diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json
index 2683284f4229ffd58a0c9517fd3ee8c0bbaa5eb1..3bcf389c7f3ac06f4023b7e7bdf6a9fa23733315 100644
--- a/app/javascript/mastodon/locales/th.json
+++ b/app/javascript/mastodon/locales/th.json
@@ -1,358 +1,388 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
-  "account.badges.bot": "Bot",
-  "account.block": "Block @{name}",
-  "account.block_domain": "Hide everything from {domain}",
-  "account.blocked": "Blocked",
-  "account.direct": "Direct Message @{name}",
-  "account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
-  "account.domain_blocked": "Domain hidden",
-  "account.edit_profile": "Edit profile",
-  "account.endorse": "Feature on profile",
-  "account.follow": "Follow",
-  "account.followers": "Followers",
-  "account.followers.empty": "No one follows this user yet.",
-  "account.follows": "Follows",
-  "account.follows.empty": "This user doesn't follow anyone yet.",
-  "account.follows_you": "Follows you",
-  "account.hide_reblogs": "Hide boosts from @{name}",
-  "account.link_verified_on": "Ownership of this link was checked on {date}",
-  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
-  "account.media": "Media",
-  "account.mention": "Mention @{name}",
-  "account.moved_to": "{name} has moved to:",
-  "account.mute": "Mute @{name}",
-  "account.mute_notifications": "Mute notifications from @{name}",
-  "account.muted": "Muted",
-  "account.posts": "Posts",
-  "account.posts_with_replies": "Toots with replies",
-  "account.report": "Report @{name}",
-  "account.requested": "Awaiting approval",
-  "account.share": "Share @{name}'s profile",
-  "account.show_reblogs": "Show boosts from @{name}",
-  "account.unblock": "Unblock @{name}",
-  "account.unblock_domain": "Unhide {domain}",
-  "account.unendorse": "Don't feature on profile",
-  "account.unfollow": "Unfollow",
-  "account.unmute": "Unmute @{name}",
-  "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account.view_full_profile": "View full profile",
-  "alert.unexpected.message": "An unexpected error occurred.",
-  "alert.unexpected.title": "Oops!",
-  "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",
-  "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",
-  "column.community": "Local timeline",
-  "column.direct": "Direct messages",
-  "column.domain_blocks": "Hidden domains",
-  "column.favourites": "Favourites",
-  "column.follow_requests": "Follow requests",
-  "column.home": "Home",
-  "column.lists": "Lists",
-  "column.mutes": "Muted users",
-  "column.notifications": "Notifications",
-  "column.pins": "Pinned toot",
-  "column.public": "Federated timeline",
-  "column_back_button.label": "Back",
-  "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.settings": "Settings",
-  "community.column_settings.media_only": "Media Only",
-  "compose_form.direct_message_warning": "This toot will only be visible to all the mentioned users.",
-  "compose_form.direct_message_warning_learn_more": "Learn more",
-  "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",
-  "compose_form.placeholder": "What is on your mind?",
-  "compose_form.publish": "Toot",
+  "account.add_or_remove_from_list": "เพิ่มหรือเอาออกจากรายการ",
+  "account.badges.bot": "บอต",
+  "account.block": "ปิดกั้น @{name}",
+  "account.block_domain": "ซ่อนทุกอย่างจาก {domain}",
+  "account.blocked": "ปิดกั้นอยู่",
+  "account.direct": "ส่งข้อความโดยตรงถึง @{name}",
+  "account.domain_blocked": "ซ่อนโดเมนอยู่",
+  "account.edit_profile": "แก้ไขโปรไฟล์",
+  "account.endorse": "แสดงให้เห็นในโปรไฟล์",
+  "account.follow": "ติดตาม",
+  "account.followers": "ผู้ติดตาม",
+  "account.followers.empty": "ยังไม่มีใครติดตามผู้ใช้นี้",
+  "account.follows": "การติดตาม",
+  "account.follows.empty": "ผู้ใช้นี้ยังไม่ได้ติดตามใคร",
+  "account.follows_you": "ติดตามคุณ",
+  "account.hide_reblogs": "ซ่อนการดันจาก @{name}",
+  "account.link_verified_on": "ตรวจสอบความเป็นเจ้าของของลิงก์นี้เมื่อ {date}",
+  "account.locked_info": "มีการตั้งสถานะความเป็นส่วนตัวของบัญชีนี้เป็นล็อคอยู่ เจ้าของตรวจทานผู้ที่สามารถติดตามเขาด้วยตนเอง",
+  "account.media": "สื่อ",
+  "account.mention": "กล่าวถึง @{name}",
+  "account.moved_to": "{name} ได้ย้ายไปยัง:",
+  "account.mute": "ปิดเสียง @{name}",
+  "account.mute_notifications": "ปิดเสียงการแจ้งเตือนจาก @{name}",
+  "account.muted": "ปิดเสียงอยู่",
+  "account.posts": "โพสต์",
+  "account.posts_with_replies": "โพสต์และการตอบกลับ",
+  "account.report": "รายงาน @{name}",
+  "account.requested": "กำลังรอการอนุมัติ คลิกเพื่อยกเลิกคำขอติดตาม",
+  "account.share": "แบ่งปันโปรไฟล์ของ @{name}",
+  "account.show_reblogs": "แสดงการดันจาก @{name}",
+  "account.unblock": "เลิกปิดกั้น @{name}",
+  "account.unblock_domain": "เลิกซ่อน {domain}",
+  "account.unendorse": "ไม่แสดงให้เห็นในโปรไฟล์",
+  "account.unfollow": "เลิกติดตาม",
+  "account.unmute": "เลิกปิดเสียง @{name}",
+  "account.unmute_notifications": "เลิกปิดเสียงการแจ้งเตือนจาก @{name}",
+  "alert.unexpected.message": "เกิดข้อผิดพลาดที่ไม่คาดคิด",
+  "alert.unexpected.title": "อุปส์!",
+  "boost_modal.combo": "คุณสามารถกด {combo} เพื่อข้ามสิ่งนี้ในครั้งถัดไป",
+  "bundle_column_error.body": "มีบางอย่างผิดพลาดขณะโหลดส่วนประกอบนี้",
+  "bundle_column_error.retry": "ลองอีกครั้ง",
+  "bundle_column_error.title": "ข้อผิดพลาดเครือข่าย",
+  "bundle_modal_error.close": "ปิด",
+  "bundle_modal_error.message": "มีบางอย่างผิดพลาดขณะโหลดส่วนประกอบนี้",
+  "bundle_modal_error.retry": "ลองอีกครั้ง",
+  "column.blocks": "ผู้ใช้ที่ปิดกั้นอยู่",
+  "column.community": "เส้นเวลาในเว็บ",
+  "column.direct": "ข้อความโดยตรง",
+  "column.domain_blocks": "โดเมนที่ซ่อนอยู่",
+  "column.favourites": "รายการโปรด",
+  "column.follow_requests": "คำขอติดตาม",
+  "column.home": "หน้าแรก",
+  "column.lists": "รายการ",
+  "column.mutes": "ผู้ใช้ที่ปิดเสียงอยู่",
+  "column.notifications": "การแจ้งเตือน",
+  "column.pins": "โพสต์ที่ปักหมุด",
+  "column.public": "เส้นเวลาที่ติดต่อกับภายนอก",
+  "column_back_button.label": "ย้อนกลับ",
+  "column_header.hide_settings": "ซ่อนการตั้งค่า",
+  "column_header.moveLeft_settings": "ย้ายคอลัมน์ไปทางซ้าย",
+  "column_header.moveRight_settings": "ย้ายคอลัมน์ไปทางขวา",
+  "column_header.pin": "ปักหมุด",
+  "column_header.show_settings": "แสดงการตั้งค่า",
+  "column_header.unpin": "ถอนหมุด",
+  "column_subheading.settings": "การตั้งค่า",
+  "community.column_settings.media_only": "สื่อเท่านั้น",
+  "compose_form.direct_message_warning": "จะส่งโพสต์นี้ไปยังผู้ใช้ที่กล่าวถึงเท่านั้น",
+  "compose_form.direct_message_warning_learn_more": "เรียนรู้เพิ่มเติม",
+  "compose_form.hashtag_warning": "จะไม่แสดงรายการโพสต์นี้ภายใต้แฮชแท็กใด ๆ เนื่องจากไม่อยู่ในรายการ เฉพาะโพสต์สาธารณะเท่านั้นที่สามารถค้นหาโดยแฮชแท็ก",
+  "compose_form.lock_disclaimer": "บัญชีของคุณไม่ได้ {locked} ใครก็ตามสามารถติดตามคุณเพื่อดูโพสต์สำหรับผู้ติดตามเท่านั้นของคุณ",
+  "compose_form.lock_disclaimer.lock": "ล็อคอยู่",
+  "compose_form.placeholder": "คุณกำลังคิดอะไรอยู่?",
+  "compose_form.poll.add_option": "เพิ่มทางเลือก",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "ทางเลือก {number}",
+  "compose_form.poll.remove_option": "เอาทางเลือกนี้ออก",
+  "compose_form.publish": "โพสต์",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive.marked": "Media is marked as sensitive",
-  "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
-  "compose_form.spoiler.marked": "Text is hidden behind warning",
-  "compose_form.spoiler.unmarked": "Text is not hidden",
-  "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}?",
-  "confirmations.delete.confirm": "Delete",
-  "confirmations.delete.message": "Are you sure you want to delete this status?",
-  "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",
+  "compose_form.sensitive.hide": "ทำเครื่องหมายสื่อว่าละเอียดอ่อน",
+  "compose_form.sensitive.marked": "มีการทำเครื่องหมายสื่อว่าละเอียดอ่อน",
+  "compose_form.sensitive.unmarked": "ไม่มีการทำเครื่องหมายสื่อว่าละเอียดอ่อน",
+  "compose_form.spoiler.marked": "มีการซ่อนข้อความอยู่หลังคำเตือน",
+  "compose_form.spoiler.unmarked": "ไม่มีการซ่อนข้อความ",
+  "compose_form.spoiler_placeholder": "เขียนคำเตือนของคุณที่นี่",
+  "confirmation_modal.cancel": "ยกเลิก",
+  "confirmations.block.block_and_report": "ปิดกั้นแล้วรายงาน",
+  "confirmations.block.confirm": "ปิดกั้น",
+  "confirmations.block.message": "คุณแน่ใจหรือไม่ว่าต้องการปิดกั้น {name}?",
+  "confirmations.delete.confirm": "ลบ",
+  "confirmations.delete.message": "คุณแน่ใจหรือไม่ว่าต้องการลบสถานะนี้?",
+  "confirmations.delete_list.confirm": "ลบ",
+  "confirmations.delete_list.message": "คุณแน่ใจหรือไม่ว่าต้องการลบรายการนี้อย่างถาวร?",
+  "confirmations.domain_block.confirm": "ซ่อนทั้งโดเมน",
   "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.redraft.confirm": "Delete & redraft",
-  "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.",
-  "confirmations.reply.confirm": "Reply",
-  "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
-  "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.account_timeline": "No toots here!",
-  "empty_column.blocks": "You haven't blocked any users yet.",
-  "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
-  "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
-  "empty_column.domain_blocks": "There are no hidden domains yet.",
-  "empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.",
-  "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.",
-  "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
-  "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.lists": "You don't have any lists yet. When you create one, it will show up here.",
-  "empty_column.mutes": "You haven't muted any users 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.developers": "Developers",
-  "getting_started.directory": "Profile directory",
-  "getting_started.documentation": "Documentation",
-  "getting_started.heading": "Getting started",
-  "getting_started.invite": "Invite people",
-  "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.",
-  "getting_started.security": "Security",
-  "getting_started.terms": "Terms of service",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
-  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
-  "home.column_settings.basic": "Basic",
-  "home.column_settings.show_reblogs": "Show boosts",
-  "home.column_settings.show_replies": "Show replies",
-  "introduction.federation.action": "Next",
-  "introduction.federation.federated.headline": "Federated",
-  "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
-  "introduction.federation.home.headline": "Home",
-  "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
-  "introduction.federation.local.headline": "Local",
-  "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
-  "introduction.interactions.favourite.headline": "Favourite",
+  "confirmations.mute.confirm": "ปิดเสียง",
+  "confirmations.mute.message": "คุณแน่ใจหรือไม่ว่าต้องการปิดเสียง {name}?",
+  "confirmations.redraft.confirm": "ลบแล้วร่างใหม่",
+  "confirmations.redraft.message": "คุณแน่ใจหรือไม่ว่าต้องการลบสถานะนี้แล้วร่างใหม่? รายการโปรดและการดันจะหายไป และการตอบกลับโพสต์ดั้งเดิมจะไม่มีความเกี่ยวพัน",
+  "confirmations.reply.confirm": "ตอบกลับ",
+  "confirmations.reply.message": "การตอบกลับตอนนี้จะเขียนทับข้อความที่คุณกำลังเขียน คุณแน่ใจหรือไม่ว่าต้องการดำเนินการต่อ?",
+  "confirmations.unfollow.confirm": "เลิกติดตาม",
+  "confirmations.unfollow.message": "คุณแน่ใจหรือไม่ว่าต้องการเลิกติดตาม {name}?",
+  "embed.instructions": "ฝังสถานะนี้ในเว็บไซต์ของคุณโดยคัดลอกโค้ดด้านล่าง",
+  "embed.preview": "นี่คือลักษณะที่จะปรากฏ:",
+  "emoji_button.activity": "กิจกรรม",
+  "emoji_button.custom": "กำหนดเอง",
+  "emoji_button.flags": "ธง",
+  "emoji_button.food": "อาหารและเครื่องดื่ม",
+  "emoji_button.label": "แทรกอีโมจิ",
+  "emoji_button.nature": "ธรรมชาติ",
+  "emoji_button.not_found": "ไม่มีอีโมโจ!! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.objects": "วัตถุ",
+  "emoji_button.people": "ผู้คน",
+  "emoji_button.recent": "ที่ใช้บ่อย",
+  "emoji_button.search": "ค้นหา...",
+  "emoji_button.search_results": "ผลลัพธ์การค้นหา",
+  "emoji_button.symbols": "สัญลักษณ์",
+  "emoji_button.travel": "การเดินทางและสถานที่",
+  "empty_column.account_timeline": "ไม่มีโพสต์ที่นี่!",
+  "empty_column.account_unavailable": "ไม่มีโปรไฟล์",
+  "empty_column.blocks": "คุณยังไม่ได้ปิดกั้นผู้ใช้ใด ๆ",
+  "empty_column.community": "เส้นเวลาในเว็บว่างเปล่า เขียนบางอย่างเป็นสาธารณะเพื่อเริ่มต้น!",
+  "empty_column.direct": "คุณยังไม่มีข้อความโดยตรงใด ๆ เมื่อคุณส่งหรือรับข้อความ ข้อความจะปรากฏที่นี่",
+  "empty_column.domain_blocks": "ยังไม่มีโดเมนที่ซ่อนอยู่",
+  "empty_column.favourited_statuses": "คุณยังไม่มีโพสต์ที่ชื่นชอบใด ๆ เมื่อคุณชื่นชอบโพสต์ โพสต์จะปรากฏที่นี่",
+  "empty_column.favourites": "ยังไม่มีใครชื่นชอบโพสต์นี้ เมื่อใครสักคนชื่นชอบ เขาจะปรากฏที่นี่",
+  "empty_column.follow_requests": "คุณยังไม่มีคำขอติดตามใด ๆ เมื่อคุณได้รับคำขอ คำขอจะปรากฏที่นี่",
+  "empty_column.hashtag": "ยังไม่มีสิ่งใดในแฮชแท็กนี้",
+  "empty_column.home": "เส้นเวลาหน้าแรกของคุณว่างเปล่า! เยี่ยมชม {public} หรือใช้การค้นหาเพื่อเริ่มต้นใช้งานและพบปะผู้ใช้อื่น ๆ",
+  "empty_column.home.public_timeline": "เส้นเวลาสาธารณะ",
+  "empty_column.list": "ยังไม่มีสิ่งใดในรายการนี้ เมื่อสมาชิกของรายการนี้โพสต์สถานะใหม่ สถานะจะปรากฏที่นี่",
+  "empty_column.lists": "คุณยังไม่มีรายการใด ๆ เมื่อคุณสร้างรายการ รายการจะปรากฏที่นี่",
+  "empty_column.mutes": "คุณยังไม่ได้ปิดเสียงผู้ใช้ใด ๆ",
+  "empty_column.notifications": "คุณยังไม่มีการแจ้งเตือนใด ๆ โต้ตอบกับผู้อื่นเพื่อเริ่มการสนทนา",
+  "empty_column.public": "ไม่มีสิ่งใดที่นี่! เขียนบางอย่างเป็นสาธารณะ หรือติดตามผู้ใช้จากเซิร์ฟเวอร์อื่น ๆ ด้วยตนเองเพื่อเติมให้เต็ม",
+  "follow_request.authorize": "อนุญาต",
+  "follow_request.reject": "ปฏิเสธ",
+  "getting_started.developers": "นักพัฒนา",
+  "getting_started.directory": "ไดเรกทอรีโปรไฟล์",
+  "getting_started.documentation": "เอกสารประกอบ",
+  "getting_started.heading": "เริ่มต้นใช้งาน",
+  "getting_started.invite": "เชิญผู้คน",
+  "getting_started.open_source_notice": "Mastodon เป็นซอฟต์แวร์เปิดต้นฉบับ คุณสามารถมีส่วนร่วมหรือรายงานปัญหาใน GitHub ที่ {github}",
+  "getting_started.security": "ความปลอดภัย",
+  "getting_started.terms": "เงื่อนไขการให้บริการ",
+  "hashtag.column_header.tag_mode.all": "และ {additional}",
+  "hashtag.column_header.tag_mode.any": "หรือ {additional}",
+  "hashtag.column_header.tag_mode.none": "โดยไม่มี {additional}",
+  "hashtag.column_settings.select.no_options_message": "ไม่พบข้อเสนอแนะ",
+  "hashtag.column_settings.select.placeholder": "ป้อนแฮชแท็ก…",
+  "hashtag.column_settings.tag_mode.all": "ทั้งหมดนี้",
+  "hashtag.column_settings.tag_mode.any": "ใดก็ตามนี้",
+  "hashtag.column_settings.tag_mode.none": "ไม่ใช่ทั้งหมดนี้",
+  "hashtag.column_settings.tag_toggle": "รวมแท็กเพิ่มเติมสำหรับคอลัมน์นี้",
+  "home.column_settings.basic": "พื้นฐาน",
+  "home.column_settings.show_reblogs": "แสดงการดัน",
+  "home.column_settings.show_replies": "แสดงการตอบกลับ",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
+  "introduction.federation.action": "ถัดไป",
+  "introduction.federation.federated.headline": "ที่ติดต่อกับภายนอก",
+  "introduction.federation.federated.text": "โพสต์สาธารณะจากเซิร์ฟเวอร์อื่น ๆ ของ Fediverse จะปรากฏในเส้นเวลาที่ติดต่อกับภายนอก",
+  "introduction.federation.home.headline": "หน้าแรก",
+  "introduction.federation.home.text": "โพสต์จากผู้คนที่คุณติดตามจะปรากฏในฟีดหน้าแรกของคุณ คุณสามารถติดตามใครก็ตามในเซิร์ฟเวอร์ใดก็ตาม!",
+  "introduction.federation.local.headline": "ในเว็บ",
+  "introduction.federation.local.text": "โพสต์สาธารณะจากผู้คนในเซิร์ฟเวอร์เดียวกันกับคุณจะปรากฏในเส้นเวลาในเว็บ",
+  "introduction.interactions.action": "เสร็จสิ้นบทช่วยสอน!",
+  "introduction.interactions.favourite.headline": "ชื่นชอบ",
   "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
-  "introduction.interactions.reblog.headline": "Boost",
+  "introduction.interactions.reblog.headline": "ดัน",
   "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
-  "introduction.interactions.reply.headline": "Reply",
+  "introduction.interactions.reply.headline": "ตอบกลับ",
   "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
-  "introduction.welcome.action": "Let's go!",
-  "introduction.welcome.headline": "First steps",
+  "introduction.welcome.action": "ไปกันเลย!",
+  "introduction.welcome.headline": "ขั้นตอนแรก",
   "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
-  "keyboard_shortcuts.back": "to navigate back",
-  "keyboard_shortcuts.blocked": "to open blocked users list",
-  "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",
-  "keyboard_shortcuts.description": "Description",
-  "keyboard_shortcuts.direct": "to open direct messages column",
-  "keyboard_shortcuts.down": "to move down in the list",
-  "keyboard_shortcuts.enter": "to open status",
-  "keyboard_shortcuts.favourite": "to favourite",
-  "keyboard_shortcuts.favourites": "to open favourites list",
-  "keyboard_shortcuts.federated": "to open federated timeline",
-  "keyboard_shortcuts.heading": "Keyboard Shortcuts",
-  "keyboard_shortcuts.home": "to open home timeline",
-  "keyboard_shortcuts.hotkey": "Hotkey",
-  "keyboard_shortcuts.legend": "to display this legend",
-  "keyboard_shortcuts.local": "to open local timeline",
-  "keyboard_shortcuts.mention": "to mention author",
-  "keyboard_shortcuts.muted": "to open muted users list",
-  "keyboard_shortcuts.my_profile": "to open your profile",
-  "keyboard_shortcuts.notifications": "to open notifications column",
-  "keyboard_shortcuts.pinned": "to open pinned toots list",
-  "keyboard_shortcuts.profile": "to open author's profile",
-  "keyboard_shortcuts.reply": "to reply",
-  "keyboard_shortcuts.requests": "to open follow requests list",
-  "keyboard_shortcuts.search": "to focus search",
-  "keyboard_shortcuts.start": "to open \"get started\" column",
-  "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
-  "keyboard_shortcuts.toot": "to start a brand new toot",
-  "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
-  "keyboard_shortcuts.up": "to move up in the list",
-  "lightbox.close": "Close",
-  "lightbox.next": "Next",
-  "lightbox.previous": "Previous",
-  "lists.account.add": "Add to list",
-  "lists.account.remove": "Remove from list",
-  "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",
-  "loading_indicator.label": "Loading...",
-  "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.apps": "Mobile apps",
-  "navigation_bar.blocks": "Blocked users",
-  "navigation_bar.community_timeline": "Local timeline",
-  "navigation_bar.compose": "Compose new toot",
-  "navigation_bar.direct": "Direct messages",
-  "navigation_bar.discover": "Discover",
-  "navigation_bar.domain_blocks": "Hidden domains",
-  "navigation_bar.edit_profile": "Edit profile",
-  "navigation_bar.favourites": "Favourites",
-  "navigation_bar.filters": "Muted words",
-  "navigation_bar.follow_requests": "Follow requests",
-  "navigation_bar.info": "About this instance",
-  "navigation_bar.keyboard_shortcuts": "Keyboard shortcuts",
-  "navigation_bar.lists": "Lists",
-  "navigation_bar.logout": "Logout",
-  "navigation_bar.mutes": "Muted users",
-  "navigation_bar.personal": "Personal",
-  "navigation_bar.pins": "Pinned toots",
-  "navigation_bar.preferences": "Preferences",
-  "navigation_bar.public_timeline": "Federated timeline",
-  "navigation_bar.security": "Security",
-  "notification.favourite": "{name} favourited your status",
-  "notification.follow": "{name} followed you",
-  "notification.mention": "{name} mentioned you",
-  "notification.reblog": "{name} boosted your status",
-  "notifications.clear": "Clear notifications",
-  "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
-  "notifications.column_settings.alert": "Desktop notifications",
-  "notifications.column_settings.favourite": "Favourites:",
-  "notifications.column_settings.filter_bar.advanced": "Display all categories",
-  "notifications.column_settings.filter_bar.category": "Quick filter bar",
-  "notifications.column_settings.filter_bar.show": "Show",
-  "notifications.column_settings.follow": "New followers:",
-  "notifications.column_settings.mention": "Mentions:",
-  "notifications.column_settings.push": "Push notifications",
-  "notifications.column_settings.reblog": "Boosts:",
-  "notifications.column_settings.show": "Show in column",
-  "notifications.column_settings.sound": "Play sound",
-  "notifications.filter.all": "All",
-  "notifications.filter.boosts": "Boosts",
-  "notifications.filter.favourites": "Favourites",
-  "notifications.filter.follows": "Follows",
-  "notifications.filter.mentions": "Mentions",
-  "notifications.group": "{count} notifications",
-  "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 post to public timelines",
-  "privacy.unlisted.short": "Unlisted",
-  "regeneration_indicator.label": "Loading…",
-  "regeneration_indicator.sublabel": "Your home feed is being prepared!",
-  "relative_time.days": "{number}d",
-  "relative_time.hours": "{number}h",
-  "relative_time.just_now": "now",
-  "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",
-  "search.placeholder": "Search",
-  "search_popout.search_format": "Advanced search format",
-  "search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
-  "search_popout.tips.hashtag": "hashtag",
-  "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",
+  "keyboard_shortcuts.back": "เพื่อนำทางย้อนกลับ",
+  "keyboard_shortcuts.blocked": "เพื่อเปิดรายการผู้ใช้ที่ปิดกั้นอยู่",
+  "keyboard_shortcuts.boost": "เพื่อดัน",
+  "keyboard_shortcuts.column": "เพื่อโฟกัสสถานะในหนึ่งในคอลัมน์",
+  "keyboard_shortcuts.compose": "เพื่อโฟกัสพื้นที่เขียนข้อความ",
+  "keyboard_shortcuts.description": "คำอธิบาย",
+  "keyboard_shortcuts.direct": "เพื่อเปิดคอลัมน์ข้อความโดยตรง",
+  "keyboard_shortcuts.down": "เพื่อย้ายลงในรายการ",
+  "keyboard_shortcuts.enter": "เพื่อเปิดสถานะ",
+  "keyboard_shortcuts.favourite": "เพื่อชื่นชอบ",
+  "keyboard_shortcuts.favourites": "เพื่อเปิดรายการโปรด",
+  "keyboard_shortcuts.federated": "เพื่อเปิดเส้นเวลาที่ติดต่อกับภายนอก",
+  "keyboard_shortcuts.heading": "แป้นพิมพ์ลัด",
+  "keyboard_shortcuts.home": "เพื่อเปิดเส้นเวลาหน้าแรก",
+  "keyboard_shortcuts.hotkey": "ปุ่มลัด",
+  "keyboard_shortcuts.legend": "เพื่อแสดงคำอธิบายนี้",
+  "keyboard_shortcuts.local": "เพื่อเปิดเส้นเวลาในเว็บ",
+  "keyboard_shortcuts.mention": "เพื่อกล่าวถึงผู้สร้าง",
+  "keyboard_shortcuts.muted": "เพื่อเปิดรายการผู้ใช้ที่ปิดเสียงอยู่",
+  "keyboard_shortcuts.my_profile": "เพื่อเปิดโปรไฟล์ของคุณ",
+  "keyboard_shortcuts.notifications": "เพื่อเปิดคอลัมน์การแจ้งเตือน",
+  "keyboard_shortcuts.pinned": "เพื่อเปิดรายการโพสต์ที่ปักหมุด",
+  "keyboard_shortcuts.profile": "เพื่อเปิดโปรไฟล์ของผู้สร้าง",
+  "keyboard_shortcuts.reply": "เพื่อตอบกลับ",
+  "keyboard_shortcuts.requests": "เพื่อเปิดรายการคำขอติดตาม",
+  "keyboard_shortcuts.search": "เพื่อโฟกัสการค้นหา",
+  "keyboard_shortcuts.start": "เพื่อเปิดคอลัมน์ \"เริ่มต้นใช้งาน\"",
+  "keyboard_shortcuts.toggle_hidden": "เพื่อแสดง/ซ่อนข้อความที่อยู่หลังคำเตือนเนื้อหา",
+  "keyboard_shortcuts.toggle_sensitivity": "เพื่อแสดง/ซ่อนสื่อ",
+  "keyboard_shortcuts.toot": "เพื่อเริ่มโพสต์ใหม่",
+  "keyboard_shortcuts.unfocus": "เพื่อเลิกโฟกัสพื้นที่เขียนข้อความ/การค้นหา",
+  "keyboard_shortcuts.up": "เพื่อย้ายขึ้นในรายการ",
+  "lightbox.close": "ปิด",
+  "lightbox.next": "ถัดไป",
+  "lightbox.previous": "ก่อนหน้า",
+  "lightbox.view_context": "ดูบริบท",
+  "lists.account.add": "เพิ่มไปยังรายการ",
+  "lists.account.remove": "เอาออกจากรายการ",
+  "lists.delete": "ลบรายการ",
+  "lists.edit": "แก้ไขรายการ",
+  "lists.edit.submit": "เปลี่ยนชื่อเรื่อง",
+  "lists.new.create": "เพิ่มรายการ",
+  "lists.new.title_placeholder": "ชื่อเรื่องรายการใหม่",
+  "lists.search": "ค้นหาในหมู่ผู้คนที่คุณติดตาม",
+  "lists.subheading": "รายการของคุณ",
+  "loading_indicator.label": "กำลังโหลด...",
+  "media_gallery.toggle_visible": "เปิด/ปิดการมองเห็น",
+  "missing_indicator.label": "ไม่พบ",
+  "missing_indicator.sublabel": "ไม่พบทรัพยากรนี้",
+  "mute_modal.hide_notifications": "ซ่อนการแจ้งเตือนจากผู้ใช้นี้?",
+  "navigation_bar.apps": "แอปสำหรับมือถือ",
+  "navigation_bar.blocks": "ผู้ใช้ที่ปิดกั้นอยู่",
+  "navigation_bar.community_timeline": "เส้นเวลาในเว็บ",
+  "navigation_bar.compose": "เขียนโพสต์ใหม่",
+  "navigation_bar.direct": "ข้อความโดยตรง",
+  "navigation_bar.discover": "ค้นพบ",
+  "navigation_bar.domain_blocks": "โดเมนที่ซ่อนอยู่",
+  "navigation_bar.edit_profile": "แก้ไขโปรไฟล์",
+  "navigation_bar.favourites": "รายการโปรด",
+  "navigation_bar.filters": "คำที่ปิดเสียงอยู่",
+  "navigation_bar.follow_requests": "คำขอติดตาม",
+  "navigation_bar.follows_and_followers": "การติดตามและผู้ติดตาม",
+  "navigation_bar.info": "เกี่ยวกับเซิร์ฟเวอร์นี้",
+  "navigation_bar.keyboard_shortcuts": "ปุ่มลัด",
+  "navigation_bar.lists": "รายการ",
+  "navigation_bar.logout": "ออกจากระบบ",
+  "navigation_bar.mutes": "ผู้ใช้ที่ปิดเสียงอยู่",
+  "navigation_bar.personal": "ส่วนบุคคล",
+  "navigation_bar.pins": "โพสต์ที่ปักหมุด",
+  "navigation_bar.preferences": "การกำหนดลักษณะ",
+  "navigation_bar.profile_directory": "ไดเรกทอรีโปรไฟล์",
+  "navigation_bar.public_timeline": "เส้นเวลาที่ติดต่อกับภายนอก",
+  "navigation_bar.security": "ความปลอดภัย",
+  "notification.favourite": "{name} ได้ชื่นชอบสถานะของคุณ",
+  "notification.follow": "{name} ได้ติดตามคุณ",
+  "notification.mention": "{name} ได้กล่าวถึงคุณ",
+  "notification.poll": "A poll you have voted in has ended",
+  "notification.reblog": "{name} ได้ดันสถานะของคุณ",
+  "notifications.clear": "ล้างการแจ้งเตือน",
+  "notifications.clear_confirmation": "คุณแน่ใจหรือไม่ว่าต้องการล้างการแจ้งเตือนทั้งหมดของคุณอย่างถาวร?",
+  "notifications.column_settings.alert": "การแจ้งเตือนบนเดสก์ท็อป",
+  "notifications.column_settings.favourite": "รายการโปรด:",
+  "notifications.column_settings.filter_bar.advanced": "แสดงหมวดหมู่ทั้งหมด",
+  "notifications.column_settings.filter_bar.category": "แถบตัวกรองด่วน",
+  "notifications.column_settings.filter_bar.show": "แสดง",
+  "notifications.column_settings.follow": "ผู้ติดตามใหม่:",
+  "notifications.column_settings.mention": "การกล่าวถึง:",
+  "notifications.column_settings.poll": "Poll results:",
+  "notifications.column_settings.push": "การแจ้งเตือนแบบผลัก",
+  "notifications.column_settings.reblog": "การดัน:",
+  "notifications.column_settings.show": "แสดงในคอลัมน์",
+  "notifications.column_settings.sound": "เล่นเสียง",
+  "notifications.filter.all": "ทั้งหมด",
+  "notifications.filter.boosts": "การดัน",
+  "notifications.filter.favourites": "รายการโปรด",
+  "notifications.filter.follows": "การติดตาม",
+  "notifications.filter.mentions": "การกล่าวถึง",
+  "notifications.filter.polls": "Poll results",
+  "notifications.group": "{count} การแจ้งเตือน",
+  "poll.closed": "ปิดแล้ว",
+  "poll.refresh": "รีเฟรช",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
+  "privacy.change": "ปรับเปลี่ยนความเป็นส่วนตัวของสถานะ",
+  "privacy.direct.long": "โพสต์ไปยังผู้ใช้ที่กล่าวถึงเท่านั้น",
+  "privacy.direct.short": "โดยตรง",
+  "privacy.private.long": "โพสต์ไปยังผู้ติดตามเท่านั้น",
+  "privacy.private.short": "ผู้ติดตามเท่านั้น",
+  "privacy.public.long": "โพสต์ไปยังเส้นเวลาสาธารณะ",
+  "privacy.public.short": "สาธารณะ",
+  "privacy.unlisted.long": "ไม่โพสต์ไปยังเส้นเวลาสาธารณะ",
+  "privacy.unlisted.short": "ไม่อยู่ในรายการ",
+  "regeneration_indicator.label": "กำลังโหลด…",
+  "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}",
+  "search.placeholder": "ค้นหา",
+  "search_popout.search_format": "รูปแบบการค้นหาขั้นสูง",
+  "search_popout.tips.full_text": "ข้อความแบบง่ายส่งคืนสถานะที่คุณได้เขียน ชื่นชอบ ดัน หรือได้รับการกล่าวถึง ตลอดจนชื่อผู้ใช้, ชื่อที่แสดง และแฮชแท็กที่ตรงกัน",
+  "search_popout.tips.hashtag": "แฮชแท็ก",
+  "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} {count, plural, one {result} other {results}}",
-  "standalone.public_title": "A look inside...",
-  "status.admin_account": "Open moderation interface for @{name}",
-  "status.admin_status": "Open this status in the moderation interface",
-  "status.block": "Block @{name}",
-  "status.cancel_reblog_private": "Unboost",
-  "status.cannot_reblog": "This post cannot be boosted",
-  "status.delete": "Delete",
-  "status.detailed_status": "Detailed conversation view",
-  "status.direct": "Direct message @{name}",
-  "status.embed": "Embed",
-  "status.favourite": "Favourite",
-  "status.filtered": "Filtered",
-  "status.load_more": "Load more",
-  "status.media_hidden": "Media hidden",
-  "status.mention": "Mention @{name}",
-  "status.more": "More",
-  "status.mute": "Mute @{name}",
-  "status.mute_conversation": "Mute conversation",
-  "status.open": "Expand this status",
-  "status.pin": "Pin on profile",
-  "status.pinned": "Pinned toot",
-  "status.read_more": "Read more",
-  "status.reblog": "Boost",
-  "status.reblog_private": "Boost to original audience",
-  "status.reblogged_by": "{name} boosted",
-  "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
-  "status.redraft": "Delete & re-draft",
-  "status.reply": "Reply",
-  "status.replyAll": "Reply to thread",
-  "status.report": "Report @{name}",
-  "status.sensitive_toggle": "Click to view",
-  "status.sensitive_warning": "Sensitive content",
-  "status.share": "Share",
-  "status.show_less": "Show less",
-  "status.show_less_all": "Show less for all",
-  "status.show_more": "Show more",
-  "status.show_more_all": "Show more for all",
-  "status.show_thread": "Show thread",
-  "status.unmute_conversation": "Unmute conversation",
-  "status.unpin": "Unpin from profile",
-  "suggestions.dismiss": "Dismiss suggestion",
-  "suggestions.header": "You might be interested in…",
-  "tabs_bar.federated_timeline": "Federated",
-  "tabs_bar.home": "Home",
-  "tabs_bar.local_timeline": "Local",
-  "tabs_bar.notifications": "Notifications",
-  "tabs_bar.search": "Search",
+  "status.admin_account": "เปิดส่วนติดต่อการควบคุมสำหรับ @{name}",
+  "status.admin_status": "เปิดสถานะนี้ในส่วนติดต่อการควบคุม",
+  "status.block": "ปิดกั้น @{name}",
+  "status.cancel_reblog_private": "เลิกดัน",
+  "status.cannot_reblog": "ไม่สามารถดันโพสต์นี้",
+  "status.copy": "คัดลอกลิงก์ไปยังสถานะ",
+  "status.delete": "ลบ",
+  "status.detailed_status": "มุมมองการสนทนาโดยละเอียด",
+  "status.direct": "ส่งข้อความโดยตรงถึง @{name}",
+  "status.embed": "ฝัง",
+  "status.favourite": "ชื่นชอบ",
+  "status.filtered": "กรองอยู่",
+  "status.load_more": "โหลดเพิ่มเติม",
+  "status.media_hidden": "ซ่อนสื่ออยู่",
+  "status.mention": "กล่าวถึง @{name}",
+  "status.more": "เพิ่มเติม",
+  "status.mute": "ปิดเสียง @{name}",
+  "status.mute_conversation": "ปิดเสียงการสนทนา",
+  "status.open": "ขยายสถานะนี้",
+  "status.pin": "ปักหมุดในโปรไฟล์",
+  "status.pinned": "โพสต์ที่ปักหมุด",
+  "status.read_more": "อ่านเพิ่มเติม",
+  "status.reblog": "ดัน",
+  "status.reblog_private": "ดันไปยังผู้ชมดั้งเดิม",
+  "status.reblogged_by": "{name} ได้ดัน",
+  "status.reblogs.empty": "ยังไม่มีใครดันโพสต์นี้ เมื่อใครสักคนดัน เขาจะปรากฏที่นี่",
+  "status.redraft": "ลบแล้วร่างใหม่",
+  "status.reply": "ตอบกลับ",
+  "status.replyAll": "ตอบกลับกระทู้",
+  "status.report": "รายงาน @{name}",
+  "status.sensitive_warning": "เนื้อหาที่ละเอียดอ่อน",
+  "status.share": "แบ่งปัน",
+  "status.show_less": "แสดงน้อยลง",
+  "status.show_less_all": "แสดงน้อยลงทั้งหมด",
+  "status.show_more": "แสดงเพิ่มเติม",
+  "status.show_more_all": "แสดงเพิ่มเติมทั้งหมด",
+  "status.show_thread": "แสดงกระทู้",
+  "status.unmute_conversation": "เลิกปิดเสียงการสนทนา",
+  "status.unpin": "ถอนหมุดจากโปรไฟล์",
+  "suggestions.dismiss": "ยกเลิกข้อเสนอแนะ",
+  "suggestions.header": "คุณอาจสนใจ…",
+  "tabs_bar.federated_timeline": "ที่ติดต่อกับภายนอก",
+  "tabs_bar.home": "หน้าแรก",
+  "tabs_bar.local_timeline": "ในเว็บ",
+  "tabs_bar.notifications": "การแจ้งเตือน",
+  "tabs_bar.search": "ค้นหา",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "ช่วงเวลาที่เหลือ",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
-  "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
-  "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",
-  "video.exit_fullscreen": "Exit full screen",
-  "video.expand": "Expand video",
-  "video.fullscreen": "Full screen",
-  "video.hide": "Hide video",
-  "video.mute": "Mute sound",
-  "video.pause": "Pause",
-  "video.play": "Play",
-  "video.unmute": "Unmute sound"
+  "ui.beforeunload": "แบบร่างของคุณจะหายไปหากคุณออกจาก Mastodon",
+  "upload_area.title": "ลากแล้วปล่อยเพื่ออัปโหลด",
+  "upload_button.label": "เพิ่มสื่อ (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "เกินขีดจำกัดการอัปโหลดไฟล์",
+  "upload_error.poll": "ไม่อนุญาตให้อัปโหลดไฟล์กับการลงคะแนน",
+  "upload_form.description": "อธิบายสำหรับผู้บกพร่องทางการมองเห็น",
+  "upload_form.focus": "ตัวอย่างการเปลี่ยนแปลง",
+  "upload_form.undo": "ลบ",
+  "upload_progress.label": "กำลังอัปโหลด...",
+  "video.close": "ปิดวิดีโอ",
+  "video.exit_fullscreen": "ออกจากเต็มหน้าจอ",
+  "video.expand": "ขยายวิดีโอ",
+  "video.fullscreen": "เต็มหน้าจอ",
+  "video.hide": "ซ่อนวิดีโอ",
+  "video.mute": "ปิดเสียง",
+  "video.pause": "หยุดชั่วคราว",
+  "video.play": "เล่น",
+  "video.unmute": "เลิกปิดเสียง"
 }
diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json
index 5d8fc229e6d01755ad892d76597bb443c1b26a64..ec4657b9bf598255285b2842c545e33f9b082596 100644
--- a/app/javascript/mastodon/locales/tr.json
+++ b/app/javascript/mastodon/locales/tr.json
@@ -1,262 +1,286 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "Listelere ekle veya kaldır",
   "account.badges.bot": "Bot",
   "account.block": "Engelle @{name}",
-  "account.block_domain": "Hide everything from {domain}",
-  "account.blocked": "Blocked",
-  "account.direct": "Direct Message @{name}",
-  "account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
-  "account.domain_blocked": "Domain hidden",
+  "account.block_domain": "{domain} alanından her şeyi gizle",
+  "account.blocked": "EngellenmiÅŸ",
+  "account.direct": "Mesaj gönder : @{name}",
+  "account.domain_blocked": "Alan adı gizlendi",
   "account.edit_profile": "Profili düzenle",
-  "account.endorse": "Feature on profile",
+  "account.endorse": "Profildeki özellik",
   "account.follow": "Takip et",
   "account.followers": "Takipçiler",
-  "account.followers.empty": "No one follows this user yet.",
+  "account.followers.empty": "Henüz kimse bu kullanıcıyı takip etmiyor.",
   "account.follows": "Takip ettikleri",
-  "account.follows.empty": "This user doesn't follow anyone yet.",
+  "account.follows.empty": "Bu kullanıcı henüz kimseyi takip etmiyor.",
   "account.follows_you": "Seni takip ediyor",
-  "account.hide_reblogs": "Hide boosts from @{name}",
-  "account.link_verified_on": "Ownership of this link was checked on {date}",
-  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
-  "account.media": "Media",
-  "account.mention": "Bahset @{name}",
-  "account.moved_to": "{name} has moved to:",
-  "account.mute": "Sustur @{name}",
-  "account.mute_notifications": "Mute notifications from @{name}",
-  "account.muted": "Muted",
+  "account.hide_reblogs": "@{name} kişisinden boost'ları gizle",
+  "account.link_verified_on": "Bu bağlantının mülkiyeti {date} tarihinde kontrol edildi",
+  "account.locked_info": "Bu hesabın gizlilik durumu kilitli olarak ayarlanmış. Sahibi, onu kimin takip edebileceğini elle inceler.",
+  "account.media": "Medya",
+  "account.mention": "@{name} kullanıcısından bahset",
+  "account.moved_to": "{name} şuraya taşındı:",
+  "account.mute": "@{name} kullanıcısını sessize al",
+  "account.mute_notifications": "@{name} kullanıcısının bildirimlerini kapat",
+  "account.muted": "Sesi kısık",
   "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",
-  "account.show_reblogs": "Show boosts from @{name}",
+  "account.posts_with_replies": "Gönderiler ve yanıtlar",
+  "account.report": "@{name} kullanıcısını bildir",
+  "account.requested": "Onay bekliyor. Takip isteğini iptal etmek için tıklayın",
+  "account.share": "@{name} kullanıcısının profilini paylaş",
+  "account.show_reblogs": "@{name} kullanıcısından boostları göster",
   "account.unblock": "Engeli kaldır @{name}",
-  "account.unblock_domain": "Unhide {domain}",
-  "account.unendorse": "Don't feature on profile",
+  "account.unblock_domain": "{domain} göster",
+  "account.unendorse": "Profilde özellik yok",
   "account.unfollow": "Takipten vazgeç",
-  "account.unmute": "Sesi aç @{name}",
-  "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account.view_full_profile": "View full profile",
-  "alert.unexpected.message": "An unexpected error occurred.",
-  "alert.unexpected.title": "Oops!",
+  "account.unmute": "Sesi aç : @{name}",
+  "account.unmute_notifications": "@{name} kullanıcısından bildirimleri aç",
+  "alert.unexpected.message": "Beklenmedik bir hata oluÅŸtu.",
+  "alert.unexpected.title": "Hay aksi!",
   "boost_modal.combo": "Bir dahaki sefere {combo} tuÅŸuna basabilirsiniz",
-  "bundle_column_error.body": "Something went wrong while loading this component.",
-  "bundle_column_error.retry": "Try again",
-  "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",
+  "bundle_column_error.body": "Bu bileşen yüklenirken bir şeyler ters gitti.",
+  "bundle_column_error.retry": "Tekrar deneyin",
+  "bundle_column_error.title": "Ağ hatası",
+  "bundle_modal_error.close": "Kapat",
+  "bundle_modal_error.message": "Bu bileşen yüklenirken bir şeyler ters gitti.",
+  "bundle_modal_error.retry": "Tekrar deneyin",
   "column.blocks": "Engellenen kullanıcılar",
   "column.community": "Yerel zaman tüneli",
-  "column.direct": "Direct messages",
-  "column.domain_blocks": "Hidden domains",
+  "column.direct": "DoÄŸrudan mesajlar",
+  "column.domain_blocks": "Gizli alan adları",
   "column.favourites": "Favoriler",
   "column.follow_requests": "Takip istekleri",
   "column.home": "Anasayfa",
-  "column.lists": "Lists",
+  "column.lists": "Listeler",
   "column.mutes": "Susturulmuş kullanıcılar",
   "column.notifications": "Bildirimler",
-  "column.pins": "Pinned toot",
+  "column.pins": "Sabitlenmiş gönderi",
   "column.public": "Federe zaman tüneli",
   "column_back_button.label": "Geri",
-  "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_header.hide_settings": "Ayarları gizle",
+  "column_header.moveLeft_settings": "Sütunu sola taşı",
+  "column_header.moveRight_settings": "Sütunu sağa taşı",
+  "column_header.pin": "Sabitle",
+  "column_header.show_settings": "Ayarları göster",
+  "column_header.unpin": "Sabitlemeyi kaldır",
   "column_subheading.settings": "Ayarlar",
-  "community.column_settings.media_only": "Media Only",
-  "compose_form.direct_message_warning": "This toot will only be visible to all the mentioned users.",
-  "compose_form.direct_message_warning_learn_more": "Learn more",
-  "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.",
+  "community.column_settings.media_only": "Sadece medya",
+  "compose_form.direct_message_warning": "Bu gönderi sadece belirtilen kullanıcılara gönderilecektir.",
+  "compose_form.direct_message_warning_learn_more": "Daha fazla bilgi edinin",
+  "compose_form.hashtag_warning": "Bu paylaşım liste dışı olduğu için hiç bir hashtag'de yer almayacak. Sadece herkese açık gönderiler hashtaglerde bulunabilir.",
   "compose_form.lock_disclaimer": "Hesabınız {locked} değil. Sadece takipçilerle paylaştığınız gönderileri görebilmek için sizi herhangi bir kullanıcı takip edebilir.",
   "compose_form.lock_disclaimer.lock": "kilitli",
-  "compose_form.placeholder": "Ne düşünüyorsun?",
-  "compose_form.publish": "Toot",
+  "compose_form.placeholder": "Aklınızdan ne geçiyor?",
+  "compose_form.poll.add_option": "Bir seçenek ekleyin",
+  "compose_form.poll.duration": "Anket süresi",
+  "compose_form.poll.option_placeholder": "Seçim {number}",
+  "compose_form.poll.remove_option": "Bu seçimi kaldır",
+  "compose_form.publish": "Gönder",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive.marked": "Media is marked as sensitive",
-  "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
-  "compose_form.spoiler.marked": "Text is hidden behind warning",
-  "compose_form.spoiler.unmarked": "Text is not hidden",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
+  "compose_form.sensitive.marked": "Medya hassas olarak iÅŸaretlendi",
+  "compose_form.sensitive.unmarked": "Medya hassas olarak iÅŸaretlenmemiÅŸ",
+  "compose_form.spoiler.marked": "Metin uyarının arkasına gizlenir",
+  "compose_form.spoiler.unmarked": "Metin gizli deÄŸil",
   "compose_form.spoiler_placeholder": "İçerik uyarısı",
   "confirmation_modal.cancel": "İptal",
+  "confirmations.block.block_and_report": "Engelle & Bildir",
   "confirmations.block.confirm": "Engelle",
   "confirmations.block.message": "{name} kullanıcısını engellemek istiyor musunuz?",
   "confirmations.delete.confirm": "Sil",
   "confirmations.delete.message": "Bu gönderiyi silmek istiyor musunuz?",
-  "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.delete_list.confirm": "Sil",
+  "confirmations.delete_list.message": "Bu listeyi kalıcı olarak silmek istediğinize emin misiniz?",
+  "confirmations.domain_block.confirm": "Alan adının tamamını gizle",
+  "confirmations.domain_block.message": "tüm {domain} alan adını engellemek istediğinizden emin misiniz? Genellikle birkaç hedefli engel ve susturma işi görür ve tercih edilir.",
   "confirmations.mute.confirm": "Sessize al",
   "confirmations.mute.message": "{name} kullanıcısını sessize almak istiyor musunuz?",
-  "confirmations.redraft.confirm": "Delete & redraft",
-  "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.",
-  "confirmations.reply.confirm": "Reply",
-  "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
-  "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:",
+  "confirmations.redraft.confirm": "Sil ve yeniden tasarla",
+  "confirmations.redraft.message": "Bu durumu silip tekrar taslaklaştırmak istediğinizden emin misiniz? Tüm cevapları, boostları ve favorileri kaybedeceksiniz.",
+  "confirmations.reply.confirm": "Yanıtla",
+  "confirmations.reply.message": "Şimdi yanıtlarken o an oluşturduğunuz mesajın üzerine yazılır. Devam etmek istediğinize emin misiniz?",
+  "confirmations.unfollow.confirm": "Takibi kaldır",
+  "confirmations.unfollow.message": "{name}'yi takipten çıkarmak istediğinizden emin misiniz?",
+  "embed.instructions": "Aşağıdaki kodu kopyalayarak bu durumu sitenize gömün.",
+  "embed.preview": "İşte nasıl görüneceği:",
   "emoji_button.activity": "Aktivite",
-  "emoji_button.custom": "Custom",
+  "emoji_button.custom": "Özel",
   "emoji_button.flags": "Bayraklar",
   "emoji_button.food": "Yiyecek ve İçecek",
   "emoji_button.label": "Emoji ekle",
   "emoji_button.nature": "DoÄŸa",
-  "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.not_found": "İfade yok!! (╯°□°)╯︵ ┻━┻",
   "emoji_button.objects": "Nesneler",
   "emoji_button.people": "İnsanlar",
-  "emoji_button.recent": "Frequently used",
-  "emoji_button.search": "Emoji ara...",
-  "emoji_button.search_results": "Search results",
+  "emoji_button.recent": "Sık kullanılan",
+  "emoji_button.search": "Ara...",
+  "emoji_button.search_results": "Arama sonuçları",
   "emoji_button.symbols": "Semboller",
   "emoji_button.travel": "Seyahat ve Yerler",
-  "empty_column.account_timeline": "No toots here!",
-  "empty_column.blocks": "You haven't blocked any users yet.",
-  "empty_column.community": "Yerel zaman tüneliniz boş. Daha fazla eğlence için herkese açık bir gönderi paylaşın.",
-  "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
-  "empty_column.domain_blocks": "There are no hidden domains yet.",
-  "empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.",
-  "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.",
-  "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
+  "empty_column.account_timeline": "Burada hiç gönderi yok!",
+  "empty_column.account_unavailable": "Profile unavailable",
+  "empty_column.blocks": "Henüz bir kullanıcıyı engellemediniz.",
+  "empty_column.community": "Yerel zaman çizelgesi boş. Daha fazla eğlence için herkese açık bir gönderi paylaşın!",
+  "empty_column.direct": "Henüz doğrudan mesajınız yok. Bir tane gönderdiğinizde veya aldığınızda burada görünecektir.",
+  "empty_column.domain_blocks": "Henüz hiçbir gizli alan adı yok.",
+  "empty_column.favourited_statuses": "Hiç favori gönderiminiz yok. Bir tane olursa burada görünecek.",
+  "empty_column.favourites": "Kimse bu gönderiyi favorilerine eklememiş. Biri eklerse burada görünecek.",
+  "empty_column.follow_requests": "Hiç takip isteğiniz yok. Bir tane aldığınızda burada görünecek.",
   "empty_column.hashtag": "Henüz bu hashtag’e sahip hiçbir gönderi yok.",
   "empty_column.home": "Henüz kimseyi takip etmiyorsunuz. {public} ziyaret edebilir veya arama kısmını kullanarak diğer kullanıcılarla iletişime geçebilirsiniz.",
   "empty_column.home.public_timeline": "herkese açık zaman tüneli",
-  "empty_column.list": "There is nothing in this list yet.",
-  "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
-  "empty_column.mutes": "You haven't muted any users yet.",
+  "empty_column.list": "Bu listede henüz hiçbir şey yok.",
+  "empty_column.lists": "Henüz hiç listeniz yok. Bir tane oluşturduğunuzda burada görünecek.",
+  "empty_column.mutes": "Henüz hiçbir kullanıcıyı sessize almadınız.",
   "empty_column.notifications": "Henüz hiçbir bildiriminiz yok. Diğer insanlarla sobhet edebilmek için etkileşime geçebilirsiniz.",
-  "empty_column.public": "Burada hiçbir gönderi yok! Herkese açık bir şeyler yazın, veya diğer sunucudaki insanları takip ederek bu alanın dolmasını sağlayın",
+  "empty_column.public": "Burada hiçbir şey yok! Herkese açık bir şeyler yazın veya burayı doldurmak için diğer sunuculardaki kullanıcıları takip edin",
   "follow_request.authorize": "Yetkilendir",
   "follow_request.reject": "Reddet",
-  "getting_started.developers": "Developers",
-  "getting_started.directory": "Profile directory",
-  "getting_started.documentation": "Documentation",
+  "getting_started.developers": "GeliÅŸtiriciler",
+  "getting_started.directory": "Profil dizini",
+  "getting_started.documentation": "Belgeler",
   "getting_started.heading": "Başlangıç",
-  "getting_started.invite": "Invite people",
+  "getting_started.invite": "İnsanları davet edin",
   "getting_started.open_source_notice": "Mastodon açık kaynaklı bir yazılımdır. Github {github}. {apps} üzerinden katkıda bulunabilir, hata raporlayabilirsiniz.",
-  "getting_started.security": "Security",
-  "getting_started.terms": "Terms of service",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
-  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "getting_started.security": "Güvenlik",
+  "getting_started.terms": "Hizmet koşulları",
+  "hashtag.column_header.tag_mode.all": "ve {additional}",
+  "hashtag.column_header.tag_mode.any": "ya da {additional}",
+  "hashtag.column_header.tag_mode.none": "{additional} olmadan",
+  "hashtag.column_settings.select.no_options_message": "Hiç öneri bulunamadı",
+  "hashtag.column_settings.select.placeholder": "Hashtagler girin…",
+  "hashtag.column_settings.tag_mode.all": "Bunların hepsi",
+  "hashtag.column_settings.tag_mode.any": "Bunların hiçbiri",
+  "hashtag.column_settings.tag_mode.none": "Bunların hiçbiri",
+  "hashtag.column_settings.tag_toggle": "Bu sütundaki ek etiketleri içer",
   "home.column_settings.basic": "Temel",
   "home.column_settings.show_reblogs": "Boost edilenleri göster",
   "home.column_settings.show_replies": "Cevapları göster",
-  "introduction.federation.action": "Next",
-  "introduction.federation.federated.headline": "Federated",
-  "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
-  "introduction.federation.home.headline": "Home",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
+  "introduction.federation.action": "İleri",
+  "introduction.federation.federated.headline": "BirleÅŸik",
+  "introduction.federation.federated.text": "Diğer dosya sunucularından gelen genel gönderiler, birleşik zaman çizelgesinde görünecektir.",
+  "introduction.federation.home.headline": "Ana sayfa",
   "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
-  "introduction.federation.local.headline": "Local",
-  "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
-  "introduction.interactions.favourite.headline": "Favourite",
-  "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
+  "introduction.federation.local.headline": "Yerel",
+  "introduction.federation.local.text": "Aynı sunucudaki kişilerin gönderileri yerel zaman tünelinde gözükecektir.",
+  "introduction.interactions.action": "Öğreticiyi bitirin!",
+  "introduction.interactions.favourite.headline": "Favori",
+  "introduction.interactions.favourite.text": "Bir gönderiyi favorilerinize alarak sonrası için saklayabilirsiniz ve yazara gönderiyi beğendiğinizi söyleyebilirsiniz.",
   "introduction.interactions.reblog.headline": "Boost",
-  "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
-  "introduction.interactions.reply.headline": "Reply",
-  "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
-  "introduction.welcome.action": "Let's go!",
-  "introduction.welcome.headline": "First steps",
-  "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
-  "keyboard_shortcuts.back": "to navigate back",
-  "keyboard_shortcuts.blocked": "to open blocked users list",
-  "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",
-  "keyboard_shortcuts.description": "Description",
-  "keyboard_shortcuts.direct": "to open direct messages column",
-  "keyboard_shortcuts.down": "to move down in the list",
-  "keyboard_shortcuts.enter": "to open status",
-  "keyboard_shortcuts.favourite": "to favourite",
-  "keyboard_shortcuts.favourites": "to open favourites list",
-  "keyboard_shortcuts.federated": "to open federated timeline",
-  "keyboard_shortcuts.heading": "Keyboard Shortcuts",
-  "keyboard_shortcuts.home": "to open home timeline",
-  "keyboard_shortcuts.hotkey": "Hotkey",
-  "keyboard_shortcuts.legend": "to display this legend",
-  "keyboard_shortcuts.local": "to open local timeline",
-  "keyboard_shortcuts.mention": "to mention author",
-  "keyboard_shortcuts.muted": "to open muted users list",
-  "keyboard_shortcuts.my_profile": "to open your profile",
-  "keyboard_shortcuts.notifications": "to open notifications column",
-  "keyboard_shortcuts.pinned": "to open pinned toots list",
-  "keyboard_shortcuts.profile": "to open author's profile",
-  "keyboard_shortcuts.reply": "to reply",
-  "keyboard_shortcuts.requests": "to open follow requests list",
-  "keyboard_shortcuts.search": "to focus search",
-  "keyboard_shortcuts.start": "to open \"get started\" column",
-  "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
-  "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",
+  "introduction.interactions.reblog.text": "Başkalarının gönderilerini boostlayarak kendi takipçilerinizle paylaşabillirsiniz.",
+  "introduction.interactions.reply.headline": "Yanıt",
+  "introduction.interactions.reply.text": "Başkalarının gönderilerini ve kendi gönderilerinizi yanıtlayabilirsiniz. Bir konuşmada zincirli bir şekilde olacaklardır.",
+  "introduction.welcome.action": "Hadi gidelim!",
+  "introduction.welcome.headline": "İlk adımlar",
+  "introduction.welcome.text": "Krallığa hoş geldiniz! Az sonra, geniş bir sunucu yelpazesinde mesaj gönderip arkadaşlarınızla konuşabileceksiniz. Ama bu sunucu, {domain}, özel (profilinizi barındırır, bu yüzden adresini hatırlayın).",
+  "keyboard_shortcuts.back": "geriye gitmek için",
+  "keyboard_shortcuts.blocked": "engelli kullanıcılar listesini açmak için",
+  "keyboard_shortcuts.boost": "boostlamak için",
+  "keyboard_shortcuts.column": "sütunlardan birindeki duruma odaklanmak için",
+  "keyboard_shortcuts.compose": "yazma alanına odaklanmak için",
+  "keyboard_shortcuts.description": "Açıklama",
+  "keyboard_shortcuts.direct": "direkt mesajlar sütununu açmak için",
+  "keyboard_shortcuts.down": "listede aşağıya inmek için",
+  "keyboard_shortcuts.enter": "durumu açmak için",
+  "keyboard_shortcuts.favourite": "favorilere eklemek için",
+  "keyboard_shortcuts.favourites": "favoriler listesini açmak için",
+  "keyboard_shortcuts.federated": "federe edilmiş zaman tünelini açmak için",
+  "keyboard_shortcuts.heading": "Klavye kısayolları",
+  "keyboard_shortcuts.home": "ana sayfa zaman çizelgesini açmak için",
+  "keyboard_shortcuts.hotkey": "Kısatuş",
+  "keyboard_shortcuts.legend": "bu efsaneyi görüntülemek için",
+  "keyboard_shortcuts.local": "yerel zaman tünelini açmak için",
+  "keyboard_shortcuts.mention": "yazardan bahsetmek için",
+  "keyboard_shortcuts.muted": "susturulmuş kullanıcı listesini açmak için",
+  "keyboard_shortcuts.my_profile": "profilinizi açmak için",
+  "keyboard_shortcuts.notifications": "bildirimler sütununu açmak için",
+  "keyboard_shortcuts.pinned": "sabitlenmiş gönderiler listesini açmak için",
+  "keyboard_shortcuts.profile": "yazarın profilini açmak için",
+  "keyboard_shortcuts.reply": "cevaplamak için",
+  "keyboard_shortcuts.requests": "takip istekleri listesini açmak için",
+  "keyboard_shortcuts.search": "aramaya odaklanmak için",
+  "keyboard_shortcuts.start": "\"başlayın\" sütununu açmak için",
+  "keyboard_shortcuts.toggle_hidden": "CW'den önceki yazıyı göstermek/gizlemek için",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
+  "keyboard_shortcuts.toot": "yeni bir gönderiye başlamak için",
+  "keyboard_shortcuts.unfocus": "aramada bir gönderiye odaklanmamak için",
+  "keyboard_shortcuts.up": "listede yukarıya çıkmak için",
   "lightbox.close": "Kapat",
-  "lightbox.next": "Next",
-  "lightbox.previous": "Previous",
-  "lists.account.add": "Add to list",
-  "lists.account.remove": "Remove from list",
-  "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",
+  "lightbox.next": "Sonraki",
+  "lightbox.previous": "Önceli",
+  "lightbox.view_context": "View context",
+  "lists.account.add": "Listeye ekle",
+  "lists.account.remove": "Listeden kaldır",
+  "lists.delete": "Listeyi sil",
+  "lists.edit": "listeyi düzenle",
+  "lists.edit.submit": "Başlığı değiştir",
+  "lists.new.create": "Liste ekle",
+  "lists.new.title_placeholder": "Yeni liste başlığı",
+  "lists.search": "Takip ettiğiniz kişiler arasından arayın",
+  "lists.subheading": "Listeleriniz",
   "loading_indicator.label": "Yükleniyor...",
   "media_gallery.toggle_visible": "Görünürlüğü değiştir",
   "missing_indicator.label": "Bulunamadı",
-  "missing_indicator.sublabel": "This resource could not be found",
-  "mute_modal.hide_notifications": "Hide notifications from this user?",
-  "navigation_bar.apps": "Mobile apps",
+  "missing_indicator.sublabel": "Bu kaynak bulunamadı",
+  "mute_modal.hide_notifications": "Bu kullanıcıdan bildirimler gizlensin mı?",
+  "navigation_bar.apps": "Mobil uygulamalar",
   "navigation_bar.blocks": "Engellenen kullanıcılar",
   "navigation_bar.community_timeline": "Yerel zaman tüneli",
-  "navigation_bar.compose": "Compose new toot",
-  "navigation_bar.direct": "Direct messages",
-  "navigation_bar.discover": "Discover",
-  "navigation_bar.domain_blocks": "Hidden domains",
+  "navigation_bar.compose": "Yeni bir gönderi yazın",
+  "navigation_bar.direct": "Direkt Mesajlar",
+  "navigation_bar.discover": "KeÅŸfet",
+  "navigation_bar.domain_blocks": "Gizli alan adları",
   "navigation_bar.edit_profile": "Profili düzenle",
   "navigation_bar.favourites": "Favoriler",
-  "navigation_bar.filters": "Muted words",
+  "navigation_bar.filters": "SusturulmuÅŸ kelimeler",
   "navigation_bar.follow_requests": "Takip istekleri",
+  "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.info": "GeniÅŸletilmiÅŸ bilgi",
-  "navigation_bar.keyboard_shortcuts": "Keyboard shortcuts",
-  "navigation_bar.lists": "Lists",
+  "navigation_bar.keyboard_shortcuts": "Klavye kısayolları",
+  "navigation_bar.lists": "Listeler",
   "navigation_bar.logout": "Çıkış",
   "navigation_bar.mutes": "Sessize alınmış kullanıcılar",
-  "navigation_bar.personal": "Personal",
-  "navigation_bar.pins": "Pinned toots",
+  "navigation_bar.personal": "KiÅŸisel",
+  "navigation_bar.pins": "Sabitlenmiş gönderiler",
   "navigation_bar.preferences": "Tercihler",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "Federe zaman tüneli",
-  "navigation_bar.security": "Security",
+  "navigation_bar.security": "Güvenlik",
   "notification.favourite": "{name} senin durumunu favorilere ekledi",
   "notification.follow": "{name} seni takip ediyor",
   "notification.mention": "{name} mentioned you",
+  "notification.poll": "Oy verdiÄŸiniz bir anket bitti",
   "notification.reblog": "{name} senin durumunu boost etti",
   "notifications.clear": "Bildirimleri temizle",
   "notifications.clear_confirmation": "Tüm bildirimlerinizi kalıcı olarak temizlemek ister misiniz?",
   "notifications.column_settings.alert": "Masaüstü bildirimleri",
   "notifications.column_settings.favourite": "Favoriler:",
-  "notifications.column_settings.filter_bar.advanced": "Display all categories",
-  "notifications.column_settings.filter_bar.category": "Quick filter bar",
-  "notifications.column_settings.filter_bar.show": "Show",
+  "notifications.column_settings.filter_bar.advanced": "Tüm kategorileri göster",
+  "notifications.column_settings.filter_bar.category": "Hızlı filtre çubuğu",
+  "notifications.column_settings.filter_bar.show": "Göster",
   "notifications.column_settings.follow": "Yeni takipçiler:",
   "notifications.column_settings.mention": "Bahsedilenler:",
-  "notifications.column_settings.push": "Push notifications",
-  "notifications.column_settings.reblog": "Boost’lar:",
+  "notifications.column_settings.poll": "Anket sonuçları:",
+  "notifications.column_settings.push": "Push bildirimleri",
+  "notifications.column_settings.reblog": "Boostlar:",
   "notifications.column_settings.show": "Bildirimlerde göster",
   "notifications.column_settings.sound": "Ses çal",
-  "notifications.filter.all": "All",
-  "notifications.filter.boosts": "Boosts",
-  "notifications.filter.favourites": "Favourites",
-  "notifications.filter.follows": "Follows",
-  "notifications.filter.mentions": "Mentions",
-  "notifications.group": "{count} notifications",
+  "notifications.filter.all": "Tümü",
+  "notifications.filter.boosts": "Boostlar",
+  "notifications.filter.favourites": "Favoriler",
+  "notifications.filter.follows": "Takip edilenler",
+  "notifications.filter.mentions": "Bahsetmeler",
+  "notifications.filter.polls": "Anket sonuçları",
+  "notifications.group": "{count} bildirim",
+  "poll.closed": "Kapandı",
+  "poll.refresh": "Yenile",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Oy ver",
+  "poll_button.add_poll": "Bir anket ekleyin",
+  "poll_button.remove_poll": "Anket kaldır",
   "privacy.change": "Gönderi gizliliğini ayarla",
   "privacy.direct.long": "Sadece bahsedilen kişilere gönder",
   "privacy.direct.short": "Direkt",
@@ -266,93 +290,99 @@
   "privacy.public.short": "Herkese açık",
   "privacy.unlisted.long": "Herkese açık zaman tüneline gönderme",
   "privacy.unlisted.short": "ListelenmemiÅŸ",
-  "regeneration_indicator.label": "Loading…",
-  "regeneration_indicator.sublabel": "Your home feed is being prepared!",
-  "relative_time.days": "{number}d",
-  "relative_time.hours": "{number}h",
-  "relative_time.just_now": "now",
-  "relative_time.minutes": "{number}m",
-  "relative_time.seconds": "{number}s",
+  "regeneration_indicator.label": "Yükleniyor…",
+  "regeneration_indicator.sublabel": "Ev akışınız hazırlanıyor!",
+  "relative_time.days": "{number}g",
+  "relative_time.hours": "{number}s",
+  "relative_time.just_now": "ÅŸimdi",
+  "relative_time.minutes": "{number}dk",
+  "relative_time.seconds": "{number}sn",
   "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.forward": "Åžu kiÅŸiye ilet : {target}",
+  "report.forward_hint": "Bu hesap başka bir sunucudan. Anonimleştirilmiş bir rapor oraya da gönderilsin mi?",
+  "report.hint": "Bu rapor sunucu moderatörlerine gönderilecek. Bu hesabı neden bildirdiğiniz hakkında bilgi verebirsiniz:",
   "report.placeholder": "Ek yorumlar",
   "report.submit": "Gönder",
   "report.target": "Raporlama",
   "search.placeholder": "Ara",
-  "search_popout.search_format": "Advanced search format",
+  "search_popout.search_format": "Gelişmiş arama formatı",
   "search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
   "search_popout.tips.hashtag": "hashtag",
-  "search_popout.tips.status": "status",
+  "search_popout.tips.status": "durum",
   "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_popout.tips.user": "kullanıcı",
+  "search_results.accounts": "İnsanlar",
+  "search_results.hashtags": "Hashtagler",
+  "search_results.statuses": "Gönderiler",
   "search_results.total": "{count, number} {count, plural, one {sonuç} other {sonuçlar}}",
-  "standalone.public_title": "A look inside...",
-  "status.admin_account": "Open moderation interface for @{name}",
-  "status.admin_status": "Open this status in the moderation interface",
-  "status.block": "Block @{name}",
-  "status.cancel_reblog_private": "Unboost",
+  "status.admin_account": "@{name} için denetim arayüzünü açın",
+  "status.admin_status": "Denetim arayüzünde bu durumu açın",
+  "status.block": "Engelle : @{name}",
+  "status.cancel_reblog_private": "Boost'u geri al",
   "status.cannot_reblog": "Bu gönderi boost edilemez",
+  "status.copy": "Bağlantı durumunu kopyala",
   "status.delete": "Sil",
-  "status.detailed_status": "Detailed conversation view",
-  "status.direct": "Direct message @{name}",
-  "status.embed": "Embed",
+  "status.detailed_status": "Detaylı yazışma dökümü",
+  "status.direct": "@{name}'e gönder",
+  "status.embed": "Gömülü",
   "status.favourite": "Favorilere ekle",
-  "status.filtered": "Filtered",
+  "status.filtered": "FiltrelenmiÅŸ",
   "status.load_more": "Daha fazla",
   "status.media_hidden": "Gizli görsel",
-  "status.mention": "Bahset @{name}",
-  "status.more": "More",
-  "status.mute": "Mute @{name}",
-  "status.mute_conversation": "Mute conversation",
+  "status.mention": "Bahset : @{name}",
+  "status.more": "Daha fazla",
+  "status.mute": "Sustur : @{name}",
+  "status.mute_conversation": "Yazışmayı sustur",
   "status.open": "Bu gönderiyi genişlet",
-  "status.pin": "Pin on profile",
-  "status.pinned": "Pinned toot",
-  "status.read_more": "Read more",
-  "status.reblog": "Boost'la",
+  "status.pin": "Profile sabitle",
+  "status.pinned": "Sabitlenmiş gönderi",
+  "status.read_more": "Daha dazla oku",
+  "status.reblog": "Boostla",
   "status.reblog_private": "Boost to original audience",
   "status.reblogged_by": "{name} boost etti",
-  "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
-  "status.redraft": "Delete & re-draft",
+  "status.reblogs.empty": "Kimse bu gönderiyi boostlamadı. Biri yaptığında burada gözükecek.",
+  "status.redraft": "Sil & tekrar taslakla",
   "status.reply": "Cevapla",
   "status.replyAll": "Konuşmayı cevapla",
   "status.report": "@{name}'i raporla",
-  "status.sensitive_toggle": "Görmek için tıklayınız",
   "status.sensitive_warning": "Hassas içerik",
-  "status.share": "Share",
-  "status.show_less": "Daha azı",
-  "status.show_less_all": "Show less for all",
-  "status.show_more": "Daha fazlası",
-  "status.show_more_all": "Show more for all",
-  "status.show_thread": "Show thread",
+  "status.share": "PaylaÅŸ",
+  "status.show_less": "Daha az göster",
+  "status.show_less_all": "Hepsi için daha az göster",
+  "status.show_more": "Daha fazla göster",
+  "status.show_more_all": "Hepsi için daha fazla göster",
+  "status.show_thread": "Başlığı göster",
   "status.unmute_conversation": "Unmute conversation",
-  "status.unpin": "Unpin from profile",
-  "suggestions.dismiss": "Dismiss suggestion",
-  "suggestions.header": "You might be interested in…",
+  "status.unpin": "Profilden sabitlemeyi kaldır",
+  "suggestions.dismiss": "Öneriyi görmezden gel",
+  "suggestions.header": "Şuna ilgi duyuyor olabilirsiniz…",
   "tabs_bar.federated_timeline": "Federe",
   "tabs_bar.home": "Ana sayfa",
   "tabs_bar.local_timeline": "Yerel",
   "tabs_bar.notifications": "Bildirimler",
-  "tabs_bar.search": "Search",
+  "tabs_bar.search": "Ara",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
-  "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
-  "upload_area.title": "Upload için sürükle bırak yapınız",
+  "ui.beforeunload": "Mastodon'dan ayrılırsanız taslağınız kaybolacak.",
+  "upload_area.title": "Karşıya yükleme için sürükle bırak yapınız",
   "upload_button.label": "Görsel ekle",
+  "upload_error.limit": "Dosya yükleme sınırı aşıldı.",
+  "upload_error.poll": "Anketlerde dosya yüklemesine izin verilmez.",
   "upload_form.description": "Describe for the visually impaired",
-  "upload_form.focus": "Crop",
+  "upload_form.focus": "Kırp",
   "upload_form.undo": "Geri al",
   "upload_progress.label": "Yükleniyor...",
-  "video.close": "Close video",
-  "video.exit_fullscreen": "Exit full screen",
-  "video.expand": "Expand video",
-  "video.fullscreen": "Full screen",
-  "video.hide": "Hide video",
-  "video.mute": "Mute sound",
-  "video.pause": "Pause",
-  "video.play": "Play",
-  "video.unmute": "Unmute sound"
+  "video.close": "Videoyu kapat",
+  "video.exit_fullscreen": "Tam ekrandan çık",
+  "video.expand": "Videoyu geniÅŸlet",
+  "video.fullscreen": "Tam ekran",
+  "video.hide": "Videoyu gizle",
+  "video.mute": "Sesi kıs",
+  "video.pause": "Duraklat",
+  "video.play": "Oynat",
+  "video.unmute": "Sesi aç"
 }
diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json
index 606dda89fc61577baade109276566c5980d76e9e..124b9fb07615266b82415178b845046dcae136d5 100644
--- a/app/javascript/mastodon/locales/uk.json
+++ b/app/javascript/mastodon/locales/uk.json
@@ -5,7 +5,6 @@
   "account.block_domain": "Заглушити {domain}",
   "account.blocked": "Заблоковані",
   "account.direct": "Пряме повідомлення @{name}",
-  "account.disclaimer_full": "Інфомація знизу може відображати профіль користувача неповністю.",
   "account.domain_blocked": "Домен приховано",
   "account.edit_profile": "Редагувати профіль",
   "account.endorse": "Feature on profile",
@@ -36,7 +35,6 @@
   "account.unfollow": "Відписатися",
   "account.unmute": "Зняти глушення @{name}",
   "account.unmute_notifications": "Показувати сповіщення від @{name}",
-  "account.view_full_profile": "Показати профіль повністю",
   "alert.unexpected.message": "Трапилась неочікувана помилка.",
   "alert.unexpected.title": "Ой!",
   "boost_modal.combo": "Ви можете натиснути {combo}, щоб пропустити це наступного разу",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "Ваш акаунт не {locked}. Кожен може підписатися на Вас та бачити Ваші приватні пости.",
   "compose_form.lock_disclaimer.lock": "приватний",
   "compose_form.placeholder": "Що у Вас на думці?",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
   "compose_form.publish": "Дмухнути",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
   "compose_form.sensitive.marked": "Медіа відмічене <b>несприйнятливим</b>",
   "compose_form.sensitive.unmarked": "Медіа відмічене сприйнятливим",
   "compose_form.spoiler.marked": "Текст приховано за попередженням",
   "compose_form.spoiler.unmarked": "Текст видимий",
   "compose_form.spoiler_placeholder": "Попередження щодо прихованого тексту",
   "confirmation_modal.cancel": "Відмінити",
+  "confirmations.block.block_and_report": "Block & Report",
   "confirmations.block.confirm": "Заблокувати",
   "confirmations.block.message": "Ви впевнені, що хочете заблокувати {name}?",
   "confirmations.delete.confirm": "Видалити",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "Символи",
   "emoji_button.travel": "Подорожі",
   "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_unavailable": "Profile unavailable",
   "empty_column.blocks": "You haven't blocked any users yet.",
   "empty_column.community": "Локальна стрічка пуста. Напишіть щось, щоб розігріти народ!",
   "empty_column.direct": "У вас ще немає прямих повідомлень. Коли ви відправите чи отримаєте якесь, воно з'явиться тут.",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "and {additional}",
   "hashtag.column_header.tag_mode.any": "or {additional}",
   "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
   "hashtag.column_settings.tag_mode.all": "All of these",
   "hashtag.column_settings.tag_mode.any": "Any of these",
   "hashtag.column_settings.tag_mode.none": "None of these",
@@ -149,6 +156,9 @@
   "home.column_settings.basic": "Основні",
   "home.column_settings.show_reblogs": "Показувати передмухи",
   "home.column_settings.show_replies": "Показувати відповіді",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
   "introduction.federation.action": "Next",
   "introduction.federation.federated.headline": "Federated",
   "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
@@ -156,7 +166,7 @@
   "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
   "introduction.federation.local.headline": "Local",
   "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
+  "introduction.interactions.action": "Finish toot-orial!",
   "introduction.interactions.favourite.headline": "Favourite",
   "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
   "introduction.interactions.reblog.headline": "Boost",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "сфокусуватися на пошуку",
   "keyboard_shortcuts.start": "to open \"get started\" column",
   "keyboard_shortcuts.toggle_hidden": "показати/приховати прихований текст",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "почати писати новий дмух",
   "keyboard_shortcuts.unfocus": "розфокусуватися з нового допису чи пошуку",
   "keyboard_shortcuts.up": "рухатися вверх списком",
   "lightbox.close": "Закрити",
   "lightbox.next": "Далі",
   "lightbox.previous": "Назад",
+  "lightbox.view_context": "View context",
   "lists.account.add": "Додати до списку",
   "lists.account.remove": "Видалити зі списку",
   "lists.delete": "Видалити список",
   "lists.edit": "Редагувати список",
+  "lists.edit.submit": "Change title",
   "lists.new.create": "Додати список",
   "lists.new.title_placeholder": "Нова назва списку",
   "lists.search": "Шукати серед людей, на яких ви підписані",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "Вподобане",
   "navigation_bar.filters": "Приховані слова",
   "navigation_bar.follow_requests": "Запити на підписку",
+  "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.info": "Про сайт",
   "navigation_bar.keyboard_shortcuts": "Гарячі клавіши",
   "navigation_bar.lists": "Списки",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Особисте",
   "navigation_bar.pins": "Закріплені дмухи",
   "navigation_bar.preferences": "Налаштування",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "Глобальна стрічка",
   "navigation_bar.security": "Безпека",
   "notification.favourite": "{name} вподобав(-ла) ваш допис",
   "notification.follow": "{name} підписався(-лась) на Вас",
   "notification.mention": "{name} згадав(-ла) Вас",
+  "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "{name} передмухнув(-ла) Ваш допис",
   "notifications.clear": "Очистити сповіщення",
   "notifications.clear_confirmation": "Ви впевнені, що хочете назавжди видалити всі сповіщеня?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Show",
   "notifications.column_settings.follow": "Нові підписники:",
   "notifications.column_settings.mention": "Згадки:",
+  "notifications.column_settings.poll": "Poll results:",
   "notifications.column_settings.push": "Push-сповіщення",
   "notifications.column_settings.reblog": "Передмухи:",
   "notifications.column_settings.show": "Показати в колонці",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favourites",
   "notifications.filter.follows": "Follows",
   "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
   "notifications.group": "{count} сповіщень",
+  "poll.closed": "Closed",
+  "poll.refresh": "Refresh",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
   "privacy.change": "Змінити видимість допису",
   "privacy.direct.long": "Показати тільки згаданим користувачам",
   "privacy.direct.short": "Направлений",
@@ -291,12 +315,12 @@
   "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.admin_account": "Open moderation interface for @{name}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "Цей допис не може бути передмухнутий",
+  "status.copy": "Copy link to status",
   "status.delete": "Видалити",
   "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "Відповісти",
   "status.replyAll": "Відповісти на тред",
   "status.report": "Поскаржитися",
-  "status.sensitive_toggle": "Натисніть, щоб подивитися",
   "status.sensitive_warning": "Непристойний зміст",
   "status.share": "Share",
   "status.show_less": "Згорнути",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "Локальна",
   "tabs_bar.notifications": "Сповіщення",
   "tabs_bar.search": "Пошук",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
   "ui.beforeunload": "Вашу чернетку буде втрачено, якщо ви покинете Mastodon.",
   "upload_area.title": "Перетягніть сюди, щоб завантажити",
   "upload_button.label": "Додати медіаконтент",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "upload_form.description": "Опишіть для людей з вадами зору",
   "upload_form.focus": "Обрізати",
   "upload_form.undo": "Видалити",
diff --git a/app/javascript/mastodon/locales/whitelist_bn.json b/app/javascript/mastodon/locales/whitelist_bn.json
new file mode 100644
index 0000000000000000000000000000000000000000..0d4f101c7a37a4c875e6999bee1a287fdb733380
--- /dev/null
+++ b/app/javascript/mastodon/locales/whitelist_bn.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/mastodon/locales/whitelist_de.json b/app/javascript/mastodon/locales/whitelist_de.json
index 0d4f101c7a37a4c875e6999bee1a287fdb733380..6c9617e609d44e682b93f663f51b286d1d638184 100644
--- a/app/javascript/mastodon/locales/whitelist_de.json
+++ b/app/javascript/mastodon/locales/whitelist_de.json
@@ -1,2 +1,9 @@
 [
+  "relative_time.seconds",
+  "relative_time.minutes",
+  "relative_time.hours",
+  "relative_time.days",
+  "account.badges.bot",
+  "compose_form.publish_loud",
+  "search_results.hashtags"
 ]
diff --git a/app/javascript/mastodon/locales/whitelist_hi.json b/app/javascript/mastodon/locales/whitelist_hi.json
new file mode 100644
index 0000000000000000000000000000000000000000..0d4f101c7a37a4c875e6999bee1a287fdb733380
--- /dev/null
+++ b/app/javascript/mastodon/locales/whitelist_hi.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/mastodon/locales/whitelist_kk.json b/app/javascript/mastodon/locales/whitelist_kk.json
new file mode 100644
index 0000000000000000000000000000000000000000..0d4f101c7a37a4c875e6999bee1a287fdb733380
--- /dev/null
+++ b/app/javascript/mastodon/locales/whitelist_kk.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/mastodon/locales/whitelist_lt.json b/app/javascript/mastodon/locales/whitelist_lt.json
new file mode 100644
index 0000000000000000000000000000000000000000..0d4f101c7a37a4c875e6999bee1a287fdb733380
--- /dev/null
+++ b/app/javascript/mastodon/locales/whitelist_lt.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/mastodon/locales/whitelist_sq.json b/app/javascript/mastodon/locales/whitelist_sq.json
new file mode 100644
index 0000000000000000000000000000000000000000..0d4f101c7a37a4c875e6999bee1a287fdb733380
--- /dev/null
+++ b/app/javascript/mastodon/locales/whitelist_sq.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json
index dfa261d6e4da3d9632988f3e2d422b8bc6c97dd9..865d3a514287a024760c65283428407b5d9c7abc 100644
--- a/app/javascript/mastodon/locales/zh-CN.json
+++ b/app/javascript/mastodon/locales/zh-CN.json
@@ -1,23 +1,22 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "从列表中添加或删除",
   "account.badges.bot": "机器人",
   "account.block": "屏蔽 @{name}",
   "account.block_domain": "隐藏来自 {domain} 的内容",
   "account.blocked": "已屏蔽",
   "account.direct": "发送私信给 @{name}",
-  "account.disclaimer_full": "此处显示的信息可能不是全部内容。",
   "account.domain_blocked": "网站已屏蔽",
   "account.edit_profile": "修改个人资料",
-  "account.endorse": "Feature on profile",
+  "account.endorse": "在个人资料中推荐此用户",
   "account.follow": "关注",
   "account.followers": "关注者",
-  "account.followers.empty": "No one follows this user yet.",
+  "account.followers.empty": "目前无人关注此用户。",
   "account.follows": "正在关注",
-  "account.follows.empty": "This user doesn't follow anyone yet.",
+  "account.follows.empty": "此用户目前没有关注任何人。",
   "account.follows_you": "关注了你",
   "account.hide_reblogs": "隐藏来自 @{name} 的转嘟",
-  "account.link_verified_on": "Ownership of this link was checked on {date}",
-  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
+  "account.link_verified_on": "此链接的所有权已在 {date} 检查",
+  "account.locked_info": "此账户已锁嘟。账户的主人会手动审核关注者。",
   "account.media": "媒体",
   "account.mention": "提及 @{name}",
   "account.moved_to": "{name} 已经迁移到:",
@@ -30,13 +29,12 @@
   "account.requested": "正在等待对方同意。点击以取消发送关注请求",
   "account.share": "分享 @{name} 的个人资料",
   "account.show_reblogs": "显示来自 @{name} 的转嘟",
-  "account.unblock": "不再屏蔽 @{name}",
+  "account.unblock": "解除屏蔽 @{name}",
   "account.unblock_domain": "不再隐藏来自 {domain} 的内容",
-  "account.unendorse": "Don't feature on profile",
+  "account.unendorse": "不在个人资料中推荐此用户",
   "account.unfollow": "取消关注",
   "account.unmute": "不再隐藏 @{name}",
   "account.unmute_notifications": "不再隐藏来自 @{name} 的通知",
-  "account.view_full_profile": "查看完整资料",
   "alert.unexpected.message": "发生了意外错误。",
   "alert.unexpected.title": "哎呀!",
   "boost_modal.combo": "下次按住 {combo} 即可跳过此提示",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "你的帐户没有{locked}。任何人都可以在关注你后立即查看仅关注者可见的嘟文。",
   "compose_form.lock_disclaimer.lock": "开启保护",
   "compose_form.placeholder": "在想啥?",
+  "compose_form.poll.add_option": "添加一个选项",
+  "compose_form.poll.duration": "投票持续时间",
+  "compose_form.poll.option_placeholder": "选项 {number}",
+  "compose_form.poll.remove_option": "移除这个选项",
   "compose_form.publish": "嘟嘟",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "标记媒体为敏感内容",
   "compose_form.sensitive.marked": "媒体已被标记为敏感内容",
   "compose_form.sensitive.unmarked": "媒体未被标记为敏感内容",
   "compose_form.spoiler.marked": "正文已被折叠在警告信息之后",
   "compose_form.spoiler.unmarked": "正文未被折叠",
   "compose_form.spoiler_placeholder": "折叠部分的警告消息",
   "confirmation_modal.cancel": "取消",
+  "confirmations.block.block_and_report": "屏蔽与举报",
   "confirmations.block.confirm": "屏蔽",
   "confirmations.block.message": "你确定要屏蔽 {name} 吗?",
   "confirmations.delete.confirm": "删除",
@@ -92,9 +96,9 @@
   "confirmations.mute.confirm": "隐藏",
   "confirmations.mute.message": "你确定要隐藏 {name} 吗?",
   "confirmations.redraft.confirm": "删除并重新编辑",
-  "confirmations.redraft.message": "你确定要删除这条嘟文并重新编辑它吗?所有相关的回复、转嘟和收藏都会被清除。",
-  "confirmations.reply.confirm": "Reply",
-  "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
+  "confirmations.redraft.message": "你确定要删除这条嘟文并重新编辑它吗?所有相关的转嘟和收藏都会被清除,回复将会被孤立。",
+  "confirmations.reply.confirm": "回复",
+  "confirmations.reply.message": "回复此消息将会覆盖当前正在编辑的信息。确定继续吗?",
   "confirmations.unfollow.confirm": "取消关注",
   "confirmations.unfollow.message": "你确定要取消关注 {name} 吗?",
   "embed.instructions": "要在你的网站上嵌入这条嘟文,请复制以下代码。",
@@ -113,97 +117,106 @@
   "emoji_button.search_results": "搜索结果",
   "emoji_button.symbols": "符号",
   "emoji_button.travel": "旅行和地点",
-  "empty_column.account_timeline": "No toots here!",
-  "empty_column.blocks": "You haven't blocked any users yet.",
+  "empty_column.account_timeline": "这里没有嘟文!",
+  "empty_column.account_unavailable": "个人资料不可用",
+  "empty_column.blocks": "你目前没有屏蔽任何用户。",
   "empty_column.community": "本站时间轴暂时没有内容,快嘟几个来抢头香啊!",
   "empty_column.direct": "你还没有使用过私信。当你发出或者收到私信时,它会在这里显示。",
-  "empty_column.domain_blocks": "There are no hidden domains yet.",
-  "empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.",
-  "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.",
-  "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
+  "empty_column.domain_blocks": "目前没有被隐藏的站点。",
+  "empty_column.favourited_statuses": "你还没有收藏过任何嘟文。收藏过的嘟文会显示在这里。",
+  "empty_column.favourites": "没人收藏过这条嘟文。假如有人收藏了,就会显示在这里。",
+  "empty_column.follow_requests": "你没有收到新的关注请求。收到了之后就会显示在这里。",
   "empty_column.hashtag": "这个话题标签下暂时没有内容。",
   "empty_column.home": "你还没有关注任何用户。快看看{public},向其他用户搭讪吧。",
   "empty_column.home.public_timeline": "公共时间轴",
   "empty_column.list": "这个列表中暂时没有内容。列表中用户所发送的的新嘟文将会在这里显示。",
-  "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
-  "empty_column.mutes": "You haven't muted any users yet.",
+  "empty_column.lists": "你没有创建过列表。你创建的列表会在这里显示。",
+  "empty_column.mutes": "你没有隐藏任何用户。",
   "empty_column.notifications": "你还没有收到过任何通知,快向其他用户搭讪吧。",
-  "empty_column.public": "这里神马都没有!写一些公开的嘟文,或者关注其他实例的用户后,这里就会有嘟文出现了哦!",
+  "empty_column.public": "这里什么都没有!写一些公开的嘟文,或者关注其他服务器的用户后,这里就会有嘟文出现了",
   "follow_request.authorize": "同意",
   "follow_request.reject": "拒绝",
   "getting_started.developers": "开发",
-  "getting_started.directory": "Profile directory",
+  "getting_started.directory": "用户资料目录",
   "getting_started.documentation": "文档",
   "getting_started.heading": "开始使用",
   "getting_started.invite": "邀请用户",
   "getting_started.open_source_notice": "Mastodon 是一个开源软件。欢迎前往 GitHub({github})贡献代码或反馈问题。",
   "getting_started.security": "帐户安全",
   "getting_started.terms": "使用条款",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
-  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "hashtag.column_header.tag_mode.all": "以及 {additional}",
+  "hashtag.column_header.tag_mode.any": "或是 {additional}",
+  "hashtag.column_header.tag_mode.none": "而不用 {additional}",
+  "hashtag.column_settings.select.no_options_message": "没有找到建议",
+  "hashtag.column_settings.select.placeholder": "输入话题标签…",
+  "hashtag.column_settings.tag_mode.all": "全部",
+  "hashtag.column_settings.tag_mode.any": "任一",
+  "hashtag.column_settings.tag_mode.none": "全都不要",
+  "hashtag.column_settings.tag_toggle": "在此栏加入额外的标签",
   "home.column_settings.basic": "基本设置",
   "home.column_settings.show_reblogs": "显示转嘟",
   "home.column_settings.show_replies": "显示回复",
-  "introduction.federation.action": "Next",
-  "introduction.federation.federated.headline": "Federated",
-  "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
-  "introduction.federation.home.headline": "Home",
-  "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
-  "introduction.federation.local.headline": "Local",
-  "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
-  "introduction.interactions.favourite.headline": "Favourite",
-  "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
-  "introduction.interactions.reblog.headline": "Boost",
-  "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
-  "introduction.interactions.reply.headline": "Reply",
-  "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
-  "introduction.welcome.action": "Let's go!",
-  "introduction.welcome.headline": "First steps",
-  "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
+  "intervals.full.days": "{number} 天",
+  "intervals.full.hours": "{number} 小时",
+  "intervals.full.minutes": "{number} 分钟",
+  "introduction.federation.action": "下一步",
+  "introduction.federation.federated.headline": "跨站",
+  "introduction.federation.federated.text": "其他跨站服务器的公共动态会显示在跨站时间线中。",
+  "introduction.federation.home.headline": "主页",
+  "introduction.federation.home.text": "你所关注的用户的动态会显示在主页里。你可以关注任何服务器上的任何人!",
+  "introduction.federation.local.headline": "本站",
+  "introduction.federation.local.text": "你所关注的用户的动态会显示在主页里,你可以关注任何服务器上的任何人。",
+  "introduction.interactions.action": "教程结束!",
+  "introduction.interactions.favourite.headline": "收藏",
+  "introduction.interactions.favourite.text": "你可以保存嘟文以便以后阅读。或者通过收藏功能告诉作者你点了个赞。",
+  "introduction.interactions.reblog.headline": "转嘟",
+  "introduction.interactions.reblog.text": "通过转嘟,你可以向你的关注者分享其他人的嘟文。",
+  "introduction.interactions.reply.headline": "回复",
+  "introduction.interactions.reply.text": "你可以向其他人回复,这些回复会像对话一样串在一起。",
+  "introduction.welcome.action": "让我们开始吧!",
+  "introduction.welcome.headline": "首先",
+  "introduction.welcome.text": "欢迎来到联邦!稍后,您将可以广播消息并和您的朋友交流,这些消息将穿越于联邦中的各式服务器。但是这台服务器,{domain},是特殊的——它保存了你的个人资料,所以请记住它的名字。",
   "keyboard_shortcuts.back": "返回上一页",
-  "keyboard_shortcuts.blocked": "to open blocked users list",
+  "keyboard_shortcuts.blocked": "打开被屏蔽用户列表",
   "keyboard_shortcuts.boost": "转嘟",
-  "keyboard_shortcuts.column": "选择第 X 栏中的嘟文",
+  "keyboard_shortcuts.column": "选择某一栏中的嘟文",
   "keyboard_shortcuts.compose": "选择嘟文撰写框",
   "keyboard_shortcuts.description": "说明",
-  "keyboard_shortcuts.direct": "to open direct messages column",
+  "keyboard_shortcuts.direct": "打开私信栏",
   "keyboard_shortcuts.down": "在列表中让光标下移",
   "keyboard_shortcuts.enter": "展开嘟文",
   "keyboard_shortcuts.favourite": "收藏嘟文",
-  "keyboard_shortcuts.favourites": "to open favourites list",
-  "keyboard_shortcuts.federated": "to open federated timeline",
+  "keyboard_shortcuts.favourites": "打开收藏列表",
+  "keyboard_shortcuts.federated": "打开跨站时间轴",
   "keyboard_shortcuts.heading": "快捷键列表",
-  "keyboard_shortcuts.home": "to open home timeline",
+  "keyboard_shortcuts.home": "打开主页时间轴",
   "keyboard_shortcuts.hotkey": "快捷键",
   "keyboard_shortcuts.legend": "显示此列表",
-  "keyboard_shortcuts.local": "to open local timeline",
+  "keyboard_shortcuts.local": "打开本站时间轴",
   "keyboard_shortcuts.mention": "提及嘟文作者",
-  "keyboard_shortcuts.muted": "to open muted users list",
-  "keyboard_shortcuts.my_profile": "to open your profile",
-  "keyboard_shortcuts.notifications": "to open notifications column",
-  "keyboard_shortcuts.pinned": "to open pinned toots list",
-  "keyboard_shortcuts.profile": "to open author's profile",
+  "keyboard_shortcuts.muted": "打开屏蔽用户列表",
+  "keyboard_shortcuts.my_profile": "打开你的个人资料",
+  "keyboard_shortcuts.notifications": "打卡通知栏",
+  "keyboard_shortcuts.pinned": "打开置顶嘟文列表",
+  "keyboard_shortcuts.profile": "打开作者的个人资料",
   "keyboard_shortcuts.reply": "回复嘟文",
-  "keyboard_shortcuts.requests": "to open follow requests list",
+  "keyboard_shortcuts.requests": "打开关注请求列表",
   "keyboard_shortcuts.search": "选择搜索框",
-  "keyboard_shortcuts.start": "to open \"get started\" column",
+  "keyboard_shortcuts.start": "打开“开始使用”栏",
   "keyboard_shortcuts.toggle_hidden": "显示或隐藏被折叠的正文",
+  "keyboard_shortcuts.toggle_sensitivity": "显示/隐藏媒体",
   "keyboard_shortcuts.toot": "发送新嘟文",
   "keyboard_shortcuts.unfocus": "取消输入",
   "keyboard_shortcuts.up": "在列表中让光标上移",
   "lightbox.close": "关闭",
-  "lightbox.next": "下一步",
-  "lightbox.previous": "上一步",
+  "lightbox.next": "下一个",
+  "lightbox.previous": "上一个",
+  "lightbox.view_context": "查看上下文",
   "lists.account.add": "添加到列表",
   "lists.account.remove": "从列表中删除",
   "lists.delete": "删除列表",
   "lists.edit": "编辑列表",
+  "lists.edit.submit": "更改标题",
   "lists.new.create": "新建列表",
   "lists.new.title_placeholder": "新列表的标题",
   "lists.search": "搜索你关注的人",
@@ -212,18 +225,19 @@
   "media_gallery.toggle_visible": "切换显示/隐藏",
   "missing_indicator.label": "找不到内容",
   "missing_indicator.sublabel": "无法找到此资源",
-  "mute_modal.hide_notifications": "同时隐藏来自这个用户的通知",
-  "navigation_bar.apps": "Mobile apps",
+  "mute_modal.hide_notifications": "同时隐藏来自这个用户的通知?",
+  "navigation_bar.apps": "移动应用",
   "navigation_bar.blocks": "已屏蔽的用户",
   "navigation_bar.community_timeline": "本站时间轴",
-  "navigation_bar.compose": "Compose new toot",
+  "navigation_bar.compose": "撰写新嘟文",
   "navigation_bar.direct": "私信",
   "navigation_bar.discover": "发现",
   "navigation_bar.domain_blocks": "已屏蔽的网站",
   "navigation_bar.edit_profile": "修改个人资料",
   "navigation_bar.favourites": "收藏的内容",
-  "navigation_bar.filters": "Muted words",
+  "navigation_bar.filters": "被隐藏的词",
   "navigation_bar.follow_requests": "关注请求",
+  "navigation_bar.follows_and_followers": "正在关注以及关注者",
   "navigation_bar.info": "关于本站",
   "navigation_bar.keyboard_shortcuts": "快捷键列表",
   "navigation_bar.lists": "列表",
@@ -232,31 +246,41 @@
   "navigation_bar.personal": "个人",
   "navigation_bar.pins": "置顶嘟文",
   "navigation_bar.preferences": "首选项",
+  "navigation_bar.profile_directory": "用户资料目录",
   "navigation_bar.public_timeline": "跨站公共时间轴",
   "navigation_bar.security": "安全",
   "notification.favourite": "{name} 收藏了你的嘟文",
   "notification.follow": "{name} 开始关注你",
   "notification.mention": "{name} 提及你",
-  "notification.reblog": "{name} 转嘟了你的嘟文",
+  "notification.poll": "你参与的一个投票已经结束",
+  "notification.reblog": "{name} 转了你的嘟文",
   "notifications.clear": "清空通知列表",
   "notifications.clear_confirmation": "你确定要永久清空通知列表吗?",
   "notifications.column_settings.alert": "桌面通知",
-  "notifications.column_settings.favourite": "当你的嘟文被收藏时:",
-  "notifications.column_settings.filter_bar.advanced": "Display all categories",
-  "notifications.column_settings.filter_bar.category": "Quick filter bar",
-  "notifications.column_settings.filter_bar.show": "Show",
+  "notifications.column_settings.favourite": "你的嘟文被收藏时:",
+  "notifications.column_settings.filter_bar.advanced": "显示所有类别",
+  "notifications.column_settings.filter_bar.category": "快速过滤栏",
+  "notifications.column_settings.filter_bar.show": "显示",
   "notifications.column_settings.follow": "当有人关注你时:",
   "notifications.column_settings.mention": "当有人在嘟文中提及你时:",
+  "notifications.column_settings.poll": "投票结果:",
   "notifications.column_settings.push": "推送通知",
   "notifications.column_settings.reblog": "当有人转嘟了你的嘟文时:",
   "notifications.column_settings.show": "在通知栏显示",
   "notifications.column_settings.sound": "播放音效",
-  "notifications.filter.all": "All",
-  "notifications.filter.boosts": "Boosts",
-  "notifications.filter.favourites": "Favourites",
-  "notifications.filter.follows": "Follows",
-  "notifications.filter.mentions": "Mentions",
+  "notifications.filter.all": "全部",
+  "notifications.filter.boosts": "转嘟",
+  "notifications.filter.favourites": "收藏",
+  "notifications.filter.follows": "关注",
+  "notifications.filter.mentions": "提及",
+  "notifications.filter.polls": "投票结果",
   "notifications.group": "{count} 条通知",
+  "poll.closed": "已关闭",
+  "poll.refresh": "刷新",
+  "poll.total_votes": "{count} 票",
+  "poll.vote": "投票",
+  "poll_button.add_poll": "发起投票",
+  "poll_button.remove_poll": "移除投票",
   "privacy.change": "设置嘟文可见范围",
   "privacy.direct.long": "只有被提及的用户能看到",
   "privacy.direct.short": "私信",
@@ -275,8 +299,8 @@
   "relative_time.seconds": "{number}ç§’",
   "reply_indicator.cancel": "取消",
   "report.forward": "发送举报至 {target}",
-  "report.forward_hint": "这名用户来自另一个实例。是否要向那个实例发送一条匿名的举报?",
-  "report.hint": "举报将会发送给你所在实例的监察员。你可以在下面填写举报这个用户的理由:",
+  "report.forward_hint": "这名用户来自另一个服务器。是否要向那个服务器发送一条匿名的举报?",
+  "report.hint": "举报将会发送给你所在服务器的监察员。你可以在下面填写举报该用户的理由:",
   "report.placeholder": "附言",
   "report.submit": "提交",
   "report.target": "举报 {target}",
@@ -291,18 +315,18 @@
   "search_results.hashtags": "话题标签",
   "search_results.statuses": "嘟文",
   "search_results.total": "共 {count, number} 个结果",
-  "standalone.public_title": "大家都在干啥?",
-  "status.admin_account": "Open moderation interface for @{name}",
-  "status.admin_status": "Open this status in the moderation interface",
+  "status.admin_account": "打开 @{name} 的管理界面",
+  "status.admin_status": "打开这条嘟文的管理界面",
   "status.block": "屏蔽 @{name}",
   "status.cancel_reblog_private": "取消转嘟",
   "status.cannot_reblog": "无法转嘟这条嘟文",
+  "status.copy": "复制嘟文链接",
   "status.delete": "删除",
-  "status.detailed_status": "Detailed conversation view",
+  "status.detailed_status": "对话详情",
   "status.direct": "发送私信给 @{name}",
   "status.embed": "嵌入",
   "status.favourite": "收藏",
-  "status.filtered": "Filtered",
+  "status.filtered": "已过滤",
   "status.load_more": "加载更多",
   "status.media_hidden": "隐藏媒体内容",
   "status.mention": "提及 @{name}",
@@ -312,39 +336,45 @@
   "status.open": "展开嘟文",
   "status.pin": "在个人资料页面置顶",
   "status.pinned": "置顶嘟文",
-  "status.read_more": "Read more",
+  "status.read_more": "阅读全文",
   "status.reblog": "转嘟",
   "status.reblog_private": "转嘟给原有关注者",
   "status.reblogged_by": "{name} 转嘟了",
-  "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
+  "status.reblogs.empty": "无人转嘟此条。如果有人转嘟了,就会显示在这里。",
   "status.redraft": "删除并重新编辑",
   "status.reply": "回复",
   "status.replyAll": "回复所有人",
   "status.report": "举报 @{name}",
-  "status.sensitive_toggle": "点击显示",
   "status.sensitive_warning": "敏感内容",
   "status.share": "分享",
   "status.show_less": "隐藏内容",
   "status.show_less_all": "隐藏所有内容",
   "status.show_more": "显示内容",
   "status.show_more_all": "显示所有内容",
-  "status.show_thread": "Show thread",
+  "status.show_thread": "显示全部对话",
   "status.unmute_conversation": "不再隐藏此对话",
   "status.unpin": "在个人资料页面取消置顶",
-  "suggestions.dismiss": "Dismiss suggestion",
-  "suggestions.header": "You might be interested in…",
+  "suggestions.dismiss": "关闭建议",
+  "suggestions.header": "您可能会感兴趣…",
   "tabs_bar.federated_timeline": "跨站",
   "tabs_bar.home": "主页",
   "tabs_bar.local_timeline": "本站",
   "tabs_bar.notifications": "通知",
   "tabs_bar.search": "搜索",
+  "time_remaining.days": "剩余 {number, plural, one {# 天} other {# 天}}",
+  "time_remaining.hours": "剩余 {number, plural, one {# 小时} other {# 小时}}",
+  "time_remaining.minutes": "剩余 {number, plural, one {# 分钟} other {# 分钟}}",
+  "time_remaining.moments": "即将结束",
+  "time_remaining.seconds": "剩余 {number, plural, one {# 秒} other {# 秒}}",
   "trends.count_by_accounts": "{count} 人正在讨论",
   "ui.beforeunload": "如果你现在离开 Mastodon,你的草稿内容将会被丢弃。",
   "upload_area.title": "将文件拖放到此处开始上传",
-  "upload_button.label": "上传媒体文件",
+  "upload_button.label": "上传媒体文件 (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "超过文件上传限制。",
+  "upload_error.poll": "投票中不允许上传文件。",
   "upload_form.description": "为视觉障碍人士添加文字说明",
   "upload_form.focus": "剪裁",
-  "upload_form.undo": "取消上传",
+  "upload_form.undo": "删除",
   "upload_progress.label": "上传中…",
   "video.close": "关闭视频",
   "video.exit_fullscreen": "退出全屏",
diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json
index e57aa6d96dd2270829fdd8a85ca0f31d94899ed0..2cfc11703dd1d7280b6194db296ebb10a0b77c25 100644
--- a/app/javascript/mastodon/locales/zh-HK.json
+++ b/app/javascript/mastodon/locales/zh-HK.json
@@ -5,7 +5,6 @@
   "account.block_domain": "隱藏來自 {domain} 的一切文章",
   "account.blocked": "封鎖",
   "account.direct": "私訊 @{name}",
-  "account.disclaimer_full": "下列資料不一定完整。",
   "account.domain_blocked": "服務站被隱藏",
   "account.edit_profile": "修改個人資料",
   "account.endorse": "Feature on profile",
@@ -36,7 +35,6 @@
   "account.unfollow": "取消關注",
   "account.unmute": "取消 @{name} 的靜音",
   "account.unmute_notifications": "取消來自 @{name} 通知的靜音",
-  "account.view_full_profile": "查看完整資料",
   "alert.unexpected.message": "發生不可預期的錯誤。",
   "alert.unexpected.title": "噢!",
   "boost_modal.combo": "如你想在下次路過這顯示,請按{combo},",
@@ -73,14 +71,20 @@
   "compose_form.lock_disclaimer": "你的用戶狀態為「{locked}」,任何人都能立即關注你,然後看到「只有關注者能看」的文章。",
   "compose_form.lock_disclaimer.lock": "公共",
   "compose_form.placeholder": "你在想甚麼?",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
   "compose_form.publish": "發文",
   "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
   "compose_form.sensitive.marked": "媒體被標示為敏感",
   "compose_form.sensitive.unmarked": "媒體沒有被標示為敏感",
   "compose_form.spoiler.marked": "文字被警告隱藏",
   "compose_form.spoiler.unmarked": "文字沒有被隱藏",
   "compose_form.spoiler_placeholder": "敏感警告訊息",
   "confirmation_modal.cancel": "取消",
+  "confirmations.block.block_and_report": "Block & Report",
   "confirmations.block.confirm": "封鎖",
   "confirmations.block.message": "你確定要封鎖{name}嗎?",
   "confirmations.delete.confirm": "刪除",
@@ -114,6 +118,7 @@
   "emoji_button.symbols": "符號",
   "emoji_button.travel": "旅遊景物",
   "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_unavailable": "Profile unavailable",
   "empty_column.blocks": "You haven't blocked any users yet.",
   "empty_column.community": "本站時間軸暫時未有內容,快寫一點東西來搶頭香啊!",
   "empty_column.direct": "你沒有個人訊息。當你發出或接收個人訊息,就會在這裡出現。",
@@ -142,6 +147,8 @@
   "hashtag.column_header.tag_mode.all": "and {additional}",
   "hashtag.column_header.tag_mode.any": "or {additional}",
   "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
   "hashtag.column_settings.tag_mode.all": "All of these",
   "hashtag.column_settings.tag_mode.any": "Any of these",
   "hashtag.column_settings.tag_mode.none": "None of these",
@@ -149,6 +156,9 @@
   "home.column_settings.basic": "基本",
   "home.column_settings.show_reblogs": "顯示被轉推的文章",
   "home.column_settings.show_replies": "顯示回應文章",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
   "introduction.federation.action": "Next",
   "introduction.federation.federated.headline": "Federated",
   "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
@@ -156,7 +166,7 @@
   "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
   "introduction.federation.local.headline": "Local",
   "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
+  "introduction.interactions.action": "Finish toot-orial!",
   "introduction.interactions.favourite.headline": "Favourite",
   "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
   "introduction.interactions.reblog.headline": "Boost",
@@ -194,16 +204,19 @@
   "keyboard_shortcuts.search": "把標示移動到搜索",
   "keyboard_shortcuts.start": "to open \"get started\" column",
   "keyboard_shortcuts.toggle_hidden": "顯示或隱藏被標為敏感的文字",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
   "keyboard_shortcuts.toot": "新的推文",
   "keyboard_shortcuts.unfocus": "把標示移離文字輸入和搜索",
   "keyboard_shortcuts.up": "在列表往上移動",
   "lightbox.close": "關閉",
   "lightbox.next": "繼續",
   "lightbox.previous": "回退",
+  "lightbox.view_context": "View context",
   "lists.account.add": "新增到列表",
   "lists.account.remove": "從列表刪除",
   "lists.delete": "刪除列表",
   "lists.edit": "編輯列表",
+  "lists.edit.submit": "Change title",
   "lists.new.create": "新增列表",
   "lists.new.title_placeholder": "新列表標題",
   "lists.search": "從你關注的用戶中搜索",
@@ -224,6 +237,7 @@
   "navigation_bar.favourites": "最愛的內容",
   "navigation_bar.filters": "Muted words",
   "navigation_bar.follow_requests": "關注請求",
+  "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.info": "關於本服務站",
   "navigation_bar.keyboard_shortcuts": "鍵盤快速鍵",
   "navigation_bar.lists": "列表",
@@ -232,11 +246,13 @@
   "navigation_bar.personal": "Personal",
   "navigation_bar.pins": "置頂文章",
   "navigation_bar.preferences": "偏好設定",
+  "navigation_bar.profile_directory": "Profile directory",
   "navigation_bar.public_timeline": "跨站時間軸",
   "navigation_bar.security": "安全",
   "notification.favourite": "{name} 收藏了你的文章",
   "notification.follow": "{name} 開始關注你",
   "notification.mention": "{name} 提及你",
+  "notification.poll": "A poll you have voted in has ended",
   "notification.reblog": "{name} 轉推你的文章",
   "notifications.clear": "清空通知紀錄",
   "notifications.clear_confirmation": "你確定要清空通知紀錄嗎?",
@@ -247,6 +263,7 @@
   "notifications.column_settings.filter_bar.show": "Show",
   "notifications.column_settings.follow": "關注你:",
   "notifications.column_settings.mention": "提及你:",
+  "notifications.column_settings.poll": "Poll results:",
   "notifications.column_settings.push": "推送通知",
   "notifications.column_settings.reblog": "轉推你的文章:",
   "notifications.column_settings.show": "在通知欄顯示",
@@ -256,7 +273,14 @@
   "notifications.filter.favourites": "Favourites",
   "notifications.filter.follows": "Follows",
   "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Poll results",
   "notifications.group": "{count} 條通知",
+  "poll.closed": "Closed",
+  "poll.refresh": "Refresh",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Vote",
+  "poll_button.add_poll": "Add a poll",
+  "poll_button.remove_poll": "Remove poll",
   "privacy.change": "調整私隱設定",
   "privacy.direct.long": "只有提及的用戶能看到",
   "privacy.direct.short": "私人訊息",
@@ -291,12 +315,12 @@
   "search_results.hashtags": "標籤",
   "search_results.statuses": "文章",
   "search_results.total": "{count, number} 項結果",
-  "standalone.public_title": "站點一瞥…",
   "status.admin_account": "Open moderation interface for @{name}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "封鎖 @{name}",
   "status.cancel_reblog_private": "取消轉推",
   "status.cannot_reblog": "這篇文章無法被轉推",
+  "status.copy": "Copy link to status",
   "status.delete": "刪除",
   "status.detailed_status": "Detailed conversation view",
   "status.direct": "私訊 @{name}",
@@ -321,7 +345,6 @@
   "status.reply": "回應",
   "status.replyAll": "回應所有人",
   "status.report": "舉報 @{name}",
-  "status.sensitive_toggle": "點擊顯示",
   "status.sensitive_warning": "敏感內容",
   "status.share": "分享",
   "status.show_less": "減少顯示",
@@ -338,10 +361,17 @@
   "tabs_bar.local_timeline": "本站",
   "tabs_bar.notifications": "通知",
   "tabs_bar.search": "搜尋",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
   "trends.count_by_accounts": "{count} 位用戶在討論",
   "ui.beforeunload": "如果你現在離開 Mastodon,你的草稿內容將會被丟棄。",
   "upload_area.title": "將檔案拖放至此上載",
   "upload_button.label": "上載媒體檔案",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
   "upload_form.description": "為視覺障礙人士添加文字說明",
   "upload_form.focus": "裁切",
   "upload_form.undo": "刪除",
diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json
index 0cbe5da5aac1e143e2082a898a083b2ac5a2f058..5715ef01a1cb85ce3cbbf8ca5895d0152fb3daf8 100644
--- a/app/javascript/mastodon/locales/zh-TW.json
+++ b/app/javascript/mastodon/locales/zh-TW.json
@@ -1,211 +1,224 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "從名單中新增或移除",
   "account.badges.bot": "機器人",
   "account.block": "封鎖 @{name}",
-  "account.block_domain": "隱藏來自 {domain} 的一切嘟文",
-  "account.blocked": "已被封鎖的",
-  "account.direct": "發送私訊給 @{name}",
-  "account.disclaimer_full": "下列資料不一定完整。",
-  "account.domain_blocked": "站點被隱藏",
-  "account.edit_profile": "編輯使用者資訊",
-  "account.endorse": "在個人資訊頁面上推薦對方",
+  "account.block_domain": "隱藏來自 {domain} 的所有嘟文",
+  "account.blocked": "已封鎖",
+  "account.direct": "傳私訊給 @{name}",
+  "account.domain_blocked": "已隱藏網域",
+  "account.edit_profile": "編輯個人資料",
+  "account.endorse": "在個人資料推薦對方",
   "account.follow": "關注",
   "account.followers": "關注者",
-  "account.followers.empty": "還沒有人關注這個使用者。",
+  "account.followers.empty": "還沒有人關注這位使用者。",
   "account.follows": "正在關注",
-  "account.follows.empty": "這個使用者還沒有關注任何人。",
-  "account.follows_you": "關注你",
+  "account.follows.empty": "這個使用者尚未關注任何使用者。",
+  "account.follows_you": "關注了你",
   "account.hide_reblogs": "隱藏來自 @{name} 的轉推",
-  "account.link_verified_on": "Ownership of this link was checked on {date}",
-  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
+  "account.link_verified_on": "此連結的所有權已在 {date} 檢查",
+  "account.locked_info": "此帳號的隱私狀態被設為鎖定,擁有者將手動審核可關注此帳號的人。",
   "account.media": "媒體",
-  "account.mention": "提到 @{name}",
-  "account.moved_to": "{name} 已經移至:",
+  "account.mention": "提及 @{name}",
+  "account.moved_to": "{name} 已遷移至:",
   "account.mute": "靜音 @{name}",
   "account.mute_notifications": "靜音來自 @{name} 的通知",
-  "account.muted": "靜音",
+  "account.muted": "已靜音",
   "account.posts": "嘟文",
   "account.posts_with_replies": "嘟文與回覆",
   "account.report": "檢舉 @{name}",
-  "account.requested": "正在等待對方同意。點擊以取消發送關注請求",
-  "account.share": "分享 @{name} 的使用者資訊",
+  "account.requested": "正在等待核准。按一下取消關注請求",
+  "account.share": "分享 @{name} 的個人資料",
   "account.show_reblogs": "顯示來自 @{name} 的嘟文",
   "account.unblock": "取消封鎖 @{name}",
-  "account.unblock_domain": "不再隱藏 {domain}",
-  "account.unendorse": "不再於個人資訊頁面上推薦對方",
+  "account.unblock_domain": "取消隱藏 {domain}",
+  "account.unendorse": "不再於個人資料頁面推薦對方",
   "account.unfollow": "取消關注",
   "account.unmute": "不再靜音 @{name}",
-  "account.unmute_notifications": "不再對來自 @{name} 的通知靜音",
-  "account.view_full_profile": "查看完整資訊",
-  "alert.unexpected.message": "發生非預期的錯誤。",
+  "account.unmute_notifications": "不再靜音來自 @{name} 的通知",
+  "alert.unexpected.message": "發生了非預期的錯誤。",
   "alert.unexpected.title": "哎呀!",
-  "boost_modal.combo": "下次你可以按 {combo} 來跳過",
-  "bundle_column_error.body": "加載本組件出錯。",
+  "boost_modal.combo": "下次您可以按 {combo} 跳過",
+  "bundle_column_error.body": "載入此組件時發生錯誤。",
   "bundle_column_error.retry": "重試",
   "bundle_column_error.title": "網路錯誤",
   "bundle_modal_error.close": "關閉",
-  "bundle_modal_error.message": "加載本組件出錯。",
+  "bundle_modal_error.message": "載入此組件時發生錯誤。",
   "bundle_modal_error.retry": "重試",
   "column.blocks": "封鎖的使用者",
   "column.community": "本地時間軸",
   "column.direct": "私訊",
-  "column.domain_blocks": "隱藏的站點",
+  "column.domain_blocks": "隱藏的網域",
   "column.favourites": "最愛",
   "column.follow_requests": "關注請求",
   "column.home": "主頁",
   "column.lists": "名單",
-  "column.mutes": "靜音的使用者",
+  "column.mutes": "被靜音的使用者",
   "column.notifications": "通知",
-  "column.pins": "置頂嘟文",
-  "column.public": "其他站點時間軸",
+  "column.pins": "釘選的嘟文",
+  "column.public": "聯邦時間軸",
   "column_back_button.label": "上一頁",
   "column_header.hide_settings": "隱藏設定",
-  "column_header.moveLeft_settings": "將欄左移",
-  "column_header.moveRight_settings": "將欄右移",
-  "column_header.pin": "固定",
+  "column_header.moveLeft_settings": "將欄位向左移動",
+  "column_header.moveRight_settings": "將欄位向右移動",
+  "column_header.pin": "釘選",
   "column_header.show_settings": "顯示設定",
-  "column_header.unpin": "取下",
+  "column_header.unpin": "取消釘選",
   "column_subheading.settings": "設定",
   "community.column_settings.media_only": "僅媒體",
-  "compose_form.direct_message_warning": "這條嘟文僅對有被提及的使用者才能看到。",
+  "compose_form.direct_message_warning": "這條嘟文只有被提及的使用者才能看到。",
   "compose_form.direct_message_warning_learn_more": "了解更多",
-  "compose_form.hashtag_warning": "此則推文將不會在任何主題標籤中看見,只有公開的推文可以用主題標籤來搜尋。",
-  "compose_form.lock_disclaimer": "你的帳號沒有{locked}。任何人都可以關注你,看到發給關注者的嘟文。",
+  "compose_form.hashtag_warning": "因這則嘟文設成「不公開」,因此它不會列在任何「#」標籤下。只有公開嘟文才能用「#」標籤找到。",
+  "compose_form.lock_disclaimer": "您的帳戶尚未{locked}。任何人都能關注您並看到您設定成僅關注者能看的嘟文。",
   "compose_form.lock_disclaimer.lock": "上鎖",
-  "compose_form.placeholder": "在想些什麼?",
+  "compose_form.placeholder": "您正在想些什麼?",
+  "compose_form.poll.add_option": "新增選擇",
+  "compose_form.poll.duration": "投票期限",
+  "compose_form.poll.option_placeholder": "第 {number} 個選擇",
+  "compose_form.poll.remove_option": "移除此選擇",
   "compose_form.publish": "嘟掉",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive.marked": "此媒體已被標註為敏感的",
-  "compose_form.sensitive.unmarked": "此媒體未被標註為敏感的",
-  "compose_form.spoiler.marked": "文字隱藏在警告後",
-  "compose_form.spoiler.unmarked": "文字不是隱藏的",
-  "compose_form.spoiler_placeholder": "內容警告",
+  "compose_form.sensitive.hide": "Mark media as sensitive",
+  "compose_form.sensitive.marked": "此媒體被標記為敏感內容",
+  "compose_form.sensitive.unmarked": "此媒體未被標記為敏感內容",
+  "compose_form.spoiler.marked": "正文已隱藏在警告之後",
+  "compose_form.spoiler.unmarked": "正文未被隱藏",
+  "compose_form.spoiler_placeholder": "請在此處寫入警告訊息",
   "confirmation_modal.cancel": "取消",
+  "confirmations.block.block_and_report": "Block & Report",
   "confirmations.block.confirm": "封鎖",
   "confirmations.block.message": "你確定要封鎖 {name} ?",
   "confirmations.delete.confirm": "刪除",
-  "confirmations.delete.message": "你確定要刪除這個狀態?",
+  "confirmations.delete.message": "你確定要刪除這條嘟文?",
   "confirmations.delete_list.confirm": "刪除",
-  "confirmations.delete_list.message": "確定要永久性地刪除這個名單嗎?",
+  "confirmations.delete_list.message": "確定要永久刪除此名單?",
   "confirmations.domain_block.confirm": "隱藏整個網域",
-  "confirmations.domain_block.message": "你真的確定要靜音所有來自 {domain} 的內容嗎? 多數情況下,封鎖或靜音幾個特定用戶應該就能滿足你的需求了。來自該站點的內容將不再出現在你的公共時間軸或通知裡。來自該站點的關注者將會被移除。",
-  "confirmations.mute.confirm": "消音",
-  "confirmations.mute.message": "你確定要消音 {name} ?",
-  "confirmations.redraft.confirm": "刪除 & 編輯",
-  "confirmations.redraft.message": "你確定要刪除這條嘟文並重新編輯它嗎?所有相關的轉嘟與最愛都會被刪除,而對原始嘟文的回覆將會變成孤兒。",
-  "confirmations.reply.confirm": "Reply",
-  "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
+  "confirmations.domain_block.message": "確定封鎖整個 {domain} 嗎?多數情況下,封鎖或靜音幾個特定使用者應該就能滿足你的需求了。您將不能在任何公開時間軸或通知中看到來自該網域的內容。來自該網域的關注者將被移除。",
+  "confirmations.mute.confirm": "靜音",
+  "confirmations.mute.message": "確定靜音 {name} ?",
+  "confirmations.redraft.confirm": "刪除並重新編輯",
+  "confirmations.redraft.message": "你確定要刪除這條嘟文並重新編輯它嗎?這麼做將失去轉嘟和最愛,而對原始嘟文的回覆將被孤立。",
+  "confirmations.reply.confirm": "回覆",
+  "confirmations.reply.message": "現在回覆將蓋掉您目前正在撰寫的訊息。是否仍要回覆?",
   "confirmations.unfollow.confirm": "取消關注",
-  "confirmations.unfollow.message": "真的不要繼續關注 {name} 了嗎?",
-  "embed.instructions": "要內嵌此嘟文,請將以下代碼貼進你的網站。",
-  "embed.preview": "看上去會變成這樣:",
+  "confirmations.unfollow.message": "真的要取消關注 {name} 嗎?",
+  "embed.instructions": "要嵌入此嘟文,請將以下代碼貼進你的網站。",
+  "embed.preview": "他會顯示成這樣:",
   "emoji_button.activity": "活動",
   "emoji_button.custom": "自訂",
-  "emoji_button.flags": "旗幟",
+  "emoji_button.flags": "旗標",
   "emoji_button.food": "飲食",
   "emoji_button.label": "插入表情符號",
-  "emoji_button.nature": "自然",
-  "emoji_button.not_found": "沒有表情符號吼!! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.nature": "大自然",
+  "emoji_button.not_found": "就沒這表情符號吼!! (╯°□°)╯︵ ┻━┻",
   "emoji_button.objects": "物件",
   "emoji_button.people": "使用者",
-  "emoji_button.recent": "常用",
+  "emoji_button.recent": "最常使用",
   "emoji_button.search": "搜尋…",
   "emoji_button.search_results": "搜尋結果",
   "emoji_button.symbols": "符號",
   "emoji_button.travel": "旅遊與地點",
-  "empty_column.account_timeline": "No toots here!",
+  "empty_column.account_timeline": "這裡還沒有嘟文!",
+  "empty_column.account_unavailable": "Profile unavailable",
   "empty_column.blocks": "你還沒有封鎖任何使用者。",
-  "empty_column.community": "本地時間軸是空的。公開寫點什麼吧!",
-  "empty_column.direct": "你還沒有使用過私訊。當你發出或著收到私訊時,它會在這裡顯示。",
-  "empty_column.domain_blocks": "還沒有隱藏任何網域。",
-  "empty_column.favourited_statuses": "你還沒有收藏任何嘟文。收藏後的嘟文會顯示在這裡。",
-  "empty_column.favourites": "還沒有人收藏此嘟文。如果有人收藏,會顯示在這裡。",
-  "empty_column.follow_requests": "還沒有人請求關注你。如果收到關注請求,會顯示在這裡。",
-  "empty_column.hashtag": "這個主題標籤下什麼都沒有。",
-  "empty_column.home": "你還沒關注任何人。造訪{public}或利用搜尋功能找到其他用者。",
+  "empty_column.community": "本地時間軸是空的。快公開嘟些文搶頭香啊!",
+  "empty_column.direct": "您還沒有任何私訊。當您私訊別人或收到私訊時,它將於此顯示。",
+  "empty_column.domain_blocks": "尚未隱藏任何網域。",
+  "empty_column.favourited_statuses": "你還沒有將任何嘟文標為最愛。最愛的嘟文將顯示於此。",
+  "empty_column.favourites": "還沒有人將此嘟文標為最愛。如果有人標成最愛,則會顯示在這裡。",
+  "empty_column.follow_requests": "您尚未收到任何關注請求。收到時會顯示於此。",
+  "empty_column.hashtag": "這個「#」標籤下什麼都沒有。",
+  "empty_column.home": "您的首頁時間軸是空的!前往 {public} 或使用搜尋功能來認識其他人。",
   "empty_column.home.public_timeline": "公開時間軸",
-  "empty_column.list": "此份名單尚未有東西。當此名單的成員嘟出了新的狀態時,它們就會出現在這裡。",
+  "empty_column.list": "此份名單還沒有東西。當此名單的成員嘟出了新的嘟文時,它們就會出現在這裡。",
   "empty_column.lists": "你還沒有建立任何名單。你建立的名單將會顯示在這裡。",
   "empty_column.mutes": "你還沒有靜音任何使用者。",
-  "empty_column.notifications": "還沒有任何通知。和別的使用者互動來開始對話。",
-  "empty_column.public": "這裡什麼都沒有! 寫一些公開的嘟文,或著關注其他站點的使用者後,這裡就會有嘟文出現了",
+  "empty_column.notifications": "您尚未收到任何通知,和別人互動開啟對話吧。",
+  "empty_column.public": "這裡什麼都沒有!嘗試寫些公開的嘟文,或著自己關注其他伺服器的使用者後就會有嘟文出現了",
   "follow_request.authorize": "授權",
   "follow_request.reject": "拒絕",
-  "getting_started.developers": "開發",
-  "getting_started.directory": "Profile directory",
+  "getting_started.developers": "開發者",
+  "getting_started.directory": "個人資料目錄",
   "getting_started.documentation": "文件",
-  "getting_started.heading": "馬上開始",
+  "getting_started.heading": "開始使用",
   "getting_started.invite": "邀請使用者",
-  "getting_started.open_source_notice": "Mastodon 是開源軟體。你可以在 GitHub {github} 上做出貢獻或是回報問題。",
-  "getting_started.security": "登入資訊",
-  "getting_started.terms": "使用條款",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
-  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "getting_started.open_source_notice": "Mastodon 是開源軟體。你可以在 GitHub {github} 上貢獻或是回報問題。",
+  "getting_started.security": "安全性",
+  "getting_started.terms": "服務條款",
+  "hashtag.column_header.tag_mode.all": "以及{additional}",
+  "hashtag.column_header.tag_mode.any": "或是{additional}",
+  "hashtag.column_header.tag_mode.none": "而不用{additional}",
+  "hashtag.column_settings.select.no_options_message": "找不到建議",
+  "hashtag.column_settings.select.placeholder": "輸入「#」標籤…",
+  "hashtag.column_settings.tag_mode.all": "全部",
+  "hashtag.column_settings.tag_mode.any": "任一",
+  "hashtag.column_settings.tag_mode.none": "全都不要",
+  "hashtag.column_settings.tag_toggle": "對此欄位加入額外標籤",
   "home.column_settings.basic": "基本",
   "home.column_settings.show_reblogs": "顯示轉推",
-  "home.column_settings.show_replies": "顯示回應",
-  "introduction.federation.action": "Next",
-  "introduction.federation.federated.headline": "Federated",
-  "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
-  "introduction.federation.home.headline": "Home",
-  "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
-  "introduction.federation.local.headline": "Local",
-  "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
-  "introduction.interactions.action": "Finish tutorial!",
-  "introduction.interactions.favourite.headline": "Favourite",
-  "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
-  "introduction.interactions.reblog.headline": "Boost",
-  "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
-  "introduction.interactions.reply.headline": "Reply",
-  "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
-  "introduction.welcome.action": "Let's go!",
-  "introduction.welcome.headline": "First steps",
-  "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
-  "keyboard_shortcuts.back": "回到上一個",
-  "keyboard_shortcuts.blocked": "到封鎖的使用者名單",
-  "keyboard_shortcuts.boost": "到轉推",
-  "keyboard_shortcuts.column": "選擇第 X 欄中的嘟文",
-  "keyboard_shortcuts.compose": "焦點移至撰寫文字區塊",
+  "home.column_settings.show_replies": "顯示回覆",
+  "intervals.full.days": "{number, plural, one {# 天} other {# 天}}",
+  "intervals.full.hours": "{number, plural, one {# 小時} other {# 小時}}",
+  "intervals.full.minutes": "{number, plural, one {# 分鐘} other {# 分鐘}}",
+  "introduction.federation.action": "下一步",
+  "introduction.federation.federated.headline": "聯邦",
+  "introduction.federation.federated.text": "來自聯邦網路中其他伺服器的公開嘟文將會在聯邦網路時間軸中顯示。",
+  "introduction.federation.home.headline": "首頁",
+  "introduction.federation.home.text": "您所關注使用者所發的嘟文將顯示在首頁的訊息來源。您能關注任何伺服器上的任何人!",
+  "introduction.federation.local.headline": "本地",
+  "introduction.federation.local.text": "跟您同伺服器之使用者所發的公開嘟文將會顯示在本地時間軸中。",
+  "introduction.interactions.action": "完成教學!",
+  "introduction.interactions.favourite.headline": "最愛",
+  "introduction.interactions.favourite.text": "您能稍候儲存嘟文,或者將嘟文加到最愛,讓作者知道您喜歡這嘟文。",
+  "introduction.interactions.reblog.headline": "轉嘟",
+  "introduction.interactions.reblog.text": "您能透過轉嘟他人嘟文來分享給您的關注者。",
+  "introduction.interactions.reply.headline": "回覆",
+  "introduction.interactions.reply.text": "您能回覆其他人或自己的嘟文。將會把這些回覆串成一串對話。",
+  "introduction.welcome.action": "開始!",
+  "introduction.welcome.headline": "第一步",
+  "introduction.welcome.text": "歡迎來到聯邦!稍候您將可以廣播訊息並跨各種各式各樣的伺服器與朋友聊天。但這台伺服器,{domain},十分特殊 -- 它寄管了您的個人資料,所以請記住這台伺服器的名稱。",
+  "keyboard_shortcuts.back": "返回上一頁",
+  "keyboard_shortcuts.blocked": "開啟「封鎖的使用者」名單",
+  "keyboard_shortcuts.boost": "轉嘟",
+  "keyboard_shortcuts.column": "將焦點放在其中一欄的嘟文",
+  "keyboard_shortcuts.compose": "將焦點移至撰寫文字區塊",
   "keyboard_shortcuts.description": "描述",
-  "keyboard_shortcuts.direct": "到私訊欄",
-  "keyboard_shortcuts.down": "在列表往下移動",
-  "keyboard_shortcuts.enter": "看嘟文",
-  "keyboard_shortcuts.favourite": "收藏",
-  "keyboard_shortcuts.favourites": "到收藏名單",
-  "keyboard_shortcuts.federated": "到其他站點時間軸",
+  "keyboard_shortcuts.direct": "開啟私訊欄",
+  "keyboard_shortcuts.down": "在名單中往下移動",
+  "keyboard_shortcuts.enter": "檢視嘟文",
+  "keyboard_shortcuts.favourite": "加入最愛",
+  "keyboard_shortcuts.favourites": "開啟最愛名單",
+  "keyboard_shortcuts.federated": "開啟聯邦時間軸",
   "keyboard_shortcuts.heading": "鍵盤快速鍵",
-  "keyboard_shortcuts.home": "到主頁時間軸",
+  "keyboard_shortcuts.home": "開啟首頁時間軸",
   "keyboard_shortcuts.hotkey": "快速鍵",
-  "keyboard_shortcuts.legend": "顯示這個說明",
-  "keyboard_shortcuts.local": "到本地時間軸",
-  "keyboard_shortcuts.mention": "到提到的作者",
-  "keyboard_shortcuts.muted": "到靜音的使用者列表",
-  "keyboard_shortcuts.my_profile": "到你的個人資訊頁",
-  "keyboard_shortcuts.notifications": "打開通知欄",
-  "keyboard_shortcuts.pinned": "到收藏的嘟文名單",
-  "keyboard_shortcuts.profile": "到嘟文作者的個人資訊頁",
-  "keyboard_shortcuts.reply": "到回應",
-  "keyboard_shortcuts.requests": "打開關注請求名單",
-  "keyboard_shortcuts.search": "把滑鼠移動到搜尋",
-  "keyboard_shortcuts.start": "到「馬上開始」",
-  "keyboard_shortcuts.toggle_hidden": "顯示或隱藏被標為敏感的嘟文",
-  "keyboard_shortcuts.toot": "新的嘟文",
-  "keyboard_shortcuts.unfocus": "取消輸入",
-  "keyboard_shortcuts.up": "在列表往上移動",
+  "keyboard_shortcuts.legend": "顯示此說明",
+  "keyboard_shortcuts.local": "開啟本地時間軸",
+  "keyboard_shortcuts.mention": "提及作者",
+  "keyboard_shortcuts.muted": "開啟靜音使用者名單",
+  "keyboard_shortcuts.my_profile": "開啟個人資料頁面",
+  "keyboard_shortcuts.notifications": "開啟通知欄",
+  "keyboard_shortcuts.pinned": "開啟釘選的嘟文名單",
+  "keyboard_shortcuts.profile": "開啟作者的個人資料頁",
+  "keyboard_shortcuts.reply": "回應嘟文",
+  "keyboard_shortcuts.requests": "開啟關注請求名單",
+  "keyboard_shortcuts.search": "將焦點移至搜尋框",
+  "keyboard_shortcuts.start": "開啟「開始使用」欄位",
+  "keyboard_shortcuts.toggle_hidden": "顯示/隱藏在內容警告之後的正文",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
+  "keyboard_shortcuts.toot": "開始發出新嘟文",
+  "keyboard_shortcuts.unfocus": "取消輸入文字區塊 / 搜尋的焦點",
+  "keyboard_shortcuts.up": "在名單中往上移動",
   "lightbox.close": "關閉",
-  "lightbox.next": "繼續",
-  "lightbox.previous": "回退",
-  "lists.account.add": "加到名單裡",
+  "lightbox.next": "下一步",
+  "lightbox.previous": "上一步",
+  "lightbox.view_context": "View context",
+  "lists.account.add": "新增至名單",
   "lists.account.remove": "從名單中移除",
   "lists.delete": "刪除名單",
-  "lists.edit": "修改名單",
+  "lists.edit": "編輯名單",
+  "lists.edit.submit": "變更標題",
   "lists.new.create": "新增名單",
-  "lists.new.title_placeholder": "名單名稱",
+  "lists.new.title_placeholder": "新名單標題",
   "lists.search": "搜尋您關注的使用者",
   "lists.subheading": "您的名單",
   "loading_indicator.label": "讀取中...",
@@ -216,47 +229,58 @@
   "navigation_bar.apps": "行動應用程式",
   "navigation_bar.blocks": "封鎖的使用者",
   "navigation_bar.community_timeline": "本地時間軸",
-  "navigation_bar.compose": "寫新的嘟文",
+  "navigation_bar.compose": "撰寫新嘟文",
   "navigation_bar.direct": "私訊",
   "navigation_bar.discover": "探索",
-  "navigation_bar.domain_blocks": "隱藏的站點",
-  "navigation_bar.edit_profile": "編輯使用者資訊",
-  "navigation_bar.favourites": "最愛",
-  "navigation_bar.filters": "消音的詞",
+  "navigation_bar.domain_blocks": "隱藏的網域",
+  "navigation_bar.edit_profile": "編輯個人資料",
+  "navigation_bar.favourites": "最愛內容",
+  "navigation_bar.filters": "靜音詞彙",
   "navigation_bar.follow_requests": "關注請求",
-  "navigation_bar.info": "關於本站",
-  "navigation_bar.keyboard_shortcuts": "快捷鍵",
+  "navigation_bar.follows_and_followers": "Follows and followers",
+  "navigation_bar.info": "關於此伺服器",
+  "navigation_bar.keyboard_shortcuts": "快速鍵",
   "navigation_bar.lists": "名單",
   "navigation_bar.logout": "登出",
   "navigation_bar.mutes": "靜音的使用者",
   "navigation_bar.personal": "個人",
-  "navigation_bar.pins": "置頂嘟文",
+  "navigation_bar.pins": "釘選的嘟文",
   "navigation_bar.preferences": "偏好設定",
-  "navigation_bar.public_timeline": "其他站點時間軸",
-  "navigation_bar.security": "登入資訊",
-  "notification.favourite": "{name}把你的嘟文加入了最愛",
-  "notification.follow": "{name}關注了你",
-  "notification.mention": "{name}提到了你",
+  "navigation_bar.profile_directory": "Profile directory",
+  "navigation_bar.public_timeline": "聯邦時間軸",
+  "navigation_bar.security": "安全性",
+  "notification.favourite": "{name} 把你的嘟文加入了最愛",
+  "notification.follow": "{name} 關注了你",
+  "notification.mention": "{name} 提到了你",
+  "notification.poll": "您投過的投票已經結束",
   "notification.reblog": "{name}轉嘟了你的嘟文",
   "notifications.clear": "清除通知",
   "notifications.clear_confirmation": "確定要永久清除你的通知嗎?",
   "notifications.column_settings.alert": "桌面通知",
   "notifications.column_settings.favourite": "最愛:",
-  "notifications.column_settings.filter_bar.advanced": "Display all categories",
-  "notifications.column_settings.filter_bar.category": "Quick filter bar",
-  "notifications.column_settings.filter_bar.show": "Show",
-  "notifications.column_settings.follow": "新的關注者:",
-  "notifications.column_settings.mention": "提到:",
+  "notifications.column_settings.filter_bar.advanced": "顯示所有分類",
+  "notifications.column_settings.filter_bar.category": "快速過濾欄",
+  "notifications.column_settings.filter_bar.show": "顯示",
+  "notifications.column_settings.follow": "新關注者:",
+  "notifications.column_settings.mention": "提及:",
+  "notifications.column_settings.poll": "投票結果:",
   "notifications.column_settings.push": "推送通知",
   "notifications.column_settings.reblog": "轉嘟:",
-  "notifications.column_settings.show": "顯示在欄位中",
+  "notifications.column_settings.show": "在欄位中顯示",
   "notifications.column_settings.sound": "播放音效",
-  "notifications.filter.all": "All",
-  "notifications.filter.boosts": "Boosts",
-  "notifications.filter.favourites": "Favourites",
-  "notifications.filter.follows": "Follows",
-  "notifications.filter.mentions": "Mentions",
+  "notifications.filter.all": "全部",
+  "notifications.filter.boosts": "轉嘟",
+  "notifications.filter.favourites": "最愛",
+  "notifications.filter.follows": "關注的使用者",
+  "notifications.filter.mentions": "提及",
+  "notifications.filter.polls": "投票結果",
   "notifications.group": "{count} 條通知",
+  "poll.closed": "已關閉",
+  "poll.refresh": "重新整理",
+  "poll.total_votes": "{count, plural, one {# 個投票} other {# 個投票}}",
+  "poll.vote": "投票",
+  "poll_button.add_poll": "建立投票",
+  "poll_button.remove_poll": "移除投票",
   "privacy.change": "調整隱私狀態",
   "privacy.direct.long": "只有被提到的使用者能看到",
   "privacy.direct.short": "私訊",
@@ -276,7 +300,7 @@
   "reply_indicator.cancel": "取消",
   "report.forward": "轉寄到 {target}",
   "report.forward_hint": "這個帳戶屬於其他站點。要像該站點發送匿名的檢舉訊息嗎?",
-  "report.hint": "這項訊息會發送到你該站點的管理員。你可以提供檢舉這個帳戶的理由:",
+  "report.hint": "這項訊息會發送到您伺服器的管理員。你可以提供檢舉這個帳戶的理由:",
   "report.placeholder": "更多訊息",
   "report.submit": "送出",
   "report.target": "檢舉 {target}",
@@ -284,19 +308,19 @@
   "search_popout.search_format": "進階搜尋格式",
   "search_popout.tips.full_text": "輸入簡單的文字,搜尋由你撰寫、最愛、轉嘟或提你的嘟文,以及符合使用者名稱、帳戶名稱和標籤。",
   "search_popout.tips.hashtag": "主題標籤",
-  "search_popout.tips.status": "狀態",
+  "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.admin_account": "Open moderation interface for @{name}",
-  "status.admin_status": "Open this status in the moderation interface",
+  "status.admin_account": "開啟 @{name} 的管理介面",
+  "status.admin_status": "在管理介面開啟此嘟文",
   "status.block": "封鎖 @{name}",
   "status.cancel_reblog_private": "取消轉嘟",
   "status.cannot_reblog": "這篇嘟文無法被轉嘟",
+  "status.copy": "將連結複製到嘟文中",
   "status.delete": "刪除",
   "status.detailed_status": "對話的詳細內容",
   "status.direct": "發送私訊給 @{name}",
@@ -310,9 +334,9 @@
   "status.mute": "靜音 @{name}",
   "status.mute_conversation": "靜音對話",
   "status.open": "展開嘟文",
-  "status.pin": "置頂到個人資訊頁",
-  "status.pinned": "置頂嘟文",
-  "status.read_more": "Read more",
+  "status.pin": "釘選到個人資料頁",
+  "status.pinned": "釘選的嘟文",
+  "status.read_more": "閱讀更多",
   "status.reblog": "轉嘟",
   "status.reblog_private": "轉嘟給原有關注者",
   "status.reblogged_by": "{name} 轉嘟了",
@@ -321,29 +345,35 @@
   "status.reply": "回覆",
   "status.replyAll": "回覆所有人",
   "status.report": "檢舉 @{name}",
-  "status.sensitive_toggle": "點擊顯示",
   "status.sensitive_warning": "敏感內容",
   "status.share": "分享",
   "status.show_less": "減少顯示",
   "status.show_less_all": "減少顯示這類嘟文",
   "status.show_more": "顯示更多",
   "status.show_more_all": "顯示更多這類嘟文",
-  "status.show_thread": "Show thread",
+  "status.show_thread": "顯示討論串",
   "status.unmute_conversation": "解除此對話的靜音",
   "status.unpin": "解除置頂",
-  "suggestions.dismiss": "Dismiss suggestion",
-  "suggestions.header": "You might be interested in…",
+  "suggestions.dismiss": "關閉建議",
+  "suggestions.header": "您可能對這些東西有興趣…",
   "tabs_bar.federated_timeline": "其他站點",
   "tabs_bar.home": "主頁",
   "tabs_bar.local_timeline": "本站",
   "tabs_bar.notifications": "通知",
   "tabs_bar.search": "搜尋",
+  "time_remaining.days": "剩餘{number, plural, one {# 天數} other {# 天數}}",
+  "time_remaining.hours": "剩餘{number, plural, one {# 小時} other {# 小時}}",
+  "time_remaining.minutes": "剩餘{number, plural, one {# 分鐘} other {# 分鐘}}",
+  "time_remaining.moments": "剩餘時間",
+  "time_remaining.seconds": "剩餘 {number, plural, one {# 秒} other {# 秒}}",
   "trends.count_by_accounts": "{count} 位使用者在討論",
   "ui.beforeunload": "如果離開 Mastodon,你的草稿將會不見。",
   "upload_area.title": "拖放來上傳",
   "upload_button.label": "上傳媒體檔案 (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_error.limit": "已達到檔案上傳限制。",
+  "upload_error.poll": "不允許在投票上傳檔案。",
   "upload_form.description": "為視障人士增加文字說明",
-  "upload_form.focus": "裁切",
+  "upload_form.focus": "變更預覽",
   "upload_form.undo": "刪除",
   "upload_progress.label": "上傳中...",
   "video.close": "關閉影片",
diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js
index 1622871b8fff5c9d1765065af187119b59295733..fae7522b2632e0923a39cedf47800c62edd53496 100644
--- a/app/javascript/mastodon/reducers/compose.js
+++ b/app/javascript/mastodon/reducers/compose.js
@@ -29,6 +29,12 @@ import {
   COMPOSE_UPLOAD_CHANGE_SUCCESS,
   COMPOSE_UPLOAD_CHANGE_FAIL,
   COMPOSE_RESET,
+  COMPOSE_POLL_ADD,
+  COMPOSE_POLL_REMOVE,
+  COMPOSE_POLL_OPTION_ADD,
+  COMPOSE_POLL_OPTION_CHANGE,
+  COMPOSE_POLL_OPTION_REMOVE,
+  COMPOSE_POLL_SETTINGS_CHANGE,
 } from '../actions/compose';
 import { TIMELINE_DELETE } from '../actions/timelines';
 import { STORE_HYDRATE } from '../actions/store';
@@ -55,6 +61,7 @@ const initialState = ImmutableMap({
   is_uploading: false,
   progress: 0,
   media_attachments: ImmutableList(),
+  poll: null,
   suggestion_token: null,
   suggestions: ImmutableList(),
   default_privacy: 'public',
@@ -64,6 +71,12 @@ const initialState = ImmutableMap({
   tagHistory: ImmutableList(),
 });
 
+const initialPoll = ImmutableMap({
+  options: ImmutableList(['', '']),
+  expires_in: 24 * 3600,
+  multiple: false,
+});
+
 function statusToTextMentions(state, status) {
   let set = ImmutableOrderedSet([]);
 
@@ -85,6 +98,7 @@ function clearAll(state) {
     map.set('privacy', state.get('default_privacy'));
     map.set('sensitive', false);
     map.update('media_attachments', list => list.clear());
+    map.set('poll', null);
     map.set('idempotencyKey', uuid());
   });
 };
@@ -117,13 +131,15 @@ function removeMedia(state, mediaId) {
   });
 };
 
-const insertSuggestion = (state, position, token, completion) => {
+const insertSuggestion = (state, position, token, completion, path) => {
   return state.withMutations(map => {
-    map.update('text', oldText => `${oldText.slice(0, position)}${completion} ${oldText.slice(position + token.length)}`);
+    map.updateIn(path, oldText => `${oldText.slice(0, position)}${completion} ${oldText.slice(position + token.length)}`);
     map.set('suggestion_token', null);
-    map.update('suggestions', ImmutableList(), list => list.clear());
-    map.set('focusDate', new Date());
-    map.set('caretPosition', position + completion.length + 1);
+    map.set('suggestions', ImmutableList());
+    if (path.length === 1 && path[0] === 'text') {
+      map.set('focusDate', new Date());
+      map.set('caretPosition', position + completion.length + 1);
+    }
     map.set('idempotencyKey', uuid());
   });
 };
@@ -179,6 +195,12 @@ const expandMentions = status => {
   return fragment.innerHTML;
 };
 
+const expiresInFromExpiresAt = expires_at => {
+  if (!expires_at) return 24 * 3600;
+  const delta = (new Date(expires_at).getTime() - Date.now()) / 1000;
+  return [300, 1800, 3600, 21600, 86400, 259200, 604800].find(expires_in => expires_in >= delta) || 24 * 3600;
+};
+
 export default function compose(state = initialState, action) {
   switch(action.type) {
   case STORE_HYDRATE:
@@ -208,6 +230,7 @@ export default function compose(state = initialState, action) {
       }
     });
   case COMPOSE_SPOILER_TEXT_CHANGE:
+    if (!state.get('spoiler')) return state;
     return state
       .set('spoiler_text', action.text)
       .set('idempotencyKey', uuid());
@@ -247,6 +270,7 @@ export default function compose(state = initialState, action) {
       map.set('spoiler', false);
       map.set('spoiler_text', '');
       map.set('privacy', state.get('default_privacy'));
+      map.set('poll', null);
       map.set('idempotencyKey', uuid());
     });
   case COMPOSE_SUBMIT_REQUEST:
@@ -289,7 +313,7 @@ export default function compose(state = initialState, action) {
   case COMPOSE_SUGGESTIONS_READY:
     return state.set('suggestions', ImmutableList(action.accounts ? action.accounts.map(item => item.id) : action.emojis)).set('suggestion_token', action.token);
   case COMPOSE_SUGGESTION_SELECT:
-    return insertSuggestion(state, action.position, action.token, action.completion);
+    return insertSuggestion(state, action.position, action.token, action.completion, action.path);
   case COMPOSE_SUGGESTION_TAGS_UPDATE:
     return updateSuggestionTags(state, action.token);
   case COMPOSE_TAG_HISTORY_UPDATE:
@@ -314,13 +338,14 @@ export default function compose(state = initialState, action) {
       }));
   case REDRAFT:
     return state.withMutations(map => {
-      map.set('text', unescapeHTML(expandMentions(action.status)));
+      map.set('text', action.raw_text || unescapeHTML(expandMentions(action.status)));
       map.set('in_reply_to', action.status.get('in_reply_to_id'));
       map.set('privacy', action.status.get('visibility'));
       map.set('media_attachments', action.status.get('media_attachments'));
       map.set('focusDate', new Date());
       map.set('caretPosition', null);
       map.set('idempotencyKey', uuid());
+      map.set('sensitive', action.status.get('sensitive'));
 
       if (action.status.get('spoiler_text').length > 0) {
         map.set('spoiler', true);
@@ -329,7 +354,27 @@ export default function compose(state = initialState, action) {
         map.set('spoiler', false);
         map.set('spoiler_text', '');
       }
+
+      if (action.status.get('poll')) {
+        map.set('poll', ImmutableMap({
+          options: action.status.getIn(['poll', 'options']).map(x => x.get('title')),
+          multiple: action.status.getIn(['poll', 'multiple']),
+          expires_in: expiresInFromExpiresAt(action.status.getIn(['poll', 'expires_at'])),
+        }));
+      }
     });
+  case COMPOSE_POLL_ADD:
+    return state.set('poll', initialPoll);
+  case COMPOSE_POLL_REMOVE:
+    return state.set('poll', null);
+  case COMPOSE_POLL_OPTION_ADD:
+    return state.updateIn(['poll', 'options'], options => options.push(action.title));
+  case COMPOSE_POLL_OPTION_CHANGE:
+    return state.setIn(['poll', 'options', action.index], action.title);
+  case COMPOSE_POLL_OPTION_REMOVE:
+    return state.updateIn(['poll', 'options'], options => options.delete(action.index));
+  case COMPOSE_POLL_SETTINGS_CHANGE:
+    return state.update('poll', poll => poll.set('expires_in', action.expiresIn).set('multiple', action.isMultiple));
   default:
     return state;
   }
diff --git a/app/javascript/mastodon/reducers/conversations.js b/app/javascript/mastodon/reducers/conversations.js
index 955a07754de087d0b1a74aaa1931f486ed2ee9a2..39065823928ae2d8e1f0fe0984ce8cc73cc04d7f 100644
--- a/app/javascript/mastodon/reducers/conversations.js
+++ b/app/javascript/mastodon/reducers/conversations.js
@@ -8,6 +8,8 @@ import {
   CONVERSATIONS_UPDATE,
   CONVERSATIONS_READ,
 } from '../actions/conversations';
+import { ACCOUNT_BLOCK_SUCCESS, ACCOUNT_MUTE_SUCCESS } from 'mastodon/actions/accounts';
+import { DOMAIN_BLOCK_SUCCESS } from 'mastodon/actions/domain_blocks';
 import compareId from '../compare_id';
 
 const initialState = ImmutableMap({
@@ -35,7 +37,7 @@ const updateConversation = (state, item) => state.update('items', list => {
   }
 });
 
-const expandNormalizedConversations = (state, conversations, next) => {
+const expandNormalizedConversations = (state, conversations, next, isLoadingRecent) => {
   let items = ImmutableList(conversations.map(conversationToMap));
 
   return state.withMutations(mutable => {
@@ -66,7 +68,7 @@ const expandNormalizedConversations = (state, conversations, next) => {
       });
     }
 
-    if (!next) {
+    if (!next && !isLoadingRecent) {
       mutable.set('hasMore', false);
     }
 
@@ -74,6 +76,10 @@ const expandNormalizedConversations = (state, conversations, next) => {
   });
 };
 
+const filterConversations = (state, accountIds) => {
+  return state.update('items', list => list.filterNot(item => item.get('accounts').some(accountId => accountIds.includes(accountId))));
+};
+
 export default function conversations(state = initialState, action) {
   switch (action.type) {
   case CONVERSATIONS_FETCH_REQUEST:
@@ -81,7 +87,7 @@ export default function conversations(state = initialState, action) {
   case CONVERSATIONS_FETCH_FAIL:
     return state.set('isLoading', false);
   case CONVERSATIONS_FETCH_SUCCESS:
-    return expandNormalizedConversations(state, action.conversations, action.next);
+    return expandNormalizedConversations(state, action.conversations, action.next, action.isLoadingRecent);
   case CONVERSATIONS_UPDATE:
     return updateConversation(state, action.conversation);
   case CONVERSATIONS_MOUNT:
@@ -96,6 +102,11 @@ export default function conversations(state = initialState, action) {
 
       return item;
     }));
+  case ACCOUNT_BLOCK_SUCCESS:
+  case ACCOUNT_MUTE_SUCCESS:
+    return filterConversations(state, [action.relationship.id]);
+  case DOMAIN_BLOCK_SUCCESS:
+    return filterConversations(state, action.accounts);
   default:
     return state;
   }
diff --git a/app/javascript/mastodon/reducers/identity_proofs.js b/app/javascript/mastodon/reducers/identity_proofs.js
new file mode 100644
index 0000000000000000000000000000000000000000..58af0a5faaa780b64506fa8e2a569d1a2e8c8ea7
--- /dev/null
+++ b/app/javascript/mastodon/reducers/identity_proofs.js
@@ -0,0 +1,25 @@
+import { Map as ImmutableMap, fromJS } from 'immutable';
+import {
+  IDENTITY_PROOFS_ACCOUNT_FETCH_REQUEST,
+  IDENTITY_PROOFS_ACCOUNT_FETCH_SUCCESS,
+  IDENTITY_PROOFS_ACCOUNT_FETCH_FAIL,
+} from '../actions/identity_proofs';
+
+const initialState = ImmutableMap();
+
+export default function identityProofsReducer(state = initialState, action) {
+  switch(action.type) {
+  case IDENTITY_PROOFS_ACCOUNT_FETCH_REQUEST:
+    return state.set('isLoading', true);
+  case IDENTITY_PROOFS_ACCOUNT_FETCH_FAIL:
+    return state.set('isLoading', false);
+  case IDENTITY_PROOFS_ACCOUNT_FETCH_SUCCESS:
+    return state.update(identity_proofs => identity_proofs.withMutations(map => {
+      map.set('isLoading', false);
+      map.set('loaded', true);
+      map.set(action.accountId, fromJS(action.identity_proofs));
+    }));
+  default:
+    return state;
+  }
+};
diff --git a/app/javascript/mastodon/reducers/index.js b/app/javascript/mastodon/reducers/index.js
index 0f0de849f789a0d1657768761bbbb43ba0b65d15..981ad8e64cfd682bfe94eba5c5504464a34fb639 100644
--- a/app/javascript/mastodon/reducers/index.js
+++ b/app/javascript/mastodon/reducers/index.js
@@ -29,6 +29,8 @@ import listAdder from './list_adder';
 import filters from './filters';
 import conversations from './conversations';
 import suggestions from './suggestions';
+import polls from './polls';
+import identity_proofs from './identity_proofs';
 
 const reducers = {
   dropdown_menu,
@@ -55,12 +57,14 @@ const reducers = {
   notifications,
   height_cache,
   custom_emojis,
+  identity_proofs,
   lists,
   listEditor,
   listAdder,
   filters,
   conversations,
   suggestions,
+  polls,
 };
 
 export default combineReducers(reducers);
diff --git a/app/javascript/mastodon/reducers/list_editor.js b/app/javascript/mastodon/reducers/list_editor.js
index 02a0dabb147b6fef1ec77a1db50cdcc1b604f07a..91e524dd550072064d874e0e5b4fa73c08252f0f 100644
--- a/app/javascript/mastodon/reducers/list_editor.js
+++ b/app/javascript/mastodon/reducers/list_editor.js
@@ -22,6 +22,7 @@ import {
 const initialState = ImmutableMap({
   listId: null,
   isSubmitting: false,
+  isChanged: false,
   title: '',
 
   accounts: ImmutableMap({
@@ -47,10 +48,16 @@ export default function listEditorReducer(state = initialState, action) {
       map.set('isSubmitting', false);
     });
   case LIST_EDITOR_TITLE_CHANGE:
-    return state.set('title', action.value);
+    return state.withMutations(map => {
+      map.set('title', action.value);
+      map.set('isChanged', true);
+    });
   case LIST_CREATE_REQUEST:
   case LIST_UPDATE_REQUEST:
-    return state.set('isSubmitting', true);
+    return state.withMutations(map => {
+      map.set('isSubmitting', true);
+      map.set('isChanged', false);
+    });
   case LIST_CREATE_FAIL:
   case LIST_UPDATE_FAIL:
     return state.set('isSubmitting', false);
diff --git a/app/javascript/mastodon/reducers/modal.js b/app/javascript/mastodon/reducers/modal.js
index 599a2443e0d5ed56a58407177e89f8f306ca8f04..a30da2db1b4ffe54409842127c03288c070e965b 100644
--- a/app/javascript/mastodon/reducers/modal.js
+++ b/app/javascript/mastodon/reducers/modal.js
@@ -10,7 +10,7 @@ export default function modal(state = initialState, action) {
   case MODAL_OPEN:
     return { modalType: action.modalType, modalProps: action.modalProps };
   case MODAL_CLOSE:
-    return initialState;
+    return (action.modalType === undefined || action.modalType === state.modalType) ? initialState : state;
   default:
     return state;
   }
diff --git a/app/javascript/mastodon/reducers/notifications.js b/app/javascript/mastodon/reducers/notifications.js
index 19a02f5b1546bde84e802d8ab854f5f3f2295a03..33fe86e002e2e92a51ce148df9e4336dc577a3bd 100644
--- a/app/javascript/mastodon/reducers/notifications.js
+++ b/app/javascript/mastodon/reducers/notifications.js
@@ -11,6 +11,7 @@ import {
   ACCOUNT_BLOCK_SUCCESS,
   ACCOUNT_MUTE_SUCCESS,
 } from '../actions/accounts';
+import { DOMAIN_BLOCK_SUCCESS } from 'mastodon/actions/domain_blocks';
 import { TIMELINE_DELETE, TIMELINE_DISCONNECT } from '../actions/timelines';
 import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
 import compareId from '../compare_id';
@@ -18,7 +19,7 @@ import compareId from '../compare_id';
 const initialState = ImmutableMap({
   items: ImmutableList(),
   hasMore: true,
-  top: true,
+  top: false,
   unread: 0,
   isLoading: false,
 });
@@ -77,8 +78,8 @@ const expandNormalizedNotifications = (state, notifications, next) => {
   });
 };
 
-const filterNotifications = (state, relationship) => {
-  return state.update('items', list => list.filterNot(item => item !== null && item.get('account') === relationship.id));
+const filterNotifications = (state, accountIds) => {
+  return state.update('items', list => list.filterNot(item => item !== null && accountIds.includes(item.get('account'))));
 };
 
 const updateTop = (state, top) => {
@@ -108,8 +109,11 @@ export default function notifications(state = initialState, action) {
   case NOTIFICATIONS_EXPAND_SUCCESS:
     return expandNormalizedNotifications(state, action.notifications, action.next);
   case ACCOUNT_BLOCK_SUCCESS:
+    return filterNotifications(state, [action.relationship.id]);
   case ACCOUNT_MUTE_SUCCESS:
-    return action.relationship.muting_notifications ? filterNotifications(state, action.relationship) : state;
+    return action.relationship.muting_notifications ? filterNotifications(state, [action.relationship.id]) : state;
+  case DOMAIN_BLOCK_SUCCESS:
+    return filterNotifications(state, action.accounts);
   case NOTIFICATIONS_CLEAR:
     return state.set('items', ImmutableList()).set('hasMore', false);
   case TIMELINE_DELETE:
diff --git a/app/javascript/mastodon/reducers/polls.js b/app/javascript/mastodon/reducers/polls.js
new file mode 100644
index 0000000000000000000000000000000000000000..9956cf83f602d9247d3d6a23bd684126b0d17773
--- /dev/null
+++ b/app/javascript/mastodon/reducers/polls.js
@@ -0,0 +1,15 @@
+import { POLLS_IMPORT } from 'mastodon/actions/importer';
+import { Map as ImmutableMap, fromJS } from 'immutable';
+
+const importPolls = (state, polls) => state.withMutations(map => polls.forEach(poll => map.set(poll.id, fromJS(poll))));
+
+const initialState = ImmutableMap();
+
+export default function polls(state = initialState, action) {
+  switch(action.type) {
+  case POLLS_IMPORT:
+    return importPolls(state, action.polls);
+  default:
+    return state;
+  }
+}
diff --git a/app/javascript/mastodon/reducers/push_notifications.js b/app/javascript/mastodon/reducers/push_notifications.js
index 85628c6b116242e38572923e8eef7be5c1958756..317352b79065b1dac77e5d79125e49fc4b96791b 100644
--- a/app/javascript/mastodon/reducers/push_notifications.js
+++ b/app/javascript/mastodon/reducers/push_notifications.js
@@ -9,6 +9,7 @@ const initialState = Immutable.Map({
     favourite: false,
     reblog: false,
     mention: false,
+    poll: false,
   }),
   isSubscribed: false,
   browserSupport: false,
diff --git a/app/javascript/mastodon/reducers/search.js b/app/javascript/mastodon/reducers/search.js
index 4758defb1b9eef853e013a22aad432493ab8f271..77b7f588c5864099516ff41cd8c1c6402a692b25 100644
--- a/app/javascript/mastodon/reducers/search.js
+++ b/app/javascript/mastodon/reducers/search.js
@@ -16,6 +16,7 @@ const initialState = ImmutableMap({
   submitted: false,
   hidden: false,
   results: ImmutableMap(),
+  searchTerm: '',
 });
 
 export default function search(state = initialState, action) {
@@ -40,7 +41,7 @@ export default function search(state = initialState, action) {
       accounts: ImmutableList(action.results.accounts.map(item => item.id)),
       statuses: ImmutableList(action.results.statuses.map(item => item.id)),
       hashtags: fromJS(action.results.hashtags),
-    })).set('submitted', true);
+    })).set('submitted', true).set('searchTerm', action.searchTerm);
   default:
     return state;
   }
diff --git a/app/javascript/mastodon/reducers/settings.js b/app/javascript/mastodon/reducers/settings.js
index 2e1878cf782e526c54fa1d9916eb397a7fb187ce..a0eea137f11057afdbe0c1019d01a0bbb36cae04 100644
--- a/app/javascript/mastodon/reducers/settings.js
+++ b/app/javascript/mastodon/reducers/settings.js
@@ -31,6 +31,7 @@ const initialState = ImmutableMap({
       favourite: true,
       reblog: true,
       mention: true,
+      poll: true,
     }),
 
     quickFilter: ImmutableMap({
@@ -44,6 +45,7 @@ const initialState = ImmutableMap({
       favourite: true,
       reblog: true,
       mention: true,
+      poll: true,
     }),
 
     sounds: ImmutableMap({
@@ -51,6 +53,7 @@ const initialState = ImmutableMap({
       favourite: true,
       reblog: true,
       mention: true,
+      poll: true,
     }),
   }),
 
diff --git a/app/javascript/mastodon/reducers/suggestions.js b/app/javascript/mastodon/reducers/suggestions.js
index 9f4b89d58659714dd370557ff1736124dc07b91a..834be728f1e2e8bff298d9306c37f985bf8b603e 100644
--- a/app/javascript/mastodon/reducers/suggestions.js
+++ b/app/javascript/mastodon/reducers/suggestions.js
@@ -4,6 +4,8 @@ import {
   SUGGESTIONS_FETCH_FAIL,
   SUGGESTIONS_DISMISS,
 } from '../actions/suggestions';
+import { ACCOUNT_BLOCK_SUCCESS, ACCOUNT_MUTE_SUCCESS } from 'mastodon/actions/accounts';
+import { DOMAIN_BLOCK_SUCCESS } from 'mastodon/actions/domain_blocks';
 import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
 
 const initialState = ImmutableMap({
@@ -24,6 +26,11 @@ export default function suggestionsReducer(state = initialState, action) {
     return state.set('isLoading', false);
   case SUGGESTIONS_DISMISS:
     return state.update('items', list => list.filterNot(id => id === action.id));
+  case ACCOUNT_BLOCK_SUCCESS:
+  case ACCOUNT_MUTE_SUCCESS:
+    return state.update('items', list => list.filterNot(id => id === action.relationship.id));
+  case DOMAIN_BLOCK_SUCCESS:
+    return state.update('items', list => list.filterNot(id => action.accounts.includes(id)));
   default:
     return state;
   }
diff --git a/app/javascript/mastodon/reducers/timelines.js b/app/javascript/mastodon/reducers/timelines.js
index 1f7ece8122f2e3f74c935c11ee117232d42f9f18..309a95a19b837eeb7dcf85cf0eea406a25833855 100644
--- a/app/javascript/mastodon/reducers/timelines.js
+++ b/app/javascript/mastodon/reducers/timelines.js
@@ -6,6 +6,7 @@ import {
   TIMELINE_EXPAND_REQUEST,
   TIMELINE_EXPAND_FAIL,
   TIMELINE_SCROLL_TOP,
+  TIMELINE_CONNECT,
   TIMELINE_DISCONNECT,
 } from '../actions/timelines';
 import {
@@ -20,6 +21,7 @@ const initialState = ImmutableMap();
 
 const initialTimeline = ImmutableMap({
   unread: 0,
+  online: false,
   top: true,
   isLoading: false,
   hasMore: true,
@@ -29,16 +31,16 @@ const initialTimeline = ImmutableMap({
 const expandNormalizedTimeline = (state, timeline, statuses, next, isPartial, isLoadingRecent) => {
   return state.update(timeline, initialTimeline, map => map.withMutations(mMap => {
     mMap.set('isLoading', false);
+    mMap.set('isPartial', isPartial);
+
     if (!next && !isLoadingRecent) mMap.set('hasMore', false);
 
-    if (!statuses.isEmpty()) {
+    if (timeline.endsWith(':pinned')) {
+      mMap.set('items', statuses.map(status => status.get('id')));
+    } else if (!statuses.isEmpty()) {
       mMap.update('items', ImmutableList(), oldIds => {
         const newIds = statuses.map(status => status.get('id'));
 
-        if (timeline.indexOf(':pinned') !== -1) {
-          return newIds;
-        }
-
         const lastIndex = oldIds.findLastIndex(id => id !== null && compareId(id, newIds.last()) >= 0) + 1;
         const firstIndex = oldIds.take(lastIndex).findLastIndex(id => id !== null && compareId(id, newIds.first()) > 0);
 
@@ -74,14 +76,15 @@ const updateTimeline = (state, timeline, status) => {
   }));
 };
 
-const deleteStatus = (state, id, accountId, references) => {
+const deleteStatus = (state, id, accountId, references, exclude_account = null) => {
   state.keySeq().forEach(timeline => {
-    state = state.updateIn([timeline, 'items'], list => list.filterNot(item => item === id));
+    if (exclude_account === null || (timeline !== `account:${exclude_account}` && !timeline.startsWith(`account:${exclude_account}:`)))
+      state = state.updateIn([timeline, 'items'], list => list.filterNot(item => item === id));
   });
 
   // Remove reblogs of deleted status
   references.forEach(ref => {
-    state = deleteStatus(state, ref[0], ref[1], []);
+    state = deleteStatus(state, ref[0], ref[1], [], exclude_account);
   });
 
   return state;
@@ -100,7 +103,7 @@ const filterTimelines = (state, relationship, statuses) => {
     }
 
     references = statuses.filter(item => item.get('reblog') === status.get('id')).map(item => [item.get('id'), item.get('account')]);
-    state      = deleteStatus(state, status.get('id'), status.get('account'), references);
+    state      = deleteStatus(state, status.get('id'), status.get('account'), references, relationship.id);
   });
 
   return state;
@@ -140,14 +143,13 @@ export default function timelines(state = initialState, action) {
     return filterTimeline('home', state, action.relationship, action.statuses);
   case TIMELINE_SCROLL_TOP:
     return updateTop(state, action.timeline, action.top);
+  case TIMELINE_CONNECT:
+    return state.update(action.timeline, initialTimeline, map => map.set('online', true));
   case TIMELINE_DISCONNECT:
     return state.update(
       action.timeline,
       initialTimeline,
-      map => map.update(
-        'items',
-        items => items.first() ? items.unshift(null) : items
-      )
+      map => map.set('online', false).update('items', items => items.first() ? items.unshift(null) : items)
     );
   default:
     return state;
diff --git a/app/javascript/mastodon/selectors/index.js b/app/javascript/mastodon/selectors/index.js
index 70f08a8eb5e0dd610cbc54bb69a07d781b216872..c87654547d47feac1cb3c17a4fbec89514cd0b67 100644
--- a/app/javascript/mastodon/selectors/index.js
+++ b/app/javascript/mastodon/selectors/index.js
@@ -1,5 +1,5 @@
 import { createSelector } from 'reselect';
-import { List as ImmutableList } from 'immutable';
+import { List as ImmutableList, is } from 'immutable';
 import { me } from '../initial_state';
 
 const getAccountBase         = (state, id) => state.getIn(['accounts', id], null);
@@ -36,12 +36,10 @@ const toServerSideType = columnType => {
   }
 };
 
-export const getFilters = (state, { contextType }) => state.get('filters', ImmutableList()).filter(filter => contextType && filter.get('context').includes(toServerSideType(contextType)) && (filter.get('expires_at') === null || Date.parse(filter.get('expires_at')) > (new Date())));
-
 const escapeRegExp = string =>
   string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
 
-export const regexFromFilters = filters => {
+const regexFromFilters = filters => {
   if (filters.size === 0) {
     return null;
   }
@@ -63,6 +61,27 @@ export const regexFromFilters = filters => {
   }).join('|'), 'i');
 };
 
+// Memoize the filter regexps for each valid server contextType
+const makeGetFiltersRegex = () => {
+  let memo = {};
+
+  return (state, { contextType }) => {
+    if (!contextType) return ImmutableList();
+
+    const serverSideType = toServerSideType(contextType);
+    const filters = state.get('filters', ImmutableList()).filter(filter => filter.get('context').includes(serverSideType) && (filter.get('expires_at') === null || Date.parse(filter.get('expires_at')) > (new Date())));
+
+    if (!memo[serverSideType] || !is(memo[serverSideType].filters, filters)) {
+      const dropRegex = regexFromFilters(filters.filter(filter => filter.get('irreversible')));
+      const regex = regexFromFilters(filters);
+      memo[serverSideType] = { filters: filters, results: [dropRegex, regex] };
+    }
+    return memo[serverSideType].results;
+  };
+};
+
+export const getFiltersRegex = makeGetFiltersRegex();
+
 export const makeGetStatus = () => {
   return createSelector(
     [
@@ -70,10 +89,10 @@ export const makeGetStatus = () => {
       (state, { id }) => state.getIn(['statuses', state.getIn(['statuses', id, 'reblog'])]),
       (state, { id }) => state.getIn(['accounts', state.getIn(['statuses', id, 'account'])]),
       (state, { id }) => state.getIn(['accounts', state.getIn(['statuses', state.getIn(['statuses', id, 'reblog']), 'account'])]),
-      getFilters,
+      getFiltersRegex,
     ],
 
-    (statusBase, statusReblog, accountBase, accountReblog, filters) => {
+    (statusBase, statusReblog, accountBase, accountReblog, filtersRegex) => {
       if (!statusBase) {
         return null;
       }
@@ -84,8 +103,13 @@ export const makeGetStatus = () => {
         statusReblog = null;
       }
 
-      const regex    = (accountReblog || accountBase).get('id') !== me && regexFromFilters(filters);
-      const filtered = regex && regex.test(statusBase.get('reblog') ? statusReblog.get('search_index') : statusBase.get('search_index'));
+      const dropRegex = (accountReblog || accountBase).get('id') !== me && filtersRegex[0];
+      if (dropRegex && dropRegex.test(statusBase.get('reblog') ? statusReblog.get('search_index') : statusBase.get('search_index'))) {
+        return null;
+      }
+
+      const regex     = (accountReblog || accountBase).get('id') !== me && filtersRegex[1];
+      const filtered  = regex && regex.test(statusBase.get('reblog') ? statusReblog.get('search_index') : statusBase.get('search_index'));
 
       return statusBase.withMutations(map => {
         map.set('reblog', statusReblog);
diff --git a/app/javascript/mastodon/service_worker/web_push_locales.js b/app/javascript/mastodon/service_worker/web_push_locales.js
index ce96ae297c5ecec87b69c64089e105aaf3385674..5ce8c7b50a1ff4bfab4ec0c527164fba47913276 100644
--- a/app/javascript/mastodon/service_worker/web_push_locales.js
+++ b/app/javascript/mastodon/service_worker/web_push_locales.js
@@ -18,6 +18,7 @@ filenames.forEach(filename => {
     'notification.follow': full['notification.follow'] || '',
     'notification.mention': full['notification.mention'] || '',
     'notification.reblog': full['notification.reblog'] || '',
+    'notification.poll': full['notification.poll'] || '',
 
     'status.show_more': full['status.show_more'] || '',
     'status.reblog': full['status.reblog'] || '',
diff --git a/app/javascript/mastodon/stream.js b/app/javascript/mastodon/stream.js
index 9928d0dd76856da80ec33eb8c35e134b7833c135..c4642344fc1191b2bbcea028228fe6b4e0c081d6 100644
--- a/app/javascript/mastodon/stream.js
+++ b/app/javascript/mastodon/stream.js
@@ -2,11 +2,11 @@ import WebSocketClient from 'websocket.js';
 
 const randomIntUpTo = max => Math.floor(Math.random() * Math.floor(max));
 
-export function connectStream(path, pollingRefresh = null, callbacks = () => ({ onDisconnect() {}, onReceive() {} })) {
+export function connectStream(path, pollingRefresh = null, callbacks = () => ({ onConnect() {}, onDisconnect() {}, onReceive() {} })) {
   return (dispatch, getState) => {
     const streamingAPIBaseURL = getState().getIn(['meta', 'streaming_api_base_url']);
     const accessToken = getState().getIn(['meta', 'access_token']);
-    const { onDisconnect, onReceive } = callbacks(dispatch, getState);
+    const { onConnect, onDisconnect, onReceive } = callbacks(dispatch, getState);
 
     let polling = null;
 
@@ -28,6 +28,8 @@ export function connectStream(path, pollingRefresh = null, callbacks = () => ({
         if (pollingRefresh) {
           clearPolling();
         }
+
+        onConnect();
       },
 
       disconnected () {
@@ -47,6 +49,8 @@ export function connectStream(path, pollingRefresh = null, callbacks = () => ({
           clearPolling();
           pollingRefresh(dispatch);
         }
+
+        onConnect();
       },
 
     });
@@ -67,11 +71,7 @@ export function connectStream(path, pollingRefresh = null, callbacks = () => ({
 export default function getStream(streamingAPIBaseURL, accessToken, stream, { connected, received, disconnected, reconnected }) {
   const params = [ `stream=${stream}` ];
 
-  if (accessToken !== null) {
-    params.push(`access_token=${accessToken}`);
-  }
-
-  const ws = new WebSocketClient(`${streamingAPIBaseURL}/api/v1/streaming/?${params.join('&')}`);
+  const ws = new WebSocketClient(`${streamingAPIBaseURL}/api/v1/streaming/?${params.join('&')}`, accessToken);
 
   ws.onopen      = connected;
   ws.onmessage   = e => received(JSON.parse(e.data));
diff --git a/app/javascript/mastodon/utils/resize_image.js b/app/javascript/mastodon/utils/resize_image.js
index d1608094f7f379592ac43820fd8014c5b4a53e97..a8ec5f3fa767286042c9da1084dca64e960584af 100644
--- a/app/javascript/mastodon/utils/resize_image.js
+++ b/app/javascript/mastodon/utils/resize_image.js
@@ -31,7 +31,7 @@ const loadImage = inputFile => new Promise((resolve, reject) => {
 });
 
 const getOrientation = (img, type = 'image/png') => new Promise(resolve => {
-  if (type !== 'image/jpeg') {
+  if (!['image/jpeg', 'image/webp'].includes(type)) {
     resolve(1);
     return;
   }
@@ -67,6 +67,14 @@ const processImage = (img, { width, height, orientation, type = 'image/png' }) =
 
   context.drawImage(img, 0, 0, width, height);
 
+  // The Tor Browser and maybe other browsers may prevent reading from canvas
+  // and return an all-white image instead. Assume reading failed if the resized
+  // image is perfectly white.
+  const imageData = context.getImageData(0, 0, width, height);
+  if (imageData.every(value => value === 255)) {
+    throw 'Failed to read from canvas';
+  }
+
   canvas.toBlob(resolve, type);
 });
 
diff --git a/app/javascript/packs/error.js b/app/javascript/packs/error.js
new file mode 100644
index 0000000000000000000000000000000000000000..685c890658a007886aaafa00509d42916de05788
--- /dev/null
+++ b/app/javascript/packs/error.js
@@ -0,0 +1,13 @@
+import ready from '../mastodon/ready';
+
+ready(() => {
+  const image = document.querySelector('img');
+
+  image.addEventListener('mouseenter', () => {
+    image.src = '/oops.gif';
+  });
+
+  image.addEventListener('mouseleave', () => {
+    image.src = '/oops.png';
+  });
+});
diff --git a/app/javascript/packs/public.js b/app/javascript/packs/public.js
index 4ab27c769281e433b38a1e9427a82371186b8286..132a9766ec7870013c326cf668ff0191beb6aa7f 100644
--- a/app/javascript/packs/public.js
+++ b/app/javascript/packs/public.js
@@ -44,6 +44,12 @@ function main() {
     }
   };
 
+  const getEmojiAnimationHandler = (swapTo) => {
+    return ({ target }) => {
+      target.src = target.getAttribute(swapTo);
+    };
+  };
+
   ready(() => {
     const locale = document.documentElement.lang;
 
@@ -116,6 +122,9 @@ function main() {
       document.head.appendChild(scrollbarWidthStyle);
       scrollbarWidthStyle.sheet.insertRule(`body.with-modals--active { margin-right: ${scrollbarWidth}px; }`, 0);
     }
+
+    delegate(document, '.custom-emoji', 'mouseover', getEmojiAnimationHandler('data-original'));
+    delegate(document, '.custom-emoji', 'mouseout', getEmojiAnimationHandler('data-static'));
   });
 
   delegate(document, '.webapp-btn', 'click', ({ target, button }) => {
@@ -126,15 +135,15 @@ function main() {
     return false;
   });
 
-  delegate(document, '.status__content__spoiler-link', 'click', ({ target }) => {
-    const contentEl = target.parentNode.parentNode.querySelector('.e-content');
+  delegate(document, '.status__content__spoiler-link', 'click', function() {
+    const contentEl = this.parentNode.parentNode.querySelector('.e-content');
 
     if (contentEl.style.display === 'block') {
       contentEl.style.display = 'none';
-      target.parentNode.style.marginBottom = 0;
+      this.parentNode.style.marginBottom = 0;
     } else {
       contentEl.style.display = 'block';
-      target.parentNode.style.marginBottom = null;
+      this.parentNode.style.marginBottom = null;
     }
 
     return false;
@@ -173,6 +182,21 @@ function main() {
     avatar.src = url;
   });
 
+  const getProfileAvatarAnimationHandler = (swapTo) => {
+    //animate avatar gifs on the profile page when moused over
+    return ({ target }) => {
+      const swapSrc = target.getAttribute(swapTo);
+      //only change the img source if autoplay is off and the image src is actually different
+      if(target.getAttribute('data-autoplay') !== 'true' && target.src !== swapSrc) {
+        target.src = swapSrc;
+      }
+    };
+  };
+
+  delegate(document, 'img#profile_page_avatar', 'mouseover', getProfileAvatarAnimationHandler('data-original'));
+
+  delegate(document, 'img#profile_page_avatar', 'mouseout', getProfileAvatarAnimationHandler('data-static'));
+
   delegate(document, '#account_header', 'change', ({ target }) => {
     const header = document.querySelector('.card .card__img img');
     const [file] = target.files || [];
@@ -192,14 +216,20 @@ function main() {
   });
 
   delegate(document, '.input-copy input', 'click', ({ target }) => {
+    target.focus();
     target.select();
+    target.setSelectionRange(0, target.value.length);
   });
 
   delegate(document, '.input-copy button', 'click', ({ target }) => {
     const input = target.parentNode.querySelector('.input-copy__wrapper input');
 
+    const oldReadOnly = input.readonly;
+
+    input.readonly = false;
     input.focus();
     input.select();
+    input.setSelectionRange(0, input.value.length);
 
     try {
       if (document.execCommand('copy')) {
@@ -213,6 +243,8 @@ function main() {
     } catch (err) {
       console.error(err);
     }
+
+    input.readonly = oldReadOnly;
   });
 }
 
diff --git a/app/javascript/styles/application.scss b/app/javascript/styles/application.scss
index 0eae63247c16ea9893c60bb4e8914064fded710b..5491b9607bf8015320ee0b286e95bff00ca4da11 100644
--- a/app/javascript/styles/application.scss
+++ b/app/javascript/styles/application.scss
@@ -16,6 +16,7 @@
 @import 'mastodon/stream_entries';
 @import 'mastodon/boost';
 @import 'mastodon/components';
+@import 'mastodon/polls';
 @import 'mastodon/introduction';
 @import 'mastodon/modal';
 @import 'mastodon/emoji_picker';
diff --git a/app/javascript/styles/contrast/diff.scss b/app/javascript/styles/contrast/diff.scss
index eee9ecc3ef7f27706957e5c66aae23f19599895b..5a40e7d79a9f0a537bc5947fa9f21c3242d0ccf1 100644
--- a/app/javascript/styles/contrast/diff.scss
+++ b/app/javascript/styles/contrast/diff.scss
@@ -5,10 +5,73 @@
       &-description {
         input {
           &::placeholder {
-            opacity: 1.0;
+            opacity: 1;
           }
         }
       }
     }
   }
 }
+
+.rich-formatting a,
+.rich-formatting p a,
+.rich-formatting li a,
+.landing-page__short-description p a,
+.status__content a,
+.reply-indicator__content a {
+  color: lighten($ui-highlight-color, 12%);
+  text-decoration: underline;
+
+  &.mention {
+    text-decoration: none;
+  }
+
+  &.mention span {
+    text-decoration: underline;
+
+    &:hover,
+    &:focus,
+    &:active {
+      text-decoration: none;
+    }
+  }
+
+  &:hover,
+  &:focus,
+  &:active {
+    text-decoration: none;
+  }
+
+  &.status__content__spoiler-link {
+    color: $secondary-text-color;
+    text-decoration: none;
+  }
+}
+
+.status__content__read-more-button {
+  text-decoration: underline;
+
+  &:hover,
+  &:focus,
+  &:active {
+    text-decoration: none;
+  }
+}
+
+.getting-started__footer a {
+  text-decoration: underline;
+
+  &:hover,
+  &:focus,
+  &:active {
+    text-decoration: none;
+  }
+}
+
+.nothing-here {
+  color: $darker-text-color;
+}
+
+.public-layout .public-account-header__tabs__tabs .counter.active::after {
+  border-bottom: 4px solid $ui-highlight-color;
+}
diff --git a/app/javascript/styles/contrast/variables.scss b/app/javascript/styles/contrast/variables.scss
index f6cadf0298cf4368fe19c726616c622c67343fea..cfe3b21dbc6f36cc601ddb650c735074cedcb26c 100644
--- a/app/javascript/styles/contrast/variables.scss
+++ b/app/javascript/styles/contrast/variables.scss
@@ -20,5 +20,5 @@ $highlight-text-color: $classic-highlight-color !default;
 $action-button-color: #8d9ac2;
 
 $inverted-text-color: $black !default;
-$lighter-text-color: darken($ui-base-color,6%) !default;
+$lighter-text-color: darken($ui-base-color, 6%) !default;
 $light-text-color: darken($ui-primary-color, 40%) !default;
diff --git a/app/javascript/styles/fonts/montserrat.scss b/app/javascript/styles/fonts/montserrat.scss
index 206f1865e5e1e59349605a8884ae2b6c0a3e8f6e..8079dc6fc9766de2723f5742ace4976823406477 100644
--- a/app/javascript/styles/fonts/montserrat.scss
+++ b/app/javascript/styles/fonts/montserrat.scss
@@ -10,7 +10,7 @@
 
 @font-face {
   font-family: 'mastodon-font-display';
-  src: local('Montserrat'),
+  src: local('Montserrat Medium'),
     url('../fonts/montserrat/Montserrat-Medium.ttf') format('truetype');
   font-weight: 500;
   font-style: normal;
diff --git a/app/javascript/styles/fonts/roboto.scss b/app/javascript/styles/fonts/roboto.scss
index 345d9ad50e29fcba225b93f5f2598e423b347c33..f9c7c50fea4354f0db1d4803f9dd213b307b3645 100644
--- a/app/javascript/styles/fonts/roboto.scss
+++ b/app/javascript/styles/fonts/roboto.scss
@@ -1,6 +1,6 @@
 @font-face {
   font-family: 'mastodon-font-sans-serif';
-  src: local('Roboto'),
+  src: local('Roboto Italic'),
     url('../fonts/roboto/roboto-italic-webfont.woff2') format('woff2'),
     url('../fonts/roboto/roboto-italic-webfont.woff') format('woff'),
     url('../fonts/roboto/roboto-italic-webfont.ttf') format('truetype'),
@@ -11,7 +11,7 @@
 
 @font-face {
   font-family: 'mastodon-font-sans-serif';
-  src: local('Roboto'),
+  src: local('Roboto Bold'),
     url('../fonts/roboto/roboto-bold-webfont.woff2') format('woff2'),
     url('../fonts/roboto/roboto-bold-webfont.woff') format('woff'),
     url('../fonts/roboto/roboto-bold-webfont.ttf') format('truetype'),
@@ -22,7 +22,7 @@
 
 @font-face {
   font-family: 'mastodon-font-sans-serif';
-  src: local('Roboto'),
+  src: local('Roboto Medium'),
     url('../fonts/roboto/roboto-medium-webfont.woff2') format('woff2'),
     url('../fonts/roboto/roboto-medium-webfont.woff') format('woff'),
     url('../fonts/roboto/roboto-medium-webfont.ttf') format('truetype'),
diff --git a/app/javascript/styles/mailer.scss b/app/javascript/styles/mailer.scss
index 74d1df8ed3edd9318352aa5bfa1d3baf6a2f7800..b4fb1d709c02dff57bc31f6dc4eca83f44409f1b 100644
--- a/app/javascript/styles/mailer.scss
+++ b/app/javascript/styles/mailer.scss
@@ -279,6 +279,8 @@ h5 {
 }
 
 .hero-with-button {
+  padding-bottom: 16px;
+
   h1 {
     margin-bottom: 4px;
   }
@@ -286,8 +288,6 @@ h5 {
   p.lead {
     margin-bottom: 32px;
   }
-
-  padding-bottom: 16px;
 }
 
 .header {
diff --git a/app/javascript/styles/mastodon-light/diff.scss b/app/javascript/styles/mastodon-light/diff.scss
index 78bc2dbb6d50e0ab8371f7d28676492feb95c48e..ee8a7d265a10afe85de1568e708191e00161650c 100644
--- a/app/javascript/styles/mastodon-light/diff.scss
+++ b/app/javascript/styles/mastodon-light/diff.scss
@@ -1,6 +1,10 @@
 // Notes!
 // Sass color functions, "darken" and "lighten" are automatically replaced.
 
+html {
+  scrollbar-color: $ui-base-color rgba($ui-base-color, 0.25);
+}
+
 // Change the colors of button texts
 .button {
   color: $white;
@@ -11,18 +15,139 @@
 }
 
 // Change default background colors of columns
-.column {
-  > .scrollable {
+.column > .scrollable,
+.getting-started,
+.column-inline-form {
+  background: $white;
+  border: 1px solid lighten($ui-base-color, 8%);
+  border-top: 0;
+}
+
+.column-back-button,
+.column-header {
+  background: $white;
+  border: 1px solid lighten($ui-base-color, 8%);
+
+  @media screen and (max-width: $no-gap-breakpoint) {
+    border-top: 0;
+  }
+
+  &--slim-button {
+    border: 0;
+    top: -49px;
+    right: 1px;
+  }
+}
+
+.column-header__back-button,
+.column-header__button,
+.column-header__button.active,
+.account__header__bar {
+  background: $white;
+}
+
+.column-header__button.active {
+  color: $ui-highlight-color;
+
+  &:hover,
+  &:active,
+  &:focus {
+    color: $ui-highlight-color;
     background: $white;
   }
 }
 
-.drawer__inner {
+.account__header__bar .avatar .account__avatar {
+  border-color: $white;
+}
+
+.getting-started__footer a {
+  color: $ui-secondary-color;
+  text-decoration: underline;
+}
+
+.column-subheading {
+  background: darken($ui-base-color, 4%);
+  border-bottom: 1px solid lighten($ui-base-color, 8%);
+}
+
+.getting-started,
+.scrollable {
+  .column-link {
+    background: $white;
+    border-bottom: 1px solid lighten($ui-base-color, 8%);
+
+    &:hover,
+    &:active,
+    &:focus {
+      background: $ui-base-color;
+    }
+  }
+}
+
+.getting-started .navigation-bar {
+  border-top: 1px solid lighten($ui-base-color, 8%);
+  border-bottom: 1px solid lighten($ui-base-color, 8%);
+
+  @media screen and (max-width: $no-gap-breakpoint) {
+    border-top: 0;
+  }
+}
+
+.compose-form__autosuggest-wrapper,
+.poll__text input[type="text"],
+.compose-form .spoiler-input__input,
+.compose-form__poll-wrapper select,
+.search__input,
+.setting-text,
+.box-widget input[type="text"],
+.box-widget input[type="email"],
+.box-widget input[type="password"],
+.box-widget textarea,
+.statuses-grid .detailed-status {
+  border: 1px solid lighten($ui-base-color, 8%);
+}
+
+.search__input {
+  @media screen and (max-width: $no-gap-breakpoint) {
+    border-top: 0;
+    border-bottom: 0;
+  }
+}
+
+.list-editor .search .search__input {
+  border-top: 0;
+  border-bottom: 0;
+}
+
+.compose-form__poll-wrapper select {
+  background: $simple-background-color url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14.933 18.467' height='19.698' width='15.929'><path d='M3.467 14.967l-3.393-3.5H14.86l-3.392 3.5c-1.866 1.925-3.666 3.5-4 3.5-.335 0-2.135-1.575-4-3.5zm.266-11.234L7.467 0 11.2 3.733l3.733 3.734H0l3.733-3.734z' fill='#{hex-color(lighten($ui-base-color, 8%))}'/></svg>") no-repeat right 8px center / auto 16px;
+}
+
+.compose-form__poll-wrapper,
+.compose-form__poll-wrapper .poll__footer {
+  border-top-color: lighten($ui-base-color, 8%);
+}
+
+.notification__filter-bar {
+  border: 1px solid lighten($ui-base-color, 8%);
+  border-top: 0;
+}
+
+.compose-form .compose-form__buttons-wrapper {
   background: $ui-base-color;
+  border: 1px solid lighten($ui-base-color, 8%);
+  border-top: 0;
+}
+
+.drawer__header,
+.drawer__inner {
+  background: $white;
+  border: 1px solid lighten($ui-base-color, 8%);
 }
 
 .drawer__inner__mastodon {
-  background: $ui-base-color url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 234.80078 31.757813" width="234.80078" height="31.757812"><path d="M19.599609 0c-1.05 0-2.10039.375-2.90039 1.125L0 16.925781v14.832031h234.80078V17.025391l-16.5-15.900391c-1.6-1.5-4.20078-1.5-5.80078 0l-13.80078 13.099609c-1.6 1.5-4.19883 1.5-5.79883 0L179.09961 1.125c-1.6-1.5-4.19883-1.5-5.79883 0L159.5 14.224609c-1.6 1.5-4.20078 1.5-5.80078 0L139.90039 1.125c-1.6-1.5-4.20078-1.5-5.80078 0l-13.79883 13.099609c-1.6 1.5-4.20078 1.5-5.80078 0L100.69922 1.125c-1.600001-1.5-4.198829-1.5-5.798829 0l-13.59961 13.099609c-1.6 1.5-4.200781 1.5-5.800781 0L61.699219 1.125c-1.6-1.5-4.198828-1.5-5.798828 0L42.099609 14.224609c-1.6 1.5-4.198828 1.5-5.798828 0L22.5 1.125C21.7.375 20.649609 0 19.599609 0z" fill="#{hex-color($white)}"/></svg>') no-repeat bottom / 100% auto;
+  background: $white url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 234.80078 31.757813" width="234.80078" height="31.757812"><path d="M19.599609 0c-1.05 0-2.10039.375-2.90039 1.125L0 16.925781v14.832031h234.80078V17.025391l-16.5-15.900391c-1.6-1.5-4.20078-1.5-5.80078 0l-13.80078 13.099609c-1.6 1.5-4.19883 1.5-5.79883 0L179.09961 1.125c-1.6-1.5-4.19883-1.5-5.79883 0L159.5 14.224609c-1.6 1.5-4.20078 1.5-5.80078 0L139.90039 1.125c-1.6-1.5-4.20078-1.5-5.80078 0l-13.79883 13.099609c-1.6 1.5-4.20078 1.5-5.80078 0L100.69922 1.125c-1.600001-1.5-4.198829-1.5-5.798829 0l-13.59961 13.099609c-1.6 1.5-4.200781 1.5-5.800781 0L61.699219 1.125c-1.6-1.5-4.198828-1.5-5.798828 0L42.099609 14.224609c-1.6 1.5-4.198828 1.5-5.798828 0L22.5 1.125C21.7.375 20.649609 0 19.599609 0z" fill="#{hex-color($ui-base-color)}"/></svg>') no-repeat bottom / 100% auto;
 }
 
 // Change the colors used in compose-form
@@ -93,16 +218,16 @@
 
 .detailed-status,
 .detailed-status__action-bar {
-  background: darken($ui-base-color, 6%);
+  background: $white;
 }
 
 // Change the background colors of status__content__spoiler-link
 .reply-indicator__content .status__content__spoiler-link,
 .status__content .status__content__spoiler-link {
-  background: $ui-base-lighter-color;
+  background: $ui-base-color;
 
   &:hover {
-    background: lighten($ui-base-lighter-color, 6%);
+    background: lighten($ui-base-color, 4%);
   }
 }
 
@@ -112,41 +237,47 @@
   background: $ui-base-color;
 }
 
+.privacy-dropdown.active .privacy-dropdown__value.active .icon-button {
+  color: $white;
+}
+
 .account-gallery__item a {
   background-color: $ui-base-color;
 }
 
 // Change the colors used in the dropdown menu
 .dropdown-menu {
-  background: $ui-base-color;
+  background: $white;
 
   &__arrow {
     &.left {
-      border-left-color: $ui-base-color;
+      border-left-color: $white;
     }
 
     &.top {
-      border-top-color: $ui-base-color;
+      border-top-color: $white;
     }
 
     &.bottom {
-      border-bottom-color: $ui-base-color;
+      border-bottom-color: $white;
     }
 
     &.right {
-      border-right-color: $ui-base-color;
+      border-right-color: $white;
     }
   }
 
   &__item {
     a {
-      background: $ui-base-color;
+      background: $white;
       color: $darker-text-color;
     }
   }
 }
 
 // Change the text colors on inverted background
+.privacy-dropdown__option.active,
+.privacy-dropdown__option:hover,
 .privacy-dropdown__option.active .privacy-dropdown__option__content,
 .privacy-dropdown__option.active .privacy-dropdown__option__content strong,
 .privacy-dropdown__option:hover .privacy-dropdown__option__content,
@@ -162,7 +293,7 @@
 .actions-modal ul li:not(:empty) a:focus button,
 .actions-modal ul li:not(:empty) a:hover,
 .actions-modal ul li:not(:empty) a:hover button,
-.admin-wrapper .sidebar ul ul a.selected,
+.admin-wrapper .sidebar ul .simple-navigation-active-leaf a,
 .simple_form .block-button,
 .simple_form .button,
 .simple_form button {
@@ -170,7 +301,7 @@
 }
 
 .dropdown-menu__separator {
-  border-bottom-color: lighten($ui-base-color, 12%);
+  border-bottom-color: lighten($ui-base-color, 4%);
 }
 
 // Change the background colors of modals
@@ -185,6 +316,12 @@
   background: $ui-base-color;
 }
 
+.column-header__collapsible-inner {
+  background: darken($ui-base-color, 4%);
+  border: 1px solid lighten($ui-base-color, 8%);
+  border-top: 0;
+}
+
 .boost-modal__action-bar,
 .confirmation-modal__action-bar,
 .mute-modal__action-bar,
@@ -230,6 +367,38 @@
 .empty-column-indicator,
 .error-column {
   color: $primary-text-color;
+  background: $white;
+}
+
+.tabs-bar {
+  background: $white;
+  border: 1px solid lighten($ui-base-color, 8%);
+  border-bottom: 0;
+
+  @media screen and (max-width: $no-gap-breakpoint) {
+    border-top: 0;
+  }
+
+  &__link {
+    padding-bottom: 14px;
+    border-bottom-width: 1px;
+    border-bottom-color: lighten($ui-base-color, 8%);
+
+    &:hover,
+    &:active,
+    &:focus {
+      background: $ui-base-color;
+    }
+
+    &.active {
+      &:hover,
+      &:active,
+      &:focus {
+        background: transparent;
+        border-bottom-color: $ui-highlight-color;
+      }
+    }
+  }
 }
 
 // Change the default colors used on some parts of the profile pages
@@ -238,7 +407,102 @@
   border-bottom-color: lighten($ui-base-color, 8%);
 }
 
+.box-widget,
+.nothing-here,
+.page-header,
+.directory__tag > a,
+.directory__tag > div,
+.landing-page__call-to-action,
+.contact-widget,
+.landing .hero-widget__text,
+.landing-page__information.contact-widget {
+  background: $white;
+  border: 1px solid lighten($ui-base-color, 8%);
+
+  @media screen and (max-width: $no-gap-breakpoint) {
+    border-left: 0;
+    border-right: 0;
+    border-top: 0;
+  }
+}
+
+.landing .hero-widget__text {
+  border-top: 0;
+  border-bottom: 0;
+}
+
+.simple_form {
+  input[type=text],
+  input[type=number],
+  input[type=email],
+  input[type=password],
+  textarea {
+    &:hover {
+      border-color: lighten($ui-base-color, 12%);
+    }
+  }
+}
+
+.landing .hero-widget__footer {
+  background: $white;
+  border: 1px solid lighten($ui-base-color, 8%);
+  border-top: 0;
+
+  @media screen and (max-width: $no-gap-breakpoint) {
+    border: 0;
+  }
+}
+
+.brand__tagline {
+  color: $ui-secondary-color;
+}
+
+.directory__tag > a {
+  &:hover,
+  &:active,
+  &:focus {
+    background: $ui-base-color;
+  }
+
+  @media screen and (max-width: $no-gap-breakpoint) {
+    border: 0;
+  }
+}
+
+.directory__tag.active > a,
+.directory__tag.active > div {
+  border-color: $ui-highlight-color;
+
+  &,
+  h4,
+  h4 small,
+  .fa,
+  .trends__item__current {
+    color: $white;
+  }
+
+  &:hover,
+  &:active,
+  &:focus {
+    background: $ui-highlight-color;
+  }
+}
+
+.batch-table {
+  &__toolbar,
+  &__row,
+  .nothing-here {
+    border-color: lighten($ui-base-color, 8%);
+  }
+}
+
 .activity-stream {
+  border: 1px solid lighten($ui-base-color, 8%);
+
+  &--under-tabs {
+    border-top: 0;
+  }
+
   .entry {
     background: $account-background-color;
 
@@ -293,6 +557,22 @@
     background: rgba($error-red, 0.5);
     text-shadow: none;
   }
+
+  .recommended {
+    border-color: $ui-highlight-color;
+    color: $ui-highlight-color;
+    background-color: rgba($ui-highlight-color, 0.1);
+  }
+}
+
+.compose-form .compose-form__warning {
+  border-color: $ui-highlight-color;
+  background-color: rgba($ui-highlight-color, 0.1);
+
+  &,
+  a {
+    color: $ui-highlight-color;
+  }
 }
 
 .status__content,
@@ -305,20 +585,47 @@
 .button.logo-button {
   color: $white;
 
-  svg path:first-child {
+  svg {
     fill: $white;
   }
 }
 
 .public-layout {
+  .account__section-headline {
+    border: 1px solid lighten($ui-base-color, 8%);
+
+    @media screen and (max-width: $no-gap-breakpoint) {
+      border-top: 0;
+    }
+  }
+
   .header,
   .public-account-header,
   .public-account-bio {
     box-shadow: none;
   }
 
+  .public-account-bio,
+  .hero-widget__text {
+    background: $account-background-color;
+    border: 1px solid lighten($ui-base-color, 8%);
+  }
+
   .header {
-    background: lighten($ui-base-color, 12%);
+    background: $ui-base-color;
+    border: 1px solid lighten($ui-base-color, 8%);
+
+    @media screen and (max-width: $no-gap-breakpoint) {
+      border: 0;
+    }
+
+    .brand {
+      &:hover,
+      &:focus,
+      &:active {
+        background: lighten($ui-base-color, 4%);
+      }
+    }
   }
 
   .public-account-header {
@@ -330,17 +637,50 @@
       }
     }
 
+    &__bar {
+      &::before {
+        background: $account-background-color;
+        border: 1px solid lighten($ui-base-color, 8%);
+        border-top: 0;
+      }
+
+      .avatar img {
+        border-color: $account-background-color;
+      }
+
+      @media screen and (max-width: $no-columns-breakpoint) {
+        background: $account-background-color;
+        border: 1px solid lighten($ui-base-color, 8%);
+        border-top: 0;
+      }
+    }
+
     &__tabs {
       &__name {
         h1,
         h1 small {
           color: $white;
+
+          @media screen and (max-width: $no-columns-breakpoint) {
+            color: $primary-text-color;
+          }
         }
       }
     }
+
+    &__extra {
+      .public-account-bio {
+        border: 0;
+      }
+
+      .public-account-bio .account__header__fields {
+        border-color: lighten($ui-base-color, 8%);
+      }
+    }
   }
 }
 
+.notification__filter-bar button.active::after,
 .account__section-headline a.active::after {
   border-color: transparent transparent $white;
 }
@@ -352,6 +692,11 @@
 .moved-account-widget,
 .memoriam-widget,
 .activity-stream,
-.nothing-here {
+.nothing-here,
+.directory__tag > a,
+.directory__tag > div,
+.card > a,
+.page-header,
+.compose-form .compose-form__warning {
   box-shadow: none;
 }
diff --git a/app/javascript/styles/mastodon-light/variables.scss b/app/javascript/styles/mastodon-light/variables.scss
index 9f6d470b13cf4e44199747219fece1e2e8a5a061..01748148f91c54d637958b4df13b4a10f8d50612 100644
--- a/app/javascript/styles/mastodon-light/variables.scss
+++ b/app/javascript/styles/mastodon-light/variables.scss
@@ -17,7 +17,7 @@ $ui-base-color: $classic-secondary-color !default;
 $ui-base-lighter-color: #b0c0cf;
 $ui-primary-color: #9bcbed;
 $ui-secondary-color: $classic-base-color !default;
-$ui-highlight-color: #2b5fd9;
+$ui-highlight-color: #2b90d9;
 
 $primary-text-color: $black !default;
 $darker-text-color: $classic-base-color !default;
diff --git a/app/javascript/styles/mastodon/_mixins.scss b/app/javascript/styles/mastodon/_mixins.scss
index d5bafe6b6a2e7a6b13371d8d9b4a87ea634f384d..faaffb30f47f37afc2cb108e8d730d18a7b26e31 100644
--- a/app/javascript/styles/mastodon/_mixins.scss
+++ b/app/javascript/styles/mastodon/_mixins.scss
@@ -1,21 +1,21 @@
-@mixin avatar-radius() {
+@mixin avatar-radius {
   border-radius: 4px;
   background: transparent no-repeat;
   background-position: 50%;
   background-clip: padding-box;
 }
 
-@mixin avatar-size($size:48px) {
+@mixin avatar-size($size: 48px) {
   width: $size;
   height: $size;
   background-size: $size $size;
 }
 
-@mixin search-input() {
+@mixin search-input {
   outline: 0;
   box-sizing: border-box;
   width: 100%;
-  border: none;
+  border: 0;
   box-shadow: none;
   font-family: inherit;
   background: $ui-base-color;
@@ -41,3 +41,34 @@
     font-size: 16px;
   }
 }
+
+@mixin search-popout {
+  background: $simple-background-color;
+  border-radius: 4px;
+  padding: 10px 14px;
+  padding-bottom: 14px;
+  margin-top: 10px;
+  color: $light-text-color;
+  box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4);
+
+  h4 {
+    text-transform: uppercase;
+    color: $light-text-color;
+    font-size: 13px;
+    font-weight: 500;
+    margin-bottom: 10px;
+  }
+
+  li {
+    padding: 4px 0;
+  }
+
+  ul {
+    margin-bottom: 10px;
+  }
+
+  em {
+    font-weight: 500;
+    color: $inverted-text-color;
+  }
+}
diff --git a/app/javascript/styles/mastodon/about.scss b/app/javascript/styles/mastodon/about.scss
index c6f249fabdf5257b7477627a981f904865e63ea3..61637ce96721214253df8bc0e2835fe8d81e8e1f 100644
--- a/app/javascript/styles/mastodon/about.scss
+++ b/app/javascript/styles/mastodon/about.scss
@@ -49,15 +49,9 @@ $small-breakpoint: 960px;
     }
   }
 
+  strong,
   em {
-    display: inline;
-    margin: 0;
-    padding: 0;
     font-weight: 700;
-    background: transparent;
-    font-family: inherit;
-    font-size: inherit;
-    line-height: inherit;
     color: lighten($darker-text-color, 10%);
   }
 
@@ -199,6 +193,7 @@ $small-breakpoint: 960px;
     }
 
     strong {
+      font-family: $font-display, sans-serif;
       font-weight: 500;
       font-size: 32px;
       line-height: 48px;
@@ -286,168 +281,6 @@ $small-breakpoint: 960px;
 }
 
 .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;
-    }
-
-    .column-1 {
-      grid-column: 1;
-      grid-row: 1;
-    }
-
-    .column-2 {
-      grid-column: 2;
-      grid-row: 1;
-    }
-
-    .column-3 {
-      grid-column: 3;
-      grid-row: 1 / 3;
-    }
-
-    .column-4 {
-      grid-column: 1 / 3;
-      grid-row: 2;
-    }
-  }
-
-  @media screen and (max-width: $small-breakpoint) {
-    .grid {
-      grid-template-columns: 40% 60%;
-
-      .column-0 {
-        display: none;
-      }
-
-      .column-1 {
-        grid-column: 1;
-        grid-row: 1;
-
-        &.non-preview .landing-page__forms {
-          height: 100%;
-        }
-      }
-
-      .column-2 {
-        grid-column: 2;
-        grid-row: 1 / 3;
-
-        &.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;
-        }
-      }
-    }
-  }
-
-  @media screen and (max-width: $column-breakpoint) {
-    .grid {
-      grid-template-columns: 100%;
-
-      .column-0 {
-        display: block;
-        grid-column: 1;
-        grid-row: 1;
-      }
-
-      .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;
-        }
-      }
-    }
-  }
-
-  .column-flex {
-    display: flex;
-    flex-direction: column;
-  }
-
-  .separator-or {
-    position: relative;
-    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: $darker-text-color;
-      text-transform: uppercase;
-      position: relative;
-      z-index: 1;
-      padding: 0 8px;
-      cursor: default;
-    }
-  }
-
   p,
   li {
     font-family: $font-sans-serif, sans-serif;
@@ -464,28 +297,6 @@ $small-breakpoint: 960px;
     }
   }
 
-  .closed-registrations-message {
-    margin-top: 20px;
-
-    &,
-    p {
-      text-align: center;
-      font-size: 12px;
-      line-height: 18px;
-      color: $darker-text-color;
-      margin-bottom: 0;
-
-      a {
-        color: $highlight-text-color;
-        text-decoration: underline;
-      }
-    }
-
-    p:last-child {
-      margin-bottom: 0;
-    }
-  }
-
   em {
     display: inline;
     margin: 0;
@@ -599,187 +410,6 @@ $small-breakpoint: 960px;
     }
   }
 
-  .container-alt {
-    width: 100%;
-    box-sizing: border-box;
-    max-width: 800px;
-    margin: 0 auto;
-    word-wrap: break-word;
-  }
-
-  .header-wrapper {
-    padding-top: 15px;
-    background: $ui-base-color;
-    background: linear-gradient(150deg, lighten($ui-base-color, 8%), $ui-base-color);
-    position: relative;
-
-    &.compact {
-      background: $ui-base-color;
-      padding-bottom: 15px;
-
-      .hero .heading {
-        padding-bottom: 20px;
-        font-family: $font-sans-serif, sans-serif;
-        font-size: 16px;
-        font-weight: 400;
-        font-size: 16px;
-        line-height: 30px;
-        color: $darker-text-color;
-
-        a {
-          color: $highlight-text-color;
-          text-decoration: underline;
-        }
-      }
-    }
-  }
-
-  .brand {
-    a {
-      padding-left: 0;
-      padding-right: 0;
-      color: $white;
-    }
-
-    img {
-      height: 32px;
-      position: relative;
-      top: 4px;
-      left: -10px;
-    }
-  }
-
-  .header {
-    line-height: 30px;
-    overflow: hidden;
-
-    .container-alt {
-      display: flex;
-      justify-content: space-between;
-    }
-
-    .links {
-      position: relative;
-      z-index: 4;
-
-      a {
-        display: flex;
-        justify-content: center;
-        align-items: center;
-        color: $darker-text-color;
-        text-decoration: none;
-        padding: 12px 16px;
-        line-height: 32px;
-        font-family: $font-display, sans-serif;
-        font-weight: 500;
-        font-size: 14px;
-
-        &:hover {
-          color: $secondary-text-color;
-        }
-      }
-
-      ul {
-        list-style: none;
-        margin: 0;
-
-        li {
-          display: inline-block;
-          vertical-align: bottom;
-          margin: 0;
-
-          &:first-child a {
-            padding-left: 0;
-          }
-
-          &:last-child a {
-            padding-right: 0;
-          }
-        }
-      }
-    }
-
-    .hero {
-      margin-top: 50px;
-      align-items: center;
-      position: relative;
-
-      .heading {
-        position: relative;
-        z-index: 4;
-        padding-bottom: 150px;
-      }
-
-      .simple_form,
-      .closed-registrations-message {
-        background: darken($ui-base-color, 4%);
-        width: 280px;
-        padding: 15px 20px;
-        border-radius: 4px 4px 0 0;
-        line-height: initial;
-        position: relative;
-        z-index: 4;
-
-        .actions {
-          margin-bottom: 0;
-
-          button,
-          .button,
-          .block-button {
-            margin-bottom: 0;
-          }
-        }
-      }
-
-      .closed-registrations-message {
-        min-height: 330px;
-        display: flex;
-        flex-direction: column;
-        justify-content: space-between;
-      }
-    }
-  }
-
-  .about-short {
-    background: darken($ui-base-color, 4%);
-    padding: 50px 0 30px;
-    font-family: $font-sans-serif, sans-serif;
-    font-size: 16px;
-    font-weight: 400;
-    font-size: 16px;
-    line-height: 30px;
-    color: $darker-text-color;
-
-    a {
-      color: $highlight-text-color;
-      text-decoration: underline;
-    }
-  }
-
-  &.alternative {
-    padding: 10px 0;
-
-    .brand {
-      text-align: center;
-      padding: 30px 0;
-      margin-bottom: 10px;
-
-      img {
-        position: static;
-        padding: 10px 0;
-      }
-
-      @media screen and (max-width: $small-breakpoint) {
-        padding: 15px 0;
-      }
-
-      @media screen and (max-width: $column-breakpoint) {
-        padding: 0;
-        margin-bottom: -10px;
-      }
-    }
-  }
-
   &__information,
   &__forms {
     padding: 20px;
@@ -796,7 +426,7 @@ $small-breakpoint: 960px;
       width: 100%;
       display: flex;
       flex-direction: row-reverse;
-      flex-wrap: wrap;
+      flex-wrap: nowrap;
       justify-content: space-between;
       align-items: center;
     }
@@ -845,6 +475,11 @@ $small-breakpoint: 960px;
       margin-bottom: 0;
     }
 
+    strong {
+      font-weight: 500;
+      color: lighten($darker-text-color, 10%);
+    }
+
     .account {
       border-bottom: 0;
       padding: 0;
@@ -968,353 +603,254 @@ $small-breakpoint: 960px;
     }
   }
 
-  &__forms {
-    height: 100%;
-
-    @media screen and (max-width: $small-breakpoint) {
-      height: auto;
-    }
-
-    @media screen and (max-width: $column-breakpoint) {
-      background: transparent;
-      box-shadow: none;
-      padding: 0 20px;
-      margin-top: 30px;
-      margin-bottom: 40px;
-
-      .separator-or {
-        span {
-          background: darken($ui-base-color, 8%);
-        }
+  @media screen and (max-width: 840px) {
+    .information-board {
+      .container-alt {
+        padding-right: 20px;
       }
-    }
-
-    hr {
-      margin: 40px 0;
-    }
 
-    .button {
-      display: block;
-    }
-
-    .subtle-hint a {
-      text-decoration: none;
+      .panel {
+        position: static;
+        margin-top: 20px;
+        width: 100%;
+        border-radius: 4px;
 
-      &:hover,
-      &:focus,
-      &:active {
-        text-decoration: underline;
+        .panel-header {
+          text-align: center;
+        }
       }
     }
   }
 
-  #mastodon-timeline {
-    display: flex;
-    -webkit-overflow-scrolling: touch;
-    -ms-overflow-style: -ms-autohiding-scrollbar;
-    font-family: $font-sans-serif, sans-serif;
-    font-size: 13px;
-    line-height: 18px;
-    font-weight: 400;
-    color: $primary-text-color;
-    width: 100%;
-    flex: 1 1 auto;
-    overflow: hidden;
-    height: 100%;
-
-    .column-header {
-      color: inherit;
-      font-family: inherit;
-      font-size: 16px;
-      line-height: inherit;
-      font-weight: inherit;
-      margin: 0;
-      padding: 0;
-    }
-
-    .column {
-      padding: 0;
-      border-radius: 4px;
-      overflow: hidden;
-      width: 100%;
-    }
-
-    .scrollable {
-      height: 400px;
-    }
-
-    p {
-      font-size: inherit;
-      line-height: inherit;
-      font-weight: inherit;
-      color: $primary-text-color;
-      margin-bottom: 20px;
-
-      &:last-child {
-        margin-bottom: 0;
-      }
+  @media screen and (max-width: 675px) {
+    .header-wrapper {
+      padding-top: 0;
 
-      a {
-        color: $secondary-text-color;
-        text-decoration: none;
+      &.compact {
+        padding-bottom: 0;
       }
-    }
-
-    .attachment-list__list {
-      margin-left: 0;
-      list-style: none;
-
-      li {
-        font-size: inherit;
-        line-height: inherit;
-        font-weight: inherit;
-        margin-bottom: 0;
 
-        a {
-          color: $dark-text-color;
-          text-decoration: none;
-
-          &:hover {
-            text-decoration: underline;
-          }
-        }
+      &.compact .hero .heading {
+        text-align: initial;
       }
     }
 
-    @media screen and (max-width: $column-breakpoint) {
-      display: none;
+    .header .container-alt,
+    .features .container-alt {
+      display: block;
     }
   }
 
-  &__features {
-    & > p {
-      padding-right: 60px;
-    }
-
-    .features-list {
-      margin: 40px 0;
-      margin-top: 30px;
-    }
-
-    &__action {
-      text-align: center;
-    }
+  .cta {
+    margin: 20px;
   }
+}
 
-  .features-list {
-    .features-list__row {
-      display: flex;
-      padding: 10px 0;
-      justify-content: space-between;
+.landing {
+  margin-bottom: 100px;
 
-      .visual {
-        flex: 0 0 auto;
-        display: flex;
-        align-items: center;
-        margin-left: 15px;
-
-        .fa {
-          display: block;
-          color: $darker-text-color;
-          font-size: 48px;
-        }
-      }
+  @media screen and (max-width: 738px) {
+    margin-bottom: 0;
+  }
 
-      .text {
-        font-size: 16px;
-        line-height: 30px;
-        color: $darker-text-color;
+  &__brand {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    padding: 50px;
 
-        h6 {
-          font-size: inherit;
-          line-height: inherit;
-          margin-bottom: 0;
-        }
-      }
+    svg {
+      fill: $primary-text-color;
+      height: 52px;
     }
 
-    @media screen and (min-width: $small-breakpoint) {
-      display: grid;
-      grid-gap: 30px;
-      grid-template-columns: 1fr 1fr;
-      grid-auto-columns: 50%;
-      grid-auto-rows: max-content;
+    @media screen and (max-width: $no-gap-breakpoint) {
+      padding: 0;
+      margin-bottom: 30px;
     }
   }
 
-  .footer-links {
-    padding-bottom: 50px;
-    text-align: right;
-    color: $dark-text-color;
+  .directory {
+    margin-top: 30px;
+    background: transparent;
+    box-shadow: none;
+    border-radius: 0;
+  }
 
-    p {
-      font-size: 14px;
-    }
+  .hero-widget {
+    margin-top: 30px;
+    margin-bottom: 0;
 
-    a {
-      color: inherit;
-      text-decoration: underline;
+    h4 {
+      padding: 10px;
+      text-transform: uppercase;
+      font-weight: 700;
+      font-size: 13px;
+      color: $darker-text-color;
     }
-  }
 
-  &__footer {
-    margin-top: 10px;
-    text-align: center;
-    color: $dark-text-color;
+    &__text {
+      border-radius: 0;
+      padding-bottom: 0;
+    }
 
-    p {
-      font-size: 14px;
+    &__footer {
+      background: $ui-base-color;
+      padding: 10px;
+      border-radius: 0 0 4px 4px;
+      display: flex;
 
-      a {
-        color: inherit;
-        text-decoration: underline;
+      &__column {
+        flex: 1 1 50%;
       }
     }
-  }
 
-  @media screen and (max-width: 840px) {
-    .container-alt {
-      padding: 0 20px;
-    }
+    .account {
+      padding: 10px 0;
+      border-bottom: 0;
 
-    .information-board {
-      .container-alt {
-        padding-right: 20px;
+      .account__display-name {
+        display: flex;
+        align-items: center;
       }
 
-      .panel {
-        position: static;
-        margin-top: 20px;
-        width: 100%;
-        border-radius: 4px;
-
-        .panel-header {
-          text-align: center;
-        }
+      .account__avatar {
+        width: 44px;
+        height: 44px;
+        background-size: 44px 44px;
       }
     }
-  }
 
-  @media screen and (max-width: 675px) {
-    .header-wrapper {
-      padding-top: 0;
+    &__counter {
+      padding: 10px;
 
-      &.compact {
-        padding-bottom: 0;
+      strong {
+        font-family: $font-display, sans-serif;
+        font-size: 15px;
+        font-weight: 700;
+        display: block;
       }
 
-      &.compact .hero .heading {
-        text-align: initial;
+      span {
+        font-size: 14px;
+        color: $darker-text-color;
       }
     }
+  }
 
-    .header .container-alt,
-    .features .container-alt {
-      display: block;
-    }
-
-    .header {
-      .links {
-        padding-top: 15px;
-        background: darken($ui-base-color, 4%);
+  .simple_form .user_agreement .label_input > label {
+    font-weight: 400;
+    color: $darker-text-color;
+  }
 
-        a {
-          padding: 12px 8px;
-        }
+  .simple_form p.lead {
+    color: $darker-text-color;
+    font-size: 15px;
+    line-height: 20px;
+    font-weight: 400;
+    margin-bottom: 25px;
+  }
 
-        .nav {
-          display: flex;
-          flex-flow: row wrap;
-          justify-content: space-around;
-        }
+  &__grid {
+    max-width: 960px;
+    margin: 0 auto;
+    display: grid;
+    grid-template-columns: minmax(0, 50%) minmax(0, 50%);
+    grid-gap: 30px;
 
-        .brand img {
-          left: 0;
-          top: 0;
-        }
-      }
+    @media screen and (max-width: 738px) {
+      grid-template-columns: minmax(0, 100%);
+      grid-gap: 10px;
 
-      .hero {
-        margin-top: 30px;
-        padding: 0;
+      &__column-login {
+        grid-row: 1;
+        display: flex;
+        flex-direction: column;
 
-        .heading {
-          padding: 30px 20px;
-          text-align: center;
+        .box-widget {
+          order: 2;
+          flex: 0 0 auto;
         }
 
-        .simple_form,
-        .closed-registrations-message {
-          background: darken($ui-base-color, 8%);
-          width: 100%;
-          border-radius: 0;
-          box-sizing: border-box;
+        .hero-widget {
+          margin-top: 0;
+          margin-bottom: 10px;
+          order: 1;
+          flex: 0 0 auto;
         }
       }
-    }
-  }
 
-  .cta {
-    margin: 20px;
-  }
-
-  &.tag-page {
-    @media screen and (max-width: $column-breakpoint) {
-      padding: 0;
-
-      .container {
-        padding: 0;
+      &__column-registration {
+        grid-row: 2;
       }
 
-      #mastodon-timeline {
-        display: flex;
-        height: 100vh;
-        border-radius: 0;
+      .directory {
+        margin-top: 10px;
       }
     }
 
-    .grid {
-      @media screen and (min-width: $small-breakpoint) {
-        grid-template-columns: 33% 67%;
-      }
+    @media screen and (max-width: $no-gap-breakpoint) {
+      grid-gap: 0;
 
-      .column-2 {
-        grid-column: 2;
-        grid-row: 1;
-      }
-    }
-
-    .brand {
-      text-align: unset;
-      padding: 0;
+      .hero-widget {
+        display: block;
+        margin-bottom: 0;
+        box-shadow: none;
 
-      img {
-        height: 48px;
-        width: auto;
+        &__img,
+        &__img img,
+        &__footer {
+          border-radius: 0;
+        }
       }
-    }
-
-    .cta {
-      margin: 0;
 
-      .button {
-        margin-right: 4px;
+      .hero-widget,
+      .box-widget,
+      .directory__tag {
+        border-bottom: 1px solid lighten($ui-base-color, 8%);
       }
-    }
 
-    @media screen and (max-width: $column-breakpoint) {
-      .grid {
-        grid-gap: 0;
+      .directory {
+        margin-top: 0;
 
-        .column-1 {
-          grid-column: 1;
-          grid-row: 1;
-        }
+        &__tag {
+          margin-bottom: 0;
+
+          & > a,
+          & > div {
+            border-radius: 0;
+            box-shadow: none;
+          }
 
-        .column-2 {
-          display: none;
+          &:last-child {
+            border-bottom: 0;
+          }
         }
       }
     }
   }
 }
+
+.brand {
+  position: relative;
+  text-decoration: none;
+}
+
+.brand__tagline {
+  display: block;
+  position: absolute;
+  bottom: -10px;
+  left: 50px;
+  width: 300px;
+  color: $ui-primary-color;
+  text-decoration: none;
+  font-size: 14px;
+
+  @media screen and (max-width: $no-gap-breakpoint) {
+    position: static;
+    width: auto;
+    margin-top: 20px;
+    color: $dark-text-color;
+  }
+}
+
diff --git a/app/javascript/styles/mastodon/accounts.scss b/app/javascript/styles/mastodon/accounts.scss
index 63a5c61b8bfcd919d1cdf0d060b8039d10dc25cd..f95313a259911cbde597d3def8c893a5e5f49625 100644
--- a/app/javascript/styles/mastodon/accounts.scss
+++ b/app/javascript/styles/mastodon/accounts.scss
@@ -68,6 +68,7 @@
         margin: 0;
         border-radius: 4px;
         background: darken($ui-base-color, 8%);
+        object-fit: cover;
       }
     }
 
@@ -196,7 +197,8 @@
   }
 }
 
-.account-role {
+.account-role,
+.simple_form .recommended {
   display: inline-block;
   padding: 4px 6px;
   cursor: default;
@@ -288,3 +290,33 @@
     border-bottom: 0;
   }
 }
+
+.directory__tag .trends__item__current {
+  width: auto;
+}
+
+.pending-account {
+  &__header {
+    color: $darker-text-color;
+
+    a {
+      color: $ui-secondary-color;
+      text-decoration: none;
+
+      &:hover,
+      &:active,
+      &:focus {
+        text-decoration: underline;
+      }
+    }
+
+    strong {
+      color: $primary-text-color;
+      font-weight: 700;
+    }
+  }
+
+  &__body {
+    margin-top: 10px;
+  }
+}
diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss
index 177f8145fa86dfce7324cfee6096edf0b1c639b7..373a1026035e2c0f7b8c780afa009a1ef646b142 100644
--- a/app/javascript/styles/mastodon/admin.scss
+++ b/app/javascript/styles/mastodon/admin.scss
@@ -50,6 +50,7 @@ $content-width: 840px;
         color: $darker-text-color;
         text-decoration: none;
         transition: all 200ms linear;
+        transition-property: color, background-color;
         border-radius: 4px 0 0 4px;
 
         i.fa {
@@ -60,6 +61,7 @@ $content-width: 840px;
           color: $primary-text-color;
           background-color: darken($ui-base-color, 5%);
           transition: all 100ms linear;
+          transition-property: color, background-color;
         }
 
         &.selected {
@@ -153,10 +155,15 @@ $content-width: 840px;
       font-weight: 500;
     }
 
-    .directory__tag a {
+    .directory__tag > a,
+    .directory__tag > div {
       box-shadow: none;
     }
 
+    .directory__tag .table-action-link .fa {
+      color: inherit;
+    }
+
     .directory__tag h4 {
       font-size: 18px;
       font-weight: 700;
@@ -164,7 +171,7 @@ $content-width: 840px;
       text-transform: none;
       padding-bottom: 0;
       margin-bottom: 0;
-      border-bottom: none;
+      border-bottom: 0;
     }
 
     & > p {
@@ -215,6 +222,11 @@ $content-width: 840px;
       color: $error-value-color;
       font-weight: 500;
     }
+
+    .neutral-hint {
+      color: $dark-text-color;
+      font-weight: 500;
+    }
   }
 
   @media screen and (max-width: $no-columns-breakpoint) {
@@ -684,3 +696,11 @@ a.name-tag,
   overflow: hidden;
   text-overflow: ellipsis;
 }
+
+.ellipsized-ip {
+  display: inline-block;
+  max-width: 120px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  vertical-align: middle;
+}
diff --git a/app/javascript/styles/mastodon/basics.scss b/app/javascript/styles/mastodon/basics.scss
index 746def6251c14349b6b5227c38ceb4f1ec7c6fc2..b5a77ce94feb2e5e1cd47acc3eec47cb36a83900 100644
--- a/app/javascript/styles/mastodon/basics.scss
+++ b/app/javascript/styles/mastodon/basics.scss
@@ -2,7 +2,8 @@
   @if type-of($color) == 'color' {
     $color: str-slice(ie-hex-str($color), 4);
   }
-  @return '%23' + unquote($color)
+
+  @return '%23' + unquote($color);
 }
 
 body {
@@ -15,7 +16,7 @@ body {
   text-rendering: optimizelegibility;
   font-feature-settings: "kern";
   text-size-adjust: none;
-  -webkit-tap-highlight-color: rgba(0,0,0,0);
+  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
   -webkit-tap-highlight-color: transparent;
 
   &.system-font {
@@ -100,12 +101,14 @@ body {
       vertical-align: middle;
       margin: 20px;
 
-      img {
-        display: block;
-        max-width: 470px;
-        width: 100%;
-        height: auto;
-        margin-top: -120px;
+      &__illustration {
+        img {
+          display: block;
+          max-width: 470px;
+          width: 100%;
+          height: auto;
+          margin-top: -120px;
+        }
       }
 
       h1 {
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index 10e094648197e6ef05b9483934d717e439ef729e..e413b00131b157767ea400be0d3430968541573f 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -46,7 +46,8 @@
     }
   }
 
-  &:disabled {
+  &:disabled,
+  &.disabled {
     background-color: $ui-primary-color;
     cursor: default;
   }
@@ -105,6 +106,10 @@
       border-color: lighten($ui-primary-color, 4%);
       color: lighten($darker-text-color, 4%);
     }
+
+    &:disabled {
+      opacity: 0.5;
+    }
   }
 
   &.button--block {
@@ -123,7 +128,7 @@
   display: inline-block;
   padding: 0;
   color: $action-button-color;
-  border: none;
+  border: 0;
   background: transparent;
   cursor: pointer;
   transition: color 100ms ease-in;
@@ -191,7 +196,7 @@
 
 .text-icon-button {
   color: $lighter-text-color;
-  border: none;
+  border: 0;
   background: transparent;
   cursor: pointer;
   font-weight: 600;
@@ -259,6 +264,41 @@
 .compose-form {
   padding: 10px;
 
+  &__sensitive-button {
+    padding: 10px;
+    padding-top: 0;
+
+    font-size: 14px;
+    font-weight: 500;
+
+    &.active {
+      color: $highlight-text-color;
+    }
+
+    input[type=checkbox] {
+      display: none;
+    }
+
+    .checkbox {
+      display: inline-block;
+      position: relative;
+      border: 1px solid $ui-primary-color;
+      box-sizing: border-box;
+      width: 18px;
+      height: 18px;
+      flex: 0 0 auto;
+      margin-right: 10px;
+      top: -1px;
+      border-radius: 4px;
+      vertical-align: middle;
+
+      &.active {
+        border-color: $highlight-text-color;
+        background: $highlight-text-color;
+      }
+    }
+  }
+
   .compose-form__warning {
     color: $inverted-text-color;
     margin-bottom: 10px;
@@ -293,17 +333,18 @@
     }
   }
 
+  .emoji-picker-dropdown {
+    position: absolute;
+    top: 5px;
+    right: 5px;
+  }
+
   .compose-form__autosuggest-wrapper {
     position: relative;
-
-    .emoji-picker-dropdown {
-      position: absolute;
-      right: 5px;
-      top: 5px;
-    }
   }
 
   .autosuggest-textarea,
+  .autosuggest-input,
   .spoiler-input {
     position: relative;
   }
@@ -311,11 +352,12 @@
   .spoiler-input {
     height: 0;
     transform-origin: bottom;
-    opacity: 0.0;
+    opacity: 0;
 
     &.spoiler-input--visible {
-      height: 47px;
-      opacity: 1.0;
+      height: 36px;
+      margin-bottom: 11px;
+      opacity: 1;
     }
   }
 
@@ -353,6 +395,11 @@
     padding-bottom: 0;
     padding-right: 10px + 22px;
     resize: none;
+    scrollbar-color: initial;
+
+    &::-webkit-scrollbar {
+      all: unset;
+    }
 
     @media screen and (max-width: 600px) {
       height: 100px !important; // prevent auto-resize textarea
@@ -360,6 +407,11 @@
     }
   }
 
+  .autosuggest-textarea__suggestions-wrapper {
+    position: relative;
+    height: 0;
+  }
+
   .autosuggest-textarea__suggestions {
     box-sizing: border-box;
     display: none;
@@ -476,7 +528,7 @@
         opacity: 0;
         transition: opacity .1s ease;
 
-        input {
+        textarea {
           background: transparent;
           color: $secondary-text-color;
           border: 0;
@@ -505,6 +557,7 @@
 
     .compose-form__upload-thumbnail {
       border-radius: 4px;
+      background-color: $base-shadow-color;
       background-position: center;
       background-size: cover;
       background-repeat: no-repeat;
@@ -520,6 +573,7 @@
     border-radius: 0 0 4px 4px;
     display: flex;
     justify-content: space-between;
+    flex: 0 0 auto;
 
     .compose-form__buttons {
       display: flex;
@@ -568,6 +622,7 @@
     display: flex;
     justify-content: flex-end;
     min-width: 0;
+    flex: 0 0 auto;
 
     .compose-form__publish-button-wrapper {
       overflow: hidden;
@@ -598,6 +653,9 @@
   margin-bottom: 10px;
   background: $ui-primary-color;
   padding: 10px;
+  min-height: 23px;
+  overflow-y: auto;
+  flex: 0 2 auto;
 }
 
 .reply-indicator__header {
@@ -638,7 +696,6 @@
   font-weight: 400;
   overflow: hidden;
   text-overflow: ellipsis;
-  white-space: pre-wrap;
   padding-top: 2px;
   color: $primary-text-color;
 
@@ -662,9 +719,10 @@
 
   p {
     margin-bottom: 20px;
+    white-space: pre-wrap;
 
     &:last-child {
-      margin-bottom: 0;
+      margin-bottom: 2px;
     }
   }
 
@@ -1126,7 +1184,7 @@
 }
 
 .account__avatar {
-  @include avatar-radius();
+  @include avatar-radius;
   position: relative;
 
   &-inline {
@@ -1136,11 +1194,11 @@
   }
 
   &-composite {
-    @include avatar-radius();
+    @include avatar-radius;
     overflow: hidden;
 
     & > div {
-      @include avatar-radius();
+      @include avatar-radius;
       float: left;
       position: relative;
       box-sizing: border-box;
@@ -1156,12 +1214,12 @@ a .account__avatar {
   @include avatar-size(48px);
 
   &-base {
-    @include avatar-radius();
+    @include avatar-radius;
     @include avatar-size(36px);
   }
 
   &-overlay {
-    @include avatar-radius();
+    @include avatar-radius;
     @include avatar-size(24px);
 
     position: absolute;
@@ -1177,57 +1235,6 @@ a .account__avatar {
   white-space: nowrap;
 }
 
-.account__header {
-  flex: 0 0 auto;
-  background: lighten($ui-base-color, 4%);
-  text-align: center;
-  background-size: cover;
-  background-position: center;
-  position: relative;
-
-  &.inactive {
-    opacity: 0.5;
-
-    .account__header__avatar {
-      filter: grayscale(100%);
-    }
-
-    .account__header__username {
-      color: $secondary-text-color;
-    }
-  }
-
-  & > div {
-    background: rgba(lighten($ui-base-color, 4%), 0.9);
-    padding: 20px 10px;
-  }
-
-  .account__header__content {
-    color: $secondary-text-color;
-  }
-
-  .account__header__display-name {
-    color: $primary-text-color;
-    display: inline-block;
-    width: 100%;
-    font-size: 20px;
-    line-height: 27px;
-    font-weight: 500;
-    overflow: hidden;
-    text-overflow: ellipsis;
-  }
-
-  .account__header__username {
-    color: $highlight-text-color;
-    font-size: 14px;
-    font-weight: 400;
-    display: block;
-    margin-bottom: 10px;
-    overflow: hidden;
-    text-overflow: ellipsis;
-  }
-}
-
 .account__disclaimer {
   padding: 10px;
   border-top: 1px solid lighten($ui-base-color, 8%);
@@ -1256,39 +1263,6 @@ a .account__avatar {
   }
 }
 
-.account__header__content {
-  color: $darker-text-color;
-  font-size: 14px;
-  font-weight: 400;
-  overflow: hidden;
-  word-break: normal;
-  word-wrap: break-word;
-
-  p {
-    margin-bottom: 20px;
-
-    &:last-child {
-      margin-bottom: 0;
-    }
-  }
-
-  a {
-    color: inherit;
-    text-decoration: underline;
-
-    &:hover {
-      text-decoration: none;
-    }
-  }
-}
-
-.account__header__display-name {
-  .emojione {
-    width: 25px;
-    height: 25px;
-  }
-}
-
 .account__action-bar {
   border-top: 1px solid lighten($ui-base-color, 8%);
   border-bottom: 1px solid lighten($ui-base-color, 8%);
@@ -1360,15 +1334,6 @@ a .account__avatar {
   }
 }
 
-.account__header__avatar {
-  background-size: 90px 90px;
-  display: block;
-  height: 90px;
-  margin: 0 auto 10px;
-  overflow: hidden;
-  width: 90px;
-}
-
 .account-authorize {
   padding: 14px 10px;
 
@@ -1459,6 +1424,15 @@ a.account__display-name {
   width: 48px;
 }
 
+.status__expand {
+  width: 68px;
+  position: absolute;
+  left: 0;
+  top: 0;
+  height: 100%;
+  cursor: pointer;
+}
+
 .muted {
   .status__content p,
   .status__content a {
@@ -1623,13 +1597,13 @@ a.account__display-name {
     .icon-button.close {
       position: absolute;
       pointer-events: none;
-      transform: scale(0.0, 1.0) translate(-100%, 0);
+      transform: scale(0, 1) translate(-100%, 0);
       opacity: 0;
     }
 
     .compose__action-bar .icon-button {
       pointer-events: auto;
-      transform: scale(1.0, 1.0) translate(0, 0);
+      transform: scale(1, 1) translate(0, 0);
       opacity: 1;
     }
   }
@@ -1824,15 +1798,42 @@ a.account__display-name {
   &.unscrollable {
     overflow-x: hidden;
   }
-}
 
-@media screen and (min-width: 360px) {
-  .columns-area {
-    padding: 10px;
-  }
+  &__panels {
+    display: flex;
+    justify-content: center;
+    width: 100%;
+    height: 100%;
 
-  .react-swipeable-view-container .columns-area {
-    height: calc(100% - 20px) !important;
+    &__pane {
+      height: 100%;
+      overflow: hidden;
+      pointer-events: none;
+      display: flex;
+      justify-content: flex-end;
+
+      &--start {
+        justify-content: flex-start;
+      }
+
+      &__inner {
+        width: 285px;
+        pointer-events: auto;
+        height: 100%;
+      }
+    }
+
+    &__main {
+      box-sizing: border-box;
+      width: 100%;
+      max-width: 600px;
+      display: flex;
+      flex-direction: column;
+
+      @media screen and (min-width: $no-gap-breakpoint) {
+        padding: 0 10px;
+      }
+    }
   }
 }
 
@@ -1898,36 +1899,6 @@ a.account__display-name {
   overflow: hidden;
 }
 
-@media screen and (min-width: 360px) {
-  .tabs-bar {
-    margin: 10px;
-    margin-bottom: 0;
-  }
-
-  .getting-started__wrapper,
-  .getting-started__trends,
-  .search {
-    margin-bottom: 10px;
-  }
-}
-
-@media screen and (max-width: 630px) {
-  .column,
-  .drawer {
-    width: 100%;
-    padding: 0;
-  }
-
-  .columns-area {
-    flex-direction: column;
-  }
-
-  .search__input,
-  .autosuggest-textarea__textarea {
-    font-size: 16px;
-  }
-}
-
 @media screen and (min-width: 631px) {
   .columns-area {
     padding: 0;
@@ -1958,76 +1929,8 @@ a.account__display-name {
   }
 }
 
-.drawer__pager {
-  box-sizing: border-box;
-  padding: 0;
-  flex-grow: 1;
-  position: relative;
-  overflow: hidden;
-  display: flex;
-}
-
-.drawer__inner {
-  position: absolute;
-  top: 0;
-  left: 0;
-  background: lighten($ui-base-color, 13%);
-  box-sizing: border-box;
-  padding: 0;
-  display: flex;
-  flex-direction: column;
-  overflow: hidden;
-  overflow-y: auto;
-  width: 100%;
-  height: 100%;
-
-  &.darker {
-    background: $ui-base-color;
-  }
-}
-
-.drawer__inner__mastodon {
-  background: lighten($ui-base-color, 13%) url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 234.80078 31.757813" width="234.80078" height="31.757812"><path d="M19.599609 0c-1.05 0-2.10039.375-2.90039 1.125L0 16.925781v14.832031h234.80078V17.025391l-16.5-15.900391c-1.6-1.5-4.20078-1.5-5.80078 0l-13.80078 13.099609c-1.6 1.5-4.19883 1.5-5.79883 0L179.09961 1.125c-1.6-1.5-4.19883-1.5-5.79883 0L159.5 14.224609c-1.6 1.5-4.20078 1.5-5.80078 0L139.90039 1.125c-1.6-1.5-4.20078-1.5-5.80078 0l-13.79883 13.099609c-1.6 1.5-4.20078 1.5-5.80078 0L100.69922 1.125c-1.600001-1.5-4.198829-1.5-5.798829 0l-13.59961 13.099609c-1.6 1.5-4.200781 1.5-5.800781 0L61.699219 1.125c-1.6-1.5-4.198828-1.5-5.798828 0L42.099609 14.224609c-1.6 1.5-4.198828 1.5-5.798828 0L22.5 1.125C21.7.375 20.649609 0 19.599609 0z" fill="#{hex-color($ui-base-color)}"/></svg>') no-repeat bottom / 100% auto;
-  flex: 1;
-  min-height: 47px;
-
-  > img {
-    display: block;
-    object-fit: contain;
-    object-position: bottom left;
-    width: 100%;
-    height: 100%;
-    pointer-events: none;
-    user-drag: none;
-    user-select: none;
-  }
-}
-
-.pseudo-drawer {
-  background: lighten($ui-base-color, 13%);
-  font-size: 13px;
-  text-align: left;
-}
-
-.drawer__header {
-  flex: 0 0 auto;
-  font-size: 16px;
-  background: lighten($ui-base-color, 8%);
-  margin-bottom: 10px;
-  display: flex;
-  flex-direction: row;
-
-  a {
-    transition: background 100ms ease-in;
-
-    &:hover {
-      background: lighten($ui-base-color, 3%);
-      transition: background 200ms ease-out;
-    }
-  }
-}
-
 .tabs-bar {
+  box-sizing: border-box;
   display: flex;
   background: lighten($ui-base-color, 8%);
   flex: 0 0 auto;
@@ -2038,6 +1941,7 @@ a.account__display-name {
   display: block;
   flex: 1 1 auto;
   padding: 15px 10px;
+  padding-bottom: 13px;
   color: $primary-text-color;
   text-decoration: none;
   text-align: center;
@@ -2045,25 +1949,27 @@ a.account__display-name {
   font-weight: 500;
   border-bottom: 2px solid lighten($ui-base-color, 8%);
   transition: all 50ms linear;
+  transition-property: border-bottom, background, color;
 
   .fa {
     font-weight: 400;
     font-size: 16px;
   }
 
-  &.active {
-    border-bottom: 2px solid $highlight-text-color;
-    color: $highlight-text-color;
-  }
-
   &:hover,
   &:focus,
   &:active {
     @media screen and (min-width: 631px) {
       background: lighten($ui-base-color, 14%);
+      border-bottom-color: lighten($ui-base-color, 14%);
     }
   }
 
+  &.active {
+    border-bottom: 2px solid $highlight-text-color;
+    color: $highlight-text-color;
+  }
+
   span {
     margin-left: 5px;
     display: none;
@@ -2078,12 +1984,350 @@ a.account__display-name {
   }
 }
 
-@media screen and (min-width: 631px) {
+.columns-area--mobile {
+  flex-direction: column;
+  width: 100%;
+  height: 100%;
+  margin: 0 auto;
+
+  .column,
+  .drawer {
+    width: 100%;
+    height: 100%;
+    padding: 0;
+  }
+
+  .autosuggest-textarea__textarea {
+    font-size: 16px;
+  }
+
+  .search__input {
+    line-height: 18px;
+    font-size: 16px;
+    padding: 15px;
+    padding-right: 30px;
+  }
+
+  .search__icon .fa {
+    top: 15px;
+  }
+
+  @media screen and (min-width: $no-gap-breakpoint) {
+    padding: 10px 0;
+  }
+
+  @media screen and (min-width: 630px) {
+    .detailed-status {
+      padding: 15px;
+
+      .media-gallery,
+      .video-player {
+        margin-top: 15px;
+      }
+    }
+
+    .account__header__bar {
+      padding: 5px 10px;
+    }
+
+    .navigation-bar,
+    .compose-form {
+      padding: 15px;
+    }
+
+    .compose-form .compose-form__publish .compose-form__publish-button-wrapper {
+      padding-top: 15px;
+    }
+
+    .status {
+      padding: 15px 15px 15px (48px + 15px * 2);
+      min-height: 48px + 2px;
+
+      &__avatar {
+        left: 15px;
+        top: 17px;
+      }
+
+      &__content {
+        padding-top: 5px;
+      }
+
+      &__prepend {
+        margin-left: 48px + 15px * 2;
+        padding-top: 15px;
+      }
+
+      &__prepend-icon-wrapper {
+        left: -32px;
+      }
+
+      .media-gallery,
+      &__action-bar,
+      .video-player {
+        margin-top: 10px;
+      }
+    }
+
+    .account {
+      padding: 15px 10px;
+
+      &__header__bio {
+        margin: 0 -10px;
+      }
+    }
+
+    .notification {
+      &__message {
+        margin-left: 48px + 15px * 2;
+        padding-top: 15px;
+      }
+
+      &__favourite-icon-wrapper {
+        left: -32px;
+      }
+
+      .status {
+        padding-top: 8px;
+      }
+
+      .account {
+        padding-top: 8px;
+      }
+
+      .account__avatar-wrapper {
+        margin-left: 17px;
+        margin-right: 15px;
+      }
+    }
+  }
+}
+
+.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%);
+  }
+}
+
+@media screen and (min-width: $no-gap-breakpoint) {
   .tabs-bar {
+    margin: 10px auto;
+    margin-bottom: 0;
+    width: 100%;
+  }
+
+  .react-swipeable-view-container .columns-area--mobile {
+    height: calc(100% - 20px) !important;
+  }
+
+  .getting-started__wrapper,
+  .getting-started__trends,
+  .search {
+    margin-bottom: 10px;
+  }
+}
+
+@media screen and (max-width: 600px + (285px * 1) + (10px * 1)) {
+  .columns-area__panels__pane--compositional {
+    display: none;
+  }
+}
+
+@media screen and (min-width: 600px + (285px * 1) + (10px * 1)) {
+  .floating-action-button,
+  .tabs-bar__link.optional {
+    display: none;
+  }
+
+  .search-page .search {
+    display: none;
+  }
+}
+
+@media screen and (max-width: 600px + (285px * 2) + (10px * 2)) {
+  .columns-area__panels__pane--navigational {
     display: none;
   }
 }
 
+@media screen and (min-width: 600px + (285px * 2) + (10px * 2)) {
+  .tabs-bar {
+    display: none;
+  }
+}
+
+.icon-with-badge {
+  position: relative;
+
+  &__badge {
+    position: absolute;
+    left: 9px;
+    top: -13px;
+    background: $ui-highlight-color;
+    border: 2px solid lighten($ui-base-color, 8%);
+    padding: 1px 6px;
+    border-radius: 6px;
+    font-size: 10px;
+    font-weight: 500;
+    line-height: 14px;
+    color: $primary-text-color;
+  }
+}
+
+.column-link--transparent .icon-with-badge__badge {
+  border-color: darken($ui-base-color, 8%);
+}
+
+.compose-panel {
+  width: 285px;
+  margin-top: 10px;
+  display: flex;
+  flex-direction: column;
+  height: calc(100% - 10px);
+  overflow-y: hidden;
+
+  .navigation-bar {
+    padding-top: 20px;
+    padding-bottom: 20px;
+    flex: 0 1 48px;
+    min-height: 20px;
+  }
+
+  .flex-spacer {
+    background: transparent;
+  }
+
+  .compose-form {
+    flex: 1;
+    overflow-y: hidden;
+    display: flex;
+    flex-direction: column;
+    min-height: 310px;
+    padding-bottom: 71px;
+    margin-bottom: -71px;
+  }
+
+  .compose-form__autosuggest-wrapper {
+    overflow-y: auto;
+    background-color: $white;
+    border-radius: 4px 4px 0 0;
+    flex: 0 1 auto;
+  }
+
+  .autosuggest-textarea__textarea {
+    overflow-y: hidden;
+  }
+
+  .compose-form__upload-thumbnail {
+    height: 80px;
+  }
+}
+
+.navigation-panel {
+  margin-top: 10px;
+  margin-bottom: 10px;
+  height: calc(100% - 20px);
+  overflow-y: auto;
+
+  hr {
+    border: 0;
+    background: transparent;
+    border-top: 1px solid lighten($ui-base-color, 4%);
+    margin: 10px 0;
+  }
+}
+
+.drawer__pager {
+  box-sizing: border-box;
+  padding: 0;
+  flex-grow: 1;
+  position: relative;
+  overflow: hidden;
+  display: flex;
+}
+
+.drawer__inner {
+  position: absolute;
+  top: 0;
+  left: 0;
+  background: lighten($ui-base-color, 13%);
+  box-sizing: border-box;
+  padding: 0;
+  display: flex;
+  flex-direction: column;
+  overflow: hidden;
+  overflow-y: auto;
+  width: 100%;
+  height: 100%;
+
+  &.darker {
+    background: $ui-base-color;
+  }
+}
+
+.drawer__inner__mastodon {
+  background: lighten($ui-base-color, 13%) url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 234.80078 31.757813" width="234.80078" height="31.757812"><path d="M19.599609 0c-1.05 0-2.10039.375-2.90039 1.125L0 16.925781v14.832031h234.80078V17.025391l-16.5-15.900391c-1.6-1.5-4.20078-1.5-5.80078 0l-13.80078 13.099609c-1.6 1.5-4.19883 1.5-5.79883 0L179.09961 1.125c-1.6-1.5-4.19883-1.5-5.79883 0L159.5 14.224609c-1.6 1.5-4.20078 1.5-5.80078 0L139.90039 1.125c-1.6-1.5-4.20078-1.5-5.80078 0l-13.79883 13.099609c-1.6 1.5-4.20078 1.5-5.80078 0L100.69922 1.125c-1.600001-1.5-4.198829-1.5-5.798829 0l-13.59961 13.099609c-1.6 1.5-4.200781 1.5-5.800781 0L61.699219 1.125c-1.6-1.5-4.198828-1.5-5.798828 0L42.099609 14.224609c-1.6 1.5-4.198828 1.5-5.798828 0L22.5 1.125C21.7.375 20.649609 0 19.599609 0z" fill="#{hex-color($ui-base-color)}"/></svg>') no-repeat bottom / 100% auto;
+  flex: 1;
+  min-height: 47px;
+  display: none;
+
+  > img {
+    display: block;
+    object-fit: contain;
+    object-position: bottom left;
+    width: 100%;
+    height: 100%;
+    pointer-events: none;
+    user-drag: none;
+    user-select: none;
+  }
+
+  @media screen and (min-height: 640px) {
+    display: block;
+  }
+}
+
+.pseudo-drawer {
+  background: lighten($ui-base-color, 13%);
+  font-size: 13px;
+  text-align: left;
+}
+
+.drawer__header {
+  flex: 0 0 auto;
+  font-size: 16px;
+  background: lighten($ui-base-color, 8%);
+  margin-bottom: 10px;
+  display: flex;
+  flex-direction: row;
+
+  a {
+    transition: background 100ms ease-in;
+
+    &:hover {
+      background: lighten($ui-base-color, 3%);
+      transition: background 200ms ease-out;
+    }
+  }
+}
+
 .scrollable {
   overflow-y: scroll;
   overflow-x: hidden;
@@ -2210,7 +2454,7 @@ a.account__display-name {
   padding: 0;
   border-radius: 30px;
   background-color: $ui-base-color;
-  transition: all 0.2s ease;
+  transition: background-color 0.2s ease;
 }
 
 .react-toggle:hover:not(.react-toggle--disabled) .react-toggle-track {
@@ -2263,7 +2507,6 @@ a.account__display-name {
 }
 
 .react-toggle-thumb {
-  transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1) 0ms;
   position: absolute;
   top: 1px;
   left: 1px;
@@ -2274,6 +2517,7 @@ a.account__display-name {
   background-color: darken($simple-background-color, 2%);
   box-sizing: border-box;
   transition: all 0.25s ease;
+  transition-property: border-color, left;
 }
 
 .react-toggle--checked .react-toggle-thumb {
@@ -2289,9 +2533,31 @@ a.account__display-name {
   padding: 15px;
   text-decoration: none;
 
-  &:hover {
+  &:hover,
+  &:focus,
+  &:active {
     background: lighten($ui-base-color, 11%);
   }
+
+  &:focus {
+    outline: 0;
+  }
+
+  &--transparent {
+    background: transparent;
+    color: $ui-secondary-color;
+
+    &:hover,
+    &:focus,
+    &:active {
+      background: transparent;
+      color: $primary-text-color;
+    }
+
+    &.active {
+      color: $ui-highlight-color;
+    }
+  }
 }
 
 .column-link__icon {
@@ -2336,6 +2602,7 @@ a.account__display-name {
 
 .getting-started {
   color: $dark-text-color;
+  overflow: auto;
 
   &__footer {
     flex: 0 0 auto;
@@ -2422,21 +2689,22 @@ a.account__display-name {
 }
 
 .setting-text {
-  color: $darker-text-color;
-  background: transparent;
-  border: none;
-  border-bottom: 2px solid $ui-primary-color;
-  box-sizing: border-box;
   display: block;
-  font-family: inherit;
-  margin-bottom: 10px;
-  padding: 7px 0;
+  box-sizing: border-box;
   width: 100%;
+  margin: 0;
+  color: $inverted-text-color;
+  background: $simple-background-color;
+  padding: 10px;
+  font-family: inherit;
+  font-size: 14px;
+  resize: vertical;
+  border: 0;
+  outline: 0;
+  border-radius: 4px;
 
-  &:focus,
-  &:active {
-    color: $primary-text-color;
-    border-bottom-color: $highlight-text-color;
+  &:focus {
+    outline: 0;
   }
 
   @media screen and (max-width: 600px) {
@@ -2494,7 +2762,7 @@ a.account__display-name {
 
     & > div {
       background: rgba($base-shadow-color, 0.6);
-      border-radius: 4px;
+      border-radius: 8px;
       padding: 12px 9px;
       flex: 0 0 auto;
       display: flex;
@@ -2505,19 +2773,18 @@ a.account__display-name {
     button,
     a {
       display: inline;
-      color: $primary-text-color;
+      color: $secondary-text-color;
       background: transparent;
       border: 0;
-      padding: 0 5px;
+      padding: 0 8px;
       text-decoration: none;
-      opacity: 0.6;
       font-size: 18px;
       line-height: 18px;
 
       &:hover,
       &:active,
       &:focus {
-        opacity: 1;
+        color: $primary-text-color;
       }
     }
 
@@ -2763,7 +3030,7 @@ a.status-card.compact:hover {
 
   & > button {
     margin: 0;
-    border: none;
+    border: 0;
     padding: 15px 0 15px 15px;
     color: inherit;
     background: transparent;
@@ -2799,6 +3066,10 @@ a.status-card.compact:hover {
   display: flex;
 }
 
+.column-header__links {
+  margin-bottom: 14px;
+}
+
 .column-header__links .text-btn {
   margin-right: 10px;
 }
@@ -2928,11 +3199,11 @@ a.status-card.compact:hover {
 }
 
 .no-reduce-motion .loading-indicator span {
-  animation: loader-label 1.15s infinite cubic-bezier(0.215, 0.610, 0.355, 1.000);
+  animation: loader-label 1.15s infinite cubic-bezier(0.215, 0.61, 0.355, 1);
 }
 
 .no-reduce-motion .loading-indicator__figure {
-  animation: loader-figure 1.15s infinite cubic-bezier(0.215, 0.610, 0.355, 1.000);
+  animation: loader-figure 1.15s infinite cubic-bezier(0.215, 0.61, 0.355, 1);
 }
 
 @keyframes loader-figure {
@@ -3014,15 +3285,49 @@ a.status-card.compact:hover {
 }
 
 .spoiler-button {
-  display: none;
-  left: 4px;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
   position: absolute;
-  text-shadow: 0 1px 1px $base-shadow-color, 1px 0 1px $base-shadow-color;
-  top: 4px;
   z-index: 100;
 
-  &.spoiler-button--visible {
+  &--minified {
     display: block;
+    left: 4px;
+    top: 4px;
+    width: auto;
+    height: auto;
+  }
+
+  &--hidden {
+    display: none;
+  }
+
+  &__overlay {
+    display: block;
+    background: transparent;
+    width: 100%;
+    height: 100%;
+    border: 0;
+
+    &__label {
+      display: inline-block;
+      background: rgba($base-overlay-background, 0.5);
+      border-radius: 8px;
+      padding: 8px 12px;
+      color: $primary-text-color;
+      font-weight: 500;
+      font-size: 14px;
+    }
+
+    &:hover,
+    &:focus,
+    &:active {
+      .spoiler-button__overlay__label {
+        background: rgba($base-overlay-background, 0.8);
+      }
+    }
   }
 }
 
@@ -3056,14 +3361,41 @@ a.status-card.compact:hover {
   display: block;
   font-weight: 500;
   margin-bottom: 10px;
+}
 
-  .column-settings__hashtag-select {
+.column-settings__hashtags {
+  .column-settings__row {
+    margin-bottom: 15px;
+  }
+
+  .column-select {
     &__control {
-      @include search-input();
+      @include search-input;
+    }
+
+    &__placeholder {
+      color: $dark-text-color;
+      padding-left: 2px;
+      font-size: 12px;
+    }
+
+    &__value-container {
+      padding-left: 6px;
     }
 
     &__multi-value {
       background: lighten($ui-base-color, 8%);
+
+      &__remove {
+        cursor: pointer;
+
+        &:hover,
+        &:active,
+        &:focus {
+          background: lighten($ui-base-color, 12%);
+          color: lighten($darker-text-color, 4%);
+        }
+      }
     }
 
     &__multi-value__label,
@@ -3071,9 +3403,42 @@ a.status-card.compact:hover {
       color: $darker-text-color;
     }
 
-    &__indicator-separator,
+    &__clear-indicator,
     &__dropdown-indicator {
-      display: none;
+      cursor: pointer;
+      transition: none;
+      color: $dark-text-color;
+
+      &:hover,
+      &:active,
+      &:focus {
+        color: lighten($dark-text-color, 4%);
+      }
+    }
+
+    &__indicator-separator {
+      background-color: lighten($ui-base-color, 8%);
+    }
+
+    &__menu {
+      @include search-popout;
+      padding: 0;
+      background: $ui-secondary-color;
+    }
+
+    &__menu-list {
+      padding: 6px;
+    }
+
+    &__option {
+      color: $inverted-text-color;
+      border-radius: 4px;
+      font-size: 14px;
+
+      &--is-focused,
+      &--is-selected {
+        background: darken($ui-secondary-color, 10%);
+      }
     }
   }
 }
@@ -3084,42 +3449,22 @@ a.status-card.compact:hover {
   }
 }
 
-.account--follows-info {
+.relationship-tag {
   color: $primary-text-color;
-  position: absolute;
-  top: 10px;
-  left: 10px;
-  opacity: 0.7;
-  display: inline-block;
+  margin-bottom: 4px;
+  display: block;
   vertical-align: top;
-  background-color: rgba($base-overlay-background, 0.4);
+  background-color: $base-overlay-background;
   text-transform: uppercase;
   font-size: 11px;
   font-weight: 500;
   padding: 4px;
   border-radius: 4px;
-}
-
-.account--muting-info {
-  color: $primary-text-color;
-  position: absolute;
-  top: 40px;
-  left: 10px;
   opacity: 0.7;
-  display: inline-block;
-  vertical-align: top;
-  background-color: rgba($base-overlay-background, 0.4);
-  text-transform: uppercase;
-  font-size: 11px;
-  font-weight: 500;
-  padding: 4px;
-  border-radius: 4px;
-}
 
-.account--action-button {
-  position: absolute;
-  top: 10px;
-  right: 20px;
+  &:hover {
+    opacity: 1;
+  }
 }
 
 .setting-toggle {
@@ -3153,6 +3498,10 @@ a.status-card.compact:hover {
     contain: strict;
   }
 
+  & > span {
+    max-width: 400px;
+  }
+
   a {
     color: $highlight-text-color;
     text-decoration: none;
@@ -3233,7 +3582,7 @@ a.status-card.compact:hover {
 
 .no-reduce-motion .shake-bottom {
   transform-origin: 50% 100%;
-  animation: shake-bottom 0.8s cubic-bezier(0.455, 0.030, 0.515, 0.955) 2s 2 both;
+  animation: shake-bottom 0.8s cubic-bezier(0.455, 0.03, 0.515, 0.955) 2s 2 both;
 }
 
 .emoji-picker-dropdown__menu {
@@ -3242,6 +3591,7 @@ a.status-card.compact:hover {
   box-shadow: 4px 4px 6px rgba($base-shadow-color, 0.4);
   border-radius: 4px;
   margin-top: 5px;
+  z-index: 2;
 
   .emoji-mart-scroll {
     transition: opacity 200ms ease;
@@ -3527,10 +3877,13 @@ a.status-card.compact:hover {
 }
 
 .search__input {
+  @include search-input;
+
   display: block;
-  padding: 10px;
+  padding: 15px;
   padding-right: 30px;
-  @include search-input();
+  line-height: 18px;
+  font-size: 16px;
 }
 
 .search__icon {
@@ -3545,12 +3898,13 @@ a.status-card.compact:hover {
 
   .fa {
     position: absolute;
-    top: 10px;
+    top: 16px;
     right: 10px;
     z-index: 2;
     display: inline-block;
     opacity: 0;
     transition: all 100ms linear;
+    transition-property: transform, opacity;
     font-size: 18px;
     width: 18px;
     height: 18px;
@@ -3574,7 +3928,7 @@ a.status-card.compact:hover {
   }
 
   .fa-times-circle {
-    top: 11px;
+    top: 17px;
     transform: rotate(0deg);
     color: $action-button-color;
     cursor: pointer;
@@ -3642,6 +3996,11 @@ a.status-card.compact:hover {
   }
 }
 
+.search-results__info {
+  padding: 10px;
+  color: $secondary-text-color;
+}
+
 .modal-root {
   position: relative;
   transition: opacity 0.3s linear;
@@ -3770,6 +4129,31 @@ a.status-card.compact:hover {
   pointer-events: none;
 }
 
+.media-modal__meta {
+  text-align: center;
+  position: absolute;
+  left: 0;
+  bottom: 20px;
+  width: 100%;
+  pointer-events: none;
+
+  &--shifted {
+    bottom: 62px;
+  }
+
+  a {
+    text-decoration: none;
+    font-weight: 500;
+    color: $ui-secondary-color;
+
+    &:hover,
+    &:focus,
+    &:active {
+      text-decoration: underline;
+    }
+  }
+}
+
 .media-modal__page-dot {
   display: inline-block;
 }
@@ -4003,14 +4387,6 @@ a.status-card.compact:hover {
   font-size: 14px;
 }
 
-.confirmation-modal {
-  max-width: 85vw;
-
-  @media screen and (min-width: 480px) {
-    max-width: 380px;
-  }
-}
-
 .mute-modal {
   line-height: 24px;
 }
@@ -4120,14 +4496,14 @@ a.status-card.compact:hover {
 }
 
 .actions-modal {
+  max-height: 80vh;
+  max-width: 80vw;
+
   .status {
     overflow-y: auto;
     max-height: 300px;
   }
 
-  max-height: 80vh;
-  max-width: 80vw;
-
   .actions-modal__item-label {
     font-weight: 500;
   }
@@ -4135,6 +4511,11 @@ a.status-card.compact:hover {
   ul {
     overflow-y: auto;
     flex-shrink: 0;
+    max-height: 80vh;
+
+    &.with-status {
+      max-height: calc(80vh - 75px);
+    }
 
     li:empty {
       margin: 0;
@@ -4175,6 +4556,7 @@ a.status-card.compact:hover {
 
 .confirmation-modal__action-bar,
 .mute-modal__action-bar {
+  .confirmation-modal__secondary-button,
   .confirmation-modal__cancel-button,
   .mute-modal__cancel-button {
     background-color: transparent;
@@ -4188,6 +4570,10 @@ a.status-card.compact:hover {
       color: darken($lighter-text-color, 4%);
     }
   }
+
+  .confirmation-modal__secondary-button {
+    flex-shrink: 1;
+  }
 }
 
 .confirmation-modal__container,
@@ -4240,6 +4626,7 @@ a.status-card.compact:hover {
   pointer-events: none;
   opacity: 0.9;
   transition: opacity 0.1s ease;
+  line-height: 18px;
 }
 
 .media-gallery__gifv {
@@ -4331,7 +4718,7 @@ a.status-card.compact:hover {
 }
 
 .media-gallery__item {
-  border: none;
+  border: 0;
   box-sizing: border-box;
   display: block;
   float: left;
@@ -4352,7 +4739,8 @@ a.status-card.compact:hover {
   display: block;
   text-decoration: none;
   color: $secondary-text-color;
-  line-height: 0;
+  position: relative;
+  z-index: 1;
 
   &,
   img {
@@ -4365,6 +4753,21 @@ a.status-card.compact:hover {
   }
 }
 
+.media-gallery__preview {
+  width: 100%;
+  height: 100%;
+  object-fit: cover;
+  position: absolute;
+  top: 0;
+  left: 0;
+  z-index: 0;
+  background: $base-overlay-background;
+
+  &--hidden {
+    display: none;
+  }
+}
+
 .media-gallery__gifv {
   height: 100%;
   overflow: hidden;
@@ -4660,6 +5063,23 @@ a.status-card.compact:hover {
     }
   }
 
+  &__link {
+    padding: 2px 10px;
+
+    a {
+      text-decoration: none;
+      font-size: 14px;
+      font-weight: 500;
+      color: $white;
+
+      &:hover,
+      &:active,
+      &:focus {
+        text-decoration: underline;
+      }
+    }
+  }
+
   &__seek {
     cursor: pointer;
     height: 24px;
@@ -4752,54 +5172,18 @@ a.status-card.compact:hover {
 
 .account-gallery__container {
   display: flex;
-  justify-content: center;
   flex-wrap: wrap;
-  padding: 2px;
+  padding: 4px 2px;
 }
 
 .account-gallery__item {
-  flex-grow: 1;
-  width: 50%;
-  overflow: hidden;
+  border: 0;
+  box-sizing: border-box;
+  display: block;
   position: relative;
-
-  &::before {
-    content: "";
-    display: block;
-    padding-top: 100%;
-  }
-
-  a {
-    display: block;
-    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: absolute;
-    color: $darker-text-color;
-    text-decoration: none;
-    border-radius: 4px;
-
-    &:hover,
-    &:active,
-    &:focus {
-      outline: 0;
-      color: $secondary-text-color;
-
-      &::before {
-        content: "";
-        display: block;
-        width: 100%;
-        height: 100%;
-        background: rgba($base-overlay-background, 0.3);
-        border-radius: 4px;
-      }
-    }
-  }
+  border-radius: 4px;
+  overflow: hidden;
+  margin: 2px;
 
   &__icons {
     position: absolute;
@@ -4867,34 +5251,7 @@ a.status-card.compact:hover {
 }
 
 .search-popout {
-  background: $simple-background-color;
-  border-radius: 4px;
-  padding: 10px 14px;
-  padding-bottom: 14px;
-  margin-top: 10px;
-  color: $light-text-color;
-  box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4);
-
-  h4 {
-    text-transform: uppercase;
-    color: $light-text-color;
-    font-size: 13px;
-    font-weight: 500;
-    margin-bottom: 10px;
-  }
-
-  li {
-    padding: 4px 0;
-  }
-
-  ul {
-    margin-bottom: 10px;
-  }
-
-  em {
-    font-weight: 500;
-    color: $inverted-text-color;
-  }
+  @include search-popout;
 }
 
 noscript {
@@ -4996,14 +5353,14 @@ noscript {
         .icon-button.close {
           pointer-events: auto;
           opacity: 1;
-          transform: scale(1.0, 1.0) translate(0, 0);
+          transform: scale(1, 1) translate(0, 0);
           bottom: 5px;
         }
 
         .compose__action-bar .icon-button {
           pointer-events: none;
           opacity: 0;
-          transform: scale(0.0, 1.0) translate(100%, 0);
+          transform: scale(0, 1) translate(100%, 0);
         }
       }
     }
@@ -5033,7 +5390,7 @@ noscript {
       box-sizing: border-box;
       display: block;
       width: 100%;
-      border: none;
+      border: 0;
       padding: 10px;
       font-family: $font-monospace, monospace;
       background: $ui-base-color;
@@ -5108,8 +5465,8 @@ noscript {
 }
 
 .column-inline-form {
-  padding: 7px 15px;
-  padding-right: 5px;
+  padding: 15px;
+  padding-right: 0;
   display: flex;
   justify-content: flex-start;
   align-items: center;
@@ -5120,7 +5477,6 @@ noscript {
 
     input {
       width: 100%;
-      margin-bottom: 6px;
 
       &:focus {
         outline: 0;
@@ -5130,7 +5486,7 @@ noscript {
 
   .icon-button {
     flex: 0 0 auto;
-    margin-left: 5px;
+    margin: 0 10px;
   }
 }
 
@@ -5281,77 +5637,193 @@ noscript {
   }
 }
 
-.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);
+.account__header__content {
+  color: $darker-text-color;
+  font-size: 14px;
+  font-weight: 400;
+  overflow: hidden;
+  word-break: normal;
+  word-wrap: break-word;
 
-  &:hover,
-  &:focus,
-  &:active {
-    background: lighten($ui-highlight-color, 7%);
+  p {
+    margin-bottom: 20px;
+
+    &:last-child {
+      margin-bottom: 0;
+    }
   }
-}
 
-.account__header .roles {
-  margin-top: 20px;
-  margin-bottom: 20px;
-  padding: 0 15px;
+  a {
+    color: inherit;
+    text-decoration: underline;
+
+    &:hover {
+      text-decoration: none;
+    }
+  }
 }
 
-.account__header .account__header__fields {
-  font-size: 14px;
-  line-height: 20px;
+.account__header {
   overflow: hidden;
-  margin: 20px -10px -20px;
-  border-bottom: 0;
-  border-top: 0;
 
-  dl {
-    border-top: 1px solid lighten($ui-base-color, 4%);
-    border-bottom: 0;
-    display: flex;
+  &.inactive {
+    opacity: 0.5;
+
+    .account__header__image,
+    .account__avatar {
+      filter: grayscale(100%);
+    }
   }
 
-  dt,
-  dd {
-    box-sizing: border-box;
-    padding: 14px 5px;
-    text-align: center;
-    max-height: 48px;
-    overflow: hidden;
-    white-space: nowrap;
-    text-overflow: ellipsis;
+  &__info {
+    position: absolute;
+    top: 10px;
+    left: 10px;
   }
 
-  dt {
-    color: $darker-text-color;
+  &__image {
+    overflow: hidden;
+    height: 145px;
+    position: relative;
     background: darken($ui-base-color, 4%);
-    width: 120px;
-    flex: 0 0 auto;
-    font-weight: 500;
+
+    img {
+      object-fit: cover;
+      display: block;
+      width: 100%;
+      height: 100%;
+      margin: 0;
+    }
   }
 
-  dd {
-    flex: 1 1 auto;
-    color: $primary-text-color;
-    background: $ui-base-color;
+  &__bar {
+    position: relative;
+    background: lighten($ui-base-color, 4%);
+    padding: 5px;
+    border-bottom: 1px solid lighten($ui-base-color, 12%);
+
+    .avatar {
+      display: block;
+      flex: 0 0 auto;
+      width: 94px;
+      margin-left: -2px;
+
+      .account__avatar {
+        background: darken($ui-base-color, 8%);
+        border: 2px solid lighten($ui-base-color, 4%);
+      }
+    }
+  }
+
+  &__tabs {
+    display: flex;
+    align-items: flex-start;
+    padding: 7px 5px;
+    margin-top: -55px;
+
+    &__buttons {
+      display: flex;
+      align-items: center;
+      padding-top: 55px;
+      overflow: hidden;
+
+      .icon-button {
+        border: 1px solid lighten($ui-base-color, 12%);
+        border-radius: 4px;
+        box-sizing: content-box;
+        padding: 2px;
+      }
+
+      .button {
+        margin: 0 8px;
+      }
+    }
+
+    &__name {
+      padding: 5px;
+
+      .account-role {
+        vertical-align: top;
+      }
+
+      .emojione {
+        width: 22px;
+        height: 22px;
+      }
+
+      h1 {
+        font-size: 16px;
+        line-height: 24px;
+        color: $primary-text-color;
+        font-weight: 500;
+        overflow: hidden;
+        white-space: nowrap;
+        text-overflow: ellipsis;
+
+        small {
+          display: block;
+          font-size: 14px;
+          color: $darker-text-color;
+          font-weight: 400;
+          overflow: hidden;
+          text-overflow: ellipsis;
+        }
+      }
+    }
+
+    .spacer {
+      flex: 1 1 auto;
+    }
+  }
+
+  &__bio {
+    overflow: hidden;
+    margin: 0 -5px;
+
+    .account__header__content {
+      padding: 20px 15px;
+      padding-bottom: 5px;
+      color: $primary-text-color;
+    }
+
+    .account__header__fields {
+      margin: 0;
+      border-top: 1px solid lighten($ui-base-color, 12%);
+
+      a {
+        color: lighten($ui-highlight-color, 8%);
+      }
+
+      dl:first-child .verified {
+        border-radius: 0 4px 0 0;
+      }
+
+      .verified a {
+        color: $valid-value-color;
+      }
+    }
+  }
+
+  &__extra {
+    margin-top: 4px;
+
+    &__links {
+      font-size: 14px;
+      color: $darker-text-color;
+
+      a {
+        display: inline-block;
+        color: $darker-text-color;
+        text-decoration: none;
+        padding: 10px;
+        padding-top: 20px;
+        font-weight: 500;
 
-    &.verified {
-      border: 1px solid rgba($valid-value-color, 0.5);
-      background: rgba($valid-value-color, 0.25);
+        strong {
+          font-weight: 700;
+          color: $primary-text-color;
+        }
+      }
     }
   }
 }
@@ -5433,3 +5905,49 @@ noscript {
     }
   }
 }
+
+.layout-toggle {
+  display: flex;
+  padding: 5px;
+
+  button {
+    box-sizing: border-box;
+    flex: 0 0 50%;
+    background: transparent;
+    padding: 5px;
+    border: 0;
+    position: relative;
+
+    &:hover,
+    &:focus,
+    &:active {
+      svg path:first-child {
+        fill: lighten($ui-base-color, 16%);
+      }
+    }
+  }
+
+  svg {
+    width: 100%;
+    height: auto;
+
+    path:first-child {
+      fill: lighten($ui-base-color, 12%);
+    }
+
+    path:last-child {
+      fill: darken($ui-base-color, 14%);
+    }
+  }
+
+  &__active {
+    color: $ui-highlight-color;
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+    background: lighten($ui-base-color, 12%);
+    border-radius: 50%;
+    padding: 0.35rem;
+  }
+}
diff --git a/app/javascript/styles/mastodon/containers.scss b/app/javascript/styles/mastodon/containers.scss
index a98fa52c47bb2b45b6f1c6fa8c9de4cf9cc5f8d3..3564bf07b4ddc96e1c6168b6e163cbf5736bd635 100644
--- a/app/javascript/styles/mastodon/containers.scss
+++ b/app/javascript/styles/mastodon/containers.scss
@@ -10,12 +10,10 @@
 }
 
 .logo-container {
-  margin: 100px auto;
-  margin-bottom: 50px;
+  margin: 100px auto 50px;
 
-  @media screen and (max-width: 400px) {
-    margin: 30px auto;
-    margin-bottom: 20px;
+  @media screen and (max-width: 500px) {
+    margin: 40px auto 0;
   }
 
   h1 {
@@ -23,7 +21,8 @@
     justify-content: center;
     align-items: center;
 
-    img {
+    svg {
+      fill: $primary-text-color;
       height: 42px;
       margin-right: 10px;
     }
@@ -123,7 +122,7 @@
   grid-auto-rows: max-content;
 
   .column-0 {
-    grid-column: 1/3;
+    grid-column: 1 / 3;
     grid-row: 1;
   }
 
@@ -138,7 +137,7 @@
   }
 
   .column-3 {
-    grid-column: 1/3;
+    grid-column: 1 / 3;
     grid-row: 3;
   }
 
@@ -258,12 +257,13 @@
       display: block;
       padding: 15px;
 
-      img {
+      svg {
         display: block;
         height: 18px;
         width: auto;
         position: relative;
         bottom: -2px;
+        fill: $primary-text-color;
 
         @media screen and (max-width: $no-gap-breakpoint) {
           height: 20px;
@@ -361,10 +361,6 @@
 
       .logo-button {
         background-color: $secondary-text-color;
-
-        svg path:last-child {
-          fill: $secondary-text-color;
-        }
       }
     }
 
@@ -677,6 +673,7 @@
           color: $darker-text-color;
           text-decoration: none;
           padding: 15px;
+          font-weight: 500;
 
           strong {
             font-weight: 700;
diff --git a/app/javascript/styles/mastodon/emoji_picker.scss b/app/javascript/styles/mastodon/emoji_picker.scss
index e49084b5f7f176b716855e33669e25b6646c8beb..4bfd665049410833c30406a9e089863aec302bd9 100644
--- a/app/javascript/styles/mastodon/emoji_picker.scss
+++ b/app/javascript/styles/mastodon/emoji_picker.scss
@@ -1,14 +1,14 @@
 .emoji-mart {
+  font-size: 13px;
+  display: inline-block;
+  color: $inverted-text-color;
+
   &,
   * {
     box-sizing: border-box;
     line-height: 1.15;
   }
 
-  font-size: 13px;
-  display: inline-block;
-  color: $inverted-text-color;
-
   .emoji-mart-emoji {
     padding: 6px;
   }
diff --git a/app/javascript/styles/mastodon/footer.scss b/app/javascript/styles/mastodon/footer.scss
index 4d75477e09b8786de6899deaa556d4e869a58938..f74c004e995994b30c89db4e2c1d2807eb1d04b7 100644
--- a/app/javascript/styles/mastodon/footer.scss
+++ b/app/javascript/styles/mastodon/footer.scss
@@ -122,10 +122,7 @@
         height: 36px;
         width: auto;
         margin: 0 auto;
-
-        path {
-          fill: lighten($ui-base-color, 34%);
-        }
+        fill: lighten($ui-base-color, 34%);
       }
 
       &:hover,
diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss
index bab982706fd5c53bd9469bf2e9f70663492e682c..456ee4e0d3d024ea068a75b7266df042bbff64c7 100644
--- a/app/javascript/styles/mastodon/forms.scss
+++ b/app/javascript/styles/mastodon/forms.scss
@@ -68,6 +68,23 @@ code {
         top: 2px;
         left: 0;
       }
+
+      label a {
+        color: $highlight-text-color;
+        text-decoration: underline;
+
+        &:hover,
+        &:active,
+        &:focus {
+          text-decoration: none;
+        }
+      }
+
+      .recommended {
+        position: absolute;
+        margin: 0 4px;
+        margin-top: -2px;
+      }
     }
   }
 
@@ -305,7 +322,7 @@ code {
       box-shadow: none;
     }
 
-    &:focus:invalid {
+    &:focus:invalid:not(:placeholder-shown) {
       border-color: lighten($error-red, 12%);
     }
 
@@ -346,6 +363,10 @@ code {
     }
   }
 
+  .input.disabled {
+    opacity: 0.5;
+  }
+
   .actions {
     margin-top: 30px;
     display: flex;
@@ -392,6 +413,10 @@ code {
       background-color: darken($ui-highlight-color, 5%);
     }
 
+    &:disabled:hover {
+      background-color: $ui-primary-color;
+    }
+
     &.negative {
       background: $error-value-color;
 
@@ -424,6 +449,10 @@ code {
     height: 41px;
   }
 
+  h4 {
+    margin-bottom: 15px !important;
+  }
+
   .label_input {
     &__wrapper {
       position: relative;
@@ -456,6 +485,42 @@ code {
       }
     }
   }
+
+  &__overlay-area {
+    position: relative;
+
+    &__overlay {
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      background: rgba($ui-base-color, 0.65);
+      backdrop-filter: blur(2px);
+      border-radius: 4px;
+
+      &__content {
+        text-align: center;
+
+        &.rich-formatting {
+          &,
+          p {
+            color: $primary-text-color;
+          }
+        }
+      }
+    }
+  }
+}
+
+.block-icon {
+  display: block;
+  margin: 0 auto;
+  margin-bottom: 10px;
+  font-size: 24px;
 }
 
 .flash-message {
@@ -478,6 +543,17 @@ code {
     color: $error-value-color;
   }
 
+  a {
+    display: inline-block;
+    color: $darker-text-color;
+    text-decoration: none;
+
+    &:hover {
+      color: $primary-text-color;
+      text-decoration: underline;
+    }
+  }
+
   p {
     margin-bottom: 15px;
   }
@@ -487,7 +563,7 @@ code {
     box-sizing: border-box;
     display: block;
     width: 100%;
-    border: none;
+    border: 0;
     padding: 10px;
     font-family: $font-monospace, monospace;
     background: $ui-base-color;
@@ -782,3 +858,65 @@ code {
     }
   }
 }
+
+.connection-prompt {
+  margin-bottom: 25px;
+
+  .fa-link {
+    background-color: darken($ui-base-color, 4%);
+    border-radius: 100%;
+    font-size: 24px;
+    padding: 10px;
+  }
+
+  &__column {
+    align-items: center;
+    display: flex;
+    flex: 1;
+    flex-direction: column;
+    flex-shrink: 1;
+    max-width: 50%;
+
+    &-sep {
+      align-self: center;
+      flex-grow: 0;
+      overflow: visible;
+      position: relative;
+      z-index: 1;
+    }
+
+    p {
+      word-break: break-word;
+    }
+  }
+
+  .account__avatar {
+    margin-bottom: 20px;
+  }
+
+  &__connection {
+    background-color: lighten($ui-base-color, 8%);
+    box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+    border-radius: 4px;
+    padding: 25px 10px;
+    position: relative;
+    text-align: center;
+
+    &::after {
+      background-color: darken($ui-base-color, 4%);
+      content: '';
+      display: block;
+      height: 100%;
+      left: 50%;
+      position: absolute;
+      top: 0;
+      width: 1px;
+    }
+  }
+
+  &__row {
+    align-items: flex-start;
+    display: flex;
+    flex-direction: row;
+  }
+}
diff --git a/app/javascript/styles/mastodon/polls.scss b/app/javascript/styles/mastodon/polls.scss
new file mode 100644
index 0000000000000000000000000000000000000000..12f57b7a9185c8a161b86dd3f04d4622e101be73
--- /dev/null
+++ b/app/javascript/styles/mastodon/polls.scss
@@ -0,0 +1,210 @@
+.poll {
+  margin-top: 16px;
+  font-size: 14px;
+
+  li {
+    margin-bottom: 10px;
+    position: relative;
+    height: 18px + 12px;
+  }
+
+  &__chart {
+    position: absolute;
+    top: 0;
+    left: 0;
+    height: 100%;
+    display: inline-block;
+    border-radius: 4px;
+    background: darken($ui-primary-color, 14%);
+
+    &.leading {
+      background: $ui-highlight-color;
+    }
+  }
+
+  &__text {
+    position: relative;
+    display: inline-block;
+    padding: 6px 0;
+    line-height: 18px;
+    cursor: default;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+
+    input[type=radio],
+    input[type=checkbox] {
+      display: none;
+    }
+
+    .autossugest-input {
+      flex: 1 1 auto;
+    }
+
+    input[type=text] {
+      display: block;
+      box-sizing: border-box;
+      width: 100%;
+      font-size: 14px;
+      color: $inverted-text-color;
+      outline: 0;
+      font-family: inherit;
+      background: $simple-background-color;
+      border: 1px solid darken($simple-background-color, 14%);
+      border-radius: 4px;
+      padding: 6px 10px;
+
+      &:focus {
+        border-color: $highlight-text-color;
+      }
+    }
+
+    &.selectable {
+      cursor: pointer;
+    }
+
+    &.editable {
+      display: flex;
+      align-items: center;
+      overflow: visible;
+    }
+  }
+
+  &__input {
+    display: inline-block;
+    position: relative;
+    border: 1px solid $ui-primary-color;
+    box-sizing: border-box;
+    width: 18px;
+    height: 18px;
+    flex: 0 0 auto;
+    margin-right: 10px;
+    top: -1px;
+    border-radius: 50%;
+    vertical-align: middle;
+
+    &.checkbox {
+      border-radius: 4px;
+    }
+
+    &.active {
+      border-color: $valid-value-color;
+      background: $valid-value-color;
+    }
+  }
+
+  &__number {
+    display: inline-block;
+    width: 36px;
+    font-weight: 700;
+    padding: 0 10px;
+    text-align: right;
+  }
+
+  &__footer {
+    padding-top: 6px;
+    padding-bottom: 5px;
+    color: $dark-text-color;
+  }
+
+  &__link {
+    display: inline;
+    background: transparent;
+    padding: 0;
+    margin: 0;
+    border: 0;
+    color: $dark-text-color;
+    text-decoration: underline;
+    font-size: inherit;
+
+    &:hover {
+      text-decoration: none;
+    }
+
+    &:active,
+    &:focus {
+      background-color: rgba($dark-text-color, .1);
+    }
+  }
+
+  .button {
+    height: 36px;
+    padding: 0 16px;
+    margin-right: 10px;
+    font-size: 14px;
+  }
+}
+
+.compose-form__poll-wrapper {
+  border-top: 1px solid darken($simple-background-color, 8%);
+
+  ul {
+    padding: 10px;
+  }
+
+  .poll__footer {
+    border-top: 1px solid darken($simple-background-color, 8%);
+    padding: 10px;
+    display: flex;
+    align-items: center;
+
+    button,
+    select {
+      flex: 1 1 50%;
+    }
+  }
+
+  .button.button-secondary {
+    font-size: 14px;
+    font-weight: 400;
+    padding: 6px 10px;
+    height: auto;
+    line-height: inherit;
+    color: $action-button-color;
+    border-color: $action-button-color;
+    margin-right: 5px;
+  }
+
+  li {
+    display: flex;
+    align-items: center;
+
+    .poll__text {
+      flex: 0 0 auto;
+      width: calc(100% - (23px + 6px));
+      margin-right: 6px;
+    }
+  }
+
+  select {
+    appearance: none;
+    box-sizing: border-box;
+    font-size: 14px;
+    color: $inverted-text-color;
+    display: inline-block;
+    width: auto;
+    outline: 0;
+    font-family: inherit;
+    background: $simple-background-color url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14.933 18.467' height='19.698' width='15.929'><path d='M3.467 14.967l-3.393-3.5H14.86l-3.392 3.5c-1.866 1.925-3.666 3.5-4 3.5-.335 0-2.135-1.575-4-3.5zm.266-11.234L7.467 0 11.2 3.733l3.733 3.734H0l3.733-3.734z' fill='#{hex-color(darken($simple-background-color, 14%))}'/></svg>") no-repeat right 8px center / auto 16px;
+    border: 1px solid darken($simple-background-color, 14%);
+    border-radius: 4px;
+    padding: 6px 10px;
+    padding-right: 30px;
+  }
+
+  .icon-button.disabled {
+    color: darken($simple-background-color, 14%);
+  }
+}
+
+.muted .poll {
+  color: $dark-text-color;
+
+  &__chart {
+    background: rgba(darken($ui-primary-color, 14%), 0.2);
+
+    &.leading {
+      background: rgba($ui-highlight-color, 0.2);
+    }
+  }
+}
diff --git a/app/javascript/styles/mastodon/reset.scss b/app/javascript/styles/mastodon/reset.scss
index e24ba8c1c015dff42f2acfd0f916cc8279b30931..f54ed5bc79b1a72231a695a6765931751d663c16 100644
--- a/app/javascript/styles/mastodon/reset.scss
+++ b/app/javascript/styles/mastodon/reset.scss
@@ -54,7 +54,7 @@ table {
 }
 
 html {
-  scrollbar-color: lighten($ui-base-color, 4%) transparent;
+  scrollbar-color: lighten($ui-base-color, 4%) rgba($base-overlay-background, 0.1);
 }
 
 ::-webkit-scrollbar {
diff --git a/app/javascript/styles/mastodon/rtl.scss b/app/javascript/styles/mastodon/rtl.scss
index 940dc8af298d529f66f3f420256bc9a1d6b5dba3..58bc53b141fe716e55195854544ef84b072dcaa8 100644
--- a/app/javascript/styles/mastodon/rtl.scss
+++ b/app/javascript/styles/mastodon/rtl.scss
@@ -43,6 +43,10 @@ body.rtl {
     left: 10px;
   }
 
+  .columns-area {
+    direction: rtl;
+  }
+
   .column-header__buttons {
     left: 0;
     right: auto;
@@ -180,7 +184,6 @@ body.rtl {
   }
 
   .fa-ul {
-    margin-left: 0;
     margin-left: 2.14285714em;
   }
 
diff --git a/app/javascript/styles/mastodon/stream_entries.scss b/app/javascript/styles/mastodon/stream_entries.scss
index d8bd30377286e1af43766e17eaccf0c8a6da55c4..19ce0ab8f06924409caa904f2df8b42151d6e2a1 100644
--- a/app/javascript/styles/mastodon/stream_entries.scss
+++ b/app/javascript/styles/mastodon/stream_entries.scss
@@ -4,6 +4,10 @@
   overflow: hidden;
   margin-bottom: 10px;
 
+  &--under-tabs {
+    border-radius: 0 0 4px 4px;
+  }
+
   @media screen and (max-width: $no-gap-breakpoint) {
     margin-bottom: 0;
     border-radius: 0;
@@ -89,23 +93,21 @@
     height: auto;
     vertical-align: middle;
     margin-right: 5px;
-
-    path:first-child {
-      fill: $primary-text-color;
-    }
-
-    path:last-child {
-      fill: $ui-highlight-color;
-    }
+    fill: $primary-text-color;
   }
 
   &:active,
   &:focus,
   &:hover {
     background: lighten($ui-highlight-color, 10%);
+  }
 
-    svg path:last-child {
-      fill: lighten($ui-highlight-color, 10%);
+  &:disabled,
+  &.disabled {
+    &:active,
+    &:focus,
+    &:hover {
+      background: $ui-primary-color;
     }
   }
 
@@ -114,10 +116,6 @@
     &:focus,
     &:hover {
       background: $error-red;
-
-      svg path:last-child {
-        fill: $error-red;
-      }
     }
   }
 
diff --git a/app/javascript/styles/mastodon/tables.scss b/app/javascript/styles/mastodon/tables.scss
index adb75afe5bdf3f361e8a5a14ce4542f084fd5844..11ac6dfeb1595ca2b325cfc0dd8a92224fc3c5d6 100644
--- a/app/javascript/styles/mastodon/tables.scss
+++ b/app/javascript/styles/mastodon/tables.scss
@@ -82,6 +82,10 @@
       }
     }
   }
+
+  &--invites tbody td {
+    vertical-align: middle;
+  }
 }
 
 .table-wrapper {
@@ -136,6 +140,19 @@ a.table-action-link {
       input {
         margin-top: 8px;
       }
+
+      &--aligned {
+        display: flex;
+        align-items: center;
+
+        input {
+          margin-top: 0;
+        }
+      }
+
+      @media screen and (max-width: $no-gap-breakpoint) {
+        display: none;
+      }
     }
 
     &__actions,
@@ -157,6 +174,10 @@ a.table-action-link {
       text-align: right;
       padding-right: 16px - 5px;
     }
+
+    @media screen and (max-width: $no-gap-breakpoint) {
+      display: none;
+    }
   }
 
   &__row {
@@ -164,6 +185,12 @@ a.table-action-link {
     border-top: 0;
     background: darken($ui-base-color, 4%);
 
+    @media screen and (max-width: $no-gap-breakpoint) {
+      &:first-child {
+        border-top: 1px solid darken($ui-base-color, 8%);
+      }
+    }
+
     &:hover {
       background: darken($ui-base-color, 2%);
     }
@@ -179,6 +206,10 @@ a.table-action-link {
     &__content {
       padding-top: 12px;
       padding-bottom: 16px;
+
+      &--unpadded {
+        padding: 0;
+      }
     }
   }
 
@@ -193,4 +224,20 @@ a.table-action-link {
       font-weight: 700;
     }
   }
+
+  .nothing-here {
+    border: 1px solid darken($ui-base-color, 8%);
+    border-top: 0;
+    box-shadow: none;
+
+    @media screen and (max-width: $no-gap-breakpoint) {
+      border-top: 1px solid darken($ui-base-color, 8%);
+    }
+  }
+
+  @media screen and (max-width: 870px) {
+    .accounts-table tbody td.optional {
+      display: none;
+    }
+  }
 }
diff --git a/app/javascript/styles/mastodon/widgets.scss b/app/javascript/styles/mastodon/widgets.scss
index c97337e4e3f77c837dd15b7a1f77df44133b92f6..acaf5b02404a7bdd0086e6560a24c337e97bcaf2 100644
--- a/app/javascript/styles/mastodon/widgets.scss
+++ b/app/javascript/styles/mastodon/widgets.scss
@@ -4,7 +4,6 @@
 
   &__img {
     width: 100%;
-    height: 167px;
     position: relative;
     overflow: hidden;
     border-radius: 4px 4px 0 0;
@@ -269,7 +268,8 @@
     box-sizing: border-box;
     margin-bottom: 10px;
 
-    a {
+    & > a,
+    & > div {
       display: flex;
       align-items: center;
       justify-content: space-between;
@@ -279,7 +279,9 @@
       text-decoration: none;
       color: inherit;
       box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
+    }
 
+    & > a {
       &:hover,
       &:active,
       &:focus {
@@ -287,11 +289,16 @@
       }
     }
 
-    &.active a {
+    &.active > a {
       background: $ui-highlight-color;
       cursor: default;
     }
 
+    &.disabled > div {
+      opacity: 0.5;
+      cursor: default;
+    }
+
     h4 {
       flex: 1 1 auto;
       font-size: 18px;
@@ -344,6 +351,7 @@
     border-radius: 50%;
     position: relative;
     margin-left: -10px;
+    background: darken($ui-base-color, 8%);
     border: 2px solid $ui-base-color;
 
     &:nth-child(1) {
@@ -368,6 +376,10 @@
     border: 0;
   }
 
+  strong {
+    font-weight: 700;
+  }
+
   thead th {
     text-align: center;
     text-transform: uppercase;
@@ -405,6 +417,11 @@
     }
   }
 
+  &__comment {
+    width: 50%;
+    vertical-align: initial !important;
+  }
+
   @media screen and (max-width: $no-gap-breakpoint) {
     tbody td.optional {
       display: none;
diff --git a/app/lib/activity_tracker.rb b/app/lib/activity_tracker.rb
index 5b497267477aff862a5e18e759841608f5e82ba2..ae3c11b6af5c99e6f852f2ac8d284218839184ed 100644
--- a/app/lib/activity_tracker.rb
+++ b/app/lib/activity_tracker.rb
@@ -4,6 +4,8 @@ class ActivityTracker
   EXPIRE_AFTER = 90.days.seconds
 
   class << self
+    include Redisable
+
     def increment(prefix)
       key = [prefix, current_week].join(':')
 
@@ -20,10 +22,6 @@ class ActivityTracker
 
     private
 
-    def redis
-      Redis.current
-    end
-
     def current_week
       Time.zone.today.cweek
     end
diff --git a/app/lib/activitypub/activity.rb b/app/lib/activitypub/activity.rb
index 87318fb1c5c33b9fb977e285b4cac5f9a082e7bf..66b5763a9cf5df8af0bc908cc36d1e80291ee144 100644
--- a/app/lib/activitypub/activity.rb
+++ b/app/lib/activitypub/activity.rb
@@ -2,6 +2,10 @@
 
 class ActivityPub::Activity
   include JsonLdHelper
+  include Redisable
+
+  SUPPORTED_TYPES = %w(Note Question).freeze
+  CONVERTED_TYPES = %w(Image Video Article Page).freeze
 
   def initialize(json, account, **options)
     @json    = json
@@ -70,8 +74,16 @@ class ActivityPub::Activity
     @object_uri ||= value_or_id(@object)
   end
 
-  def redis
-    Redis.current
+  def unsupported_object_type?
+    @object.is_a?(String) || !(supported_object_type? || converted_object_type?)
+  end
+
+  def supported_object_type?
+    equals_or_includes_any?(@object['type'], SUPPORTED_TYPES)
+  end
+
+  def converted_object_type?
+    equals_or_includes_any?(@object['type'], CONVERTED_TYPES)
   end
 
   def distribute(status)
@@ -123,6 +135,24 @@ class ActivityPub::Activity
     redis.setex("delete_upon_arrival:#{@account.id}:#{uri}", 6.hours.seconds, uri)
   end
 
+  def status_from_object
+    # If the status is already known, return it
+    status = status_from_uri(object_uri)
+
+    return status unless status.nil?
+
+    # If the boosted toot is embedded and it is a self-boost, handle it like a Create
+    unless unsupported_object_type?
+      actor_id = value_or_id(first_of_value(@object['attributedTo']))
+
+      if actor_id == @account.uri
+        return ActivityPub::Activity.factory({ 'type' => 'Create', 'actor' => actor_id, 'object' => @object }, @account).perform
+      end
+    end
+
+    fetch_remote_original_status
+  end
+
   def fetch_remote_original_status
     if object_uri.start_with?('http')
       return if ActivityPub::TagManager.instance.local_uri?(object_uri)
@@ -137,4 +167,21 @@ class ActivityPub::Activity
   ensure
     redis.del(key)
   end
+
+  def fetch?
+    !@options[:delivery]
+  end
+
+  def followed_by_local_accounts?
+    @account.passive_relationships.exists?
+  end
+
+  def requested_through_relay?
+    @options[:relayed_through_account] && Relay.find_by(inbox_url: @options[:relayed_through_account].inbox_url)&.enabled?
+  end
+
+  def reject_payload!
+    Rails.logger.info("Rejected #{@json['type']} activity #{@json['id']} from #{@account.uri}#{@options[:relayed_through_account] && "via #{@options[:relayed_through_account].uri}"}")
+    nil
+  end
 end
diff --git a/app/lib/activitypub/activity/announce.rb b/app/lib/activitypub/activity/announce.rb
index 34d1b7cbd0fe1f04f1a5fda453f1f95056e9a6a2..1aa6ee9ec2dd72679488bc92994cefc0e5ac8d9f 100644
--- a/app/lib/activitypub/activity/announce.rb
+++ b/app/lib/activitypub/activity/announce.rb
@@ -2,10 +2,11 @@
 
 class ActivityPub::Activity::Announce < ActivityPub::Activity
   def perform
-    original_status   = status_from_uri(object_uri)
-    original_status ||= fetch_remote_original_status
+    return reject_payload! if delete_arrived_first?(@json['id']) || !related_to_local_activity?
 
-    return if original_status.nil? || delete_arrived_first?(@json['id']) || !announceable?(original_status)
+    original_status = status_from_object
+
+    return reject_payload! if original_status.nil? || !announceable?(original_status)
 
     status = Status.find_by(account: @account, reblog: original_status)
 
@@ -41,4 +42,16 @@ class ActivityPub::Activity::Announce < ActivityPub::Activity
   def announceable?(status)
     status.account_id == @account.id || status.public_visibility? || status.unlisted_visibility?
   end
+
+  def related_to_local_activity?
+    followed_by_local_accounts? || requested_through_relay? || reblog_of_local_status?
+  end
+
+  def requested_through_relay?
+    super || Relay.find_by(inbox_url: @account.inbox_url)&.enabled?
+  end
+
+  def reblog_of_local_status?
+    status_from_uri(object_uri)&.account&.local?
+  end
 end
diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb
index b49657d4b14625238630ae3b2c07956f90a6225e..00f0dd42d7ba3817b788052b8820d1a98279561b 100644
--- a/app/lib/activitypub/activity/create.rb
+++ b/app/lib/activitypub/activity/create.rb
@@ -1,16 +1,12 @@
 # frozen_string_literal: true
 
 class ActivityPub::Activity::Create < ActivityPub::Activity
-  SUPPORTED_TYPES = %w(Note).freeze
-  CONVERTED_TYPES = %w(Image Video Article Page).freeze
-
   def perform
-    return if unsupported_object_type? || invalid_origin?(@object['id'])
-    return if Tombstone.exists?(uri: @object['id'])
+    return reject_payload! if unsupported_object_type? || invalid_origin?(@object['id']) || Tombstone.exists?(uri: @object['id']) || !related_to_local_activity?
 
     RedisLock.acquire(lock_options) do |lock|
       if lock.acquired?
-        return if delete_arrived_first?(object_uri)
+        return if delete_arrived_first?(object_uri) || poll_vote?
 
         @status = find_existing_status
 
@@ -44,6 +40,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
     end
 
     resolve_thread(@status)
+    fetch_replies(@status)
     distribute(@status)
     forward_for_reply if @status.public_visibility? || @status.unlisted_visibility?
   end
@@ -71,6 +68,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
         thread: replied_to_status,
         conversation: conversation_from_uri(@object['conversation']),
         media_attachment_ids: process_attachments.take(4).map(&:id),
+        poll: process_poll,
       }
     end
   end
@@ -163,7 +161,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
     return if tag['href'].blank?
 
     account = account_from_uri(tag['href'])
-    account = ::FetchRemoteAccountService.new.call(tag['href'], id: false) if account.nil?
+    account = ::FetchRemoteAccountService.new.call(tag['href']) if account.nil?
 
     return if account.nil?
 
@@ -196,7 +194,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
       next if attachment['url'].blank?
 
       href             = Addressable::URI.parse(attachment['url']).normalize.to_s
-      media_attachment = MediaAttachment.create(account: @account, remote_url: href, description: attachment['name'].presence, focus: attachment['focalPoint'])
+      media_attachment = MediaAttachment.create(account: @account, remote_url: href, description: attachment['name'].presence, focus: attachment['focalPoint'], blurhash: supported_blurhash?(attachment['blurhash']) ? attachment['blurhash'] : nil)
       media_attachments << media_attachment
 
       next if unsupported_media_type?(attachment['mediaType']) || skip_download?
@@ -212,15 +210,68 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
     media_attachments
   end
 
+  def process_poll
+    return unless @object['type'] == 'Question' && (@object['anyOf'].is_a?(Array) || @object['oneOf'].is_a?(Array))
+
+    expires_at = begin
+      if @object['closed'].is_a?(String)
+        @object['closed']
+      elsif !@object['closed'].nil? && !@object['closed'].is_a?(FalseClass)
+        Time.now.utc
+      else
+        @object['endTime']
+      end
+    end
+
+    if @object['anyOf'].is_a?(Array)
+      multiple = true
+      items    = @object['anyOf']
+    else
+      multiple = false
+      items    = @object['oneOf']
+    end
+
+    @account.polls.new(
+      multiple: multiple,
+      expires_at: expires_at,
+      options: items.map { |item| item['name'].presence || item['content'] }.compact,
+      cached_tallies: items.map { |item| item.dig('replies', 'totalItems') || 0 }
+    )
+  end
+
+  def poll_vote?
+    return false if replied_to_status.nil? || replied_to_status.preloadable_poll.nil? || !replied_to_status.local? || !replied_to_status.preloadable_poll.options.include?(@object['name'])
+
+    unless replied_to_status.preloadable_poll.expired?
+      replied_to_status.preloadable_poll.votes.create!(account: @account, choice: replied_to_status.preloadable_poll.options.index(@object['name']), uri: @object['id'])
+      ActivityPub::DistributePollUpdateWorker.perform_in(3.minutes, replied_to_status.id) unless replied_to_status.preloadable_poll.hide_totals?
+    end
+
+    true
+  end
+
   def resolve_thread(status)
     return unless status.reply? && status.thread.nil? && Request.valid_url?(in_reply_to_uri)
     ThreadResolveWorker.perform_async(status.id, in_reply_to_uri)
   end
 
+  def fetch_replies(status)
+    collection = @object['replies']
+    return if collection.nil?
+    replies = ActivityPub::FetchRepliesService.new.call(status, collection, false)
+    return unless replies.nil?
+    uri = value_or_id(collection)
+    ActivityPub::FetchRepliesWorker.perform_async(status.id, uri) unless uri.nil?
+  end
+
   def conversation_from_uri(uri)
     return nil if uri.nil?
     return Conversation.find_by(id: OStatus::TagManager.instance.unique_tag_to_local_id(uri, 'Conversation')) if OStatus::TagManager.instance.local_id?(uri)
-    Conversation.find_by(uri: uri) || Conversation.create(uri: uri)
+    begin
+      Conversation.find_or_create_by!(uri: uri)
+    rescue ActiveRecord::RecordInvalid, ActiveRecord::RecordNotUnique
+      retry
+    end
   end
 
   def visibility_from_audience
@@ -318,38 +369,41 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
     @object['nameMap'].is_a?(Hash) && !@object['nameMap'].empty?
   end
 
-  def unsupported_object_type?
-    @object.is_a?(String) || !(supported_object_type? || converted_object_type?)
-  end
-
   def unsupported_media_type?(mime_type)
-    mime_type.present? && !(MediaAttachment::IMAGE_MIME_TYPES + MediaAttachment::VIDEO_MIME_TYPES).include?(mime_type)
-  end
-
-  def supported_object_type?
-    equals_or_includes_any?(@object['type'], SUPPORTED_TYPES)
+    mime_type.present? && !MediaAttachment.supported_mime_types.include?(mime_type)
   end
 
-  def converted_object_type?
-    equals_or_includes_any?(@object['type'], CONVERTED_TYPES)
+  def supported_blurhash?(blurhash)
+    components = blurhash.blank? ? nil : Blurhash.components(blurhash)
+    components.present? && components.none? { |comp| comp > 5 }
   end
 
   def skip_download?
     return @skip_download if defined?(@skip_download)
-    @skip_download ||= DomainBlock.find_by(domain: @account.domain)&.reject_media?
+    @skip_download ||= DomainBlock.reject_media?(@account.domain)
   end
 
-  def invalid_origin?(url)
-    return true if unsupported_uri_scheme?(url)
+  def reply_to_local?
+    !replied_to_status.nil? && replied_to_status.account.local?
+  end
 
-    needle   = Addressable::URI.parse(url).host
-    haystack = Addressable::URI.parse(@account.uri).host
+  def related_to_local_activity?
+    fetch? || followed_by_local_accounts? || requested_through_relay? ||
+      responds_to_followed_account? || addresses_local_accounts?
+  end
 
-    !haystack.casecmp(needle).zero?
+  def responds_to_followed_account?
+    !replied_to_status.nil? && (replied_to_status.account.local? || replied_to_status.account.passive_relationships.exists?)
   end
 
-  def reply_to_local?
-    !replied_to_status.nil? && replied_to_status.account.local?
+  def addresses_local_accounts?
+    return true if @options[:delivered_to_account_id]
+
+    local_usernames = (as_array(@object['to']) + as_array(@object['cc'])).uniq.select { |uri| ActivityPub::TagManager.instance.local_uri?(uri) }.map { |uri| ActivityPub::TagManager.instance.uri_to_local_id(uri, :username) }
+
+    return false if local_usernames.empty?
+
+    Account.local.where(username: local_usernames).exists?
   end
 
   def forward_for_reply
diff --git a/app/lib/activitypub/activity/delete.rb b/app/lib/activitypub/activity/delete.rb
index dc76dd3e222ca3e8fd07816d4df4c8530f038121..0eb14b89cef4383dc59e9f0c8884388d39e1a84a 100644
--- a/app/lib/activitypub/activity/delete.rb
+++ b/app/lib/activitypub/activity/delete.rb
@@ -45,7 +45,7 @@ class ActivityPub::Activity::Delete < ActivityPub::Activity
     rebloggers_ids = @status.reblogs.includes(:account).references(:account).merge(Account.local).pluck(:account_id)
     inboxes        = Account.where(id: ::Follow.where(target_account_id: rebloggers_ids).select(:account_id)).inboxes - [@account.preferred_inbox_url]
 
-    ActivityPub::DeliveryWorker.push_bulk(inboxes) do |inbox_url|
+    ActivityPub::LowPriorityDeliveryWorker.push_bulk(inboxes) do |inbox_url|
       [payload, rebloggers_ids.first, inbox_url]
     end
   end
@@ -61,7 +61,12 @@ class ActivityPub::Activity::Delete < ActivityPub::Activity
 
   def forward_for_reply
     return unless @json['signature'].present? && reply_to_local?
-    ActivityPub::RawDistributionWorker.perform_async(Oj.dump(@json), replied_to_status.account_id, [@account.preferred_inbox_url])
+
+    inboxes = replied_to_status.account.followers.inboxes - [@account.preferred_inbox_url]
+
+    ActivityPub::LowPriorityDeliveryWorker.push_bulk(inboxes) do |inbox_url|
+      [payload, replied_to_status.account_id, inbox_url]
+    end
   end
 
   def delete_now!
@@ -75,13 +80,4 @@ class ActivityPub::Activity::Delete < ActivityPub::Activity
   def lock_options
     { redis: Redis.current, key: "create:#{object_uri}" }
   end
-
-  def invalid_origin?(url)
-    return true if unsupported_uri_scheme?(url)
-
-    needle   = Addressable::URI.parse(url).host
-    haystack = Addressable::URI.parse(@account.uri).host
-
-    !haystack.casecmp(needle).zero?
-  end
 end
diff --git a/app/lib/activitypub/activity/flag.rb b/app/lib/activitypub/activity/flag.rb
index 0d10d6c3c93557fcab03cf387975c346eae4a750..1659bc61fe52676ed66977ed93121a8a671282f6 100644
--- a/app/lib/activitypub/activity/flag.rb
+++ b/app/lib/activitypub/activity/flag.rb
@@ -14,7 +14,8 @@ class ActivityPub::Activity::Flag < ActivityPub::Activity
         @account,
         target_account,
         status_ids: target_statuses.nil? ? [] : target_statuses.map(&:id),
-        comment: @json['content'] || ''
+        comment: @json['content'] || '',
+        uri: report_uri
       )
     end
   end
@@ -22,10 +23,14 @@ class ActivityPub::Activity::Flag < ActivityPub::Activity
   private
 
   def skip_reports?
-    DomainBlock.find_by(domain: @account.domain)&.reject_reports?
+    DomainBlock.reject_reports?(@account.domain)
   end
 
   def object_uris
     @object_uris ||= Array(@object.is_a?(Array) ? @object.map { |item| value_or_id(item) } : value_or_id(@object))
   end
+
+  def report_uri
+    @json['id'] unless @json['id'].nil? || invalid_origin?(@json['id'])
+  end
 end
diff --git a/app/lib/activitypub/activity/follow.rb b/app/lib/activitypub/activity/follow.rb
index 1e805c0d1758fa4349ff89de051b2cc3f66a0afe..3eb88339aebaa6cf4abbd0c4e857a00a06ebe52a 100644
--- a/app/lib/activitypub/activity/follow.rb
+++ b/app/lib/activitypub/activity/follow.rb
@@ -1,6 +1,8 @@
 # frozen_string_literal: true
 
 class ActivityPub::Activity::Follow < ActivityPub::Activity
+  include Payloadable
+
   def perform
     target_account = account_from_uri(object_uri)
 
@@ -28,7 +30,7 @@ class ActivityPub::Activity::Follow < ActivityPub::Activity
   end
 
   def reject_follow_request!(target_account)
-    json = ActiveModelSerializers::SerializableResource.new(FollowRequest.new(account: @account, target_account: target_account, uri: @json['id']), serializer: ActivityPub::RejectFollowSerializer, adapter: ActivityPub::Adapter).to_json
+    json = Oj.dump(serialize_payload(FollowRequest.new(account: @account, target_account: target_account, uri: @json['id']), ActivityPub::RejectFollowSerializer))
     ActivityPub::DeliveryWorker.perform_async(json, target_account.id, @account.inbox_url)
   end
 end
diff --git a/app/lib/activitypub/activity/update.rb b/app/lib/activitypub/activity/update.rb
index 67dae3f81388a87c6ebfee0d54c6a4334ecfaa21..70035325b65b4dfc02307db5ceceb0df33281ef7 100644
--- a/app/lib/activitypub/activity/update.rb
+++ b/app/lib/activitypub/activity/update.rb
@@ -4,7 +4,11 @@ class ActivityPub::Activity::Update < ActivityPub::Activity
   SUPPORTED_TYPES = %w(Application Group Organization Person Service).freeze
 
   def perform
-    update_account if equals_or_includes_any?(@object['type'], SUPPORTED_TYPES)
+    if equals_or_includes_any?(@object['type'], SUPPORTED_TYPES)
+      update_account
+    elsif equals_or_includes_any?(@object['type'], %w(Question))
+      update_poll
+    end
   end
 
   private
@@ -14,4 +18,13 @@ class ActivityPub::Activity::Update < ActivityPub::Activity
 
     ActivityPub::ProcessAccountService.new.call(@account.username, @account.domain, @object, signed_with_known_key: true)
   end
+
+  def update_poll
+    return reject_payload! if invalid_origin?(@object['id'])
+
+    status = Status.find_by(uri: object_uri, account_id: @account.id)
+    return if status.nil? || status.preloadable_poll.nil?
+
+    ActivityPub::ProcessPollService.new.call(status.preloadable_poll, @object)
+  end
 end
diff --git a/app/lib/activitypub/adapter.rb b/app/lib/activitypub/adapter.rb
index 99f4d93055403d39b8ebfb7e1b9d7eea861c08e5..c259c96f410fb87c531656c3c6a586f4e985867d 100644
--- a/app/lib/activitypub/adapter.rb
+++ b/app/lib/activitypub/adapter.rb
@@ -1,30 +1,25 @@
 # frozen_string_literal: true
 
 class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base
-  CONTEXT = {
-    '@context': [
-      'https://www.w3.org/ns/activitystreams',
-      'https://w3id.org/security/v1',
-
-      {
-        'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers',
-        'sensitive'                 => 'as:sensitive',
-        'movedTo'                   => { '@id' => 'as:movedTo', '@type' => '@id' },
-        'alsoKnownAs'               => { '@id' => 'as:alsoKnownAs', '@type' => '@id' },
-        'Hashtag'                   => 'as:Hashtag',
-        'ostatus'                   => 'http://ostatus.org#',
-        'atomUri'                   => 'ostatus:atomUri',
-        'inReplyToAtomUri'          => 'ostatus:inReplyToAtomUri',
-        'conversation'              => 'ostatus:conversation',
-        'toot'                      => 'http://joinmastodon.org/ns#',
-        'Emoji'                     => 'toot:Emoji',
-        'focalPoint'                => { '@container' => '@list', '@id' => 'toot:focalPoint' },
-        'featured'                  => { '@id' => 'toot:featured', '@type' => '@id' },
-        'schema'                    => 'http://schema.org#',
-        'PropertyValue'             => 'schema:PropertyValue',
-        'value'                     => 'schema:value',
-      },
-    ],
+  NAMED_CONTEXT_MAP = {
+    activitystreams: 'https://www.w3.org/ns/activitystreams',
+    security: 'https://w3id.org/security/v1',
+  }.freeze
+
+  CONTEXT_EXTENSION_MAP = {
+    manually_approves_followers: { 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers' },
+    sensitive: { 'sensitive' => 'as:sensitive' },
+    hashtag: { 'Hashtag' => 'as:Hashtag' },
+    moved_to: { 'movedTo' => { '@id' => 'as:movedTo', '@type' => '@id' } },
+    also_known_as: { 'alsoKnownAs' => { '@id' => 'as:alsoKnownAs', '@type' => '@id' } },
+    emoji: { 'toot' => 'http://joinmastodon.org/ns#', 'Emoji' => 'toot:Emoji' },
+    featured: { 'toot' => 'http://joinmastodon.org/ns#', 'featured' => { '@id' => 'toot:featured', '@type' => '@id' } },
+    property_value: { 'schema' => 'http://schema.org#', 'PropertyValue' => 'schema:PropertyValue', 'value' => 'schema:value' },
+    atom_uri: { 'ostatus' => 'http://ostatus.org#', 'atomUri' => 'ostatus:atomUri' },
+    conversation: { 'ostatus' => 'http://ostatus.org#', 'inReplyToAtomUri' => 'ostatus:inReplyToAtomUri', 'conversation' => 'ostatus:conversation' },
+    focal_point: { 'toot' => 'http://joinmastodon.org/ns#', 'focalPoint' => { '@container' => '@list', '@id' => 'toot:focalPoint' } },
+    identity_proof: { 'toot' => 'http://joinmastodon.org/ns#', 'IdentityProof' => 'toot:IdentityProof' },
+    blurhash: { 'toot' => 'http://joinmastodon.org/ns#', 'blurhash' => 'toot:blurhash' },
   }.freeze
 
   def self.default_key_transform
@@ -36,8 +31,36 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base
   end
 
   def serializable_hash(options = nil)
-    options = serialization_options(options)
-    serialized_hash = ActiveModelSerializers::Adapter::Attributes.new(serializer, instance_options).serializable_hash(options)
-    CONTEXT.merge(self.class.transform_key_casing!(serialized_hash, instance_options))
+    options         = serialization_options(options)
+    serialized_hash = serializer.serializable_hash(options)
+    serialized_hash = self.class.transform_key_casing!(serialized_hash, instance_options)
+
+    { '@context' => serialized_context }.merge(serialized_hash)
+  end
+
+  private
+
+  def serialized_context
+    context_array = []
+
+    serializer_options = serializer.send(:instance_options) || {}
+    named_contexts     = [:activitystreams] + serializer._named_contexts.keys + serializer_options.fetch(:named_contexts, {}).keys
+    context_extensions = serializer._context_extensions.keys + serializer_options.fetch(:context_extensions, {}).keys
+
+    named_contexts.each do |key|
+      context_array << NAMED_CONTEXT_MAP[key]
+    end
+
+    extensions = context_extensions.each_with_object({}) do |key, h|
+      h.merge!(CONTEXT_EXTENSION_MAP[key])
+    end
+
+    context_array << extensions unless extensions.empty?
+
+    if context_array.size == 1
+      context_array.first
+    else
+      context_array
+    end
   end
 end
diff --git a/app/lib/activitypub/serializer.rb b/app/lib/activitypub/serializer.rb
new file mode 100644
index 0000000000000000000000000000000000000000..07bd8c494612e2117d3d1dd55fc34cd9953ced9b
--- /dev/null
+++ b/app/lib/activitypub/serializer.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+class ActivityPub::Serializer < ActiveModel::Serializer
+  with_options instance_writer: false, instance_reader: true do |serializer|
+    serializer.class_attribute :_named_contexts
+    serializer.class_attribute :_context_extensions
+
+    self._named_contexts     ||= {}
+    self._context_extensions ||= {}
+  end
+
+  def self.inherited(base)
+    super
+
+    base._named_contexts     = _named_contexts.dup
+    base._context_extensions = _context_extensions.dup
+  end
+
+  def self.context(*named_contexts)
+    named_contexts.each do |context|
+      _named_contexts[context] = true
+    end
+  end
+
+  def self.context_extensions(*extension_names)
+    extension_names.each do |extension_name|
+      _context_extensions[extension_name] = true
+    end
+  end
+end
diff --git a/app/lib/activitypub/tag_manager.rb b/app/lib/activitypub/tag_manager.rb
index be3a562d00cdf46ec9b758f42389016673cddcc7..595291342a361ea583adc5cfc9e4b19450c42c42 100644
--- a/app/lib/activitypub/tag_manager.rb
+++ b/app/lib/activitypub/tag_manager.rb
@@ -48,6 +48,12 @@ class ActivityPub::TagManager
     activity_account_status_url(target.account, target)
   end
 
+  def replies_uri_for(target, page_params = nil)
+    raise ArgumentError, 'target must be a local activity' unless %i(note comment activity).include?(target.object_type) && target.local?
+
+    replies_account_status_url(target.account, target, page_params)
+  end
+
   # Primary audience of a status
   # Public statuses go out to primarily the public collection
   # Unlisted and private statuses go out primarily to the followers collection
@@ -59,7 +65,14 @@ class ActivityPub::TagManager
     when 'unlisted', 'private'
       [account_followers_url(status.account)]
     when 'direct', 'limited'
-      status.active_mentions.map { |mention| uri_for(mention.account) }
+      if status.account.silenced?
+        # Only notify followers if the account is locally silenced
+        account_ids = status.active_mentions.pluck(:account_id)
+        to = status.account.followers.where(id: account_ids).map { |account| uri_for(account) }
+        to.concat(FollowRequest.where(target_account_id: status.account_id, account_id: account_ids).map { |request| uri_for(request.account) })
+      else
+        status.active_mentions.map { |mention| uri_for(mention.account) }
+      end
     end
   end
 
@@ -80,7 +93,16 @@ class ActivityPub::TagManager
       cc << COLLECTIONS[:public]
     end
 
-    cc.concat(status.active_mentions.map { |mention| uri_for(mention.account) }) unless status.direct_visibility? || status.limited_visibility?
+    unless status.direct_visibility? || status.limited_visibility?
+      if status.account.silenced?
+        # Only notify followers if the account is locally silenced
+        account_ids = status.active_mentions.pluck(:account_id)
+        cc.concat(status.account.followers.where(id: account_ids).map { |account| uri_for(account) })
+        cc.concat(FollowRequest.where(target_account_id: status.account_id, account_id: account_ids).map { |request| uri_for(request.account) })
+      else
+        cc.concat(status.active_mentions.map { |mention| uri_for(mention.account) })
+      end
+    end
 
     cc
   end
diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb
index f99df33e54f0d2d61104a8bbc1029008eb3f5b0d..ca3d890a813f7a503a38762ace96313f966131eb 100644
--- a/app/lib/feed_manager.rb
+++ b/app/lib/feed_manager.rb
@@ -4,6 +4,7 @@ require 'singleton'
 
 class FeedManager
   include Singleton
+  include Redisable
 
   MAX_ITEMS = 400
 
@@ -34,8 +35,8 @@ class FeedManager
   end
 
   def unpush_from_home(account, status)
-    return false unless remove_from_feed(:home, account.id, status)
-    Redis.current.publish("timeline:#{account.id}", Oj.dump(event: :delete, payload: status.id.to_s))
+    return false unless remove_from_feed(:home, account.id, status, account.user&.aggregates_reblogs?)
+    redis.publish("timeline:#{account.id}", Oj.dump(event: :delete, payload: status.id.to_s))
     true
   end
 
@@ -52,8 +53,8 @@ class FeedManager
   end
 
   def unpush_from_list(list, status)
-    return false unless remove_from_feed(:list, list.id, status)
-    Redis.current.publish("timeline:list:#{list.id}", Oj.dump(event: :delete, payload: status.id.to_s))
+    return false unless remove_from_feed(:list, list.id, status, list.account.user&.aggregates_reblogs?)
+    redis.publish("timeline:list:#{list.id}", Oj.dump(event: :delete, payload: status.id.to_s))
     true
   end
 
@@ -104,7 +105,7 @@ class FeedManager
     oldest_home_score = redis.zrange(timeline_key, 0, 0, with_scores: true)&.first&.last&.to_i || 0
 
     from_account.statuses.select('id, reblog_of_id').where('id > ?', oldest_home_score).reorder(nil).find_each do |status|
-      remove_from_feed(:home, into_account.id, status)
+      remove_from_feed(:home, into_account.id, status, into_account.user&.aggregates_reblogs?)
     end
   end
 
@@ -142,10 +143,6 @@ class FeedManager
 
   private
 
-  def redis
-    Redis.current
-  end
-
   def push_update_required?(timeline_id)
     redis.exists("subscribed:#{timeline_id}")
   end
@@ -223,7 +220,8 @@ class FeedManager
     status         = status.reblog if status.reblog?
 
     !combined_regex.match(Formatter.instance.plaintext(status)).nil? ||
-      (status.spoiler_text.present? && !combined_regex.match(status.spoiler_text).nil?)
+      (status.spoiler_text.present? && !combined_regex.match(status.spoiler_text).nil?) ||
+      (status.preloadable_poll && !combined_regex.match(status.preloadable_poll.options.join("\n\n")).nil?)
   end
 
   # Adds a status to an account's feed, returning true if a status was
@@ -277,10 +275,11 @@ class FeedManager
   # with reblogs, and returning true if a status was removed. As with
   # `add_to_feed`, this does not trigger push updates, so callers must
   # do so if appropriate.
-  def remove_from_feed(timeline_type, account_id, status)
+  def remove_from_feed(timeline_type, account_id, status, aggregate_reblogs = true)
     timeline_key = key(timeline_type, account_id)
+    reblog_key   = key(timeline_type, account_id, 'reblogs')
 
-    if status.reblog?
+    if status.reblog? && (aggregate_reblogs.nil? || aggregate_reblogs)
       # 1. If the reblogging status is not in the feed, stop.
       status_rank = redis.zrevrank(timeline_key, status.id)
       return false if status_rank.nil?
@@ -289,6 +288,7 @@ class FeedManager
       reblog_set_key = key(timeline_type, account_id, "reblogs:#{status.reblog_of_id}")
 
       redis.srem(reblog_set_key, status.id)
+      redis.zrem(reblog_key, status.reblog_of_id)
       # 3. Re-insert another reblog or original into the feed if one
       # remains in the set. We could pick a random element, but this
       # set should generally be small, and it seems ideal to show the
@@ -296,12 +296,14 @@ class FeedManager
       other_reblog = redis.smembers(reblog_set_key).map(&:to_i).min
 
       redis.zadd(timeline_key, other_reblog, other_reblog) if other_reblog
+      redis.zadd(reblog_key, other_reblog, status.reblog_of_id) if other_reblog
 
       # 4. Remove the reblogging status from the feed (as normal)
       # (outside conditional)
     else
       # If the original is getting deleted, no use for reblog references
       redis.del(key(timeline_type, account_id, "reblogs:#{status.id}"))
+      redis.zrem(reblog_key, status.id)
     end
 
     redis.zrem(timeline_key, status.id)
diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb
index 05fd9eeb1261abeeb9bcbb1dbc046c5a385f9cfd..6b5a8563ad829dcd883b01454d90fdb467af3300 100644
--- a/app/lib/formatter.rb
+++ b/app/lib/formatter.rb
@@ -19,6 +19,10 @@ class Formatter
 
     raw_content = status.text
 
+    if options[:inline_poll_options] && status.preloadable_poll
+      raw_content = raw_content + "\n\n" + status.preloadable_poll.options.map { |title| "[ ] #{title}" }.join("\n")
+    end
+
     return '' if raw_content.blank?
 
     unless status.local?
@@ -67,6 +71,12 @@ class Formatter
     html.html_safe # rubocop:disable Rails/OutputSafety
   end
 
+  def format_poll_option(status, option, **options)
+    html = encode(option.title)
+    html = encode_custom_emojis(html, status.emojis, options[:autoplay])
+    html.html_safe # rubocop:disable Rails/OutputSafety
+  end
+
   def format_display_name(account, **options)
     html = encode(account.display_name.presence || account.username)
     html = encode_custom_emojis(html, account.emojis, options[:autoplay]) if options[:custom_emojify]
@@ -99,7 +109,7 @@ class Formatter
   end
 
   def encode_and_link_urls(html, accounts = nil, options = {})
-    entities = Extractor.extract_entities_with_indices(html, extract_url_without_protocol: false)
+    entities = utf8_friendly_extractor(html, extract_url_without_protocol: false)
 
     if accounts.is_a?(Hash)
       options  = accounts
@@ -127,11 +137,7 @@ class Formatter
   def encode_custom_emojis(html, emojis, animate = false)
     return html if emojis.empty?
 
-    emoji_map = if animate
-                  emojis.each_with_object({}) { |e, h| h[e.shortcode] = full_asset_url(e.image.url) }
-                else
-                  emojis.each_with_object({}) { |e, h| h[e.shortcode] = full_asset_url(e.image.url(:static)) }
-                end
+    emoji_map = emojis.each_with_object({}) { |e, h| h[e.shortcode] = [full_asset_url(e.image.url), full_asset_url(e.image.url(:static))] }
 
     i                     = -1
     tag_open_index        = nil
@@ -147,7 +153,14 @@ class Formatter
         emoji     = emoji_map[shortcode]
 
         if emoji
-          replacement = "<img draggable=\"false\" class=\"emojione\" alt=\":#{encode(shortcode)}:\" title=\":#{encode(shortcode)}:\" src=\"#{encode(emoji)}\" />"
+          original_url, static_url = emoji
+          replacement = begin
+            if animate
+              "<img draggable=\"false\" class=\"emojione\" alt=\":#{encode(shortcode)}:\" title=\":#{encode(shortcode)}:\" src=\"#{encode(original_url)}\" />"
+            else
+              "<img draggable=\"false\" class=\"emojione custom-emoji\" alt=\":#{encode(shortcode)}:\" title=\":#{encode(shortcode)}:\" src=\"#{encode(static_url)}\" data-original=\"#{original_url}\" data-static=\"#{static_url}\" />"
+            end
+          end
           before_html = shortname_start_index.positive? ? html[0..shortname_start_index - 1] : ''
           html        = before_html + replacement + html[i + 1..-1]
           i          += replacement.size - (shortcode.size + 2) - 1
@@ -177,7 +190,7 @@ class Formatter
   end
 
   def rewrite(text, entities)
-    chars = text.to_s.to_char_a
+    text = text.to_s
 
     # Sort by start index
     entities = entities.sort_by do |entity|
@@ -189,16 +202,54 @@ class Formatter
 
     last_index = entities.reduce(0) do |index, entity|
       indices = entity.respond_to?(:indices) ? entity.indices : entity[:indices]
-      result << encode(chars[index...indices.first].join)
+      result << encode(text[index...indices.first])
       result << yield(entity)
       indices.last
     end
 
-    result << encode(chars[last_index..-1].join)
+    result << encode(text[last_index..-1])
 
     result.flatten.join
   end
 
+  UNICODE_ESCAPE_BLACKLIST_RE = /\p{Z}|\p{P}/
+
+  def utf8_friendly_extractor(text, options = {})
+    old_to_new_index = [0]
+
+    escaped = text.chars.map do |c|
+      output = begin
+        if c.ord.to_s(16).length > 2 && UNICODE_ESCAPE_BLACKLIST_RE.match(c).nil?
+          CGI.escape(c)
+        else
+          c
+        end
+      end
+
+      old_to_new_index << old_to_new_index.last + output.length
+
+      output
+    end.join
+
+    # Note: I couldn't obtain list_slug with @user/list-name format
+    # for mention so this requires additional check
+    special = Extractor.extract_urls_with_indices(escaped, options).map do |extract|
+      new_indices = [
+        old_to_new_index.find_index(extract[:indices].first),
+        old_to_new_index.find_index(extract[:indices].last),
+      ]
+
+      next extract.merge(
+        indices: new_indices,
+        url: text[new_indices.first..new_indices.last - 1]
+      )
+    end
+
+    standard = Extractor.extract_entities_with_indices(text, options)
+
+    Extractor.remove_overlapping_entities(special + standard)
+  end
+
   def link_to_url(entity, options = {})
     url        = Addressable::URI.parse(entity[:url])
     html_attrs = { target: '_blank', rel: 'nofollow noopener' }
diff --git a/app/lib/language_detector.rb b/app/lib/language_detector.rb
index 58c8e206940ab3c3bd584be0ae84dd903fa45ffb..6f9511a54192a70cbb646ec371f6d7e2102e36f2 100644
--- a/app/lib/language_detector.rb
+++ b/app/lib/language_detector.rb
@@ -3,7 +3,8 @@
 class LanguageDetector
   include Singleton
 
-  CHARACTER_THRESHOLD = 140
+  WORDS_THRESHOLD        = 4
+  RELIABLE_CHARACTERS_RE = /[\p{Hebrew}\p{Arabic}\p{Syriac}\p{Thaana}\p{Nko}\p{Han}\p{Katakana}\p{Hiragana}\p{Hangul}]+/m
 
   def initialize
     @identifier = CLD3::NNetLanguageIdentifier.new(1, 2048)
@@ -11,15 +12,14 @@ class LanguageDetector
 
   def detect(text, account)
     input_text = prepare_text(text)
+
     return if input_text.blank?
 
     detect_language_code(input_text) || default_locale(account)
   end
 
   def language_names
-    @language_names =
-      CLD3::TaskContextParams::LANGUAGE_NAMES.map { |name| iso6391(name.to_s).to_sym }
-                                             .uniq
+    @language_names = CLD3::TaskContextParams::LANGUAGE_NAMES.map { |name| iso6391(name.to_s).to_sym }.uniq
   end
 
   private
@@ -29,12 +29,29 @@ class LanguageDetector
   end
 
   def unreliable_input?(text)
-    text.size < CHARACTER_THRESHOLD
+    !reliable_input?(text)
+  end
+
+  def reliable_input?(text)
+    sufficient_text_length?(text) || language_specific_character_set?(text)
+  end
+
+  def sufficient_text_length?(text)
+    text.split(/\s+/).size >= WORDS_THRESHOLD
+  end
+
+  def language_specific_character_set?(text)
+    words = text.scan(RELIABLE_CHARACTERS_RE)
+
+    if words.present?
+      words.reduce(0) { |acc, elem| acc + elem.size }.to_f / text.size.to_f > 0.3
+    else
+      false
+    end
   end
 
   def detect_language_code(text)
     return if unreliable_input?(text)
-
     result = @identifier.find_language(text)
     iso6391(result.language.to_s).to_sym if result.reliable?
   end
@@ -52,7 +69,7 @@ class LanguageDetector
     new_text = remove_html(text)
     new_text.gsub!(FetchLinkCardService::URL_PATTERN, '')
     new_text.gsub!(Account::MENTION_RE, '')
-    new_text.gsub!(Tag::HASHTAG_RE, '')
+    new_text.gsub!(Tag::HASHTAG_RE) { |string| string.gsub(/[#_]/, '#' => '', '_' => ' ').gsub(/[a-z][A-Z]|[a-zA-Z][\d]/) { |s| s.insert(1, ' ') }.downcase }
     new_text.gsub!(/:#{CustomEmoji::SHORTCODE_RE_FRAGMENT}:/, '')
     new_text.gsub!(/\s+/, ' ')
     new_text
@@ -77,6 +94,6 @@ class LanguageDetector
   end
 
   def default_locale(account)
-    return account.user_locale&.to_sym || I18n.default_locale if account.local?
+    account.user_locale&.to_sym || I18n.default_locale if account.local?
   end
 end
diff --git a/app/lib/ostatus/activity/base.rb b/app/lib/ostatus/activity/base.rb
index c5933f3adfecfeb6e6612bc53f11742da1d6aca7..db70f19980cd584afac66dda7d9d4707ebac4df1 100644
--- a/app/lib/ostatus/activity/base.rb
+++ b/app/lib/ostatus/activity/base.rb
@@ -1,6 +1,8 @@
 # frozen_string_literal: true
 
 class OStatus::Activity::Base
+  include Redisable
+
   def initialize(xml, account = nil, **options)
     @xml     = xml
     @account = account
@@ -66,8 +68,4 @@ class OStatus::Activity::Base
       Status.find_by(uri: uri)
     end
   end
-
-  def redis
-    Redis.current
-  end
 end
diff --git a/app/lib/ostatus/activity/creation.rb b/app/lib/ostatus/activity/creation.rb
index 3840c8fbfed5b6507419ca5d8d4f07ae902ad66f..60de712db8adec04c6f63be0a7ce11e243e5b3df 100644
--- a/app/lib/ostatus/activity/creation.rb
+++ b/app/lib/ostatus/activity/creation.rb
@@ -148,7 +148,7 @@ class OStatus::Activity::Creation < OStatus::Activity::Base
   end
 
   def save_media
-    do_not_download = DomainBlock.find_by(domain: @account.domain)&.reject_media?
+    do_not_download = DomainBlock.reject_media?(@account.domain)
     media_attachments = []
 
     @xml.xpath('./xmlns:link[@rel="enclosure"]', xmlns: OStatus::TagManager::XMLNS).each do |link|
@@ -176,7 +176,7 @@ class OStatus::Activity::Creation < OStatus::Activity::Base
   end
 
   def save_emojis(parent)
-    do_not_download = DomainBlock.find_by(domain: parent.account.domain)&.reject_media?
+    do_not_download = DomainBlock.reject_media?(parent.account.domain)
 
     return if do_not_download
 
diff --git a/app/lib/ostatus/atom_serializer.rb b/app/lib/ostatus/atom_serializer.rb
index 7a181fb404563e0fa845b3138611b253b2b3fde4..9a05d96cf9cf721fc4402f227db4c7be050e66ed 100644
--- a/app/lib/ostatus/atom_serializer.rb
+++ b/app/lib/ostatus/atom_serializer.rb
@@ -352,7 +352,7 @@ class OStatus::AtomSerializer
     append_element(entry, 'link', nil, rel: :alternate, type: 'application/activity+json', href: ActivityPub::TagManager.instance.uri_for(status)) if status.account.local?
 
     append_element(entry, 'summary', status.spoiler_text, 'xml:lang': status.language) if status.spoiler_text?
-    append_element(entry, 'content', Formatter.instance.format(status).to_str || '.', type: 'html', 'xml:lang': status.language)
+    append_element(entry, 'content', Formatter.instance.format(status, inline_poll_options: true).to_str || '.', type: 'html', 'xml:lang': status.language)
 
     status.active_mentions.sort_by(&:id).each do |mentioned|
       append_element(entry, 'link', nil, rel: :mentioned, 'ostatus:object-type': OStatus::TagManager::TYPES[:person], href: OStatus::TagManager.instance.uri_for(mentioned.account))
diff --git a/app/lib/potential_friendship_tracker.rb b/app/lib/potential_friendship_tracker.rb
index 017a9748d5f979caa16712c3a2fabe4d185be702..188aa4a275657e6166c014147e68ab4c2b7d8192 100644
--- a/app/lib/potential_friendship_tracker.rb
+++ b/app/lib/potential_friendship_tracker.rb
@@ -11,6 +11,8 @@ class PotentialFriendshipTracker
   }.freeze
 
   class << self
+    include Redisable
+
     def record(account_id, target_account_id, action)
       return if account_id == target_account_id
 
@@ -31,11 +33,5 @@ class PotentialFriendshipTracker
       return [] if account_ids.empty?
       Account.searchable.where(id: account_ids)
     end
-
-    private
-
-    def redis
-      Redis.current
-    end
   end
 end
diff --git a/app/lib/proof_provider.rb b/app/lib/proof_provider.rb
new file mode 100644
index 0000000000000000000000000000000000000000..102c50f4f9ef83e3abf8773bd4f81ea2b54a24f2
--- /dev/null
+++ b/app/lib/proof_provider.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module ProofProvider
+  SUPPORTED_PROVIDERS = %w(keybase).freeze
+
+  def self.find(identifier, proof = nil)
+    case identifier
+    when 'keybase'
+      ProofProvider::Keybase.new(proof)
+    end
+  end
+end
diff --git a/app/lib/proof_provider/keybase.rb b/app/lib/proof_provider/keybase.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8e51d714646497bbb5e08f0e892fdcf51a852715
--- /dev/null
+++ b/app/lib/proof_provider/keybase.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+class ProofProvider::Keybase
+  BASE_URL = ENV.fetch('KEYBASE_BASE_URL', 'https://keybase.io')
+  DOMAIN   = ENV.fetch('KEYBASE_DOMAIN', Rails.configuration.x.web_domain)
+
+  class Error < StandardError; end
+
+  class ExpectedProofLiveError < Error; end
+
+  class UnexpectedResponseError < Error; end
+
+  def initialize(proof = nil)
+    @proof = proof
+  end
+
+  def serializer_class
+    ProofProvider::Keybase::Serializer
+  end
+
+  def worker_class
+    ProofProvider::Keybase::Worker
+  end
+
+  def validate!
+    unless @proof.token&.size == 66
+      @proof.errors.add(:base, I18n.t('identity_proofs.errors.keybase.invalid_token'))
+      return
+    end
+
+    # Do not perform synchronous validation for remote accounts
+    return if @proof.provider_username.blank? || !@proof.account.local?
+
+    if verifier.valid?
+      @proof.verified = true
+      @proof.live     = false
+    else
+      @proof.errors.add(:base, I18n.t('identity_proofs.errors.keybase.verification_failed', kb_username: @proof.provider_username))
+    end
+  end
+
+  def refresh!
+    worker_class.new.perform(@proof)
+  rescue ProofProvider::Keybase::Error
+    nil
+  end
+
+  def on_success_path(user_agent = nil)
+    verifier.on_success_path(user_agent)
+  end
+
+  def badge
+    @badge ||= ProofProvider::Keybase::Badge.new(@proof.account.username, @proof.provider_username, @proof.token, domain)
+  end
+
+  def verifier
+    @verifier ||= ProofProvider::Keybase::Verifier.new(@proof.account.username, @proof.provider_username, @proof.token, domain)
+  end
+
+  private
+
+  def domain
+    if @proof.account.local?
+      DOMAIN
+    else
+      @proof.account.domain
+    end
+  end
+end
diff --git a/app/lib/proof_provider/keybase/badge.rb b/app/lib/proof_provider/keybase/badge.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f587b1cc74480f152d8c0b75b6707a551036fc3b
--- /dev/null
+++ b/app/lib/proof_provider/keybase/badge.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+class ProofProvider::Keybase::Badge
+  include RoutingHelper
+
+  def initialize(local_username, provider_username, token, domain)
+    @local_username    = local_username
+    @provider_username = provider_username
+    @token             = token
+    @domain            = domain
+  end
+
+  def proof_url
+    "#{ProofProvider::Keybase::BASE_URL}/#{@provider_username}/sigchain\##{@token}"
+  end
+
+  def profile_url
+    "#{ProofProvider::Keybase::BASE_URL}/#{@provider_username}"
+  end
+
+  def icon_url
+    "#{ProofProvider::Keybase::BASE_URL}/#{@provider_username}/proof_badge/#{@token}?username=#{@local_username}&domain=#{@domain}"
+  end
+
+  def avatar_url
+    Rails.cache.fetch("proof_providers/keybase/#{@provider_username}/avatar_url", expires_in: 5.minutes) { remote_avatar_url } || default_avatar_url
+  end
+
+  private
+
+  def remote_avatar_url
+    request = Request.new(:get, "#{ProofProvider::Keybase::BASE_URL}/_/api/1.0/user/pic_url.json", params: { username: @provider_username })
+
+    request.perform do |res|
+      json = Oj.load(res.body_with_limit, mode: :strict)
+      json['pic_url'] if json.is_a?(Hash)
+    end
+  rescue Oj::ParseError, HTTP::Error, OpenSSL::SSL::SSLError
+    nil
+  end
+
+  def default_avatar_url
+    asset_pack_path('media/images/proof_providers/keybase.png')
+  end
+end
diff --git a/app/lib/proof_provider/keybase/config_serializer.rb b/app/lib/proof_provider/keybase/config_serializer.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2840f18230c108967b51f10c85adcb9ffcc5845f
--- /dev/null
+++ b/app/lib/proof_provider/keybase/config_serializer.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+class ProofProvider::Keybase::ConfigSerializer < ActiveModel::Serializer
+  include RoutingHelper
+  include ActionView::Helpers::TextHelper
+
+  attributes :version, :domain, :display_name, :username,
+             :brand_color, :logo, :description, :prefill_url,
+             :profile_url, :check_url, :check_path, :avatar_path,
+             :contact
+
+  def version
+    1
+  end
+
+  def domain
+    ProofProvider::Keybase::DOMAIN
+  end
+
+  def display_name
+    Setting.site_title
+  end
+
+  def logo
+    { svg_black: full_asset_url(asset_pack_path('media/images/logo_transparent_black.svg')), svg_full: full_asset_url(asset_pack_path('media/images/logo.svg')) }
+  end
+
+  def brand_color
+    '#282c37'
+  end
+
+  def description
+    strip_tags(Setting.site_short_description.presence || I18n.t('about.about_mastodon_html'))
+  end
+
+  def username
+    { min: 1, max: 30, re: '[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?' }
+  end
+
+  def prefill_url
+    params = {
+      provider: 'keybase',
+      token: '%{sig_hash}',
+      provider_username: '%{kb_username}',
+      username: '%{username}',
+      user_agent: '%{kb_ua}',
+    }
+
+    CGI.unescape(new_settings_identity_proof_url(params))
+  end
+
+  def profile_url
+    CGI.unescape(short_account_url('%{username}')) # rubocop:disable Style/FormatStringToken
+  end
+
+  def check_url
+    CGI.unescape(api_proofs_url(username: '%{username}', provider: 'keybase'))
+  end
+
+  def check_path
+    ['signatures']
+  end
+
+  def avatar_path
+    ['avatar']
+  end
+
+  def contact
+    [Setting.site_contact_email.presence || 'unknown'].compact
+  end
+end
diff --git a/app/lib/proof_provider/keybase/serializer.rb b/app/lib/proof_provider/keybase/serializer.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d29283600ef35bf2f29501a3f23b7963f1589590
--- /dev/null
+++ b/app/lib/proof_provider/keybase/serializer.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+class ProofProvider::Keybase::Serializer < ActiveModel::Serializer
+  include RoutingHelper
+
+  attribute :avatar
+
+  has_many :identity_proofs, key: :signatures
+
+  def avatar
+    full_asset_url(object.avatar_original_url)
+  end
+
+  class AccountIdentityProofSerializer < ActiveModel::Serializer
+    attributes :sig_hash, :kb_username
+
+    def sig_hash
+      object.token
+    end
+
+    def kb_username
+      object.provider_username
+    end
+  end
+end
diff --git a/app/lib/proof_provider/keybase/verifier.rb b/app/lib/proof_provider/keybase/verifier.rb
new file mode 100644
index 0000000000000000000000000000000000000000..af69b1bfc84676b3fcd69c4b10ca20fa1e1ee114
--- /dev/null
+++ b/app/lib/proof_provider/keybase/verifier.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+class ProofProvider::Keybase::Verifier
+  def initialize(local_username, provider_username, token, domain)
+    @local_username    = local_username
+    @provider_username = provider_username
+    @token             = token
+    @domain            = domain
+  end
+
+  def valid?
+    request = Request.new(:get, "#{ProofProvider::Keybase::BASE_URL}/_/api/1.0/sig/proof_valid.json", params: query_params)
+
+    request.perform do |res|
+      json = Oj.load(res.body_with_limit, mode: :strict)
+
+      if json.is_a?(Hash)
+        json.fetch('proof_valid', false)
+      else
+        false
+      end
+    end
+  rescue Oj::ParseError, HTTP::Error, OpenSSL::SSL::SSLError
+    false
+  end
+
+  def on_success_path(user_agent = nil)
+    url = Addressable::URI.parse("#{ProofProvider::Keybase::BASE_URL}/_/proof_creation_success")
+    url.query_values = query_params.merge(kb_ua: user_agent || 'unknown')
+    url.to_s
+  end
+
+  def status
+    request = Request.new(:get, "#{ProofProvider::Keybase::BASE_URL}/_/api/1.0/sig/proof_live.json", params: query_params)
+
+    request.perform do |res|
+      raise ProofProvider::Keybase::UnexpectedResponseError unless res.code == 200
+
+      json = Oj.load(res.body_with_limit, mode: :strict)
+
+      raise ProofProvider::Keybase::UnexpectedResponseError unless json.is_a?(Hash) && json.key?('proof_valid') && json.key?('proof_live')
+
+      json
+    end
+  rescue Oj::ParseError, HTTP::Error, OpenSSL::SSL::SSLError
+    raise ProofProvider::Keybase::UnexpectedResponseError
+  end
+
+  private
+
+  def query_params
+    {
+      domain: @domain,
+      kb_username: @provider_username,
+      username: @local_username,
+      sig_hash: @token,
+    }
+  end
+end
diff --git a/app/lib/proof_provider/keybase/worker.rb b/app/lib/proof_provider/keybase/worker.rb
new file mode 100644
index 0000000000000000000000000000000000000000..bcdd18cc56145d524c7b264cd067fe8bc72f656f
--- /dev/null
+++ b/app/lib/proof_provider/keybase/worker.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+class ProofProvider::Keybase::Worker
+  include Sidekiq::Worker
+
+  sidekiq_options queue: 'pull', retry: 20, unique: :until_executed
+
+  sidekiq_retry_in do |count, exception|
+    # Retry aggressively when the proof is valid but not live in Keybase.
+    # This is likely because Keybase just hasn't noticed the proof being
+    # served from here yet.
+
+    if exception.class == ProofProvider::Keybase::ExpectedProofLiveError
+      case count
+      when 0..2 then 0.seconds
+      when 2..6 then 1.second
+      end
+    end
+  end
+
+  def perform(proof_id)
+    proof  = proof_id.is_a?(AccountIdentityProof) ? proof_id : AccountIdentityProof.find(proof_id)
+    status = proof.provider_instance.verifier.status
+
+    # If Keybase thinks the proof is valid, and it exists here in Mastodon,
+    # then it should be live. Keybase just has to notice that it's here
+    # and then update its state. That might take a couple seconds.
+    raise ProofProvider::Keybase::ExpectedProofLiveError if status['proof_valid'] && !status['proof_live']
+
+    proof.update!(verified: status['proof_valid'], live: status['proof_live'])
+  end
+end
diff --git a/app/lib/request.rb b/app/lib/request.rb
index ef4aeaf29018ebfab1797f8ee33a2a37b1826e19..e555ae6a109b759255f5333c801345ed64413ccf 100644
--- a/app/lib/request.rb
+++ b/app/lib/request.rb
@@ -171,7 +171,7 @@ class Request
         outer_e = nil
 
         Resolv::DNS.open do |dns|
-          dns.timeouts = 1
+          dns.timeouts = 5
 
           addresses = dns.getaddresses(host).take(2)
           time_slot = 10.0 / addresses.size
diff --git a/app/lib/sanitize_config.rb b/app/lib/sanitize_config.rb
index 1bba4a5a6eb3c90379699d705b3b76e584134f0b..aba8ce9f615cbb611b8f70ec3f6599918b2ce0df 100644
--- a/app/lib/sanitize_config.rb
+++ b/app/lib/sanitize_config.rb
@@ -19,6 +19,22 @@ class Sanitize
       node['class'] = class_list.join(' ')
     end
 
+    UNSUPPORTED_ELEMENTS_TRANSFORMER = lambda do |env|
+      return unless %w(h1 h2 h3 h4 h5 h6 blockquote pre ul ol li).include?(env[:node_name])
+
+      case env[:node_name]
+      when 'li'
+        env[:node].traverse do |node|
+          next unless %w(p ul ol li).include?(node.name)
+
+          node.add_next_sibling('<br>') if node.next_sibling
+          node.replace(node.children) unless node.text?
+        end
+      else
+        env[:node].name = 'p'
+      end
+    end
+
     MASTODON_STRICT ||= freeze_config(
       elements: %w(p br span a),
 
@@ -40,6 +56,7 @@ class Sanitize
 
       transformers: [
         CLASS_WHITELIST_TRANSFORMER,
+        UNSUPPORTED_ELEMENTS_TRANSFORMER,
       ]
     )
 
diff --git a/app/lib/sidekiq_error_handler.rb b/app/lib/sidekiq_error_handler.rb
index 23785cf055837cfca43beb24594ef32a73ea716e..8eb6b942dba17302880dcb87fd490652e14bc813 100644
--- a/app/lib/sidekiq_error_handler.rb
+++ b/app/lib/sidekiq_error_handler.rb
@@ -3,9 +3,11 @@
 class SidekiqErrorHandler
   def call(*)
     yield
-  rescue Mastodon::HostValidationError => e
-    Rails.logger.error "#{e.class}: #{e.message}"
-    Rails.logger.error e.backtrace.join("\n")
+  rescue Mastodon::HostValidationError
     # Do not retry
+  ensure
+    socket = Thread.current[:statsd_socket]
+    socket&.close
+    Thread.current[:statsd_socket] = nil
   end
 end
diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb
index 19b8544103ed99836e870160a735f4bc18f7a0ba..bf2e5a962f37626cfc3ee5062c22f74c2345240b 100644
--- a/app/lib/user_settings_decorator.rb
+++ b/app/lib/user_settings_decorator.rb
@@ -32,6 +32,8 @@ class UserSettingsDecorator
     user.settings['theme']               = theme_preference if change?('setting_theme')
     user.settings['hide_network']        = hide_network_preference if change?('setting_hide_network')
     user.settings['aggregate_reblogs']   = aggregate_reblogs_preference if change?('setting_aggregate_reblogs')
+    user.settings['show_application']    = show_application_preference if change?('setting_show_application')
+    user.settings['advanced_layout']     = advanced_layout_preference if change?('setting_advanced_layout')
   end
 
   def merged_notification_emails
@@ -90,6 +92,10 @@ class UserSettingsDecorator
     boolean_cast_setting 'setting_hide_network'
   end
 
+  def show_application_preference
+    boolean_cast_setting 'setting_show_application'
+  end
+
   def theme_preference
     settings['setting_theme']
   end
@@ -102,6 +108,10 @@ class UserSettingsDecorator
     boolean_cast_setting 'setting_aggregate_reblogs'
   end
 
+  def advanced_layout_preference
+    boolean_cast_setting 'setting_advanced_layout'
+  end
+
   def boolean_cast_setting(key)
     ActiveModel::Type::Boolean.new.cast(settings[key])
   end
diff --git a/app/mailers/admin_mailer.rb b/app/mailers/admin_mailer.rb
index a30468eb8b5778033359db79360fe84b5713d1ba..db154cad53afe9a5b5b25c92f7286676ecbcb4d6 100644
--- a/app/mailers/admin_mailer.rb
+++ b/app/mailers/admin_mailer.rb
@@ -14,4 +14,14 @@ class AdminMailer < ApplicationMailer
       mail to: @me.user_email, subject: I18n.t('admin_mailer.new_report.subject', instance: @instance, id: @report.id)
     end
   end
+
+  def new_pending_account(recipient, user)
+    @account  = user.account
+    @me       = recipient
+    @instance = Rails.configuration.x.local_domain
+
+    locale_for_account(@me) do
+      mail to: @me.user_email, subject: I18n.t('admin_mailer.new_pending_account.subject', instance: @instance, username: @account.username)
+    end
+  end
 end
diff --git a/app/models/account.rb b/app/models/account.rb
index 963c8b8449c7837690579423c2bff8fe0c244a00..9fcb3293a080b4ae6f74bfeb64b81b5e59ea5f42 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -28,8 +28,6 @@
 #  header_updated_at       :datetime
 #  avatar_remote_url       :string
 #  subscription_expires_at :datetime
-#  silenced                :boolean          default(FALSE), not null
-#  suspended               :boolean          default(FALSE), not null
 #  locked                  :boolean          default(FALSE), not null
 #  header_remote_url       :string           default(""), not null
 #  last_webfingered_at     :datetime
@@ -45,6 +43,8 @@
 #  actor_type              :string
 #  discoverable            :boolean
 #  also_known_as           :string           is an Array
+#  silenced_at             :datetime
+#  suspended_at            :datetime
 #
 
 class Account < ApplicationRecord
@@ -82,10 +82,10 @@ class Account < ApplicationRecord
   scope :local, -> { where(domain: nil) }
   scope :expiring, ->(time) { remote.where.not(subscription_expires_at: nil).where('subscription_expires_at < ?', time) }
   scope :partitioned, -> { order(Arel.sql('row_number() over (partition by domain)')) }
-  scope :silenced, -> { where(silenced: true) }
-  scope :suspended, -> { where(suspended: true) }
-  scope :without_suspended, -> { where(suspended: false) }
-  scope :without_silenced, -> { where(silenced: false) }
+  scope :silenced, -> { where.not(silenced_at: nil) }
+  scope :suspended, -> { where.not(suspended_at: nil) }
+  scope :without_suspended, -> { where(suspended_at: nil) }
+  scope :without_silenced, -> { where(silenced_at: nil) }
   scope :recent, -> { reorder(id: :desc) }
   scope :bots, -> { where(actor_type: %w(Application Service)) }
   scope :alphabetic, -> { order(domain: :asc, username: :asc) }
@@ -94,21 +94,27 @@ class Account < ApplicationRecord
   scope :matches_display_name, ->(value) { where(arel_table[:display_name].matches("#{value}%")) }
   scope :matches_domain, ->(value) { where(arel_table[:domain].matches("%#{value}%")) }
   scope :searchable, -> { without_suspended.where(moved_to_account_id: nil) }
-  scope :discoverable, -> { searchable.without_silenced.where(discoverable: true).joins(:account_stat).where(AccountStat.arel_table[:followers_count].gteq(MIN_FOLLOWERS_DISCOVERY)).by_recent_status }
+  scope :discoverable, -> { searchable.without_silenced.where(discoverable: true).joins(:account_stat).where(AccountStat.arel_table[:followers_count].gteq(MIN_FOLLOWERS_DISCOVERY)) }
   scope :tagged_with, ->(tag) { joins(:accounts_tags).where(accounts_tags: { tag_id: tag }) }
   scope :by_recent_status, -> { order(Arel.sql('(case when account_stats.last_status_at is null then 1 else 0 end) asc, account_stats.last_status_at desc')) }
   scope :popular, -> { order('account_stats.followers_count desc') }
+  scope :by_domain_and_subdomains, ->(domain) { where(domain: domain).or(where(arel_table[:domain].matches('%.' + domain))) }
 
   delegate :email,
            :unconfirmed_email,
            :current_sign_in_ip,
            :current_sign_in_at,
            :confirmed?,
+           :approved?,
+           :pending?,
+           :disabled?,
+           :role,
            :admin?,
            :moderator?,
            :staff?,
            :locale,
            :hides_network?,
+           :shows_application?,
            to: :user,
            prefix: true,
            allow_nil: true
@@ -162,25 +168,35 @@ class Account < ApplicationRecord
     ResolveAccountService.new.call(acct)
   end
 
-  def silence!
-    update!(silenced: true)
+  def silenced?
+    silenced_at.present?
+  end
+
+  def silence!(date = nil)
+    date ||= Time.now.utc
+    update!(silenced_at: date)
   end
 
   def unsilence!
-    update!(silenced: false)
+    update!(silenced_at: nil)
+  end
+
+  def suspended?
+    suspended_at.present?
   end
 
-  def suspend!
+  def suspend!(date = nil)
+    date ||= Time.now.utc
     transaction do
       user&.disable! if local?
-      update!(suspended: true)
+      update!(suspended_at: date)
     end
   end
 
   def unsuspend!
     transaction do
       user&.enable! if local?
-      update!(suspended: false)
+      update!(suspended_at: nil)
     end
   end
 
@@ -191,6 +207,10 @@ class Account < ApplicationRecord
     end
   end
 
+  def sign?
+    true
+  end
+
   def keypair
     @keypair ||= OpenSSL::PKey::RSA.new(private_key || public_key)
   end
@@ -240,6 +260,7 @@ class Account < ApplicationRecord
   def fields_attributes=(attributes)
     fields     = []
     old_fields = self[:fields] || []
+    old_fields = [] if old_fields.is_a?(Hash)
 
     if attributes.is_a?(Hash)
       attributes.each_value do |attr|
@@ -264,6 +285,7 @@ class Account < ApplicationRecord
     return if fields.size >= DEFAULT_FIELDS_SIZE
 
     tmp = self[:fields] || []
+    tmp = [] if tmp.is_a?(Hash)
 
     (DEFAULT_FIELDS_SIZE - tmp.size).times do
       tmp << { name: '', value: '' }
@@ -385,7 +407,7 @@ class Account < ApplicationRecord
       DeliveryFailureTracker.filter(urls)
     end
 
-    def search_for(terms, limit = 10)
+    def search_for(terms, limit = 10, offset = 0)
       textsearch, query = generate_query_for_search(terms)
 
       sql = <<-SQL.squish
@@ -394,18 +416,18 @@ class Account < ApplicationRecord
           ts_rank_cd(#{textsearch}, #{query}, 32) AS rank
         FROM accounts
         WHERE #{query} @@ #{textsearch}
-          AND accounts.suspended = false
+          AND accounts.suspended_at IS NULL
           AND accounts.moved_to_account_id IS NULL
         ORDER BY rank DESC
-        LIMIT ?
+        LIMIT ? OFFSET ?
       SQL
 
-      records = find_by_sql([sql, limit])
+      records = find_by_sql([sql, limit, offset])
       ActiveRecord::Associations::Preloader.new.preload(records, :account_stat)
       records
     end
 
-    def advanced_search_for(terms, account, limit = 10, following = false)
+    def advanced_search_for(terms, account, limit = 10, following = false, offset = 0)
       textsearch, query = generate_query_for_search(terms)
 
       if following
@@ -422,14 +444,14 @@ class Account < ApplicationRecord
           LEFT OUTER JOIN follows AS f ON (accounts.id = f.account_id AND f.target_account_id = ?) OR (accounts.id = f.target_account_id AND f.account_id = ?)
           WHERE accounts.id IN (SELECT * FROM first_degree)
             AND #{query} @@ #{textsearch}
-            AND accounts.suspended = false
+            AND accounts.suspended_at IS NULL
             AND accounts.moved_to_account_id IS NULL
           GROUP BY accounts.id
           ORDER BY rank DESC
-          LIMIT ?
+          LIMIT ? OFFSET ?
         SQL
 
-        records = find_by_sql([sql, account.id, account.id, account.id, limit])
+        records = find_by_sql([sql, account.id, account.id, account.id, limit, offset])
       else
         sql = <<-SQL.squish
           SELECT
@@ -438,14 +460,14 @@ class Account < ApplicationRecord
           FROM accounts
           LEFT OUTER JOIN follows AS f ON (accounts.id = f.account_id AND f.target_account_id = ?) OR (accounts.id = f.target_account_id AND f.account_id = ?)
           WHERE #{query} @@ #{textsearch}
-            AND accounts.suspended = false
+            AND accounts.suspended_at IS NULL
             AND accounts.moved_to_account_id IS NULL
           GROUP BY accounts.id
           ORDER BY rank DESC
-          LIMIT ?
+          LIMIT ? OFFSET ?
         SQL
 
-        records = find_by_sql([sql, account.id, account.id, limit])
+        records = find_by_sql([sql, account.id, account.id, limit, offset])
       end
 
       ActiveRecord::Associations::Preloader.new.preload(records, :account_stat)
@@ -469,6 +491,7 @@ class Account < ApplicationRecord
 
   before_create :generate_keys
   before_validation :prepare_contents, if: :local?
+  before_validation :prepare_username, on: :create
   before_destroy :clean_feed_manager
 
   private
@@ -478,6 +501,10 @@ class Account < ApplicationRecord
     note&.strip!
   end
 
+  def prepare_username
+    username&.squish!
+  end
+
   def generate_keys
     return unless local? && !Rails.env.test?
 
diff --git a/app/models/account_conversation.rb b/app/models/account_conversation.rb
index cc6b39279866bceb1c01a7d8e25d2fb394bdd146..0c03747e2ae7b0793e8ffc16411d17d57290f765 100644
--- a/app/models/account_conversation.rb
+++ b/app/models/account_conversation.rb
@@ -30,7 +30,8 @@ class AccountConversation < ApplicationRecord
     if participant_account_ids.empty?
       [account]
     else
-      Account.where(id: participant_account_ids)
+      participants = Account.where(id: participant_account_ids)
+      participants.empty? ? [account] : participants
     end
   end
 
diff --git a/app/models/account_domain_block.rb b/app/models/account_domain_block.rb
index e352000c3a24ba50bba04890cec0cebbcc22ca30..3aaffde9a952d3bcd6eb568273b5beb127314477 100644
--- a/app/models/account_domain_block.rb
+++ b/app/models/account_domain_block.rb
@@ -12,9 +12,10 @@
 
 class AccountDomainBlock < ApplicationRecord
   include Paginable
+  include DomainNormalizable
 
   belongs_to :account
-  validates :domain, presence: true, uniqueness: { scope: :account_id }
+  validates :domain, presence: true, uniqueness: { scope: :account_id }, domain: true
 
   after_commit :remove_blocking_cache
   after_commit :remove_relationship_cache
diff --git a/app/models/account_filter.rb b/app/models/account_filter.rb
index b10f50db778b100e1aa477dcd6ac8ad01c7b4a7e..c3b1fe08d8f59c6b7a9a5dfe4379e4c27f9073b4 100644
--- a/app/models/account_filter.rb
+++ b/app/models/account_filter.rb
@@ -22,7 +22,7 @@ class AccountFilter
 
   def set_defaults!
     params['local']  = '1' if params['remote'].blank?
-    params['active'] = '1' if params['suspended'].blank? && params['silenced'].blank?
+    params['active'] = '1' if params['suspended'].blank? && params['silenced'].blank? && params['pending'].blank?
   end
 
   def scope_for(key, value)
@@ -35,6 +35,10 @@ class AccountFilter
       Account.where(domain: value)
     when 'active'
       Account.without_suspended
+    when 'pending'
+      accounts_with_users.merge User.pending
+    when 'disabled'
+      accounts_with_users.merge User.disabled
     when 'silenced'
       Account.silenced
     when 'suspended'
diff --git a/app/models/account_identity_proof.rb b/app/models/account_identity_proof.rb
new file mode 100644
index 0000000000000000000000000000000000000000..10b66cccf9b55b581013004ccd9bfe5f196e1ab2
--- /dev/null
+++ b/app/models/account_identity_proof.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+# == Schema Information
+#
+# Table name: account_identity_proofs
+#
+#  id                :bigint(8)        not null, primary key
+#  account_id        :bigint(8)
+#  provider          :string           default(""), not null
+#  provider_username :string           default(""), not null
+#  token             :text             default(""), not null
+#  verified          :boolean          default(FALSE), not null
+#  live              :boolean          default(FALSE), not null
+#  created_at        :datetime         not null
+#  updated_at        :datetime         not null
+#
+
+class AccountIdentityProof < ApplicationRecord
+  belongs_to :account
+
+  validates :provider, inclusion: { in: ProofProvider::SUPPORTED_PROVIDERS }
+  validates :provider_username, format: { with: /\A[a-z0-9_]+\z/i }, length: { minimum: 2, maximum: 30 }
+  validates :provider_username, uniqueness: { scope: [:account_id, :provider] }
+  validates :token, format: { with: /\A[a-f0-9]+\z/ }, length: { maximum: 66 }
+
+  validate :validate_with_provider, if: :token_changed?
+
+  scope :active, -> { where(verified: true, live: true) }
+
+  after_commit :queue_worker, if: :saved_change_to_token?
+
+  delegate :refresh!, :on_success_path, :badge, to: :provider_instance
+
+  def provider_instance
+    @provider_instance ||= ProofProvider.find(provider, self)
+  end
+
+  private
+
+  def queue_worker
+    provider_instance.worker_class.perform_async(id)
+  end
+
+  def validate_with_provider
+    provider_instance.validate!
+  end
+end
diff --git a/app/models/admin/account_action.rb b/app/models/admin/account_action.rb
index 84c3f880d2556efd5005cd59dea1d273f604af6f..bdbd342fb3ccf3fb0444a831125b72d90ef5f8e9 100644
--- a/app/models/admin/account_action.rb
+++ b/app/models/admin/account_action.rb
@@ -17,10 +17,13 @@ class Admin::AccountAction
                 :type,
                 :text,
                 :report_id,
-                :warning_preset_id,
-                :send_email_notification
+                :warning_preset_id
 
-  attr_reader :warning
+  attr_reader :warning, :send_email_notification
+
+  def send_email_notification=(value)
+    @send_email_notification = ActiveModel::Type::Boolean.new.cast(value)
+  end
 
   def save!
     ApplicationRecord.transaction do
diff --git a/app/models/concerns/account_associations.rb b/app/models/concerns/account_associations.rb
index 7dafeee34ca67cd69986c2d6cf0c402d0f469e13..70855e0543ee83464b1d588ffaacc69554d019b8 100644
--- a/app/models/concerns/account_associations.rb
+++ b/app/models/concerns/account_associations.rb
@@ -7,6 +7,9 @@ module AccountAssociations
     # Local users
     has_one :user, inverse_of: :account, dependent: :destroy
 
+    # Identity proofs
+    has_many :identity_proofs, class_name: 'AccountIdentityProof', dependent: :destroy, inverse_of: :account
+
     # Timelines
     has_many :stream_entries, inverse_of: :account, dependent: :destroy
     has_many :statuses, inverse_of: :account, dependent: :destroy
@@ -26,6 +29,7 @@ module AccountAssociations
 
     # Media
     has_many :media_attachments, dependent: :destroy
+    has_many :polls, dependent: :destroy
 
     # PuSH subscriptions
     has_many :subscriptions, dependent: :destroy
@@ -55,5 +59,6 @@ module AccountAssociations
 
     # Hashtags
     has_and_belongs_to_many :tags
+    has_many :featured_tags, -> { includes(:tag) }, dependent: :destroy, inverse_of: :account
   end
 end
diff --git a/app/models/concerns/account_avatar.rb b/app/models/concerns/account_avatar.rb
index 2d5ebfca35aea67c09a2d5bb1862e2ee5cb8a1d1..5fff3ef5d2128399463897dc837fd402045bd3c8 100644
--- a/app/models/concerns/account_avatar.rb
+++ b/app/models/concerns/account_avatar.rb
@@ -3,7 +3,7 @@
 module AccountAvatar
   extend ActiveSupport::Concern
 
-  IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif'].freeze
+  IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'].freeze
   LIMIT = 2.megabytes
 
   class_methods do
diff --git a/app/models/concerns/account_finder_concern.rb b/app/models/concerns/account_finder_concern.rb
index 7e3bbde097799a711f6921125b629ede25e4b8d2..ccd7bfa12311310d8ce3cbf66677e7fc86ae3780 100644
--- a/app/models/concerns/account_finder_concern.rb
+++ b/app/models/concerns/account_finder_concern.rb
@@ -13,7 +13,7 @@ module AccountFinderConcern
     end
 
     def representative
-      find_local(Setting.site_contact_username.gsub(/\A@/, '')) || Account.local.find_by(suspended: false)
+      find_local(Setting.site_contact_username.strip.gsub(/\A@/, '')) || Account.local.without_suspended.first
     end
 
     def find_local(username)
diff --git a/app/models/concerns/account_header.rb b/app/models/concerns/account_header.rb
index 067e166eb6ce5e340a86489c1c12d525c2c24dfd..a748fdff72df33e23613364f55ecb53950febf6e 100644
--- a/app/models/concerns/account_header.rb
+++ b/app/models/concerns/account_header.rb
@@ -3,7 +3,7 @@
 module AccountHeader
   extend ActiveSupport::Concern
 
-  IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif'].freeze
+  IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'].freeze
   LIMIT = 2.megabytes
   MAX_PIXELS = 750_000 # 1500x500px
 
diff --git a/app/models/concerns/attachmentable.rb b/app/models/concerns/attachmentable.rb
index de4cf87757715ebef2c6814f6679f570f351dc91..7c78bb45698dccf8e9036cc3e2eb53272ee2ba43 100644
--- a/app/models/concerns/attachmentable.rb
+++ b/app/models/concerns/attachmentable.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-require 'mime/types'
+require 'mime/types/columnar'
 
 module Attachmentable
   extend ActiveSupport::Concern
@@ -10,10 +10,21 @@ module Attachmentable
   included do
     before_post_process :set_file_extensions
     before_post_process :check_image_dimensions
+    before_post_process :set_file_content_type
   end
 
   private
 
+  def set_file_content_type
+    self.class.attachment_definitions.each_key do |attachment_name|
+      attachment = send(attachment_name)
+
+      next if attachment.blank? || attachment.queued_for_write[:original].blank?
+
+      attachment.instance_write :content_type, calculated_content_type(attachment)
+    end
+  end
+
   def set_file_extensions
     self.class.attachment_definitions.each_key do |attachment_name|
       attachment = send(attachment_name)
@@ -47,4 +58,12 @@ module Attachmentable
 
     extension
   end
+
+  def calculated_content_type(attachment)
+    content_type = Paperclip.run('file', '-b --mime :file', file: attachment.queued_for_write[:original].path).split(/[:;\s]+/).first.chomp
+    content_type = 'video/mp4' if content_type == 'video/x-m4v'
+    content_type
+  rescue Terrapin::CommandLineError
+    ''
+  end
 end
diff --git a/app/models/concerns/domain_normalizable.rb b/app/models/concerns/domain_normalizable.rb
index dff3e5414f13a995236f1111f33dadbec4ef0cbb..c00b3142fa73f99129562b4c2d262633329160de 100644
--- a/app/models/concerns/domain_normalizable.rb
+++ b/app/models/concerns/domain_normalizable.rb
@@ -4,12 +4,12 @@ module DomainNormalizable
   extend ActiveSupport::Concern
 
   included do
-    before_validation :normalize_domain
+    before_save :normalize_domain
   end
 
   private
 
   def normalize_domain
-    self.domain = TagManager.instance.normalize_domain(domain)
+    self.domain = TagManager.instance.normalize_domain(domain&.strip)
   end
 end
diff --git a/app/models/concerns/expireable.rb b/app/models/concerns/expireable.rb
index 2c06314760cd34df4fff886c0c5489ca86e93aa6..f7d2bab498a19571cf375be43355f93c8de98edf 100644
--- a/app/models/concerns/expireable.rb
+++ b/app/models/concerns/expireable.rb
@@ -18,7 +18,11 @@ module Expireable
     end
 
     def expired?
-      !expires_at.nil? && expires_at < Time.now.utc
+      expires? && expires_at < Time.now.utc
+    end
+
+    def expires?
+      !expires_at.nil?
     end
   end
 end
diff --git a/app/models/concerns/ldap_authenticable.rb b/app/models/concerns/ldap_authenticable.rb
new file mode 100644
index 0000000000000000000000000000000000000000..84ff84c4b05c856c30cf7190db6ed392df3dd063
--- /dev/null
+++ b/app/models/concerns/ldap_authenticable.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module LdapAuthenticable
+  extend ActiveSupport::Concern
+
+  def ldap_setup(_attributes)
+    self.confirmed_at = Time.now.utc
+    self.admin        = false
+    self.external     = true
+
+    save!
+  end
+
+  class_methods do
+    def 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, agreement: true, account_attributes: { username: attributes[Devise.ldap_uid.to_sym].first })
+        resource.ldap_setup(attributes)
+      end
+
+      resource
+    end
+  end
+end
diff --git a/app/models/concerns/omniauthable.rb b/app/models/concerns/omniauthable.rb
index f263fe7af04761de25c995676342442178dda999..283033083959caf767db8450ddde1c1f6f77d382 100644
--- a/app/models/concerns/omniauthable.rb
+++ b/app/models/concerns/omniauthable.rb
@@ -7,6 +7,8 @@ module Omniauthable
   TEMP_EMAIL_REGEX = /\Achange@me/
 
   included do
+    devise :omniauthable
+
     def omniauth_providers
       Devise.omniauth_configs.keys
     end
@@ -63,6 +65,8 @@ module Omniauthable
       {
         email: email || "#{TEMP_EMAIL_PREFIX}-#{auth.uid}-#{auth.provider}.com",
         password: Devise.friendly_token[0, 20],
+        agreement: true,
+        external: true,
         account_attributes: {
           username: ensure_unique_username(auth.uid),
           display_name: display_name,
diff --git a/app/models/concerns/pam_authenticable.rb b/app/models/concerns/pam_authenticable.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6169d4dfaa103e38fe43150690d512f46cd4f5cf
--- /dev/null
+++ b/app/models/concerns/pam_authenticable.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+module PamAuthenticable
+  extend ActiveSupport::Concern
+
+  included do
+    devise :pam_authenticatable if ENV['PAM_ENABLED'] == 'true'
+
+    def pam_conflict(_attributes)
+      # Block pam login tries on traditional account
+    end
+
+    def pam_conflict?
+      if Devise.pam_authentication
+        encrypted_password.present? && pam_managed_user?
+      else
+        false
+      end
+    end
+
+    def pam_get_name
+      if account.present?
+        account.username
+      else
+        super
+      end
+    end
+
+    def pam_setup(_attributes)
+      account = Account.new(username: pam_get_name)
+      account.save!(validate: false)
+
+      self.email        = "#{account.username}@#{find_pam_suffix}" if email.nil? && find_pam_suffix
+      self.confirmed_at = Time.now.utc
+      self.admin        = false
+      self.account      = account
+      self.external     = true
+
+      account.destroy! unless save
+    end
+
+    def self.pam_get_user(attributes = {})
+      return nil unless attributes[:email]
+
+      resource = begin
+        if Devise.check_at_sign && !attributes[:email].index('@')
+          joins(:account).find_by(accounts: { username: attributes[:email] })
+        else
+          find_by(email: attributes[:email])
+        end
+      end
+
+      if resource.nil?
+        resource = new(email: attributes[:email], agreement: true)
+
+        if Devise.check_at_sign && !resource[:email].index('@')
+          resource[:email] = Rpam2.getenv(resource.find_pam_service, attributes[:email], attributes[:password], 'email', false)
+          resource[:email] = "#{attributes[:email]}@#{resource.find_pam_suffix}" unless resource[:email]
+        end
+      end
+
+      resource
+    end
+
+    def self.authenticate_with_pam(attributes = {})
+      super if Devise.pam_authentication
+    end
+  end
+end
diff --git a/app/models/concerns/redisable.rb b/app/models/concerns/redisable.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c6cf9735960c1cb64765b7e6e2d0a5e4d79e7d02
--- /dev/null
+++ b/app/models/concerns/redisable.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module Redisable
+  extend ActiveSupport::Concern
+
+  private
+
+  def redis
+    Redis.current
+  end
+end
diff --git a/app/models/concerns/status_threading_concern.rb b/app/models/concerns/status_threading_concern.rb
index b9c800c2aabdbb3a262dd9839ee6c6ede2f7a2a4..15eb695cd04aaa9d43f975ba891d15860fb99963 100644
--- a/app/models/concerns/status_threading_concern.rb
+++ b/app/models/concerns/status_threading_concern.rb
@@ -11,6 +11,10 @@ module StatusThreadingConcern
     find_statuses_from_tree_path(descendant_ids(limit, max_child_id, since_child_id, depth), account, promote: true)
   end
 
+  def self_replies(limit)
+    account.statuses.where(in_reply_to_id: id, visibility: [:public, :unlisted]).reorder(id: :asc).limit(limit)
+  end
+
   private
 
   def ancestor_ids(limit)
diff --git a/app/models/concerns/user_roles.rb b/app/models/concerns/user_roles.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a42b4a17265d4c45af8d628b2b722ecb159d8167
--- /dev/null
+++ b/app/models/concerns/user_roles.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+module UserRoles
+  extend ActiveSupport::Concern
+
+  included do
+    scope :admins, -> { where(admin: true) }
+    scope :moderators, -> { where(moderator: true) }
+    scope :staff, -> { admins.or(moderators) }
+  end
+
+  def staff?
+    admin? || moderator?
+  end
+
+  def role=(value)
+    case value
+    when 'admin'
+      self.admin     = true
+      self.moderator = false
+    when 'moderator'
+      self.admin     = false
+      self.moderator = true
+    else
+      self.admin     = false
+      self.moderator = false
+    end
+  end
+
+  def role
+    if admin?
+      'admin'
+    elsif moderator?
+      'moderator'
+    else
+      'user'
+    end
+  end
+
+  def role?(role)
+    case role
+    when 'user'
+      true
+    when 'moderator'
+      staff?
+    when 'admin'
+      admin?
+    else
+      false
+    end
+  end
+
+  def promote!
+    if moderator?
+      update!(moderator: false, admin: true)
+    elsif !admin?
+      update!(moderator: true)
+    end
+  end
+
+  def demote!
+    if admin?
+      update!(admin: false, moderator: true)
+    elsif moderator?
+      update!(moderator: false)
+    end
+  end
+end
diff --git a/app/models/custom_emoji.rb b/app/models/custom_emoji.rb
index d3cc7050492ea5523ccde7596eebcfba777d4f3c..def1b3faa162057c89a80601ac45df7f5a3ae9c1 100644
--- a/app/models/custom_emoji.rb
+++ b/app/models/custom_emoji.rb
@@ -27,18 +27,21 @@ class CustomEmoji < ApplicationRecord
     :(#{SHORTCODE_RE_FRAGMENT}):
     (?=[^[:alnum:]:]|$)/x
 
+  IMAGE_MIME_TYPES = %w(image/png image/gif image/webp).freeze
+
   has_one :local_counterpart, -> { where(domain: nil) }, class_name: 'CustomEmoji', primary_key: :shortcode, foreign_key: :shortcode
 
   has_attached_file :image, styles: { static: { format: 'png', convert_options: '-coalesce -strip' } }
 
   before_validation :downcase_domain
 
-  validates_attachment :image, content_type: { content_type: 'image/png' }, presence: true, size: { less_than: LIMIT }
+  validates_attachment :image, content_type: { content_type: IMAGE_MIME_TYPES }, presence: true, size: { less_than: LIMIT }
   validates :shortcode, uniqueness: { scope: :domain }, format: { with: /\A#{SHORTCODE_RE_FRAGMENT}\z/ }, length: { minimum: 2 }
 
   scope :local,      -> { where(domain: nil) }
   scope :remote,     -> { where.not(domain: nil) }
   scope :alphabetic, -> { order(domain: :asc, shortcode: :asc) }
+  scope :by_domain_and_subdomains, ->(domain) { where(domain: domain).or(where(arel_table[:domain].matches('%.' + domain))) }
 
   remotable_attachment :image, LIMIT
 
diff --git a/app/models/custom_filter.rb b/app/models/custom_filter.rb
index 342207a55dfebe51e4cf63259477091e17206287..382562fb843a36fba848f8a365cd0b9afb1062c8 100644
--- a/app/models/custom_filter.rb
+++ b/app/models/custom_filter.rb
@@ -35,6 +35,13 @@ class CustomFilter < ApplicationRecord
   before_validation :clean_up_contexts
   after_commit :remove_cache
 
+  def expires_in
+    return @expires_in if defined?(@expires_in)
+    return nil if expires_at.nil?
+
+    [30.minutes, 1.hour, 6.hours, 12.hours, 1.day, 1.week].find { |expires_in| expires_in.from_now >= expires_at }
+  end
+
   private
 
   def clean_up_contexts
diff --git a/app/models/domain_block.rb b/app/models/domain_block.rb
index 1064ea7c8f29bbdf3763f365e644a44b0e30860d..c230fb14bda41a021f62e5eb4eb1ae4dd8fa2c09 100644
--- a/app/models/domain_block.rb
+++ b/app/models/domain_block.rb
@@ -17,14 +17,53 @@ class DomainBlock < ApplicationRecord
 
   enum severity: [:silence, :suspend, :noop]
 
-  attr_accessor :retroactive
-
-  validates :domain, presence: true, uniqueness: true
+  validates :domain, presence: true, uniqueness: true, domain: true
 
   has_many :accounts, foreign_key: :domain, primary_key: :domain
   delegate :count, to: :accounts, prefix: true
 
-  def self.blocked?(domain)
-    where(domain: domain, severity: :suspend).exists?
+  scope :matches_domain, ->(value) { where(arel_table[:domain].matches("%#{value}%")) }
+
+  class << self
+    def suspend?(domain)
+      !!rule_for(domain)&.suspend?
+    end
+
+    def silence?(domain)
+      !!rule_for(domain)&.silence?
+    end
+
+    def reject_media?(domain)
+      !!rule_for(domain)&.reject_media?
+    end
+
+    def reject_reports?(domain)
+      !!rule_for(domain)&.reject_reports?
+    end
+
+    alias blocked? suspend?
+
+    def rule_for(domain)
+      return if domain.blank?
+
+      uri      = Addressable::URI.new.tap { |u| u.host = domain.gsub(/[\/]/, '') }
+      segments = uri.normalized_host.split('.')
+      variants = segments.map.with_index { |_, i| segments[i..-1].join('.') }
+
+      where(domain: variants[0..-2]).order(Arel.sql('char_length(domain) desc')).first
+    end
+  end
+
+  def stricter_than?(other_block)
+    return true  if suspend?
+    return false if other_block.suspend? && (silence? || noop?)
+    return false if other_block.silence? && noop?
+
+    (reject_media || !other_block.reject_media) && (reject_reports || !other_block.reject_reports)
+  end
+
+  def affected_accounts_count
+    scope = suspend? ? accounts.where(suspended_at: created_at) : accounts.where(silenced_at: created_at)
+    scope.count
   end
 end
diff --git a/app/models/email_domain_block.rb b/app/models/email_domain_block.rb
index 0fcd36477b927942e5e02dca35db7dcfdafe8999..bc70dea254a5407da4344a6adfc4e022ad3410ad 100644
--- a/app/models/email_domain_block.rb
+++ b/app/models/email_domain_block.rb
@@ -12,7 +12,7 @@
 class EmailDomainBlock < ApplicationRecord
   include DomainNormalizable
 
-  validates :domain, presence: true, uniqueness: true
+  validates :domain, presence: true, uniqueness: true, domain: true
 
   def self.block?(email)
     _, domain = email.split('@', 2)
diff --git a/app/models/export.rb b/app/models/export.rb
index a2520e9c244f34cf0ef609be5b06a8d4e169672f..cab01f11ad004c7e3e76b72dc3769eb25ce994bd 100644
--- a/app/models/export.rb
+++ b/app/models/export.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 require 'csv'
 
 class Export
@@ -13,16 +14,24 @@ class Export
   end
 
   def to_muted_accounts_csv
-    to_csv account.muting.select(:username, :domain)
+    CSV.generate(headers: ['Account address', 'Hide notifications'], write_headers: true) do |csv|
+      account.mute_relationships.includes(:target_account).reorder(id: :desc).each do |mute|
+        csv << [acct(mute.target_account), mute.hide_notifications]
+      end
+    end
   end
 
   def to_following_accounts_csv
-    to_csv account.following.select(:username, :domain)
+    CSV.generate(headers: ['Account address', 'Show boosts'], write_headers: true) do |csv|
+      account.active_relationships.includes(:target_account).reorder(id: :desc).each do |follow|
+        csv << [acct(follow.target_account), follow.show_reblogs]
+      end
+    end
   end
 
   def to_lists_csv
     CSV.generate do |csv|
-      account.owned_lists.select(:title).each do |list|
+      account.owned_lists.select(:title, :id).each do |list|
         list.accounts.select(:username, :domain).each do |account|
           csv << [list.title, acct(account)]
         end
diff --git a/app/models/featured_tag.rb b/app/models/featured_tag.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d06ae26a8902995bbfaa870812380703ff6b6a44
--- /dev/null
+++ b/app/models/featured_tag.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+# == Schema Information
+#
+# Table name: featured_tags
+#
+#  id             :bigint(8)        not null, primary key
+#  account_id     :bigint(8)
+#  tag_id         :bigint(8)
+#  statuses_count :bigint(8)        default(0), not null
+#  last_status_at :datetime
+#  created_at     :datetime         not null
+#  updated_at     :datetime         not null
+#
+
+class FeaturedTag < ApplicationRecord
+  belongs_to :account, inverse_of: :featured_tags, required: true
+  belongs_to :tag, inverse_of: :featured_tags, required: true
+
+  delegate :name, to: :tag, allow_nil: true
+
+  validates_associated :tag, on: :create
+  validates :name, presence: true, on: :create
+  validate :validate_featured_tags_limit, on: :create
+
+  def name=(str)
+    self.tag = Tag.find_or_initialize_by(name: str.strip.delete('#').mb_chars.downcase.to_s)
+  end
+
+  def increment(timestamp)
+    update(statuses_count: statuses_count + 1, last_status_at: timestamp)
+  end
+
+  def decrement(deleted_status_id)
+    update(statuses_count: [0, statuses_count - 1].max, last_status_at: account.statuses.where(visibility: %i(public unlisted)).tagged_with(tag).where.not(id: deleted_status_id).select(:created_at).first&.created_at)
+  end
+
+  def reset_data
+    self.statuses_count = account.statuses.where(visibility: %i(public unlisted)).tagged_with(tag).count
+    self.last_status_at = account.statuses.where(visibility: %i(public unlisted)).tagged_with(tag).select(:created_at).first&.created_at
+  end
+
+  private
+
+  def validate_featured_tags_limit
+    errors.add(:base, I18n.t('featured_tags.errors.limit')) if account.featured_tags.count >= 10
+  end
+end
diff --git a/app/models/feed.rb b/app/models/feed.rb
index 5bce88f25522df0a9797a30672e46195e30c2793..0e8943ff863bde253b75912a6870345bf974f048 100644
--- a/app/models/feed.rb
+++ b/app/models/feed.rb
@@ -1,6 +1,8 @@
 # frozen_string_literal: true
 
 class Feed
+  include Redisable
+
   def initialize(type, id)
     @type = type
     @id   = id
@@ -27,8 +29,4 @@ class Feed
   def key
     FeedManager.instance.key(@type, @id)
   end
-
-  def redis
-    Redis.current
-  end
 end
diff --git a/app/models/follow_request.rb b/app/models/follow_request.rb
index c5451a0507ac58df3894a9796ba13cdcee4b8731..96ac7eaa593d9fac53f30d3a9444c7ba3d30ea99 100644
--- a/app/models/follow_request.rb
+++ b/app/models/follow_request.rb
@@ -26,7 +26,7 @@ class FollowRequest < ApplicationRecord
 
   def authorize!
     account.follow!(target_account, reblogs: show_reblogs, uri: uri)
-    MergeWorker.perform_async(target_account.id, account.id)
+    MergeWorker.perform_async(target_account.id, account.id) if account.local?
     destroy!
   end
 
diff --git a/app/models/form/account_batch.rb b/app/models/form/account_batch.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f1b7a45664f25173a1000a7fdabee37876c77e9f
--- /dev/null
+++ b/app/models/form/account_batch.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+class Form::AccountBatch
+  include ActiveModel::Model
+  include Authorization
+  include Payloadable
+
+  attr_accessor :account_ids, :action, :current_account
+
+  def save
+    case action
+    when 'unfollow'
+      unfollow!
+    when 'remove_from_followers'
+      remove_from_followers!
+    when 'block_domains'
+      block_domains!
+    when 'approve'
+      approve!
+    when 'reject'
+      reject!
+    end
+  end
+
+  private
+
+  def unfollow!
+    accounts.find_each do |target_account|
+      UnfollowService.new.call(current_account, target_account)
+    end
+  end
+
+  def remove_from_followers!
+    current_account.passive_relationships.where(account_id: account_ids).find_each do |follow|
+      reject_follow!(follow)
+    end
+  end
+
+  def block_domains!
+    AfterAccountDomainBlockWorker.push_bulk(account_domains) do |domain|
+      [current_account.id, domain]
+    end
+  end
+
+  def account_domains
+    accounts.pluck(Arel.sql('distinct domain')).compact
+  end
+
+  def accounts
+    Account.where(id: account_ids)
+  end
+
+  def reject_follow!(follow)
+    follow.destroy
+
+    return unless follow.account.activitypub?
+
+    ActivityPub::DeliveryWorker.perform_async(Oj.dump(serialize_payload(follow, ActivityPub::RejectFollowSerializer)), current_account.id, follow.account.inbox_url)
+  end
+
+  def approve!
+    users = accounts.includes(:user).map(&:user)
+
+    users.each { |user| authorize(user, :approve?) }
+         .each(&:approve!)
+  end
+
+  def reject!
+    records = accounts.includes(:user)
+
+    records.each { |account| authorize(account.user, :reject?) }
+           .each { |account| SuspendAccountService.new.call(account, including_user: true, destroy: true, skip_distribution: true) }
+  end
+end
diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb
index eca71bf6214f466efb2782c5b12a04fd19a985f0..86a86ec6661275de64b9d270a358c66674b50718 100644
--- a/app/models/form/admin_settings.rb
+++ b/app/models/form/admin_settings.rb
@@ -3,49 +3,94 @@
 class Form::AdminSettings
   include ActiveModel::Model
 
-  delegate(
-    :site_contact_username,
-    :site_contact_username=,
-    :site_contact_email,
-    :site_contact_email=,
-    :site_title,
-    :site_title=,
-    :site_short_description,
-    :site_short_description=,
-    :site_description,
-    :site_description=,
-    :site_extended_description,
-    :site_extended_description=,
-    :site_terms,
-    :site_terms=,
-    :open_registrations,
-    :open_registrations=,
-    :closed_registrations_message,
-    :closed_registrations_message=,
-    :open_deletion,
-    :open_deletion=,
-    :timeline_preview,
-    :timeline_preview=,
-    :show_staff_badge,
-    :show_staff_badge=,
-    :bootstrap_timeline_accounts,
-    :bootstrap_timeline_accounts=,
-    :theme,
-    :theme=,
-    :min_invite_role,
-    :min_invite_role=,
-    :activity_api_enabled,
-    :activity_api_enabled=,
-    :peers_api_enabled,
-    :peers_api_enabled=,
-    :show_known_fediverse_at_about_page,
-    :show_known_fediverse_at_about_page=,
-    :preview_sensitive_media,
-    :preview_sensitive_media=,
-    :custom_css,
-    :custom_css=,
-    :profile_directory,
-    :profile_directory=,
-    to: Setting
-  )
+  KEYS = %i(
+    site_contact_username
+    site_contact_email
+    site_title
+    site_short_description
+    site_description
+    site_extended_description
+    site_terms
+    registrations_mode
+    closed_registrations_message
+    open_deletion
+    timeline_preview
+    show_staff_badge
+    bootstrap_timeline_accounts
+    theme
+    min_invite_role
+    activity_api_enabled
+    peers_api_enabled
+    show_known_fediverse_at_about_page
+    preview_sensitive_media
+    custom_css
+    profile_directory
+    thumbnail
+    hero
+    mascot
+  ).freeze
+
+  BOOLEAN_KEYS = %i(
+    open_deletion
+    timeline_preview
+    show_staff_badge
+    activity_api_enabled
+    peers_api_enabled
+    show_known_fediverse_at_about_page
+    preview_sensitive_media
+    profile_directory
+  ).freeze
+
+  UPLOAD_KEYS = %i(
+    thumbnail
+    hero
+    mascot
+  ).freeze
+
+  attr_accessor(*KEYS)
+
+  validates :site_short_description, :site_description, html: { wrap_with: :p }
+  validates :site_extended_description, :site_terms, :closed_registrations_message, html: true
+  validates :registrations_mode, inclusion: { in: %w(open approved none) }
+  validates :min_invite_role, inclusion: { in: %w(disabled user moderator admin) }
+  validates :site_contact_email, :site_contact_username, presence: true
+  validates :site_contact_username, existing_username: true
+  validates :bootstrap_timeline_accounts, existing_username: { multiple: true }
+
+  def initialize(_attributes = {})
+    super
+    initialize_attributes
+  end
+
+  def save
+    return false unless valid?
+
+    KEYS.each do |key|
+      value = instance_variable_get("@#{key}")
+
+      if UPLOAD_KEYS.include?(key) && !value.nil?
+        upload = SiteUpload.where(var: key).first_or_initialize(var: key)
+        upload.update(file: value)
+      else
+        setting = Setting.where(var: key).first_or_initialize(var: key)
+        setting.update(value: typecast_value(key, value))
+      end
+    end
+  end
+
+  private
+
+  def initialize_attributes
+    KEYS.each do |key|
+      instance_variable_set("@#{key}", Setting.public_send(key)) if instance_variable_get("@#{key}").nil?
+    end
+  end
+
+  def typecast_value(key, value)
+    if BOOLEAN_KEYS.include?(key)
+      value == '1'
+    else
+      value
+    end
+  end
 end
diff --git a/app/models/form/status_batch.rb b/app/models/form/status_batch.rb
index 89872806754ed9da47289f45dae468a970dce910..933dfdaca1ba5a7465093b921833b05f6da960f5 100644
--- a/app/models/form/status_batch.rb
+++ b/app/models/form/status_batch.rb
@@ -35,6 +35,7 @@ class Form::StatusBatch
   def delete_statuses
     Status.where(id: status_ids).reorder(nil).find_each do |status|
       RemovalWorker.perform_async(status.id)
+      Tombstone.find_or_create_by(uri: status.uri, account: status.account, by_moderator: true)
       log_action :destroy, status
     end
 
diff --git a/app/models/import.rb b/app/models/import.rb
index 55e970b0d8716775f2c41f26d397b5eb0610a814..a7a0d806577f2a185049bfba7725d4d5e935ea9e 100644
--- a/app/models/import.rb
+++ b/app/models/import.rb
@@ -13,20 +13,30 @@
 #  data_file_size    :integer
 #  data_updated_at   :datetime
 #  account_id        :bigint(8)        not null
+#  overwrite         :boolean          default(FALSE), not null
 #
 
 class Import < ApplicationRecord
-  FILE_TYPES = ['text/plain', 'text/csv'].freeze
+  FILE_TYPES = %w(text/plain text/csv).freeze
+  MODES = %i(merge overwrite).freeze
 
   self.inheritance_column = false
 
   belongs_to :account
 
-  enum type: [:following, :blocking, :muting]
+  enum type: [:following, :blocking, :muting, :domain_blocking]
 
   validates :type, presence: true
 
   has_attached_file :data
   validates_attachment_content_type :data, content_type: FILE_TYPES
   validates_attachment_presence :data
+
+  def mode
+    overwrite? ? :overwrite : :merge
+  end
+
+  def mode=(str)
+    self.overwrite = str.to_sym == :overwrite
+  end
 end
diff --git a/app/models/instance.rb b/app/models/instance.rb
index 7448d465c3c4eaf90a48b820d13352fdf3f4f3b8..797a191e07698294b7f82b91aa96209171e4213c 100644
--- a/app/models/instance.rb
+++ b/app/models/instance.rb
@@ -7,12 +7,12 @@ class Instance
 
   def initialize(resource)
     @domain         = resource.domain
-    @accounts_count = resource.accounts_count
-    @domain_block   = resource.is_a?(DomainBlock) ? resource : DomainBlock.find_by(domain: domain)
+    @accounts_count = resource.is_a?(DomainBlock) ? nil : resource.accounts_count
+    @domain_block   = resource.is_a?(DomainBlock) ? resource : DomainBlock.rule_for(domain)
   end
 
-  def cached_sample_accounts
-    Rails.cache.fetch("#{cache_key}/sample_accounts", expires_in: 12.hours) { Account.where(domain: domain).searchable.joins(:account_stat).popular.limit(3) }
+  def countable?
+    @accounts_count.present?
   end
 
   def to_param
diff --git a/app/models/instance_filter.rb b/app/models/instance_filter.rb
index 3483d8cd6e996ec7104909e1d37a7761c56a8372..848fff53e15c5ee416224e39624d64b96295bc8c 100644
--- a/app/models/instance_filter.rb
+++ b/app/models/instance_filter.rb
@@ -9,9 +9,13 @@ class InstanceFilter
 
   def results
     if params[:limited].present?
-      DomainBlock.order(id: :desc)
+      scope = DomainBlock
+      scope = scope.matches_domain(params[:by_domain]) if params[:by_domain].present?
+      scope.order(id: :desc)
     else
-      Account.remote.by_domain_accounts
+      scope = Account.remote
+      scope = scope.matches_domain(params[:by_domain]) if params[:by_domain].present?
+      scope.by_domain_accounts
     end
   end
 end
diff --git a/app/models/invite.rb b/app/models/invite.rb
index fe23224625f8d15ca4eff0c41f68ec2f5ecec1d4..02ab8e0b2170926fc0e1125163615643f8b5115f 100644
--- a/app/models/invite.rb
+++ b/app/models/invite.rb
@@ -17,7 +17,7 @@
 class Invite < ApplicationRecord
   include Expireable
 
-  belongs_to :user
+  belongs_to :user, inverse_of: :invites
   has_many :users, inverse_of: :invite
 
   scope :available, -> { where(expires_at: nil).or(where('expires_at >= ?', Time.now.utc)) }
@@ -25,7 +25,7 @@ class Invite < ApplicationRecord
   before_validation :set_code
 
   def valid_for_use?
-    (max_uses.nil? || uses < max_uses) && !expired?
+    (max_uses.nil? || uses < max_uses) && !expired? && !(user.nil? || user.disabled?)
   end
 
   private
diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb
index 6b939124fa44e7378222632b5fa7a107073e1542..b1c5589478fb194f88a2b11f1a930af328459465 100644
--- a/app/models/media_attachment.rb
+++ b/app/models/media_attachment.rb
@@ -18,19 +18,27 @@
 #  account_id          :bigint(8)
 #  description         :text
 #  scheduled_status_id :bigint(8)
+#  blurhash            :string
 #
 
 class MediaAttachment < ApplicationRecord
   self.inheritance_column = nil
 
-  enum type: [:image, :gifv, :video, :unknown]
+  enum type: [:image, :gifv, :video, :unknown, :audio]
 
-  IMAGE_FILE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif'].freeze
+  IMAGE_FILE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif', '.webp'].freeze
   VIDEO_FILE_EXTENSIONS = ['.webm', '.mp4', '.m4v', '.mov'].freeze
+  AUDIO_FILE_EXTENSIONS = ['.ogg', '.oga', '.mp3', '.wav', '.flac', '.opus'].freeze
 
-  IMAGE_MIME_TYPES             = ['image/jpeg', 'image/png', 'image/gif'].freeze
-  VIDEO_MIME_TYPES             = ['video/webm', 'video/mp4', 'video/quicktime'].freeze
+  IMAGE_MIME_TYPES             = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'].freeze
+  VIDEO_MIME_TYPES             = ['video/webm', 'video/mp4', 'video/quicktime', 'video/ogg'].freeze
   VIDEO_CONVERTIBLE_MIME_TYPES = ['video/webm', 'video/quicktime'].freeze
+  AUDIO_MIME_TYPES             = ['audio/wave', 'audio/wav', 'audio/x-wav', 'audio/x-pn-wave', 'audio/ogg', 'audio/mpeg', 'audio/mp3', 'audio/webm', 'audio/flac'].freeze
+
+  BLURHASH_OPTIONS = {
+    x_comp: 4,
+    y_comp: 4,
+  }.freeze
 
   IMAGE_STYLES = {
     original: {
@@ -41,6 +49,7 @@ class MediaAttachment < ApplicationRecord
     small: {
       pixels: 160_000, # 400x400px
       file_geometry_parser: FastGeometryParser,
+      blurhash: BLURHASH_OPTIONS,
     },
   }.freeze
 
@@ -53,11 +62,26 @@ class MediaAttachment < ApplicationRecord
       },
       format: 'png',
       time: 0,
+      file_geometry_parser: FastGeometryParser,
+      blurhash: BLURHASH_OPTIONS,
+    },
+  }.freeze
+
+  AUDIO_STYLES = {
+    original: {
+      format: 'mp3',
+      content_type: 'audio/mpeg',
+      convert_options: {
+        output: {
+          'q:a' => 2,
+        },
+      },
     },
   }.freeze
 
   VIDEO_FORMAT = {
     format: 'mp4',
+    content_type: 'video/mp4',
     convert_options: {
       output: {
         'loglevel' => 'fatal',
@@ -74,6 +98,11 @@ class MediaAttachment < ApplicationRecord
     },
   }.freeze
 
+  VIDEO_CONVERTED_STYLES = {
+    small: VIDEO_STYLES[:small],
+    original: VIDEO_FORMAT,
+  }.freeze
+
   IMAGE_LIMIT = 8.megabytes
   VIDEO_LIMIT = 40.megabytes
 
@@ -84,11 +113,11 @@ class MediaAttachment < ApplicationRecord
   has_attached_file :file,
                     styles: ->(f) { file_styles f },
                     processors: ->(f) { file_processors f },
-                    convert_options: { all: '-quality 90 -strip' }
+                    convert_options: { all: '-quality 90 -strip +set modify-date +set create-date' }
 
-  validates_attachment_content_type :file, content_type: IMAGE_MIME_TYPES + VIDEO_MIME_TYPES
-  validates_attachment_size :file, less_than: IMAGE_LIMIT, unless: :video?
-  validates_attachment_size :file, less_than: VIDEO_LIMIT, if: :video?
+  validates_attachment_content_type :file, content_type: IMAGE_MIME_TYPES + VIDEO_MIME_TYPES + AUDIO_MIME_TYPES
+  validates_attachment_size :file, less_than: IMAGE_LIMIT, unless: :larger_media_format?
+  validates_attachment_size :file, less_than: VIDEO_LIMIT, if: :larger_media_format?
   remotable_attachment :file, VIDEO_LIMIT
 
   include Attachmentable
@@ -111,6 +140,14 @@ class MediaAttachment < ApplicationRecord
     file.blank? && remote_url.present?
   end
 
+  def larger_media_format?
+    video? || gifv? || audio?
+  end
+
+  def audio_or_video?
+    audio? || video?
+  end
+
   def to_param
     shortcode
   end
@@ -140,33 +177,37 @@ class MediaAttachment < ApplicationRecord
   before_save :set_meta
 
   class << self
+    def supported_mime_types
+      IMAGE_MIME_TYPES + VIDEO_MIME_TYPES + AUDIO_MIME_TYPES
+    end
+
+    def supported_file_extensions
+      IMAGE_FILE_EXTENSIONS + VIDEO_FILE_EXTENSIONS + AUDIO_FILE_EXTENSIONS
+    end
+
     private
 
     def file_styles(f)
-      if f.instance.file_content_type == 'image/gif'
-        {
-          small: IMAGE_STYLES[:small],
-          original: VIDEO_FORMAT,
-        }
-      elsif IMAGE_MIME_TYPES.include? f.instance.file_content_type
+      if f.instance.file_content_type == 'image/gif' || VIDEO_CONVERTIBLE_MIME_TYPES.include?(f.instance.file_content_type)
+        VIDEO_CONVERTED_STYLES
+      elsif IMAGE_MIME_TYPES.include?(f.instance.file_content_type)
         IMAGE_STYLES
-      elsif VIDEO_CONVERTIBLE_MIME_TYPES.include?(f.instance.file_content_type)
-        {
-          small: VIDEO_STYLES[:small],
-          original: VIDEO_FORMAT,
-        }
-      else
+      elsif VIDEO_MIME_TYPES.include?(f.instance.file_content_type)
         VIDEO_STYLES
+      else
+        AUDIO_STYLES
       end
     end
 
     def file_processors(f)
       if f.file_content_type == 'image/gif'
-        [:gif_transcoder]
-      elsif VIDEO_MIME_TYPES.include? f.file_content_type
-        [:video_transcoder]
+        [:gif_transcoder, :blurhash_transcoder]
+      elsif VIDEO_MIME_TYPES.include?(f.file_content_type)
+        [:video_transcoder, :blurhash_transcoder, :type_corrector]
+      elsif AUDIO_MIME_TYPES.include?(f.file_content_type)
+        [:transcoder, :type_corrector]
       else
-        [:lazy_thumbnail]
+        [:lazy_thumbnail, :blurhash_transcoder, :type_corrector]
       end
     end
   end
@@ -189,7 +230,15 @@ class MediaAttachment < ApplicationRecord
   end
 
   def set_type_and_extension
-    self.type = VIDEO_MIME_TYPES.include?(file_content_type) ? :video : :image
+    self.type = begin
+      if VIDEO_MIME_TYPES.include?(file_content_type)
+        :video
+      elsif AUDIO_MIME_TYPES.include?(file_content_type)
+        :audio
+      else
+        :image
+      end
+    end
   end
 
   def set_meta
@@ -232,7 +281,7 @@ class MediaAttachment < ApplicationRecord
       frame_rate: movie.frame_rate,
       duration: movie.duration,
       bitrate: movie.bitrate,
-    }
+    }.compact
   end
 
   def reset_parent_cache
diff --git a/app/models/notification.rb b/app/models/notification.rb
index 2f0a9b78c7a040d0065ad8256db0229b216045b9..498673ff13d8630437b2391f3577874098f9a88d 100644
--- a/app/models/notification.rb
+++ b/app/models/notification.rb
@@ -22,9 +22,10 @@ class Notification < ApplicationRecord
     follow:         'Follow',
     follow_request: 'FollowRequest',
     favourite:      'Favourite',
+    poll:           'Poll',
   }.freeze
 
-  STATUS_INCLUDES = [:account, :application, :media_attachments, :tags, active_mentions: :account, reblog: [:account, :application, :media_attachments, :tags, active_mentions: :account]].freeze
+  STATUS_INCLUDES = [:account, :application, :preloadable_poll, :media_attachments, :tags, active_mentions: :account, reblog: [:account, :application, :preloadable_poll, :media_attachments, :tags, active_mentions: :account]].freeze
 
   belongs_to :account, optional: true
   belongs_to :from_account, class_name: 'Account', optional: true
@@ -35,16 +36,21 @@ class Notification < ApplicationRecord
   belongs_to :follow,         foreign_type: 'Follow',        foreign_key: 'activity_id', optional: true
   belongs_to :follow_request, foreign_type: 'FollowRequest', foreign_key: 'activity_id', optional: true
   belongs_to :favourite,      foreign_type: 'Favourite',     foreign_key: 'activity_id', optional: true
+  belongs_to :poll,           foreign_type: 'Poll',          foreign_key: 'activity_id', optional: true
 
   validates :account_id, uniqueness: { scope: [:activity_type, :activity_id] }
   validates :activity_type, inclusion: { in: TYPE_CLASS_MAP.values }
 
-  scope :browserable, ->(exclude_types = []) {
+  scope :browserable, ->(exclude_types = [], account_id = nil) {
     types = TYPE_CLASS_MAP.values - activity_types_from_types(exclude_types + [:follow_request])
-    where(activity_type: types)
+    if account_id.nil?
+      where(activity_type: types)
+    else
+      where(activity_type: types, from_account_id: account_id)
+    end
   }
 
-  cache_associated :from_account, status: STATUS_INCLUDES, mention: [status: STATUS_INCLUDES], favourite: [:account, status: STATUS_INCLUDES], follow: :account
+  cache_associated :from_account, status: STATUS_INCLUDES, mention: [status: STATUS_INCLUDES], favourite: [:account, status: STATUS_INCLUDES], follow: :account, poll: [status: STATUS_INCLUDES]
 
   def type
     @type ||= TYPE_CLASS_MAP.invert[activity_type].to_sym
@@ -58,6 +64,8 @@ class Notification < ApplicationRecord
       favourite&.status
     when :mention
       mention&.status
+    when :poll
+      poll&.status
     end
   end
 
@@ -97,7 +105,7 @@ class Notification < ApplicationRecord
     return unless new_record?
 
     case activity_type
-    when 'Status', 'Follow', 'Favourite', 'FollowRequest'
+    when 'Status', 'Follow', 'Favourite', 'FollowRequest', 'Poll'
       self.from_account_id = activity&.account_id
     when 'Mention'
       self.from_account_id = activity&.status&.account_id
diff --git a/app/models/poll.rb b/app/models/poll.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8f72c7b1124312ae20fc53edf067a6f2f610f4e6
--- /dev/null
+++ b/app/models/poll.rb
@@ -0,0 +1,108 @@
+# frozen_string_literal: true
+# == Schema Information
+#
+# Table name: polls
+#
+#  id              :bigint(8)        not null, primary key
+#  account_id      :bigint(8)
+#  status_id       :bigint(8)
+#  expires_at      :datetime
+#  options         :string           default([]), not null, is an Array
+#  cached_tallies  :bigint(8)        default([]), not null, is an Array
+#  multiple        :boolean          default(FALSE), not null
+#  hide_totals     :boolean          default(FALSE), not null
+#  votes_count     :bigint(8)        default(0), not null
+#  last_fetched_at :datetime
+#  created_at      :datetime         not null
+#  updated_at      :datetime         not null
+#  lock_version    :integer          default(0), not null
+#
+
+class Poll < ApplicationRecord
+  include Expireable
+
+  belongs_to :account
+  belongs_to :status
+
+  has_many :votes, class_name: 'PollVote', inverse_of: :poll, dependent: :destroy
+
+  has_many :notifications, as: :activity, dependent: :destroy
+
+  validates :options, presence: true
+  validates :expires_at, presence: true, if: :local?
+  validates_with PollValidator, on: :create, if: :local?
+
+  scope :attached, -> { where.not(status_id: nil) }
+  scope :unattached, -> { where(status_id: nil) }
+
+  before_validation :prepare_options
+  before_validation :prepare_votes_count
+
+  after_initialize :prepare_cached_tallies
+
+  after_commit :reset_parent_cache, on: :update
+
+  def loaded_options
+    options.map.with_index { |title, key| Option.new(self, key.to_s, title, show_totals_now? ? cached_tallies[key] : nil) }
+  end
+
+  def possibly_stale?
+    remote? && last_fetched_before_expiration? && time_passed_since_last_fetch?
+  end
+
+  def voted?(account)
+    account.id == account_id || votes.where(account: account).exists?
+  end
+
+  delegate :local?, to: :account
+
+  def remote?
+    !local?
+  end
+
+  def emojis
+    @emojis ||= CustomEmoji.from_text(options.join(' '), account.domain)
+  end
+
+  class Option < ActiveModelSerializers::Model
+    attributes :id, :title, :votes_count, :poll
+
+    def initialize(poll, id, title, votes_count)
+      @poll        = poll
+      @id          = id
+      @title       = title
+      @votes_count = votes_count
+    end
+  end
+
+  private
+
+  def prepare_cached_tallies
+    self.cached_tallies = options.map { 0 } if cached_tallies.empty?
+  end
+
+  def prepare_votes_count
+    self.votes_count = cached_tallies.sum unless cached_tallies.empty?
+  end
+
+  def prepare_options
+    self.options = options.map(&:strip).reject(&:blank?)
+  end
+
+  def reset_parent_cache
+    return if status_id.nil?
+    Rails.cache.delete("statuses/#{status_id}")
+  end
+
+  def last_fetched_before_expiration?
+    last_fetched_at.nil? || expires_at.nil? || last_fetched_at < expires_at
+  end
+
+  def time_passed_since_last_fetch?
+    last_fetched_at.nil? || last_fetched_at < 1.minute.ago
+  end
+
+  def show_totals_now?
+    expired? || !hide_totals?
+  end
+end
diff --git a/app/models/poll_vote.rb b/app/models/poll_vote.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ad24eb6914a0e0ad2e54b3b3f7539ae79430bb01
--- /dev/null
+++ b/app/models/poll_vote.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+# == Schema Information
+#
+# Table name: poll_votes
+#
+#  id         :bigint(8)        not null, primary key
+#  account_id :bigint(8)
+#  poll_id    :bigint(8)
+#  choice     :integer          default(0), not null
+#  created_at :datetime         not null
+#  updated_at :datetime         not null
+#  uri        :string
+#
+
+class PollVote < ApplicationRecord
+  belongs_to :account
+  belongs_to :poll, inverse_of: :votes
+
+  validates :choice, presence: true
+  validates_with VoteValidator
+
+  after_create_commit :increment_counter_cache
+
+  delegate :local?, to: :account
+
+  def object_type
+    :vote
+  end
+
+  private
+
+  def increment_counter_cache
+    poll.cached_tallies[choice] = (poll.cached_tallies[choice] || 0) + 1
+    poll.save
+  rescue ActiveRecord::StaleObjectError
+    poll.reload
+    retry
+  end
+end
diff --git a/app/models/preview_card.rb b/app/models/preview_card.rb
index a792b352bd7c34d88e4139116ec99dbd50aeb7f5..f26ea0c748085001a28c459e28569d0daa48b282 100644
--- a/app/models/preview_card.rb
+++ b/app/models/preview_card.rb
@@ -25,7 +25,7 @@
 #
 
 class PreviewCard < ApplicationRecord
-  IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif'].freeze
+  IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'].freeze
   LIMIT = 1.megabytes
 
   self.inheritance_column = false
diff --git a/app/models/relay.rb b/app/models/relay.rb
index 7478c110d4557552a8bdd13192d77a1933787070..6934a5c628760f689ceb60244f07ef3eef06ef9d 100644
--- a/app/models/relay.rb
+++ b/app/models/relay.rb
@@ -29,6 +29,7 @@ class Relay < ApplicationRecord
     payload     = Oj.dump(follow_activity(activity_id))
 
     update!(state: :pending, follow_activity_id: activity_id)
+    DeliveryFailureTracker.new(inbox_url).track_success!
     ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
   end
 
@@ -37,6 +38,7 @@ class Relay < ApplicationRecord
     payload     = Oj.dump(unfollow_activity(activity_id))
 
     update!(state: :idle, follow_activity_id: nil)
+    DeliveryFailureTracker.new(inbox_url).track_success!
     ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
   end
 
diff --git a/app/models/report.rb b/app/models/report.rb
index 2804020f5273bcfca453adea85dc50230dab733e..5192ceef799cceee317fc8322eb23c81b2658596 100644
--- a/app/models/report.rb
+++ b/app/models/report.rb
@@ -13,9 +13,12 @@
 #  action_taken_by_account_id :bigint(8)
 #  target_account_id          :bigint(8)        not null
 #  assigned_account_id        :bigint(8)
+#  uri                        :string
 #
 
 class Report < ApplicationRecord
+  include Paginable
+
   belongs_to :account
   belongs_to :target_account, class_name: 'Account'
   belongs_to :action_taken_by_account, class_name: 'Account', optional: true
@@ -25,9 +28,16 @@ class Report < ApplicationRecord
 
   scope :unresolved, -> { where(action_taken: false) }
   scope :resolved,   -> { where(action_taken: true) }
+  scope :with_accounts, -> { includes([:account, :target_account, :action_taken_by_account, :assigned_account].each_with_object({}) { |k, h| h[k] = { user: [:invite_request, :invite] } }) }
 
   validates :comment, length: { maximum: 1000 }
 
+  def local?
+    false # Force uri_for to use uri attribute
+  end
+
+  before_validation :set_uri, only: :create
+
   def object_type
     :flag
   end
@@ -89,4 +99,8 @@ class Report < ApplicationRecord
 
     Admin::ActionLog.from("(#{sql}) AS admin_action_logs")
   end
+
+  def set_uri
+    self.uri = ActivityPub::TagManager.instance.generate_uri_for(self) if uri.nil? && account.local?
+  end
 end
diff --git a/app/models/report_filter.rb b/app/models/report_filter.rb
index 56ab28df7f13fb744883cb1f955d3dc506bfdcc2..a392d60c3c0b4b927634ee9b45868405b9efeffd 100644
--- a/app/models/report_filter.rb
+++ b/app/models/report_filter.rb
@@ -9,9 +9,11 @@ class ReportFilter
 
   def results
     scope = Report.unresolved
+
     params.each do |key, value|
       scope = scope.merge scope_for(key, value)
     end
+
     scope
   end
 
diff --git a/app/models/site_upload.rb b/app/models/site_upload.rb
index 14d68376727619d8e448c53b851ce392f922283a..cf10b30fc98ee3d23d0d3433b38834584c702eb8 100644
--- a/app/models/site_upload.rb
+++ b/app/models/site_upload.rb
@@ -18,6 +18,7 @@ class SiteUpload < ApplicationRecord
   has_attached_file :file
 
   validates_attachment_content_type :file, content_type: /\Aimage\/.*\z/
+  validates :file, presence: true
   validates :var, presence: true, uniqueness: true
 
   before_save :set_meta
diff --git a/app/models/status.rb b/app/models/status.rb
index 035423b40289d726ce4c7c1c66c73cdb9c5fc6c9..9f934075cf385aa785a4f1049dc8e9c03bf24d07 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -21,6 +21,7 @@
 #  account_id             :bigint(8)        not null
 #  application_id         :bigint(8)
 #  in_reply_to_account_id :bigint(8)
+#  poll_id                :bigint(8)
 #
 
 class Status < ApplicationRecord
@@ -44,6 +45,7 @@ class Status < ApplicationRecord
   belongs_to :account, inverse_of: :statuses
   belongs_to :in_reply_to_account, foreign_key: 'in_reply_to_account_id', class_name: 'Account', optional: true
   belongs_to :conversation, optional: true
+  belongs_to :preloadable_poll, class_name: 'Poll', foreign_key: 'poll_id', optional: true
 
   belongs_to :thread, foreign_key: 'in_reply_to_id', class_name: 'Status', inverse_of: :replies, optional: true
   belongs_to :reblog, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblogs, optional: true
@@ -61,25 +63,29 @@ class Status < ApplicationRecord
   has_one :notification, as: :activity, dependent: :destroy
   has_one :stream_entry, as: :activity, inverse_of: :status
   has_one :status_stat, inverse_of: :status
+  has_one :poll, inverse_of: :status, dependent: :destroy
 
   validates :uri, uniqueness: true, presence: true, unless: :local?
   validates :text, presence: true, unless: -> { with_media? || reblog? }
   validates_with StatusLengthValidator
   validates_with DisallowedHashtagsValidator
   validates :reblog, uniqueness: { scope: :account }, if: :reblog?
+  validates :visibility, exclusion: { in: %w(direct limited) }, if: :reblog?
+
+  accepts_nested_attributes_for :poll
 
   default_scope { recent }
 
   scope :recent, -> { reorder(id: :desc) }
-  scope :remote, -> { where(local: false).or(where.not(uri: nil)) }
+  scope :remote, -> { where(local: false).where.not(uri: nil) }
   scope :local,  -> { where(local: true).or(where(uri: nil)) }
 
   scope :without_replies, -> { where('statuses.reply = FALSE OR statuses.in_reply_to_account_id = statuses.account_id') }
   scope :without_reblogs, -> { where('statuses.reblog_of_id IS NULL') }
   scope :with_public_visibility, -> { where(visibility: :public) }
   scope :tagged_with, ->(tag) { joins(:statuses_tags).where(statuses_tags: { tag_id: tag }) }
-  scope :excluding_silenced_accounts, -> { left_outer_joins(:account).where(accounts: { silenced: false }) }
-  scope :including_silenced_accounts, -> { left_outer_joins(:account).where(accounts: { silenced: true }) }
+  scope :excluding_silenced_accounts, -> { left_outer_joins(:account).where(accounts: { silenced_at: nil }) }
+  scope :including_silenced_accounts, -> { left_outer_joins(:account).where.not(accounts: { silenced_at: nil }) }
   scope :not_excluded_by_account, ->(account) { where.not(account_id: account.excluded_from_timeline_account_ids) }
   scope :not_domain_blocked_by_account, ->(account) { account.excluded_from_timeline_domains.blank? ? left_outer_joins(:account) : left_outer_joins(:account).where('accounts.domain IS NULL OR accounts.domain NOT IN (?)', account.excluded_from_timeline_domains) }
   scope :tagged_with_all, ->(tags) {
@@ -101,6 +107,7 @@ class Status < ApplicationRecord
                    :tags,
                    :preview_cards,
                    :stream_entry,
+                   :preloadable_poll,
                    account: :account_stat,
                    active_mentions: { account: :account_stat },
                    reblog: [
@@ -111,6 +118,7 @@ class Status < ApplicationRecord
                      :media_attachments,
                      :conversation,
                      :status_stat,
+                     :preloadable_poll,
                      account: :account_stat,
                      active_mentions: { account: :account_stat },
                    ],
@@ -196,6 +204,8 @@ class Status < ApplicationRecord
     public_visibility? || unlisted_visibility?
   end
 
+  alias sign? distributable?
+
   def with_media?
     media_attachments.any?
   end
@@ -205,7 +215,12 @@ class Status < ApplicationRecord
   end
 
   def emojis
-    @emojis ||= CustomEmoji.from_text([spoiler_text, text].join(' '), account.domain)
+    return @emojis if defined?(@emojis)
+
+    fields  = [spoiler_text, text]
+    fields += preloadable_poll.options unless preloadable_poll.nil?
+
+    @emojis = CustomEmoji.from_text(fields.join(' '), account.domain)
   end
 
   def mark_for_mass_destruction!
@@ -250,6 +265,8 @@ class Status < ApplicationRecord
   before_validation :set_conversation
   before_validation :set_local
 
+  after_create :set_poll_id
+
   class << self
     def selectable_visibilities
       visibilities.keys - %w(direct limited)
@@ -438,9 +455,13 @@ class Status < ApplicationRecord
     self.reblog = reblog.reblog if reblog? && reblog.reblog?
   end
 
+  def set_poll_id
+    update_column(:poll_id, poll.id) unless poll.nil?
+  end
+
   def set_visibility
+    self.visibility = reblog.visibility if reblog? && visibility.nil?
     self.visibility = (account.locked? ? :private : :public) if visibility.nil?
-    self.visibility = reblog.visibility if reblog?
     self.sensitive  = false if sensitive.nil?
   end
 
@@ -478,7 +499,7 @@ class Status < ApplicationRecord
     return if direct_visibility?
 
     account&.increment_count!(:statuses_count)
-    reblog&.increment_count!(:reblogs_count) if reblog? && (public_visibility? || unlisted_visibility?)
+    reblog&.increment_count!(:reblogs_count) if reblog?
     thread&.increment_count!(:replies_count) if in_reply_to_id.present? && (public_visibility? || unlisted_visibility?)
   end
 
@@ -486,7 +507,7 @@ class Status < ApplicationRecord
     return if direct_visibility? || marked_for_mass_destruction?
 
     account&.decrement_count!(:statuses_count)
-    reblog&.decrement_count!(:reblogs_count) if reblog? && (public_visibility? || unlisted_visibility?)
+    reblog&.decrement_count!(:reblogs_count) if reblog?
     thread&.decrement_count!(:replies_count) if in_reply_to_id.present? && (public_visibility? || unlisted_visibility?)
   end
 
diff --git a/app/models/tag.rb b/app/models/tag.rb
index 99830ae92c66e95fb9004ba245f878ddf56f99c0..b371d59c1be396a5070e12d913aff4b6fe616e27 100644
--- a/app/models/tag.rb
+++ b/app/models/tag.rb
@@ -14,15 +14,17 @@ class Tag < ApplicationRecord
   has_and_belongs_to_many :accounts
   has_and_belongs_to_many :sample_accounts, -> { searchable.discoverable.popular.limit(3) }, class_name: 'Account'
 
+  has_many :featured_tags, dependent: :destroy, inverse_of: :tag
   has_one :account_tag_stat, dependent: :destroy
 
-  HASHTAG_NAME_RE = '[[:word:]_]*[[:alpha:]_·][[:word:]_]*'
+  HASHTAG_NAME_RE = '([[:word:]_][[:word:]_·]*[[:alpha:]_·][[:word:]_·]*[[:word:]_])|([[:word:]_]*[[:alpha:]][[:word:]_]*)'
   HASHTAG_RE = /(?:^|[^\/\)\w])#(#{HASHTAG_NAME_RE})/i
 
-  validates :name, presence: true, uniqueness: true, format: { with: /\A#{HASHTAG_NAME_RE}\z/i }
+  validates :name, presence: true, uniqueness: true, format: { with: /\A(#{HASHTAG_NAME_RE})\z/i }
 
   scope :discoverable, -> { joins(:account_tag_stat).where(AccountTagStat.arel_table[:accounts_count].gt(0)).where(account_tag_stats: { hidden: false }).order(Arel.sql('account_tag_stats.accounts_count desc')) }
   scope :hidden, -> { where(account_tag_stats: { hidden: true }) }
+  scope :most_used, ->(account) { joins(:statuses).where(statuses: { account: account }).group(:id).order(Arel.sql('count(*) desc')) }
 
   delegate :accounts_count,
            :accounts_count=,
@@ -62,9 +64,21 @@ class Tag < ApplicationRecord
   end
 
   class << self
-    def search_for(term, limit = 5)
+    def search_for(term, limit = 5, offset = 0)
       pattern = sanitize_sql_like(term.strip) + '%'
-      Tag.where('lower(name) like lower(?)', pattern).order(:name).limit(limit)
+
+      Tag.where('lower(name) like lower(?)', pattern)
+         .order(:name)
+         .limit(limit)
+         .offset(offset)
+    end
+
+    def find_normalized(name)
+      find_by(name: name.mb_chars.downcase.to_s)
+    end
+
+    def find_normalized!(name)
+      find_normalized(name) || raise(ActiveRecord::RecordNotFound)
     end
   end
 
diff --git a/app/models/tombstone.rb b/app/models/tombstone.rb
index 997bb65fd068c4b0f33e8ba03e363e3338de1e4e..bf666c43ac19933c3c015baa2fd78a88352517a1 100644
--- a/app/models/tombstone.rb
+++ b/app/models/tombstone.rb
@@ -4,11 +4,12 @@
 #
 # Table name: tombstones
 #
-#  id         :bigint(8)        not null, primary key
-#  account_id :bigint(8)
-#  uri        :string           not null
-#  created_at :datetime         not null
-#  updated_at :datetime         not null
+#  id           :bigint(8)        not null, primary key
+#  account_id   :bigint(8)
+#  uri          :string           not null
+#  created_at   :datetime         not null
+#  updated_at   :datetime         not null
+#  by_moderator :boolean
 #
 
 class Tombstone < ApplicationRecord
diff --git a/app/models/trending_tags.rb b/app/models/trending_tags.rb
index 3a8be21649b936a2cd5ad02a4e9621472785a8a7..148535c2121e0a2c9d783a8fb971226ac5d00e29 100644
--- a/app/models/trending_tags.rb
+++ b/app/models/trending_tags.rb
@@ -7,6 +7,8 @@ class TrendingTags
   THRESHOLD            = 5
 
   class << self
+    include Redisable
+
     def record_use!(tag, account, at_time = Time.now.utc)
       return if disallowed_hashtags.include?(tag.name) || account.silenced? || account.bot?
 
@@ -59,9 +61,5 @@ class TrendingTags
       @disallowed_hashtags = @disallowed_hashtags.split(' ') if @disallowed_hashtags.is_a? String
       @disallowed_hashtags = @disallowed_hashtags.map(&:downcase)
     end
-
-    def redis
-      Redis.current
-    end
   end
 end
diff --git a/app/models/user.rb b/app/models/user.rb
index 5aa5c2b15c4a6be9b64fc822092785dc6a9811cc..a44c9c9c1d576b8f5e0ac5b2964bcfb0f63d3e67 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -37,11 +37,12 @@
 #  remember_token            :string
 #  chosen_languages          :string           is an Array
 #  created_by_application_id :bigint(8)
+#  approved                  :boolean          default(TRUE), not null
 #
 
 class User < ApplicationRecord
   include Settings::Extend
-  include Omniauthable
+  include UserRoles
 
   # The home and list feeds will be stored in Redis for this amount
   # of time, and status fan-out to followers will include only people
@@ -61,9 +62,9 @@ class User < ApplicationRecord
   devise :registerable, :recoverable, :rememberable, :trackable, :validatable,
          :confirmable
 
-  devise :pam_authenticatable if ENV['PAM_ENABLED'] == 'true'
-
-  devise :omniauthable
+  include Omniauthable
+  include PamAuthenticable
+  include LdapAuthenticable
 
   belongs_to :account, inverse_of: :user
   belongs_to :invite, counter_cache: :uses, optional: true
@@ -72,24 +73,29 @@ class User < ApplicationRecord
 
   has_many :applications, class_name: 'Doorkeeper::Application', as: :owner
   has_many :backups, inverse_of: :user
+  has_many :invites, inverse_of: :user
+
+  has_one :invite_request, class_name: 'UserInviteRequest', inverse_of: :user, dependent: :destroy
+  accepts_nested_attributes_for :invite_request, reject_if: ->(attributes) { attributes['text'].blank? }
 
   validates :locale, inclusion: I18n.available_locales.map(&:to_s), if: :locale?
-  validates_with BlacklistedEmailValidator, if: :email_changed?
+  validates_with BlacklistedEmailValidator, on: :create
   validates_with EmailMxValidator, if: :validate_email_dns?
   validates :agreement, acceptance: { allow_nil: false, accept: [true, 'true', '1'] }, on: :create
 
   scope :recent, -> { order(id: :desc) }
-  scope :admins, -> { where(admin: true) }
-  scope :moderators, -> { where(moderator: true) }
-  scope :staff, -> { admins.or(moderators) }
+  scope :pending, -> { where(approved: false) }
+  scope :approved, -> { where(approved: true) }
   scope :confirmed, -> { where.not(confirmed_at: nil) }
   scope :enabled, -> { where(disabled: false) }
+  scope :disabled, -> { where(disabled: true) }
   scope :inactive, -> { where(arel_table[:current_sign_in_at].lt(ACTIVE_DURATION.ago)) }
-  scope :active, -> { confirmed.where(arel_table[:current_sign_in_at].gteq(ACTIVE_DURATION.ago)).joins(:account).where(accounts: { suspended: false }) }
+  scope :active, -> { confirmed.where(arel_table[:current_sign_in_at].gteq(ACTIVE_DURATION.ago)).joins(:account).where(accounts: { suspended_at: nil }) }
   scope :matches_email, ->(value) { where(arel_table[:email].matches("#{value}%")) }
   scope :emailable, -> { confirmed.enabled.joins(:account).merge(Account.searchable) }
 
   before_validation :sanitize_languages
+  before_create :set_approved
 
   # This avoids a deprecation warning from Rails 5.1
   # It seems possible that a future release of devise-two-factor will
@@ -100,42 +106,11 @@ class User < ApplicationRecord
 
   delegate :auto_play_gif, :default_sensitive, :unfollow_modal, :boost_modal, :delete_modal,
            :reduce_motion, :system_font_ui, :noindex, :theme, :display_media, :hide_network,
-           :expand_spoilers, :default_language, :aggregate_reblogs, to: :settings, prefix: :setting, allow_nil: false
+           :expand_spoilers, :default_language, :aggregate_reblogs, :show_application,
+           :advanced_layout, to: :settings, prefix: :setting, allow_nil: false
 
   attr_reader :invite_code
-
-  def pam_conflict(_)
-    # block pam login tries on traditional account
-    nil
-  end
-
-  def pam_conflict?
-    return false unless Devise.pam_authentication
-    encrypted_password.present? && pam_managed_user?
-  end
-
-  def pam_get_name
-    return account.username if account.present?
-    super
-  end
-
-  def pam_setup(_attributes)
-    acc = Account.new(username: pam_get_name)
-    acc.save!(validate: false)
-
-    self.email = "#{acc.username}@#{find_pam_suffix}" if email.nil? && find_pam_suffix
-    self.confirmed_at = Time.now.utc
-    self.admin = false
-    self.account = acc
-
-    acc.destroy! unless save
-  end
-
-  def ldap_setup(_attributes)
-    self.confirmed_at = Time.now.utc
-    self.admin = false
-    save!
-  end
+  attr_writer :external
 
   def confirmed?
     confirmed_at.present?
@@ -145,31 +120,8 @@ class User < ApplicationRecord
     invite_id.present?
   end
 
-  def staff?
-    admin? || moderator?
-  end
-
-  def role
-    if admin?
-      'admin'
-    elsif moderator?
-      'moderator'
-    else
-      'user'
-    end
-  end
-
-  def role?(role)
-    case role
-    when 'user'
-      true
-    when 'moderator'
-      staff?
-    when 'admin'
-      admin?
-    else
-      false
-    end
+  def valid_invitation?
+    invite_id.present? && invite.valid_for_use?
   end
 
   def disable!
@@ -183,39 +135,50 @@ class User < ApplicationRecord
   end
 
   def confirm
-    new_user = !confirmed?
+    new_user      = !confirmed?
+    self.approved = true if open_registrations?
 
     super
-    prepare_new_user! if new_user
+
+    if new_user && approved?
+      prepare_new_user!
+    elsif new_user
+      notify_staff_about_pending_account!
+    end
   end
 
   def confirm!
-    new_user = !confirmed?
+    new_user      = !confirmed?
+    self.approved = true if open_registrations?
 
     skip_confirmation!
     save!
-    prepare_new_user! if new_user
+
+    prepare_new_user! if new_user && approved?
   end
 
-  def update_tracked_fields!(request)
-    super
-    prepare_returning_user!
+  def pending?
+    !approved?
   end
 
-  def promote!
-    if moderator?
-      update!(moderator: false, admin: true)
-    elsif !admin?
-      update!(moderator: true)
-    end
+  def active_for_authentication?
+    super && approved?
   end
 
-  def demote!
-    if admin?
-      update!(admin: false, moderator: true)
-    elsif moderator?
-      update!(moderator: false)
-    end
+  def inactive_message
+    !approved? ? :pending : super
+  end
+
+  def approve!
+    return if approved?
+
+    update!(approved: true)
+    prepare_new_user!
+  end
+
+  def update_tracked_fields!(request)
+    super
+    prepare_returning_user!
   end
 
   def disable_two_factor!
@@ -236,6 +199,10 @@ class User < ApplicationRecord
     settings.notification_emails['report']
   end
 
+  def allows_pending_account_emails?
+    settings.notification_emails['pending_account']
+  end
+
   def hides_network?
     @hides_network ||= settings.hide_network
   end
@@ -244,6 +211,10 @@ class User < ApplicationRecord
     @aggregates_reblogs ||= settings.aggregate_reblogs
   end
 
+  def shows_application?
+    @shows_application ||= settings.show_application
+  end
+
   def token_for_app(a)
     return nil if a.nil? || a.owner != self
     Doorkeeper::AccessToken
@@ -293,41 +264,6 @@ class User < ApplicationRecord
     super
   end
 
-  def self.pam_get_user(attributes = {})
-    return nil unless attributes[:email]
-    resource =
-      if Devise.check_at_sign && !attributes[:email].index('@')
-        joins(:account).find_by(accounts: { username: attributes[:email] })
-      else
-        find_by(email: attributes[:email])
-      end
-
-    if resource.blank?
-      resource = new(email: attributes[:email], agreement: true)
-      if Devise.check_at_sign && !resource[:email].index('@')
-        resource[:email] = Rpam2.getenv(resource.find_pam_service, attributes[:email], attributes[:password], 'email', false)
-        resource[:email] = "#{attributes[:email]}@#{resource.find_pam_suffix}" unless resource[:email]
-      end
-    end
-    resource
-  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, agreement: true, 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
-  end
-
   def show_all_media?
     setting_display_media == 'show_all'
   end
@@ -344,6 +280,18 @@ class User < ApplicationRecord
 
   private
 
+  def set_approved
+    self.approved = open_registrations? || valid_invitation? || external?
+  end
+
+  def open_registrations?
+    Setting.registrations_mode == 'open'
+  end
+
+  def external?
+    !!@external
+  end
+
   def sanitize_languages
     return if chosen_languages.nil?
     chosen_languages.reject!(&:blank?)
@@ -361,6 +309,13 @@ class User < ApplicationRecord
     regenerate_feed! if needs_feed_update?
   end
 
+  def notify_staff_about_pending_account!
+    User.staff.includes(:account).each do |u|
+      next unless u.allows_pending_account_emails?
+      AdminMailer.new_pending_account(u.account, self).deliver_later
+    end
+  end
+
   def regenerate_feed!
     return unless Redis.current.setnx("account:#{account_id}:regeneration", true)
     Redis.current.expire("account:#{account_id}:regeneration", 1.day.seconds)
diff --git a/app/models/user_invite_request.rb b/app/models/user_invite_request.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2b76c88b944dcd491bd1cb4760ebef0fc3d8aa95
--- /dev/null
+++ b/app/models/user_invite_request.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+# == Schema Information
+#
+# Table name: user_invite_requests
+#
+#  id         :bigint(8)        not null, primary key
+#  user_id    :bigint(8)
+#  text       :text
+#  created_at :datetime         not null
+#  updated_at :datetime         not null
+#
+
+class UserInviteRequest < ApplicationRecord
+  belongs_to :user, inverse_of: :invite_request
+  validates :text, presence: true, length: { maximum: 420 }
+end
diff --git a/app/policies/poll_policy.rb b/app/policies/poll_policy.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9d69eb5bb832b3c7d77a7eb6f5c968df0de0e7c7
--- /dev/null
+++ b/app/policies/poll_policy.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class PollPolicy < ApplicationPolicy
+  def vote?
+    StatusPolicy.new(current_account, record.status).show? && !current_account.blocking?(record.account) && !record.account.blocking?(current_account)
+  end
+end
diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb
index 57af5c61c86b32b7cd32aacdcbde5462de9d4145..d832bff75d4daaea2544b59b45596b7b2a6c0b49 100644
--- a/app/policies/user_policy.rb
+++ b/app/policies/user_policy.rb
@@ -21,6 +21,14 @@ class UserPolicy < ApplicationPolicy
     staff?
   end
 
+  def approve?
+    staff? && !record.approved?
+  end
+
+  def reject?
+    staff? && !record.approved?
+  end
+
   def disable?
     staff? && !record.admin?
   end
@@ -36,7 +44,7 @@ class UserPolicy < ApplicationPolicy
   private
 
   def promoteable?
-    !record.staff? || !record.admin?
+    record.approved? && (!record.staff? || !record.admin?)
   end
 
   def demoteable?
diff --git a/app/presenters/account_relationships_presenter.rb b/app/presenters/account_relationships_presenter.rb
index e4aaa65f6ff706fb742178c290861f3d83b9b878..b05673a3d46103d6966708b948cccbedb9754869 100644
--- a/app/presenters/account_relationships_presenter.rb
+++ b/app/presenters/account_relationships_presenter.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class AccountRelationshipsPresenter
-  attr_reader :following, :followed_by, :blocking,
+  attr_reader :following, :followed_by, :blocking, :blocked_by,
               :muting, :requested, :domain_blocking,
               :endorsed
 
@@ -12,6 +12,7 @@ class AccountRelationshipsPresenter
     @following       = cached[:following].merge(Account.following_map(@uncached_account_ids, @current_account_id))
     @followed_by     = cached[:followed_by].merge(Account.followed_by_map(@uncached_account_ids, @current_account_id))
     @blocking        = cached[:blocking].merge(Account.blocking_map(@uncached_account_ids, @current_account_id))
+    @blocked_by      = cached[:blocked_by].merge(Account.blocked_by_map(@uncached_account_ids, @current_account_id))
     @muting          = cached[:muting].merge(Account.muting_map(@uncached_account_ids, @current_account_id))
     @requested       = cached[:requested].merge(Account.requested_map(@uncached_account_ids, @current_account_id))
     @domain_blocking = cached[:domain_blocking].merge(Account.domain_blocking_map(@uncached_account_ids, @current_account_id))
@@ -22,6 +23,7 @@ class AccountRelationshipsPresenter
     @following.merge!(options[:following_map] || {})
     @followed_by.merge!(options[:followed_by_map] || {})
     @blocking.merge!(options[:blocking_map] || {})
+    @blocked_by.merge!(options[:blocked_by_map] || {})
     @muting.merge!(options[:muting_map] || {})
     @requested.merge!(options[:requested_map] || {})
     @domain_blocking.merge!(options[:domain_blocking_map] || {})
@@ -37,6 +39,7 @@ class AccountRelationshipsPresenter
       following: {},
       followed_by: {},
       blocking: {},
+      blocked_by: {},
       muting: {},
       requested: {},
       domain_blocking: {},
@@ -64,6 +67,7 @@ class AccountRelationshipsPresenter
         following:       { account_id => following[account_id] },
         followed_by:     { account_id => followed_by[account_id] },
         blocking:        { account_id => blocking[account_id] },
+        blocked_by:      { account_id => blocked_by[account_id] },
         muting:          { account_id => muting[account_id] },
         requested:       { account_id => requested[account_id] },
         domain_blocking: { account_id => domain_blocking[account_id] },
diff --git a/app/presenters/activitypub/collection_presenter.rb b/app/presenters/activitypub/collection_presenter.rb
index ec84ab1a3dd8cd40a830674f7791a17c99b14835..28331f0c41d6005880d17b79e260345a8e42cf1e 100644
--- a/app/presenters/activitypub/collection_presenter.rb
+++ b/app/presenters/activitypub/collection_presenter.rb
@@ -1,5 +1,5 @@
 # frozen_string_literal: true
 
 class ActivityPub::CollectionPresenter < ActiveModelSerializers::Model
-  attributes :id, :type, :size, :items, :part_of, :first, :last, :next, :prev
+  attributes :id, :type, :size, :items, :page, :part_of, :first, :last, :next, :prev
 end
diff --git a/app/presenters/instance_presenter.rb b/app/presenters/instance_presenter.rb
index dc77162d441aa3ee8e8f641cc5dacc6e3240a4f1..f3a73209afe56658c78372d3f2b272e5fbcdd10b 100644
--- a/app/presenters/instance_presenter.rb
+++ b/app/presenters/instance_presenter.rb
@@ -2,25 +2,28 @@
 
 class InstancePresenter
   delegate(
-    :closed_registrations_message,
     :site_contact_email,
-    :open_registrations,
     :site_title,
     :site_short_description,
     :site_description,
     :site_extended_description,
     :site_terms,
+    :closed_registrations_message,
     to: Setting
   )
 
   def contact_account
-    Account.find_local(Setting.site_contact_username.gsub(/\A@/, ''))
+    Account.find_local(Setting.site_contact_username.strip.gsub(/\A@/, ''))
   end
 
   def user_count
     Rails.cache.fetch('user_count') { User.confirmed.joins(:account).merge(Account.without_suspended).count }
   end
 
+  def active_user_count
+    Rails.cache.fetch('active_user_count') { Redis.current.pfcount(*(0..3).map { |i| "activity:logins:#{i.weeks.ago.utc.to_date.cweek}" }) }
+  end
+
   def status_count
     Rails.cache.fetch('local_status_count') { Account.local.joins(:account_stat).sum('account_stats.statuses_count') }.to_i
   end
@@ -29,6 +32,10 @@ class InstancePresenter
     Rails.cache.fetch('distinct_domain_count') { Account.distinct.count(:domain) }
   end
 
+  def sample_accounts
+    Rails.cache.fetch('sample_accounts', expires_in: 12.hours) { Account.discoverable.popular.limit(3) }
+  end
+
   def version_number
     Mastodon::Version
   end
diff --git a/app/serializers/activitypub/accept_follow_serializer.rb b/app/serializers/activitypub/accept_follow_serializer.rb
index 3e23591a527492ee5b2869bf1b0293e9d2ffef21..1c1c6ab73bb5783db05276c865d429cadf1fb6c8 100644
--- a/app/serializers/activitypub/accept_follow_serializer.rb
+++ b/app/serializers/activitypub/accept_follow_serializer.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class ActivityPub::AcceptFollowSerializer < ActiveModel::Serializer
+class ActivityPub::AcceptFollowSerializer < ActivityPub::Serializer
   attributes :id, :type, :actor
 
   has_one :object, serializer: ActivityPub::FollowSerializer
diff --git a/app/serializers/activitypub/activity_serializer.rb b/app/serializers/activitypub/activity_serializer.rb
index 50c4f6a049ac43b641df331ba45c29e047675854..c06d5c87ca3855f0a9c6d6dd20c10ec1eebec1df 100644
--- a/app/serializers/activitypub/activity_serializer.rb
+++ b/app/serializers/activitypub/activity_serializer.rb
@@ -1,10 +1,10 @@
 # frozen_string_literal: true
 
-class ActivityPub::ActivitySerializer < ActiveModel::Serializer
+class ActivityPub::ActivitySerializer < ActivityPub::Serializer
   attributes :id, :type, :actor, :published, :to, :cc
 
-  has_one :proper, key: :object, serializer: ActivityPub::NoteSerializer, unless: :announce?
-  attribute :proper_uri, key: :object, if: :announce?
+  has_one :proper, key: :object, serializer: ActivityPub::NoteSerializer, if: :serialize_object?
+  attribute :proper_uri, key: :object, unless: :serialize_object?
   attribute :atom_uri, if: :announce?
 
   def id
@@ -42,4 +42,10 @@ class ActivityPub::ActivitySerializer < ActiveModel::Serializer
   def announce?
     object.reblog?
   end
+
+  def serialize_object?
+    return true unless announce?
+    # Serialize private self-boosts of local toots
+    object.account == object.proper.account && object.proper.private_visibility? && object.local?
+  end
 end
diff --git a/app/serializers/activitypub/actor_serializer.rb b/app/serializers/activitypub/actor_serializer.rb
index 6746c1782929a94fb622de10ede547f2c822c271..0644219fb69bf5babc78e725150f70cfa480dc51 100644
--- a/app/serializers/activitypub/actor_serializer.rb
+++ b/app/serializers/activitypub/actor_serializer.rb
@@ -1,8 +1,13 @@
 # frozen_string_literal: true
 
-class ActivityPub::ActorSerializer < ActiveModel::Serializer
+class ActivityPub::ActorSerializer < ActivityPub::Serializer
   include RoutingHelper
 
+  context :security
+
+  context_extensions :manually_approves_followers, :featured, :also_known_as,
+                     :moved_to, :property_value, :hashtag, :emoji, :identity_proof
+
   attributes :id, :type, :following, :followers,
              :inbox, :outbox, :featured,
              :preferred_username, :name, :summary,
@@ -16,7 +21,7 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer
   attribute :moved_to, if: :moved?
   attribute :also_known_as, if: :also_known_as?
 
-  class EndpointsSerializer < ActiveModel::Serializer
+  class EndpointsSerializer < ActivityPub::Serializer
     include RoutingHelper
 
     attributes :shared_inbox
@@ -110,7 +115,7 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer
   end
 
   def virtual_attachments
-    object.fields
+    object.fields + object.identity_proofs.active
   end
 
   def moved_to
@@ -124,7 +129,7 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer
   class CustomEmojiSerializer < ActivityPub::EmojiSerializer
   end
 
-  class TagSerializer < ActiveModel::Serializer
+  class TagSerializer < ActivityPub::Serializer
     include RoutingHelper
 
     attributes :type, :href, :name
@@ -142,7 +147,7 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer
     end
   end
 
-  class Account::FieldSerializer < ActiveModel::Serializer
+  class Account::FieldSerializer < ActivityPub::Serializer
     attributes :type, :name, :value
 
     def type
@@ -153,4 +158,24 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer
       Formatter.instance.format_field(object.account, object.value)
     end
   end
+
+  class AccountIdentityProofSerializer < ActivityPub::Serializer
+    attributes :type, :name, :signature_algorithm, :signature_value
+
+    def type
+      'IdentityProof'
+    end
+
+    def name
+      object.provider_username
+    end
+
+    def signature_algorithm
+      object.provider
+    end
+
+    def signature_value
+      object.token
+    end
+  end
 end
diff --git a/app/serializers/activitypub/add_serializer.rb b/app/serializers/activitypub/add_serializer.rb
index c0906e8d036418d5318390b107602a266786a706..6f5aab17f95ddb86e2f864e4fa28b4eafd71d165 100644
--- a/app/serializers/activitypub/add_serializer.rb
+++ b/app/serializers/activitypub/add_serializer.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class ActivityPub::AddSerializer < ActiveModel::Serializer
+class ActivityPub::AddSerializer < ActivityPub::Serializer
   include RoutingHelper
 
   attributes :type, :actor, :target
diff --git a/app/serializers/activitypub/block_serializer.rb b/app/serializers/activitypub/block_serializer.rb
index 624ce2fce8107b9ff37786f7a825a991b37b5069..e6c69329d8cb26c761ba0f1e0f4b22ab6136183d 100644
--- a/app/serializers/activitypub/block_serializer.rb
+++ b/app/serializers/activitypub/block_serializer.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class ActivityPub::BlockSerializer < ActiveModel::Serializer
+class ActivityPub::BlockSerializer < ActivityPub::Serializer
   attributes :id, :type, :actor
   attribute :virtual_object, key: :object
 
diff --git a/app/serializers/activitypub/collection_serializer.rb b/app/serializers/activitypub/collection_serializer.rb
index e8960131bb2aded7eb6108247716be6347297a47..da1ba735fc25063c69c83e4aedb88796ce7ed55d 100644
--- a/app/serializers/activitypub/collection_serializer.rb
+++ b/app/serializers/activitypub/collection_serializer.rb
@@ -1,13 +1,14 @@
 # frozen_string_literal: true
 
-class ActivityPub::CollectionSerializer < ActiveModel::Serializer
+class ActivityPub::CollectionSerializer < ActivityPub::Serializer
   def self.serializer_for(model, options)
     return ActivityPub::NoteSerializer if model.class.name == 'Status'
     return ActivityPub::CollectionSerializer if model.class.name == 'ActivityPub::CollectionPresenter'
     super
   end
 
-  attributes :id, :type
+  attribute :id, if: -> { object.id.present? }
+  attribute :type
   attribute :total_items, if: -> { object.size.present? }
   attribute :next, if: -> { object.next.present? }
   attribute :prev, if: -> { object.prev.present? }
@@ -37,6 +38,6 @@ class ActivityPub::CollectionSerializer < ActiveModel::Serializer
   end
 
   def page?
-    object.part_of.present?
+    object.part_of.present? || object.page.present?
   end
 end
diff --git a/app/serializers/activitypub/delete_actor_serializer.rb b/app/serializers/activitypub/delete_actor_serializer.rb
index ddf59be9709ef1cc21af267f935fbb28611ac1cb..a6c5e2385eb266b6e1eed613456adcfe1c92cae3 100644
--- a/app/serializers/activitypub/delete_actor_serializer.rb
+++ b/app/serializers/activitypub/delete_actor_serializer.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class ActivityPub::DeleteActorSerializer < ActiveModel::Serializer
+class ActivityPub::DeleteActorSerializer < ActivityPub::Serializer
   attributes :id, :type, :actor, :to
   attribute :virtual_object, key: :object
 
diff --git a/app/serializers/activitypub/delete_serializer.rb b/app/serializers/activitypub/delete_serializer.rb
index 5012a8383ff517003906f65474636f6b7e2da4db..a7d5bd469856fb6ab1e98472249dadfd56d55066 100644
--- a/app/serializers/activitypub/delete_serializer.rb
+++ b/app/serializers/activitypub/delete_serializer.rb
@@ -1,7 +1,9 @@
 # frozen_string_literal: true
 
-class ActivityPub::DeleteSerializer < ActiveModel::Serializer
-  class TombstoneSerializer < ActiveModel::Serializer
+class ActivityPub::DeleteSerializer < ActivityPub::Serializer
+  class TombstoneSerializer < ActivityPub::Serializer
+    context_extensions :atom_uri
+
     attributes :id, :type, :atom_uri
 
     def id
diff --git a/app/serializers/activitypub/emoji_serializer.rb b/app/serializers/activitypub/emoji_serializer.rb
index 7b06b1e5db2aa5a23814a977c740040774236b4c..4dc38f3ea6e571d6c0d1a362a9f88fb392cf5b90 100644
--- a/app/serializers/activitypub/emoji_serializer.rb
+++ b/app/serializers/activitypub/emoji_serializer.rb
@@ -1,8 +1,10 @@
 # frozen_string_literal: true
 
-class ActivityPub::EmojiSerializer < ActiveModel::Serializer
+class ActivityPub::EmojiSerializer < ActivityPub::Serializer
   include RoutingHelper
 
+  context_extensions :emoji
+
   attributes :id, :type, :name, :updated
 
   has_one :icon, serializer: ActivityPub::ImageSerializer
diff --git a/app/serializers/activitypub/flag_serializer.rb b/app/serializers/activitypub/flag_serializer.rb
index 53e8f726db3131c0b1fa0b080cf3918e7f0b82ff..2f2a707d36299719edb2ca0973b997ac9f81fd7a 100644
--- a/app/serializers/activitypub/flag_serializer.rb
+++ b/app/serializers/activitypub/flag_serializer.rb
@@ -1,11 +1,10 @@
 # frozen_string_literal: true
 
-class ActivityPub::FlagSerializer < ActiveModel::Serializer
+class ActivityPub::FlagSerializer < ActivityPub::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
 
diff --git a/app/serializers/activitypub/follow_serializer.rb b/app/serializers/activitypub/follow_serializer.rb
index bb204ee8f36916e4b1a3a4ca582f86861b93249e..9228d7716e31d7b91f617857775dce81d74f923a 100644
--- a/app/serializers/activitypub/follow_serializer.rb
+++ b/app/serializers/activitypub/follow_serializer.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class ActivityPub::FollowSerializer < ActiveModel::Serializer
+class ActivityPub::FollowSerializer < ActivityPub::Serializer
   attributes :id, :type, :actor
   attribute :virtual_object, key: :object
 
diff --git a/app/serializers/activitypub/image_serializer.rb b/app/serializers/activitypub/image_serializer.rb
index 3c08f77e8313985ff63d42d13dd0870efc2c4998..1060f969149b03cd7a4a5bb87f2813f53afbfd25 100644
--- a/app/serializers/activitypub/image_serializer.rb
+++ b/app/serializers/activitypub/image_serializer.rb
@@ -1,8 +1,10 @@
 # frozen_string_literal: true
 
-class ActivityPub::ImageSerializer < ActiveModel::Serializer
+class ActivityPub::ImageSerializer < ActivityPub::Serializer
   include RoutingHelper
 
+  context_extensions :focal_point
+
   attributes :type, :media_type, :url
   attribute :focal_point, if: :focal_point?
 
diff --git a/app/serializers/activitypub/like_serializer.rb b/app/serializers/activitypub/like_serializer.rb
index c1a7ff6f63743e210afd128004d2523c5af0f7af..0f170ddb4e82777d2e2ae8e4b5bf2e3199b6e29f 100644
--- a/app/serializers/activitypub/like_serializer.rb
+++ b/app/serializers/activitypub/like_serializer.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class ActivityPub::LikeSerializer < ActiveModel::Serializer
+class ActivityPub::LikeSerializer < ActivityPub::Serializer
   attributes :id, :type, :actor
   attribute :virtual_object, key: :object
 
diff --git a/app/serializers/activitypub/note_serializer.rb b/app/serializers/activitypub/note_serializer.rb
index c9d23e25fa8543e6d594fdc3bd39f57bbac8dc6a..67f596e78a65042a85821ae7693047dbfefc9e4e 100644
--- a/app/serializers/activitypub/note_serializer.rb
+++ b/app/serializers/activitypub/note_serializer.rb
@@ -1,6 +1,9 @@
 # frozen_string_literal: true
 
-class ActivityPub::NoteSerializer < ActiveModel::Serializer
+class ActivityPub::NoteSerializer < ActivityPub::Serializer
+  context_extensions :atom_uri, :conversation, :sensitive,
+                     :hashtag, :emoji, :focal_point, :blurhash
+
   attributes :id, :type, :summary,
              :in_reply_to, :published, :url,
              :attributed_to, :to, :cc, :sensitive,
@@ -13,12 +16,20 @@ class ActivityPub::NoteSerializer < ActiveModel::Serializer
   has_many :media_attachments, key: :attachment
   has_many :virtual_tags, key: :tag
 
+  has_one :replies, serializer: ActivityPub::CollectionSerializer, if: :local?
+
+  has_many :poll_options, key: :one_of, if: :poll_and_not_multiple?
+  has_many :poll_options, key: :any_of, if: :poll_and_multiple?
+
+  attribute :end_time, if: :poll_and_expires?
+  attribute :closed, if: :poll_and_expired?
+
   def id
     ActivityPub::TagManager.instance.uri_for(object)
   end
 
   def type
-    'Note'
+    object.preloadable_poll ? 'Question' : 'Note'
   end
 
   def summary
@@ -33,6 +44,22 @@ class ActivityPub::NoteSerializer < ActiveModel::Serializer
     { object.language => Formatter.instance.format(object) }
   end
 
+  def replies
+    replies = object.self_replies(5).pluck(:id, :uri)
+    last_id = replies.last&.first
+
+    ActivityPub::CollectionPresenter.new(
+      type: :unordered,
+      id: ActivityPub::TagManager.instance.replies_uri_for(object),
+      first: ActivityPub::CollectionPresenter.new(
+        type: :unordered,
+        part_of: ActivityPub::TagManager.instance.replies_uri_for(object),
+        items: replies.map(&:second),
+        next: last_id ? ActivityPub::TagManager.instance.replies_uri_for(object, page: true, min_id: last_id) : nil
+      )
+    )
+  end
+
   def language?
     object.language.present?
   end
@@ -97,10 +124,36 @@ class ActivityPub::NoteSerializer < ActiveModel::Serializer
     object.account.local?
   end
 
-  class MediaAttachmentSerializer < ActiveModel::Serializer
+  def poll_options
+    object.preloadable_poll.loaded_options
+  end
+
+  def poll_and_multiple?
+    object.preloadable_poll&.multiple?
+  end
+
+  def poll_and_not_multiple?
+    object.preloadable_poll && !object.preloadable_poll.multiple?
+  end
+
+  def closed
+    object.preloadable_poll.expires_at.iso8601
+  end
+
+  alias end_time closed
+
+  def poll_and_expires?
+    object.preloadable_poll&.expires_at&.present?
+  end
+
+  def poll_and_expired?
+    object.preloadable_poll&.expired?
+  end
+
+  class MediaAttachmentSerializer < ActivityPub::Serializer
     include RoutingHelper
 
-    attributes :type, :media_type, :url, :name
+    attributes :type, :media_type, :url, :name, :blurhash
     attribute :focal_point, if: :focal_point?
 
     def type
@@ -128,7 +181,7 @@ class ActivityPub::NoteSerializer < ActiveModel::Serializer
     end
   end
 
-  class MentionSerializer < ActiveModel::Serializer
+  class MentionSerializer < ActivityPub::Serializer
     attributes :type, :href, :name
 
     def type
@@ -144,7 +197,7 @@ class ActivityPub::NoteSerializer < ActiveModel::Serializer
     end
   end
 
-  class TagSerializer < ActiveModel::Serializer
+  class TagSerializer < ActivityPub::Serializer
     include RoutingHelper
 
     attributes :type, :href, :name
@@ -164,4 +217,34 @@ class ActivityPub::NoteSerializer < ActiveModel::Serializer
 
   class CustomEmojiSerializer < ActivityPub::EmojiSerializer
   end
+
+  class OptionSerializer < ActivityPub::Serializer
+    class RepliesSerializer < ActivityPub::Serializer
+      attributes :type, :total_items
+
+      def type
+        'Collection'
+      end
+
+      def total_items
+        object.votes_count
+      end
+    end
+
+    attributes :type, :name
+
+    has_one :replies, serializer: ActivityPub::NoteSerializer::OptionSerializer::RepliesSerializer
+
+    def type
+      'Note'
+    end
+
+    def name
+      object.title
+    end
+
+    def replies
+      object
+    end
+  end
 end
diff --git a/app/serializers/activitypub/public_key_serializer.rb b/app/serializers/activitypub/public_key_serializer.rb
index 38e9e93baaac97dc6d9b42676df9b875ea0c9116..62ed49e81d27657fc0fc624fb3985052df53ad0a 100644
--- a/app/serializers/activitypub/public_key_serializer.rb
+++ b/app/serializers/activitypub/public_key_serializer.rb
@@ -1,6 +1,8 @@
 # frozen_string_literal: true
 
-class ActivityPub::PublicKeySerializer < ActiveModel::Serializer
+class ActivityPub::PublicKeySerializer < ActivityPub::Serializer
+  context :security
+
   attributes :id, :owner, :public_key_pem
 
   def id
diff --git a/app/serializers/activitypub/reject_follow_serializer.rb b/app/serializers/activitypub/reject_follow_serializer.rb
index 7814f4f5759d450b8a7d58c1b0a9345c767634f2..4996c9a3c35455e76dadc94d68f3b8d2e525da83 100644
--- a/app/serializers/activitypub/reject_follow_serializer.rb
+++ b/app/serializers/activitypub/reject_follow_serializer.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class ActivityPub::RejectFollowSerializer < ActiveModel::Serializer
+class ActivityPub::RejectFollowSerializer < ActivityPub::Serializer
   attributes :id, :type, :actor
 
   has_one :object, serializer: ActivityPub::FollowSerializer
diff --git a/app/serializers/activitypub/remove_serializer.rb b/app/serializers/activitypub/remove_serializer.rb
index c2a5ae1b3a8ac496cf866e27946c308e1f3c5a1c..7fefda59da3ee839cb8196d4b5eed9f21b44249b 100644
--- a/app/serializers/activitypub/remove_serializer.rb
+++ b/app/serializers/activitypub/remove_serializer.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class ActivityPub::RemoveSerializer < ActiveModel::Serializer
+class ActivityPub::RemoveSerializer < ActivityPub::Serializer
   include RoutingHelper
 
   attributes :type, :actor, :target
diff --git a/app/serializers/activitypub/undo_announce_serializer.rb b/app/serializers/activitypub/undo_announce_serializer.rb
index 4fc042727ad6898aae581d824332ba6df3372421..6758af6792afdd4afc845a7d74a92aad6c33bf2d 100644
--- a/app/serializers/activitypub/undo_announce_serializer.rb
+++ b/app/serializers/activitypub/undo_announce_serializer.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class ActivityPub::UndoAnnounceSerializer < ActiveModel::Serializer
+class ActivityPub::UndoAnnounceSerializer < ActivityPub::Serializer
   attributes :id, :type, :actor, :to
 
   has_one :object, serializer: ActivityPub::ActivitySerializer
diff --git a/app/serializers/activitypub/undo_block_serializer.rb b/app/serializers/activitypub/undo_block_serializer.rb
index 2f43d8402a38a259ade75353940c5a18f96bc72e..b4f049377715504b1b2b3de64d5cb2bc7f70d804 100644
--- a/app/serializers/activitypub/undo_block_serializer.rb
+++ b/app/serializers/activitypub/undo_block_serializer.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class ActivityPub::UndoBlockSerializer < ActiveModel::Serializer
+class ActivityPub::UndoBlockSerializer < ActivityPub::Serializer
   attributes :id, :type, :actor
 
   has_one :object, serializer: ActivityPub::BlockSerializer
diff --git a/app/serializers/activitypub/undo_follow_serializer.rb b/app/serializers/activitypub/undo_follow_serializer.rb
index e5b7f143d793428a7859cbe0439f5606b901a4bf..9b3e0ca3cb23b1c10045a930f660744c67bb2fbc 100644
--- a/app/serializers/activitypub/undo_follow_serializer.rb
+++ b/app/serializers/activitypub/undo_follow_serializer.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class ActivityPub::UndoFollowSerializer < ActiveModel::Serializer
+class ActivityPub::UndoFollowSerializer < ActivityPub::Serializer
   attributes :id, :type, :actor
 
   has_one :object, serializer: ActivityPub::FollowSerializer
diff --git a/app/serializers/activitypub/undo_like_serializer.rb b/app/serializers/activitypub/undo_like_serializer.rb
index 25f4ccaaed5ac120fc777f165f199b305c7b08bd..20c786cb76966c3257f29efe81ff1039a2e5973b 100644
--- a/app/serializers/activitypub/undo_like_serializer.rb
+++ b/app/serializers/activitypub/undo_like_serializer.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class ActivityPub::UndoLikeSerializer < ActiveModel::Serializer
+class ActivityPub::UndoLikeSerializer < ActivityPub::Serializer
   attributes :id, :type, :actor
 
   has_one :object, serializer: ActivityPub::LikeSerializer
diff --git a/app/serializers/activitypub/update_poll_serializer.rb b/app/serializers/activitypub/update_poll_serializer.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1d47b976435afd7c116e76d6d03776437145962b
--- /dev/null
+++ b/app/serializers/activitypub/update_poll_serializer.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class ActivityPub::UpdatePollSerializer < ActivityPub::Serializer
+  attributes :id, :type, :actor, :to
+
+  has_one :object, serializer: ActivityPub::NoteSerializer
+
+  def id
+    [ActivityPub::TagManager.instance.uri_for(object), '#updates/', object.preloadable_poll.updated_at.to_i].join
+  end
+
+  def type
+    'Update'
+  end
+
+  def actor
+    ActivityPub::TagManager.instance.uri_for(object.account)
+  end
+
+  def to
+    ActivityPub::TagManager.instance.to(object)
+  end
+
+  def cc
+    ActivityPub::TagManager.instance.cc(object)
+  end
+end
diff --git a/app/serializers/activitypub/update_serializer.rb b/app/serializers/activitypub/update_serializer.rb
index 48d7a192946a70875e79fc5ee8f6d44e605674c4..a5eb857d3fe6dce8245c4bff5ffb170157c2fce7 100644
--- a/app/serializers/activitypub/update_serializer.rb
+++ b/app/serializers/activitypub/update_serializer.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class ActivityPub::UpdateSerializer < ActiveModel::Serializer
+class ActivityPub::UpdateSerializer < ActivityPub::Serializer
   attributes :id, :type, :actor, :to
 
   has_one :object, serializer: ActivityPub::ActorSerializer
diff --git a/app/serializers/activitypub/vote_serializer.rb b/app/serializers/activitypub/vote_serializer.rb
new file mode 100644
index 0000000000000000000000000000000000000000..71ef5c77e3daf07881ab904c5c4360cf64f17c80
--- /dev/null
+++ b/app/serializers/activitypub/vote_serializer.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+class ActivityPub::VoteSerializer < ActivityPub::Serializer
+  class NoteSerializer < ActivityPub::Serializer
+    attributes :id, :type, :name, :attributed_to,
+               :in_reply_to, :to
+
+    def id
+      ActivityPub::TagManager.instance.uri_for(object) || [ActivityPub::TagManager.instance.uri_for(object.account), '#votes/', object.id].join
+    end
+
+    def type
+      'Note'
+    end
+
+    def name
+      object.poll.options[object.choice.to_i]
+    end
+
+    def attributed_to
+      ActivityPub::TagManager.instance.uri_for(object.account)
+    end
+
+    def in_reply_to
+      ActivityPub::TagManager.instance.uri_for(object.poll.status)
+    end
+
+    def to
+      ActivityPub::TagManager.instance.uri_for(object.poll.account)
+    end
+  end
+
+  attributes :id, :type, :actor, :to
+
+  has_one :object, serializer: ActivityPub::VoteSerializer::NoteSerializer
+
+  def id
+    [ActivityPub::TagManager.instance.uri_for(object.account), '#votes/', object.id, '/activity'].join
+  end
+
+  def type
+    'Create'
+  end
+
+  def actor
+    ActivityPub::TagManager.instance.uri_for(object.account)
+  end
+
+  def to
+    ActivityPub::TagManager.instance.uri_for(object.poll.account)
+  end
+end
diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb
index a7a3d770ce6eb26b5e560251017d88bacde703ba..8daf36e0a5680279299ea0c61535c054e93d7a06 100644
--- a/app/serializers/initial_state_serializer.rb
+++ b/app/serializers/initial_state_serializer.rb
@@ -14,6 +14,8 @@ class InitialStateSerializer < ActiveModel::Serializer
       domain: Rails.configuration.x.local_domain,
       admin: object.admin&.id&.to_s,
       search_enabled: Chewy.enabled?,
+      repository: Mastodon::Version.repository,
+      source_url: Mastodon::Version.source_url,
       version: Mastodon::Version.to_s,
       invites_enabled: Setting.min_invite_role == 'user',
       mascot: instance_presenter.mascot&.file&.url,
@@ -29,6 +31,7 @@ class InitialStateSerializer < ActiveModel::Serializer
       store[:display_media]   = object.current_account.user.setting_display_media
       store[:expand_spoilers] = object.current_account.user.setting_expand_spoilers
       store[:reduce_motion]   = object.current_account.user.setting_reduce_motion
+      store[:advanced_layout] = object.current_account.user.setting_advanced_layout
       store[:is_staff]        = object.current_account.user.staff?
     end
 
@@ -57,7 +60,7 @@ class InitialStateSerializer < ActiveModel::Serializer
   end
 
   def media_attachments
-    { accept_content_types: MediaAttachment::IMAGE_FILE_EXTENSIONS + MediaAttachment::VIDEO_FILE_EXTENSIONS + MediaAttachment::IMAGE_MIME_TYPES + MediaAttachment::VIDEO_MIME_TYPES }
+    { accept_content_types: MediaAttachment.supported_file_extensions + MediaAttachment.supported_mime_types }
   end
 
   private
diff --git a/app/serializers/manifest_serializer.rb b/app/serializers/manifest_serializer.rb
index 859ef0d1495513158a1677223016c70f0b99436e..28127437d568831e33836d2bef63ae2addcc6b73 100644
--- a/app/serializers/manifest_serializer.rb
+++ b/app/serializers/manifest_serializer.rb
@@ -18,7 +18,7 @@ class ManifestSerializer < ActiveModel::Serializer
   end
 
   def description
-    strip_tags(object.site_description.presence || I18n.t('about.about_mastodon_html'))
+    strip_tags(object.site_short_description.presence || I18n.t('about.about_mastodon_html'))
   end
 
   def icons
@@ -52,6 +52,14 @@ class ManifestSerializer < ActiveModel::Serializer
   end
 
   def share_target
-    { url_template: 'share?title={title}&text={text}&url={url}' }
+    {
+      url_template: 'share?title={title}&text={text}&url={url}',
+      action: 'share',
+      params: {
+        title: 'title',
+        text: 'text',
+        url: 'url',
+      },
+    }
   end
 end
diff --git a/app/serializers/oembed_serializer.rb b/app/serializers/oembed_serializer.rb
index 0c8350e2d2b19020824dd39a23a427ffee2ce3aa..01689633b2d8ffa728639d4ea2cfe939862d5aab 100644
--- a/app/serializers/oembed_serializer.rb
+++ b/app/serializers/oembed_serializer.rb
@@ -43,6 +43,7 @@ class OEmbedSerializer < ActiveModel::Serializer
       style: 'max-width: 100%; border: 0',
       width: width,
       height: height,
+      allowfullscreen: true,
     }
 
     content_tag(:iframe, nil, attributes) + content_tag(:script, nil, src: full_asset_url('embed.js', skip_pipeline: true), async: true)
diff --git a/app/serializers/rest/admin/account_serializer.rb b/app/serializers/rest/admin/account_serializer.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f579d330286404fd27ff7800790b4de298f82129
--- /dev/null
+++ b/app/serializers/rest/admin/account_serializer.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+
+class REST::Admin::AccountSerializer < ActiveModel::Serializer
+  attributes :id, :username, :domain, :created_at,
+             :email, :ip, :role, :confirmed, :suspended,
+             :silenced, :disabled, :approved, :locale,
+             :invite_request
+
+  attribute :created_by_application_id, if: :created_by_application?
+  attribute :invited_by_account_id, if: :invited?
+
+  has_one :account, serializer: REST::AccountSerializer
+
+  def id
+    object.id.to_s
+  end
+
+  def email
+    object.user_email
+  end
+
+  def ip
+    object.user_current_sign_in_ip.to_s.presence
+  end
+
+  def role
+    object.user_role
+  end
+
+  def suspended
+    object.suspended?
+  end
+
+  def silenced
+    object.silenced?
+  end
+
+  def confirmed
+    object.user_confirmed?
+  end
+
+  def disabled
+    object.user_disabled?
+  end
+
+  def approved
+    object.user_approved?
+  end
+
+  def account
+    object
+  end
+
+  def locale
+    object.user_locale
+  end
+
+  def created_by_application_id
+    object.user&.created_by_application_id&.to_s&.presence
+  end
+
+  def invite_request
+    object.user&.invite_request&.text
+  end
+
+  def invited_by_account_id
+    object.user&.invite&.user&.account_id&.to_s&.presence
+  end
+
+  def invited?
+    object.user&.invited?
+  end
+
+  def created_by_application?
+    object.user&.created_by_application_id&.present?
+  end
+end
diff --git a/app/serializers/rest/admin/report_serializer.rb b/app/serializers/rest/admin/report_serializer.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7a77132c038858615793d569a15bef781e3e264b
--- /dev/null
+++ b/app/serializers/rest/admin/report_serializer.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class REST::Admin::ReportSerializer < ActiveModel::Serializer
+  attributes :id, :action_taken, :comment, :created_at, :updated_at
+
+  has_one :account, serializer: REST::Admin::AccountSerializer
+  has_one :target_account, serializer: REST::Admin::AccountSerializer
+  has_one :assigned_account, serializer: REST::Admin::AccountSerializer
+  has_one :action_taken_by_account, serializer: REST::Admin::AccountSerializer
+
+  has_many :statuses, serializer: REST::StatusSerializer
+
+  def id
+    object.id.to_s
+  end
+end
diff --git a/app/serializers/rest/application_serializer.rb b/app/serializers/rest/application_serializer.rb
index a9316cd4b75a748814693b8219a77b5aa895dba3..ab68219ade8fb21a5d75069557ffe92f1ce7ded6 100644
--- a/app/serializers/rest/application_serializer.rb
+++ b/app/serializers/rest/application_serializer.rb
@@ -2,7 +2,7 @@
 
 class REST::ApplicationSerializer < ActiveModel::Serializer
   attributes :id, :name, :website, :redirect_uri,
-             :client_id, :client_secret
+             :client_id, :client_secret, :vapid_key
 
   def id
     object.id.to_s
@@ -19,4 +19,8 @@ class REST::ApplicationSerializer < ActiveModel::Serializer
   def website
     object.website.presence
   end
+
+  def vapid_key
+    Rails.configuration.x.vapid_public_key
+  end
 end
diff --git a/app/serializers/rest/identity_proof_serializer.rb b/app/serializers/rest/identity_proof_serializer.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0e7415935a099dd23a971da119d248cd7c4f19c3
--- /dev/null
+++ b/app/serializers/rest/identity_proof_serializer.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class REST::IdentityProofSerializer < ActiveModel::Serializer
+  attributes :provider, :provider_username, :updated_at, :proof_url, :profile_url
+
+  def proof_url
+    object.badge.proof_url
+  end
+
+  def profile_url
+    object.badge.profile_url
+  end
+
+  def provider
+    object.provider.capitalize
+  end
+end
diff --git a/app/serializers/rest/instance_serializer.rb b/app/serializers/rest/instance_serializer.rb
index e3e64ea8767fcda5b1e93fb7ad786f39be60966a..1bd71683ce83b0bba180166fd7d2d2d6b77e1313 100644
--- a/app/serializers/rest/instance_serializer.rb
+++ b/app/serializers/rest/instance_serializer.rb
@@ -3,9 +3,9 @@
 class REST::InstanceSerializer < ActiveModel::Serializer
   include RoutingHelper
 
-  attributes :uri, :title, :description, :email,
+  attributes :uri, :title, :short_description, :description, :email,
              :version, :urls, :stats, :thumbnail,
-             :languages
+             :languages, :registrations, :approval_required
 
   has_one :contact_account, serializer: REST::AccountSerializer
 
@@ -19,6 +19,10 @@ class REST::InstanceSerializer < ActiveModel::Serializer
     Setting.site_title
   end
 
+  def short_description
+    Setting.site_short_description
+  end
+
   def description
     Setting.site_description
   end
@@ -32,7 +36,7 @@ class REST::InstanceSerializer < ActiveModel::Serializer
   end
 
   def thumbnail
-    instance_presenter.thumbnail ? full_asset_url(instance_presenter.thumbnail.file.url) : full_pack_url('preview.jpg')
+    instance_presenter.thumbnail ? full_asset_url(instance_presenter.thumbnail.file.url) : full_pack_url('media/images/preview.jpg')
   end
 
   def stats
@@ -51,6 +55,14 @@ class REST::InstanceSerializer < ActiveModel::Serializer
     [I18n.default_locale]
   end
 
+  def registrations
+    Setting.registrations_mode != 'none' && !Rails.configuration.x.single_user_mode
+  end
+
+  def approval_required
+    Setting.registrations_mode == 'approved'
+  end
+
   private
 
   def instance_presenter
diff --git a/app/serializers/rest/media_attachment_serializer.rb b/app/serializers/rest/media_attachment_serializer.rb
index 51011788bae1a772dcd5919979ea772d255a6ec2..1b3498ea4ebc1ae858d2f25f7ef8d20ec35bdc72 100644
--- a/app/serializers/rest/media_attachment_serializer.rb
+++ b/app/serializers/rest/media_attachment_serializer.rb
@@ -5,7 +5,7 @@ class REST::MediaAttachmentSerializer < ActiveModel::Serializer
 
   attributes :id, :type, :url, :preview_url,
              :remote_url, :text_url, :meta,
-             :description
+             :description, :blurhash
 
   def id
     object.id.to_s
diff --git a/app/serializers/rest/notification_serializer.rb b/app/serializers/rest/notification_serializer.rb
index 541a6b8b5c4c2a83a3e421cbf27b4802568955e2..80812ad0df9cd5d8f740ff78d8d28287b84c10c8 100644
--- a/app/serializers/rest/notification_serializer.rb
+++ b/app/serializers/rest/notification_serializer.rb
@@ -11,6 +11,6 @@ class REST::NotificationSerializer < ActiveModel::Serializer
   end
 
   def status_type?
-    [:favourite, :reblog, :mention].include?(object.type)
+    [:favourite, :reblog, :mention, :poll].include?(object.type)
   end
 end
diff --git a/app/serializers/rest/poll_serializer.rb b/app/serializers/rest/poll_serializer.rb
new file mode 100644
index 0000000000000000000000000000000000000000..356c45b83868de1d96d257cc5838d0085df37e67
--- /dev/null
+++ b/app/serializers/rest/poll_serializer.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+class REST::PollSerializer < ActiveModel::Serializer
+  attributes :id, :expires_at, :expired,
+             :multiple, :votes_count
+
+  has_many :loaded_options, key: :options
+  has_many :emojis, serializer: REST::CustomEmojiSerializer
+
+  attribute :voted, if: :current_user?
+
+  def id
+    object.id.to_s
+  end
+
+  def expired
+    object.expired?
+  end
+
+  def voted
+    object.voted?(current_user.account)
+  end
+
+  def current_user?
+    !current_user.nil?
+  end
+
+  class OptionSerializer < ActiveModel::Serializer
+    attributes :title, :votes_count
+  end
+end
diff --git a/app/serializers/rest/preferences_serializer.rb b/app/serializers/rest/preferences_serializer.rb
new file mode 100644
index 0000000000000000000000000000000000000000..119f0e06d89a5831ea7702478bdb8a05b2934194
--- /dev/null
+++ b/app/serializers/rest/preferences_serializer.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+class REST::PreferencesSerializer < ActiveModel::Serializer
+  attribute :posting_default_privacy, key: 'posting:default:visibility'
+  attribute :posting_default_sensitive, key: 'posting:default:sensitive'
+  attribute :posting_default_language, key: 'posting:default:language'
+
+  attribute :reading_default_sensitive_media, key: 'reading:expand:media'
+  attribute :reading_default_sensitive_text, key: 'reading:expand:spoilers'
+
+  def posting_default_privacy
+    object.user.setting_default_privacy
+  end
+
+  def posting_default_sensitive
+    object.user.setting_default_sensitive
+  end
+
+  def posting_default_language
+    object.user.setting_default_language.presence
+  end
+
+  def reading_default_sensitive_media
+    object.user.setting_display_media
+  end
+
+  def reading_default_sensitive_text
+    object.user.setting_expand_spoilers
+  end
+end
diff --git a/app/serializers/rest/relationship_serializer.rb b/app/serializers/rest/relationship_serializer.rb
index c6c722a54ea0d30a5031c048a4230caa2be64890..1a3fd915cbcd738b10fb65091a1fc33b6fd3d10b 100644
--- a/app/serializers/rest/relationship_serializer.rb
+++ b/app/serializers/rest/relationship_serializer.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class REST::RelationshipSerializer < ActiveModel::Serializer
-  attributes :id, :following, :showing_reblogs, :followed_by, :blocking,
+  attributes :id, :following, :showing_reblogs, :followed_by, :blocking, :blocked_by,
              :muting, :muting_notifications, :requested, :domain_blocking,
              :endorsed
 
@@ -27,6 +27,10 @@ class REST::RelationshipSerializer < ActiveModel::Serializer
     instance_options[:relationships].blocking[object.id] || false
   end
 
+  def blocked_by
+    instance_options[:relationships].blocked_by[object.id] || false
+  end
+
   def muting
     instance_options[:relationships].muting[object.id] ? true : false
   end
diff --git a/app/serializers/rest/status_serializer.rb b/app/serializers/rest/status_serializer.rb
index bfc2d78b41f8f1f9c87599d08f143417bbcde729..c9b76cb162041494a4dcd8972bbea2d3638c0008 100644
--- a/app/serializers/rest/status_serializer.rb
+++ b/app/serializers/rest/status_serializer.rb
@@ -3,7 +3,7 @@
 class REST::StatusSerializer < ActiveModel::Serializer
   attributes :id, :created_at, :in_reply_to_id, :in_reply_to_account_id,
              :sensitive, :spoiler_text, :visibility, :language,
-             :uri, :content, :url, :replies_count, :reblogs_count,
+             :uri, :url, :replies_count, :reblogs_count,
              :favourites_count
 
   attribute :favourited, if: :current_user?
@@ -11,8 +11,11 @@ class REST::StatusSerializer < ActiveModel::Serializer
   attribute :muted, if: :current_user?
   attribute :pinned, if: :pinnable?
 
+  attribute :content, unless: :source_requested?
+  attribute :text, if: :source_requested?
+
   belongs_to :reblog, serializer: REST::StatusSerializer
-  belongs_to :application
+  belongs_to :application, if: :show_application?
   belongs_to :account, serializer: REST::AccountSerializer
 
   has_many :media_attachments, serializer: REST::MediaAttachmentSerializer
@@ -21,6 +24,7 @@ class REST::StatusSerializer < ActiveModel::Serializer
   has_many :emojis, serializer: REST::CustomEmojiSerializer
 
   has_one :preview_card, key: :card, serializer: REST::PreviewCardSerializer
+  has_one :preloadable_poll, key: :poll, serializer: REST::PollSerializer
 
   def id
     object.id.to_s
@@ -38,6 +42,10 @@ class REST::StatusSerializer < ActiveModel::Serializer
     !current_user.nil?
   end
 
+  def show_application?
+    object.account.user_shows_application? || (current_user? && current_user.account_id == object.account_id)
+  end
+
   def visibility
     # This visibility is masked behind "private"
     # to avoid API changes because there are no
@@ -100,6 +108,10 @@ class REST::StatusSerializer < ActiveModel::Serializer
       %w(public unlisted).include?(object.visibility)
   end
 
+  def source_requested?
+    instance_options[:source_requested]
+  end
+
   def ordered_mentions
     object.active_mentions.to_a.sort_by(&:id)
   end
diff --git a/app/serializers/rest/web_push_subscription_serializer.rb b/app/serializers/rest/web_push_subscription_serializer.rb
index 7fd952a567bf62d1f37ab030b25d3e551ab0e2f5..194cc0a8c7e40c20a75700692cd883142324e58b 100644
--- a/app/serializers/rest/web_push_subscription_serializer.rb
+++ b/app/serializers/rest/web_push_subscription_serializer.rb
@@ -4,7 +4,7 @@ class REST::WebPushSubscriptionSerializer < ActiveModel::Serializer
   attributes :id, :endpoint, :alerts, :server_key
 
   def alerts
-    object.data&.dig('alerts') || {}
+    (object.data&.dig('alerts') || {}).each_with_object({}) { |(k, v), h| h[k] = ActiveModel::Type::Boolean.new.cast(v) }
   end
 
   def server_key
diff --git a/app/serializers/rss/account_serializer.rb b/app/serializers/rss/account_serializer.rb
index bde360a41f05f79609a27444968068551c8115df..88eca79ed2311cacf7ceb4b58da32942c8586cce 100644
--- a/app/serializers/rss/account_serializer.rb
+++ b/app/serializers/rss/account_serializer.rb
@@ -11,7 +11,7 @@ class RSS::AccountSerializer
     builder.title("#{display_name(account)} (@#{account.local_username_and_domain})")
            .description(account_description(account))
            .link(TagManager.instance.url_for(account))
-           .logo(full_asset_url(asset_pack_path('logo.svg')))
+           .logo(full_pack_url('media/images/logo.svg'))
            .accent_color('2b90d9')
 
     builder.image(full_asset_url(account.avatar.url(:original))) if account.avatar?
@@ -22,7 +22,7 @@ class RSS::AccountSerializer
         item.title(status.title)
             .link(TagManager.instance.url_for(status))
             .pub_date(status.created_at)
-            .description(status.spoiler_text.presence || Formatter.instance.format(status).to_str)
+            .description(status.spoiler_text.presence || Formatter.instance.format(status, inline_poll_options: true).to_str)
 
         status.media_attachments.each do |media|
           item.enclosure(full_asset_url(media.file.url(:original, false)), media.file.content_type, length: media.file.size)
diff --git a/app/serializers/rss/tag_serializer.rb b/app/serializers/rss/tag_serializer.rb
index 7680a8da55c0a75c2513f5c974ca549cf07b7dbd..644380149bab9ceae35120d0a077687a038635ef 100644
--- a/app/serializers/rss/tag_serializer.rb
+++ b/app/serializers/rss/tag_serializer.rb
@@ -12,7 +12,7 @@ class RSS::TagSerializer
     builder.title("##{tag.name}")
            .description(strip_tags(I18n.t('about.about_hashtag_html', hashtag: tag.name)))
            .link(tag_url(tag))
-           .logo(full_asset_url(asset_pack_path('logo.svg')))
+           .logo(full_pack_url('media/images/logo.svg'))
            .accent_color('2b90d9')
 
     statuses.each do |status|
diff --git a/app/services/account_search_service.rb b/app/services/account_search_service.rb
index 7edbd9b479540ccc4a1a9ea7ea7187b1a1b9041e..7bdffbbd22c94f9bd3096c727d86819bfd0810d4 100644
--- a/app/services/account_search_service.rb
+++ b/app/services/account_search_service.rb
@@ -1,11 +1,12 @@
 # frozen_string_literal: true
 
 class AccountSearchService < BaseService
-  attr_reader :query, :limit, :options, :account
+  attr_reader :query, :limit, :offset, :options, :account
 
-  def call(query, limit, account = nil, options = {})
+  def call(query, account = nil, options = {})
     @query   = query.strip
-    @limit   = limit
+    @limit   = options[:limit].to_i
+    @offset  = options[:offset].to_i
     @options = options
     @account = account
 
@@ -83,11 +84,11 @@ class AccountSearchService < BaseService
   end
 
   def advanced_search_results
-    Account.advanced_search_for(terms_for_query, account, limit, options[:following])
+    Account.advanced_search_for(terms_for_query, account, limit, options[:following], offset)
   end
 
   def simple_search_results
-    Account.search_for(terms_for_query, limit)
+    Account.search_for(terms_for_query, limit, offset)
   end
 
   def terms_for_query
diff --git a/app/services/activitypub/fetch_remote_poll_service.rb b/app/services/activitypub/fetch_remote_poll_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..854a32d050a75e0d0e9f58e804556de873ab5526
--- /dev/null
+++ b/app/services/activitypub/fetch_remote_poll_service.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class ActivityPub::FetchRemotePollService < BaseService
+  include JsonLdHelper
+
+  def call(poll, on_behalf_of = nil)
+    json = fetch_resource(poll.status.uri, true, on_behalf_of)
+    return unless supported_context?(json)
+    ActivityPub::ProcessPollService.new.call(poll, json)
+  end
+end
diff --git a/app/services/activitypub/fetch_replies_service.rb b/app/services/activitypub/fetch_replies_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8cb309e52a86330932235ae3b945f6d762ced113
--- /dev/null
+++ b/app/services/activitypub/fetch_replies_service.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+class ActivityPub::FetchRepliesService < BaseService
+  include JsonLdHelper
+
+  def call(parent_status, collection_or_uri, allow_synchronous_requests = true)
+    @account = parent_status.account
+    @allow_synchronous_requests = allow_synchronous_requests
+
+    @items = collection_items(collection_or_uri)
+    return if @items.nil?
+
+    FetchReplyWorker.push_bulk(filtered_replies)
+
+    @items
+  end
+
+  private
+
+  def collection_items(collection_or_uri)
+    collection = fetch_collection(collection_or_uri)
+    return unless collection.is_a?(Hash)
+
+    collection = fetch_collection(collection['first']) if collection['first'].present?
+    return unless collection.is_a?(Hash)
+
+    case collection['type']
+    when 'Collection', 'CollectionPage'
+      collection['items']
+    when 'OrderedCollection', 'OrderedCollectionPage'
+      collection['orderedItems']
+    end
+  end
+
+  def fetch_collection(collection_or_uri)
+    return collection_or_uri if collection_or_uri.is_a?(Hash)
+    return unless @allow_synchronous_requests
+    return if invalid_origin?(collection_or_uri)
+    fetch_resource_without_id_validation(collection_or_uri, nil, true)
+  end
+
+  def filtered_replies
+    # Only fetch replies to the same server as the original status to avoid
+    # amplification attacks.
+
+    # Also limit to 5 fetched replies to limit potential for DoS.
+    @items.map { |item| value_or_id(item) }.reject { |uri| invalid_origin?(uri) }.take(5)
+  end
+end
diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb
index 487456f3afcec2fec587d409a583310ed041d7b5..3857e7c16d58991b3f6fc2f55adbe187e45f6ad1 100644
--- a/app/services/activitypub/process_account_service.rb
+++ b/app/services/activitypub/process_account_service.rb
@@ -15,6 +15,8 @@ class ActivityPub::ProcessAccountService < BaseService
     @domain      = domain
     @collections = {}
 
+    return if auto_suspend?
+
     RedisLock.acquire(lock_options) do |lock|
       if lock.acquired?
         @account        = Account.find_remote(@username, @domain)
@@ -24,6 +26,7 @@ class ActivityPub::ProcessAccountService < BaseService
         create_account if @account.nil?
         update_account
         process_tags
+        process_attachments
       else
         raise Mastodon::RaceConditionError
       end
@@ -49,12 +52,12 @@ class ActivityPub::ProcessAccountService < BaseService
 
   def create_account
     @account = Account.new
-    @account.protocol    = :activitypub
-    @account.username    = @username
-    @account.domain      = @domain
-    @account.suspended   = true if auto_suspend?
-    @account.silenced    = true if auto_silence?
-    @account.private_key = nil
+    @account.protocol     = :activitypub
+    @account.username     = @username
+    @account.domain       = @domain
+    @account.private_key  = nil
+    @account.suspended_at = domain_block.created_at if auto_suspend?
+    @account.silenced_at  = domain_block.created_at if auto_silence?
   end
 
   def update_account
@@ -151,7 +154,7 @@ class ActivityPub::ProcessAccountService < BaseService
 
   def property_values
     return unless @json['attachment'].is_a?(Array)
-    @json['attachment'].select { |attachment| attachment['type'] == 'PropertyValue' }.map { |attachment| attachment.slice('name', 'value') }
+    as_array(@json['attachment']).select { |attachment| attachment['type'] == 'PropertyValue' }.map { |attachment| attachment.slice('name', 'value') }
   end
 
   def mismatching_origin?(url)
@@ -204,7 +207,7 @@ class ActivityPub::ProcessAccountService < BaseService
 
   def domain_block
     return @domain_block if defined?(@domain_block)
-    @domain_block = DomainBlock.find_by(domain: @domain)
+    @domain_block = DomainBlock.rule_for(@domain)
   end
 
   def key_changed?
@@ -212,7 +215,7 @@ class ActivityPub::ProcessAccountService < BaseService
   end
 
   def clear_tombstones!
-    Tombstone.delete_all(account_id: @account.id)
+    Tombstone.where(account_id: @account.id).delete_all
   end
 
   def protocol_changed?
@@ -231,6 +234,23 @@ class ActivityPub::ProcessAccountService < BaseService
     end
   end
 
+  def process_attachments
+    return if @json['attachment'].blank?
+
+    previous_proofs = @account.identity_proofs.to_a
+    current_proofs  = []
+
+    as_array(@json['attachment']).each do |attachment|
+      next unless equals_or_includes?(attachment['type'], 'IdentityProof')
+      current_proofs << process_identity_proof(attachment)
+    end
+
+    previous_proofs.each do |previous_proof|
+      next if current_proofs.any? { |current_proof| current_proof.id == previous_proof.id }
+      previous_proof.delete
+    end
+  end
+
   def process_emoji(tag)
     return if skip_download?
     return if tag['name'].blank? || tag['icon'].blank? || tag['icon']['url'].blank?
@@ -247,4 +267,12 @@ class ActivityPub::ProcessAccountService < BaseService
     emoji.image_remote_url = image_url
     emoji.save
   end
+
+  def process_identity_proof(attachment)
+    provider          = attachment['signatureAlgorithm']
+    provider_username = attachment['name']
+    token             = attachment['signatureValue']
+
+    @account.identity_proofs.where(provider: provider, provider_username: provider_username).find_or_create_by(provider: provider, provider_username: provider_username, token: token)
+  end
 end
diff --git a/app/services/activitypub/process_collection_service.rb b/app/services/activitypub/process_collection_service.rb
index 5c54aad89f18407d6c05d51481717296e066b8d1..881df478bf53c7b265df09c1cf01917c4a9ae382 100644
--- a/app/services/activitypub/process_collection_service.rb
+++ b/app/services/activitypub/process_collection_service.rb
@@ -44,6 +44,7 @@ class ActivityPub::ProcessCollectionService < BaseService
   end
 
   def verify_account!
+    @options[:relayed_through_account] = @account
     @account = ActivityPub::LinkedDataSignature.new(@json).verify_account!
   rescue JSON::LD::JsonLdError => e
     Rails.logger.debug "Could not verify LD-Signature for #{value_or_id(@json['actor'])}: #{e.message}"
diff --git a/app/services/activitypub/process_poll_service.rb b/app/services/activitypub/process_poll_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..61357abd3ca6aa24812159a743cc61385a7171a8
--- /dev/null
+++ b/app/services/activitypub/process_poll_service.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+class ActivityPub::ProcessPollService < BaseService
+  include JsonLdHelper
+
+  def call(poll, json)
+    @json = json
+    return unless expected_type?
+
+    previous_expires_at = poll.expires_at
+
+    expires_at = begin
+      if @json['closed'].is_a?(String)
+        @json['closed']
+      elsif !@json['closed'].nil? && !@json['closed'].is_a?(FalseClass)
+        Time.now.utc
+      else
+        @json['endTime']
+      end
+    end
+
+    items = begin
+      if @json['anyOf'].is_a?(Array)
+        @json['anyOf']
+      else
+        @json['oneOf']
+      end
+    end
+
+    latest_options = items.map { |item| item['name'].presence || item['content'] }
+
+    # If for some reasons the options were changed, it invalidates all previous
+    # votes, so we need to remove them
+    poll.votes.delete_all if latest_options != poll.options
+
+    begin
+      poll.update!(
+        last_fetched_at: Time.now.utc,
+        expires_at: expires_at,
+        options: latest_options,
+        cached_tallies: items.map { |item| item.dig('replies', 'totalItems') || 0 }
+      )
+    rescue ActiveRecord::StaleObjectError
+      poll.reload
+      retry
+    end
+
+    # If the poll had no expiration date set but now has, and people have voted,
+    # schedule a notification.
+    if previous_expires_at.nil? && poll.expires_at.present? && poll.votes.exists?
+      PollExpirationNotifyWorker.perform_at(poll.expires_at + 5.minutes, poll.id)
+    end
+  end
+
+  private
+
+  def expected_type?
+    equals_or_includes_any?(@json['type'], %w(Question))
+  end
+end
diff --git a/app/services/after_block_domain_from_account_service.rb b/app/services/after_block_domain_from_account_service.rb
index 180f134032375f8af3d27c7a07d03f1a2471e91b..f50bde261d299025620da1d6ef1ff5f5cffbeb3f 100644
--- a/app/services/after_block_domain_from_account_service.rb
+++ b/app/services/after_block_domain_from_account_service.rb
@@ -1,6 +1,8 @@
 # frozen_string_literal: true
 
 class AfterBlockDomainFromAccountService < BaseService
+  include Payloadable
+
   # This service does not create an AccountDomainBlock record,
   # it's meant to be called after such a record has been created
   # synchronously, to "clean up"
@@ -8,12 +10,24 @@ class AfterBlockDomainFromAccountService < BaseService
     @account = account
     @domain  = domain
 
+    clear_notifications!
+    remove_follows!
     reject_existing_followers!
     reject_pending_follow_requests!
   end
 
   private
 
+  def remove_follows!
+    @account.active_relationships.where(account: Account.where(domain: @domain)).includes(:target_account).reorder(nil).find_each do |follow|
+      UnfollowService.new.call(@account, follow.target_account)
+    end
+  end
+
+  def clear_notifications!
+    Notification.where(account: @account).where(from_account: Account.where(domain: @domain)).in_batches.delete_all
+  end
+
   def reject_existing_followers!
     @account.passive_relationships.where(account: Account.where(domain: @domain)).includes(:account).reorder(nil).find_each do |follow|
       reject_follow!(follow)
@@ -31,12 +45,6 @@ class AfterBlockDomainFromAccountService < BaseService
 
     return unless follow.account.activitypub?
 
-    json = ActiveModelSerializers::SerializableResource.new(
-      follow,
-      serializer: ActivityPub::RejectFollowSerializer,
-      adapter: ActivityPub::Adapter
-    ).to_json
-
-    ActivityPub::DeliveryWorker.perform_async(json, @account.id, follow.account.inbox_url)
+    ActivityPub::DeliveryWorker.perform_async(Oj.dump(serialize_payload(follow, ActivityPub::RejectFollowSerializer)), @account.id, follow.account.inbox_url)
   end
 end
diff --git a/app/services/after_block_service.rb b/app/services/after_block_service.rb
index 706db0d6334d9a82fbbc52bcc90ef7fb7f4050f5..2a0e10a79a60e294edb490ed928b58e6541e3908 100644
--- a/app/services/after_block_service.rb
+++ b/app/services/after_block_service.rb
@@ -2,43 +2,25 @@
 
 class AfterBlockService < BaseService
   def call(account, target_account)
-    clear_home_feed(account, target_account)
-    clear_notifications(account, target_account)
-    clear_conversations(account, target_account)
+    @account        = account
+    @target_account = target_account
+
+    clear_home_feed!
+    clear_notifications!
+    clear_conversations!
   end
 
   private
 
-  def clear_home_feed(account, target_account)
-    FeedManager.instance.clear_from_timeline(account, target_account)
+  def clear_home_feed!
+    FeedManager.instance.clear_from_timeline(@account, @target_account)
   end
 
-  def clear_conversations(account, target_account)
-    AccountConversation.where(account: account)
-                       .where('? = ANY(participant_account_ids)', target_account.id)
-                       .in_batches
-                       .destroy_all
+  def clear_conversations!
+    AccountConversation.where(account: @account).where('? = ANY(participant_account_ids)', @target_account.id).in_batches.destroy_all
   end
 
-  def clear_notifications(account, target_account)
-    Notification.where(account: account)
-                .joins(:follow)
-                .where(activity_type: 'Follow', follows: { account_id: target_account.id })
-                .delete_all
-
-    Notification.where(account: account)
-                .joins(mention: :status)
-                .where(activity_type: 'Mention', statuses: { account_id: target_account.id })
-                .delete_all
-
-    Notification.where(account: account)
-                .joins(:favourite)
-                .where(activity_type: 'Favourite', favourites: { account_id: target_account.id })
-                .delete_all
-
-    Notification.where(account: account)
-                .joins(:status)
-                .where(activity_type: 'Status', statuses: { account_id: target_account.id })
-                .delete_all
+  def clear_notifications!
+    Notification.where(account: @account).where(from_account: @target_account).in_batches.delete_all
   end
 end
diff --git a/app/services/app_sign_up_service.rb b/app/services/app_sign_up_service.rb
index d621cc462c6460af70157690c1524cb42a0f2735..6dee9cd81568eb1b208183e70a90df3a66701954 100644
--- a/app/services/app_sign_up_service.rb
+++ b/app/services/app_sign_up_service.rb
@@ -18,6 +18,6 @@ class AppSignUpService < BaseService
   private
 
   def allowed_registrations?
-    Setting.open_registrations && !Rails.configuration.x.single_user_mode
+    Setting.registrations_mode != 'none' && !Rails.configuration.x.single_user_mode
   end
 end
diff --git a/app/services/authorize_follow_service.rb b/app/services/authorize_follow_service.rb
index f2e3ebe7d00b4770fea3dd2e478dfead17ee0027..29b8700c7c7d06781d00d8d11b695f8da7b779b0 100644
--- a/app/services/authorize_follow_service.rb
+++ b/app/services/authorize_follow_service.rb
@@ -1,6 +1,8 @@
 # frozen_string_literal: true
 
 class AuthorizeFollowService < BaseService
+  include Payloadable
+
   def call(source_account, target_account, **options)
     if options[:skip_follow_request]
       follow_request = FollowRequest.new(account: source_account, target_account: target_account, uri: options[:follow_request_uri])
@@ -24,11 +26,7 @@ class AuthorizeFollowService < BaseService
   end
 
   def build_json(follow_request)
-    ActiveModelSerializers::SerializableResource.new(
-      follow_request,
-      serializer: ActivityPub::AcceptFollowSerializer,
-      adapter: ActivityPub::Adapter
-    ).to_json
+    Oj.dump(serialize_payload(follow_request, ActivityPub::AcceptFollowSerializer))
   end
 
   def build_xml(follow_request)
diff --git a/app/services/backup_service.rb b/app/services/backup_service.rb
index 4cfa22ab893604277313a921bc1c208de4092c2f..12e4fa8b441ccccac5dfd91a6422239421b87655 100644
--- a/app/services/backup_service.rb
+++ b/app/services/backup_service.rb
@@ -142,5 +142,7 @@ class BackupService < BaseService
         io.write(buffer)
       end
     end
+  rescue Errno::ENOENT
+    Rails.logger.warn "Could not backup file #{filename}: file not found"
   end
 end
diff --git a/app/services/batched_remove_status_service.rb b/app/services/batched_remove_status_service.rb
index 2e61904fc770f6f4011c784fb7dafe77bf502514..e328b17391b94008a2027295cf5cc7692fe97d25 100644
--- a/app/services/batched_remove_status_service.rb
+++ b/app/services/batched_remove_status_service.rb
@@ -2,6 +2,7 @@
 
 class BatchedRemoveStatusService < BaseService
   include StreamEntryRenderer
+  include Redisable
 
   # Delete given statuses and reblogs of them
   # Dispatch PuSH updates of the deleted statuses, but only local ones
@@ -34,6 +35,8 @@ class BatchedRemoveStatusService < BaseService
     statuses.group_by(&:account_id).each_value do |account_statuses|
       account = account_statuses.first.account
 
+      next unless account
+
       unpush_from_home_timelines(account, account_statuses)
       unpush_from_list_timelines(account, account_statuses)
 
@@ -109,10 +112,6 @@ class BatchedRemoveStatusService < BaseService
     end
   end
 
-  def redis
-    Redis.current
-  end
-
   def build_xml(stream_entry)
     return @activity_xml[stream_entry.id] if @activity_xml.key?(stream_entry.id)
 
diff --git a/app/services/block_domain_service.rb b/app/services/block_domain_service.rb
index a1fe93665b117b7df8051fe88c0d177d302a2714..c6eef04d420fe75a7ee8d4e79e965a16ecf719f1 100644
--- a/app/services/block_domain_service.rb
+++ b/app/services/block_domain_service.rb
@@ -29,7 +29,7 @@ class BlockDomainService < BaseService
   end
 
   def silence_accounts!
-    blocked_domain_accounts.in_batches.update_all(silenced: true)
+    blocked_domain_accounts.without_silenced.in_batches.update_all(silenced_at: @domain_block.created_at)
   end
 
   def clear_media!
@@ -43,9 +43,9 @@ class BlockDomainService < BaseService
   end
 
   def suspend_accounts!
-    blocked_domain_accounts.where(suspended: false).reorder(nil).find_each do |account|
+    blocked_domain_accounts.without_suspended.reorder(nil).find_each do |account|
       UnsubscribeService.new.call(account) if account.subscribed?
-      SuspendAccountService.new.call(account)
+      SuspendAccountService.new.call(account, suspended_at: @domain_block.created_at)
     end
   end
 
@@ -76,7 +76,7 @@ class BlockDomainService < BaseService
   end
 
   def blocked_domain_accounts
-    Account.where(domain: blocked_domain)
+    Account.by_domain_and_subdomains(blocked_domain)
   end
 
   def media_from_blocked_domain
@@ -84,6 +84,6 @@ class BlockDomainService < BaseService
   end
 
   def emojis_from_blocked_domains
-    CustomEmoji.where(domain: blocked_domain)
+    CustomEmoji.by_domain_and_subdomains(blocked_domain)
   end
 end
diff --git a/app/services/block_service.rb b/app/services/block_service.rb
index 140b238df3e418dcab536a1506fa021cd9aac094..0d9a6eccda47e47ed190285c467b79e2964d7e36 100644
--- a/app/services/block_service.rb
+++ b/app/services/block_service.rb
@@ -1,11 +1,14 @@
 # frozen_string_literal: true
 
 class BlockService < BaseService
+  include Payloadable
+
   def call(account, target_account)
     return if account.id == target_account.id
 
     UnfollowService.new.call(account, target_account) if account.following?(target_account)
     UnfollowService.new.call(target_account, account) if target_account.following?(account)
+    RejectFollowService.new.call(target_account, account) if target_account.requested?(account)
 
     block = account.block!(target_account)
 
@@ -25,11 +28,7 @@ class BlockService < BaseService
   end
 
   def build_json(block)
-    ActiveModelSerializers::SerializableResource.new(
-      block,
-      serializer: ActivityPub::BlockSerializer,
-      adapter: ActivityPub::Adapter
-    ).to_json
+    Oj.dump(serialize_payload(block, ActivityPub::BlockSerializer))
   end
 
   def build_xml(block)
diff --git a/app/services/concerns/payloadable.rb b/app/services/concerns/payloadable.rb
new file mode 100644
index 0000000000000000000000000000000000000000..13d9c3548353e538be69e52a9abaf69b3da7283a
--- /dev/null
+++ b/app/services/concerns/payloadable.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Payloadable
+  def serialize_payload(record, serializer, options = {})
+    signer    = options.delete(:signer)
+    sign_with = options.delete(:sign_with)
+    payload   = ActiveModelSerializers::SerializableResource.new(record, options.merge(serializer: serializer, adapter: ActivityPub::Adapter)).as_json
+
+    if (record.respond_to?(:sign?) && record.sign?) && signer && signing_enabled?
+      ActivityPub::LinkedDataSignature.new(payload).sign!(signer, sign_with: sign_with)
+    else
+      payload
+    end
+  end
+
+  def signing_enabled?
+    true
+  end
+end
diff --git a/app/services/favourite_service.rb b/app/services/favourite_service.rb
index b565bcc3203f30c9f2544c0fccbab496d7fddf7c..128a24ad61e59f484ebda27e432d4f7ee32d96e3 100644
--- a/app/services/favourite_service.rb
+++ b/app/services/favourite_service.rb
@@ -2,6 +2,7 @@
 
 class FavouriteService < BaseService
   include Authorization
+  include Payloadable
 
   # Favourite a status and notify remote user
   # @param [Account] account
@@ -43,11 +44,7 @@ class FavouriteService < BaseService
   end
 
   def build_json(favourite)
-    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
-      favourite,
-      serializer: ActivityPub::LikeSerializer,
-      adapter: ActivityPub::Adapter
-    ).as_json).sign!(favourite.account))
+    Oj.dump(serialize_payload(favourite, ActivityPub::LikeSerializer))
   end
 
   def build_xml(favourite)
diff --git a/app/services/fetch_link_card_service.rb b/app/services/fetch_link_card_service.rb
index 7979c312e5d771c84efbca492e495c4e54ccb019..494aaed759c3899961a15f1a06fb3e545df37675 100644
--- a/app/services/fetch_link_card_service.rb
+++ b/app/services/fetch_link_card_service.rb
@@ -165,7 +165,7 @@ class FetchLinkCardService < BaseService
   end
 
   def meta_property(page, property)
-    page.at_xpath("//meta[@property=\"#{property}\"]")&.attribute('content')&.value || page.at_xpath("//meta[@name=\"#{property}\"]")&.attribute('content')&.value
+    page.at_xpath("//meta[contains(concat(' ', normalize-space(@property), ' '), ' #{property} ')]")&.attribute('content')&.value || page.at_xpath("//meta[@name=\"#{property}\"]")&.attribute('content')&.value
   end
 
   def lock_options
diff --git a/app/services/follow_service.rb b/app/services/follow_service.rb
index 9d36a1449dff3721b028d0400d71b85848c141c5..17fbb9cb4fa3dc68af2e9993291d378aa676e4de 100644
--- a/app/services/follow_service.rb
+++ b/app/services/follow_service.rb
@@ -1,6 +1,9 @@
 # frozen_string_literal: true
 
 class FollowService < BaseService
+  include Redisable
+  include Payloadable
+
   # Follow a remote user, notify remote user about the follow
   # @param [Account] source_account From which to follow
   # @param [String, Account] uri User URI to follow in the form of username@domain (or account record)
@@ -10,7 +13,7 @@ class FollowService < BaseService
     target_account = ResolveAccountService.new.call(target_account, skip_webfinger: true)
 
     raise ActiveRecord::RecordNotFound if target_account.nil? || target_account.id == source_account.id || target_account.suspended?
-    raise Mastodon::NotPermittedError  if target_account.blocking?(source_account) || source_account.blocking?(target_account) || target_account.moved?
+    raise Mastodon::NotPermittedError  if target_account.blocking?(source_account) || source_account.blocking?(target_account) || target_account.moved? || source_account.domain_blocking?(target_account.domain)
 
     if source_account.following?(target_account)
       # We're already following this account, but we'll call follow! again to
@@ -67,10 +70,6 @@ class FollowService < BaseService
     follow
   end
 
-  def redis
-    Redis.current
-  end
-
   def build_follow_request_xml(follow_request)
     OStatus::AtomSerializer.render(OStatus::AtomSerializer.new.follow_request_salmon(follow_request))
   end
@@ -80,10 +79,6 @@ class FollowService < BaseService
   end
 
   def build_json(follow_request)
-    ActiveModelSerializers::SerializableResource.new(
-      follow_request,
-      serializer: ActivityPub::FollowSerializer,
-      adapter: ActivityPub::Adapter
-    ).to_json
+    Oj.dump(serialize_payload(follow_request, ActivityPub::FollowSerializer))
   end
 end
diff --git a/app/services/import_service.rb b/app/services/import_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4ee431ea33fb715e78e625ab34d0e9e26eff381d
--- /dev/null
+++ b/app/services/import_service.rb
@@ -0,0 +1,101 @@
+# frozen_string_literal: true
+
+require 'csv'
+
+class ImportService < BaseService
+  ROWS_PROCESSING_LIMIT = 20_000
+
+  def call(import)
+    @import  = import
+    @account = @import.account
+
+    case @import.type
+    when 'following'
+      import_follows!
+    when 'blocking'
+      import_blocks!
+    when 'muting'
+      import_mutes!
+    when 'domain_blocking'
+      import_domain_blocks!
+    end
+  end
+
+  private
+
+  def import_follows!
+    parse_import_data!(['Account address'])
+    import_relationships!('follow', 'unfollow', @account.following, follow_limit, reblogs: 'Show boosts')
+  end
+
+  def import_blocks!
+    parse_import_data!(['Account address'])
+    import_relationships!('block', 'unblock', @account.blocking, ROWS_PROCESSING_LIMIT)
+  end
+
+  def import_mutes!
+    parse_import_data!(['Account address'])
+    import_relationships!('mute', 'unmute', @account.muting, ROWS_PROCESSING_LIMIT, notifications: 'Hide notifications')
+  end
+
+  def import_domain_blocks!
+    parse_import_data!(['#domain'])
+    items = @data.take(ROWS_PROCESSING_LIMIT).map { |row| row['#domain'].strip }
+
+    if @import.overwrite?
+      presence_hash = items.each_with_object({}) { |id, mapping| mapping[id] = true }
+
+      @account.domain_blocks.find_each do |domain_block|
+        if presence_hash[domain_block.domain]
+          items.delete(domain_block.domain)
+        else
+          @account.unblock_domain!(domain_block.domain)
+        end
+      end
+    end
+
+    items.each do |domain|
+      @account.block_domain!(domain)
+    end
+
+    AfterAccountDomainBlockWorker.push_bulk(items) do |domain|
+      [@account.id, domain]
+    end
+  end
+
+  def import_relationships!(action, undo_action, overwrite_scope, limit, extra_fields = {})
+    items = @data.take(limit).map { |row| [row['Account address']&.strip, Hash[extra_fields.map { |key, header| [key, row[header]&.strip] }]] }.reject { |(id, _)| id.blank? }
+
+    if @import.overwrite?
+      presence_hash = items.each_with_object({}) { |(id, extra), mapping| mapping[id] = [true, extra] }
+
+      overwrite_scope.find_each do |target_account|
+        if presence_hash[target_account.acct]
+          items.delete(target_account.acct)
+          extra = presence_hash[target_account.acct][1]
+          Import::RelationshipWorker.perform_async(@account.id, target_account.acct, action, extra)
+        else
+          Import::RelationshipWorker.perform_async(@account.id, target_account.acct, undo_action)
+        end
+      end
+    end
+
+    Import::RelationshipWorker.push_bulk(items) do |acct, extra|
+      [@account.id, acct, action, extra]
+    end
+  end
+
+  def parse_import_data!(default_headers)
+    data = CSV.parse(import_data, headers: true)
+    data = CSV.parse(import_data, headers: default_headers) unless data.headers&.first&.strip&.include?(' ')
+    @data = data.reject(&:blank?)
+  end
+
+  def import_data
+    Paperclip.io_adapters.for(@import.data).read
+  end
+
+  def follow_limit
+    FollowLimitValidator.limit_for_account(@account)
+  end
+end
diff --git a/app/services/notify_service.rb b/app/services/notify_service.rb
index b80ceef03c2428270ee14a29aebc28773a8938d3..b5c721589505b3b834a9ef33ebaa7ca2e2fa0c4f 100644
--- a/app/services/notify_service.rb
+++ b/app/services/notify_service.rb
@@ -38,6 +38,10 @@ class NotifyService < BaseService
     false
   end
 
+  def blocked_poll?
+    false
+  end
+
   def following_sender?
     return @following_sender if defined?(@following_sender)
     @following_sender = @recipient.following?(@notification.from_account) || @recipient.requested?(@notification.from_account)
@@ -88,7 +92,7 @@ class NotifyService < BaseService
 
   def blocked?
     blocked   = @recipient.suspended?                            # Skip if the recipient account is suspended anyway
-    blocked ||= from_self?                                       # Skip for interactions with self
+    blocked ||= from_self? && @notification.type != :poll        # Skip for interactions with self
 
     return blocked if message? && from_staff?
 
diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb
index cc3453f995a1722cc9cd2dcfea2889b64f0de65c..7830aee11876b348c73acc99a06952675508e0b5 100644
--- a/app/services/post_status_service.rb
+++ b/app/services/post_status_service.rb
@@ -1,6 +1,8 @@
 # frozen_string_literal: true
 
 class PostStatusService < BaseService
+  include Redisable
+
   MIN_SCHEDULE_OFFSET = 5.minutes.freeze
 
   # Post a text status update, fetch and notify remote users mentioned
@@ -13,6 +15,7 @@ class PostStatusService < BaseService
   # @option [String] :spoiler_text
   # @option [String] :language
   # @option [String] :scheduled_at
+  # @option [Hash] :poll Optional poll to attach
   # @option [Enumerable] :media_ids Optional array of media IDs to attach
   # @option [Doorkeeper::Application] :application
   # @option [String] :idempotency Optional idempotency key
@@ -46,7 +49,7 @@ class PostStatusService < BaseService
   def preprocess_attributes!
     @text         = @options.delete(:spoiler_text) if @text.blank? && @options[:spoiler_text].present?
     @visibility   = @options[:visibility] || @account.user&.setting_default_privacy
-    @visibility   = :unlisted if @visibility == :public && @account.silenced
+    @visibility   = :unlisted if @visibility == :public && @account.silenced?
     @scheduled_at = @options[:scheduled_at]&.to_datetime
     @scheduled_at = nil if scheduled_in_the_past?
   rescue ArgumentError
@@ -66,7 +69,11 @@ class PostStatusService < BaseService
   end
 
   def schedule_status!
-    if @account.statuses.build(status_attributes).valid?
+    status_for_validation = @account.statuses.build(status_attributes)
+
+    if status_for_validation.valid?
+      status_for_validation.destroy
+
       # The following transaction block is needed to wrap the UPDATEs to
       # the media attachments when the scheduled status is created
 
@@ -83,16 +90,17 @@ class PostStatusService < BaseService
     DistributionWorker.perform_async(@status.id)
     Pubsubhubbub::DistributionWorker.perform_async(@status.stream_entry.id)
     ActivityPub::DistributionWorker.perform_async(@status.id)
+    PollExpirationNotifyWorker.perform_at(@status.poll.expires_at, @status.poll.id) if @status.poll
   end
 
   def validate_media!
     return if @options[:media_ids].blank? || !@options[:media_ids].is_a?(Enumerable)
 
-    raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > 4
+    raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > 4 || @options[:poll].present?
 
-    @media = MediaAttachment.where(status_id: nil).where(id: @options[:media_ids].take(4).map(&:to_i))
+    @media = @account.media_attachments.where(status_id: nil).where(id: @options[:media_ids].take(4).map(&:to_i))
 
-    raise Mastodon::ValidationError, I18n.t('media_attachments.validations.images_and_video') if @media.size > 1 && @media.find(&:video?)
+    raise Mastodon::ValidationError, I18n.t('media_attachments.validations.images_and_video') if @media.size > 1 && @media.find(&:audio_or_video?)
   end
 
   def language_from_option(str)
@@ -107,10 +115,6 @@ class PostStatusService < BaseService
     ProcessHashtagsService.new
   end
 
-  def redis
-    Redis.current
-  end
-
   def scheduled?
     @scheduled_at.present?
   end
@@ -151,12 +155,13 @@ class PostStatusService < BaseService
       text: @text,
       media_attachments: @media || [],
       thread: @in_reply_to,
+      poll_attributes: poll_attributes,
       sensitive: (@options[:sensitive].nil? ? @account.user&.setting_default_sensitive : @options[:sensitive]) || @options[:spoiler_text].present?,
       spoiler_text: @options[:spoiler_text] || '',
       visibility: @visibility,
       language: language_from_option(@options[:language]) || @account.user&.setting_default_language&.presence || LanguageDetector.instance.detect(@text, @account),
       application: @options[:application],
-    }
+    }.compact
   end
 
   def scheduled_status_attributes
@@ -167,6 +172,12 @@ class PostStatusService < BaseService
     }
   end
 
+  def poll_attributes
+    return if @options[:poll].blank?
+
+    @options[:poll].merge(account: @account)
+  end
+
   def scheduled_options
     @options.tap do |options_hash|
       options_hash[:in_reply_to_id] = options_hash.delete(:thread)&.id
diff --git a/app/services/process_hashtags_service.rb b/app/services/process_hashtags_service.rb
index cf7471c9893ebd39a82cf00658f01b1ff3439f3b..d5ec076a8b24f4cdb34885fc82961cc11fdb5a29 100644
--- a/app/services/process_hashtags_service.rb
+++ b/app/services/process_hashtags_service.rb
@@ -2,12 +2,22 @@
 
 class ProcessHashtagsService < BaseService
   def call(status, tags = [])
-    tags = Extractor.extract_hashtags(status.text) if status.local?
+    tags    = Extractor.extract_hashtags(status.text) if status.local?
+    records = []
 
     tags.map { |str| str.mb_chars.downcase }.uniq(&:to_s).each do |name|
       tag = Tag.where(name: name).first_or_create(name: name)
+
       status.tags << tag
+      records << tag
+
       TrendingTags.record_use!(tag, status.account, status.created_at) if status.public_visibility?
     end
+
+    return unless status.public_visibility? || status.unlisted_visibility?
+
+    status.account.featured_tags.where(tag_id: records.map(&:id)).each do |featured_tag|
+      featured_tag.increment(status.created_at)
+    end
   end
 end
diff --git a/app/services/process_mentions_service.rb b/app/services/process_mentions_service.rb
index 2595c5fd3668c9743e3eed5d318b007c6ac1de15..bc607dff3953c210f67b42a33c518753afa52d3b 100644
--- a/app/services/process_mentions_service.rb
+++ b/app/services/process_mentions_service.rb
@@ -2,6 +2,7 @@
 
 class ProcessMentionsService < BaseService
   include StreamEntryRenderer
+  include Payloadable
 
   # Scan status for mentions and fetch remote mentioned users, create
   # local mention pointers, send Salmon notifications to mentioned
@@ -25,7 +26,7 @@ class ProcessMentionsService < BaseService
         end
       end
 
-      next match if mention_undeliverable?(mentioned_account) || mentioned_account&.suspended
+      next match if mention_undeliverable?(mentioned_account) || mentioned_account&.suspended?
 
       mentions << mentioned_account.mentions.where(status: status).first_or_create(status: status)
 
@@ -61,12 +62,7 @@ class ProcessMentionsService < BaseService
 
   def activitypub_json
     return @activitypub_json if defined?(@activitypub_json)
-    payload = ActiveModelSerializers::SerializableResource.new(
-      @status,
-      serializer: ActivityPub::ActivitySerializer,
-      adapter: ActivityPub::Adapter
-    ).as_json
-    @activitypub_json = Oj.dump(@status.distributable? ? ActivityPub::LinkedDataSignature.new(payload).sign!(@status.account) : payload)
+    @activitypub_json = Oj.dump(serialize_payload(@status, ActivityPub::ActivitySerializer, signer: @status.account))
   end
 
   def resolve_account_service
diff --git a/app/services/reblog_service.rb b/app/services/reblog_service.rb
index 33ddef8b88d9482d63b0128ea5a9a53b96e13a6b..9cf4bc128b8f1958f5b5b548384726835918afb4 100644
--- a/app/services/reblog_service.rb
+++ b/app/services/reblog_service.rb
@@ -3,12 +3,14 @@
 class ReblogService < BaseService
   include Authorization
   include StreamEntryRenderer
+  include Payloadable
 
   # Reblog a status and notify its remote author
   # @param [Account] account Account to reblog from
   # @param [Status] reblogged_status Status to be reblogged
+  # @param [Hash] options
   # @return [Status]
-  def call(account, reblogged_status)
+  def call(account, reblogged_status, options = {})
     reblogged_status = reblogged_status.reblog if reblogged_status.reblog?
 
     authorize_with account, reblogged_status, :reblog?
@@ -17,7 +19,9 @@ class ReblogService < BaseService
 
     return reblog unless reblog.nil?
 
-    reblog = account.statuses.create!(reblog: reblogged_status, text: '')
+    visibility = options[:visibility] || account.user&.setting_default_privacy
+    visibility = reblogged_status.visibility if reblogged_status.hidden?
+    reblog = account.statuses.create!(reblog: reblogged_status, text: '', visibility: visibility)
 
     DistributionWorker.perform_async(reblog.id)
     Pubsubhubbub::DistributionWorker.perform_async(reblog.stream_entry.id)
@@ -35,7 +39,7 @@ class ReblogService < BaseService
     reblogged_status = reblog.reblog
 
     if reblogged_status.account.local?
-      NotifyService.new.call(reblogged_status.account, reblog)
+      LocalNotificationWorker.perform_async(reblogged_status.account_id, reblog.id, reblog.class.name)
     elsif reblogged_status.account.ostatus?
       NotificationWorker.perform_async(stream_entry_to_xml(reblog.stream_entry), reblog.account_id, reblogged_status.account_id)
     elsif reblogged_status.account.activitypub? && !reblogged_status.account.following?(reblog.account)
@@ -50,10 +54,6 @@ class ReblogService < BaseService
   end
 
   def build_json(reblog)
-    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
-      reblog,
-      serializer: ActivityPub::ActivitySerializer,
-      adapter: ActivityPub::Adapter
-    ).as_json).sign!(reblog.account))
+    Oj.dump(serialize_payload(reblog, ActivityPub::ActivitySerializer, signer: reblog.account))
   end
 end
diff --git a/app/services/reject_follow_service.rb b/app/services/reject_follow_service.rb
index a91266aa4b65b6447e1558cdc7373fda46a50aed..f87d0ba914f6382fc5904f885b21da6384c26543 100644
--- a/app/services/reject_follow_service.rb
+++ b/app/services/reject_follow_service.rb
@@ -1,6 +1,8 @@
 # frozen_string_literal: true
 
 class RejectFollowService < BaseService
+  include Payloadable
+
   def call(source_account, target_account)
     follow_request = FollowRequest.find_by!(account: source_account, target_account: target_account)
     follow_request.reject!
@@ -19,11 +21,7 @@ class RejectFollowService < BaseService
   end
 
   def build_json(follow_request)
-    ActiveModelSerializers::SerializableResource.new(
-      follow_request,
-      serializer: ActivityPub::RejectFollowSerializer,
-      adapter: ActivityPub::Adapter
-    ).to_json
+    Oj.dump(serialize_payload(follow_request, ActivityPub::RejectFollowSerializer))
   end
 
   def build_xml(follow_request)
diff --git a/app/services/remove_status_service.rb b/app/services/remove_status_service.rb
index 11d28e783d04c86d5c48ccca49370badc3311e34..81adc5aae54dcb0fe8c4c7f1849cd0e493db3dc2 100644
--- a/app/services/remove_status_service.rb
+++ b/app/services/remove_status_service.rb
@@ -2,6 +2,8 @@
 
 class RemoveStatusService < BaseService
   include StreamEntryRenderer
+  include Redisable
+  include Payloadable
 
   def call(status, **options)
     @payload      = Oj.dump(event: :delete, payload: status.id.to_s)
@@ -9,20 +11,26 @@ class RemoveStatusService < BaseService
     @account      = status.account
     @tags         = status.tags.pluck(:name).to_a
     @mentions     = status.active_mentions.includes(:account).to_a
-    @reblogs      = status.reblogs.to_a
+    @reblogs      = status.reblogs.includes(:account).to_a
     @stream_entry = status.stream_entry
     @options      = options
 
-    remove_from_self if status.account.local?
-    remove_from_followers
-    remove_from_lists
-    remove_from_affected
-    remove_reblogs
-    remove_from_hashtags
-    remove_from_public
-    remove_from_media if status.media_attachments.any?
-
-    @status.destroy!
+    RedisLock.acquire(lock_options) do |lock|
+      if lock.acquired?
+        remove_from_self if status.account.local?
+        remove_from_followers
+        remove_from_lists
+        remove_from_affected
+        remove_reblogs
+        remove_from_hashtags
+        remove_from_public
+        remove_from_media if status.media_attachments.any?
+
+        @status.destroy!
+      else
+        raise Mastodon::RaceConditionError
+      end
+    end
 
     # There is no reason to send out Undo activities when the
     # cause is that the original object has been removed, since
@@ -55,7 +63,7 @@ class RemoveStatusService < BaseService
 
   def remove_from_affected
     @mentions.map(&:account).select(&:local?).each do |account|
-      Redis.current.publish("timeline:#{account.id}", @payload)
+      redis.publish("timeline:#{account.id}", @payload)
     end
   end
 
@@ -76,8 +84,8 @@ class RemoveStatusService < BaseService
     end
 
     # ActivityPub
-    ActivityPub::DeliveryWorker.push_bulk(target_accounts.select(&:activitypub?).uniq(&:inbox_url)) do |target_account|
-      [signed_activity_json, @account.id, target_account.inbox_url]
+    ActivityPub::DeliveryWorker.push_bulk(target_accounts.select(&:activitypub?).uniq(&:preferred_inbox_url)) do |target_account|
+      [signed_activity_json, @account.id, target_account.preferred_inbox_url]
     end
   end
 
@@ -108,15 +116,7 @@ class RemoveStatusService < BaseService
   end
 
   def signed_activity_json
-    @signed_activity_json ||= Oj.dump(ActivityPub::LinkedDataSignature.new(activity_json).sign!(@account))
-  end
-
-  def activity_json
-    @activity_json ||= ActiveModelSerializers::SerializableResource.new(
-      @status,
-      serializer: @status.reblog? ? ActivityPub::UndoAnnounceSerializer : ActivityPub::DeleteSerializer,
-      adapter: ActivityPub::Adapter
-    ).as_json
+    @signed_activity_json ||= Oj.dump(serialize_payload(@status, @status.reblog? ? ActivityPub::UndoAnnounceSerializer : ActivityPub::DeleteSerializer, signer: @account))
   end
 
   def remove_reblogs
@@ -130,29 +130,33 @@ class RemoveStatusService < BaseService
   end
 
   def remove_from_hashtags
+    @account.featured_tags.where(tag_id: @status.tags.pluck(:id)).each do |featured_tag|
+      featured_tag.decrement(@status.id)
+    end
+
     return unless @status.public_visibility?
 
     @tags.each do |hashtag|
-      Redis.current.publish("timeline:hashtag:#{hashtag}", @payload)
-      Redis.current.publish("timeline:hashtag:#{hashtag}:local", @payload) if @status.local?
+      redis.publish("timeline:hashtag:#{hashtag}", @payload)
+      redis.publish("timeline:hashtag:#{hashtag}:local", @payload) if @status.local?
     end
   end
 
   def remove_from_public
     return unless @status.public_visibility?
 
-    Redis.current.publish('timeline:public', @payload)
-    Redis.current.publish('timeline:public:local', @payload) if @status.local?
+    redis.publish('timeline:public', @payload)
+    redis.publish('timeline:public:local', @payload) if @status.local?
   end
 
   def remove_from_media
     return unless @status.public_visibility?
 
-    Redis.current.publish('timeline:public:media', @payload)
-    Redis.current.publish('timeline:public:local:media', @payload) if @status.local?
+    redis.publish('timeline:public:media', @payload)
+    redis.publish('timeline:public:local:media', @payload) if @status.local?
   end
 
-  def redis
-    Redis.current
+  def lock_options
+    { redis: Redis.current, key: "distribute:#{@status.id}" }
   end
 end
diff --git a/app/services/report_service.rb b/app/services/report_service.rb
index 1bcc1c0d56c3a7e3e15e82ecbf5eccc6078ea9c7..1e955c1e704b70574511426e1e7f25097889d257 100644
--- a/app/services/report_service.rb
+++ b/app/services/report_service.rb
@@ -1,6 +1,8 @@
 # frozen_string_literal: true
 
 class ReportService < BaseService
+  include Payloadable
+
   def call(source_account, target_account, options = {})
     @source_account = source_account
     @target_account = target_account
@@ -21,7 +23,8 @@ class ReportService < BaseService
     @report = @source_account.reports.create!(
       target_account: @target_account,
       status_ids: @status_ids,
-      comment: @comment
+      comment: @comment,
+      uri: @options[:uri]
     )
   end
 
@@ -43,12 +46,7 @@ class ReportService < BaseService
   end
 
   def payload
-    Oj.dump(ActiveModelSerializers::SerializableResource.new(
-      @report,
-      serializer: ActivityPub::FlagSerializer,
-      adapter: ActivityPub::Adapter,
-      account: some_local_account
-    ).as_json)
+    Oj.dump(serialize_payload(@report, ActivityPub::FlagSerializer, account: some_local_account))
   end
 
   def some_local_account
diff --git a/app/services/resolve_account_service.rb b/app/services/resolve_account_service.rb
index 4ff351c5f72644253390a6c05ba7fb3b3b7dbcb5..e557706da5c12a6d06798f8a77163b6188c0f2cd 100644
--- a/app/services/resolve_account_service.rb
+++ b/app/services/resolve_account_service.rb
@@ -48,7 +48,7 @@ class ResolveAccountService < BaseService
       return
     end
 
-    return if links_missing?
+    return if links_missing? || auto_suspend?
     return Account.find_local(@username) if TagManager.instance.local_domain?(@domain)
 
     RedisLock.acquire(lock_options) do |lock|
@@ -119,9 +119,9 @@ class ResolveAccountService < BaseService
     Rails.logger.debug "Creating new remote account for #{@username}@#{@domain}"
 
     @account = Account.new(username: @username, domain: @domain)
-    @account.suspended   = true if auto_suspend?
-    @account.silenced    = true if auto_silence?
-    @account.private_key = nil
+    @account.suspended_at = domain_block.created_at if auto_suspend?
+    @account.silenced_at  = domain_block.created_at if auto_silence?
+    @account.private_key  = nil
   end
 
   def update_account
@@ -146,7 +146,7 @@ class ResolveAccountService < BaseService
 
   def domain_block
     return @domain_block if defined?(@domain_block)
-    @domain_block = DomainBlock.find_by(domain: @domain)
+    @domain_block = DomainBlock.rule_for(@domain)
   end
 
   def atom_url
diff --git a/app/services/resolve_url_service.rb b/app/services/resolve_url_service.rb
index ed0c569230f64f3e459eb7f893a3f55738fe8fbf..b98759bf68b698d5bd5fce4d5f74e380ab7a8725 100644
--- a/app/services/resolve_url_service.rb
+++ b/app/services/resolve_url_service.rb
@@ -20,7 +20,7 @@ class ResolveURLService < BaseService
   def process_url
     if equals_or_includes_any?(type, %w(Application Group Organization Person Service))
       FetchRemoteAccountService.new.call(atom_url, body, protocol)
-    elsif equals_or_includes_any?(type, %w(Note Article Image Video Page))
+    elsif equals_or_includes_any?(type, %w(Note Article Image Video Page Question))
       FetchRemoteStatusService.new.call(atom_url, body, protocol)
     end
   end
diff --git a/app/services/search_service.rb b/app/services/search_service.rb
index 1c31e0509a8549ba0de1f20c6cf3cf380ce92ec7..e0da61dac5b81545ffce7e158d1c8c7b408b8f39 100644
--- a/app/services/search_service.rb
+++ b/app/services/search_service.rb
@@ -1,18 +1,18 @@
 # frozen_string_literal: true
 
 class SearchService < BaseService
-  attr_accessor :query, :account, :limit, :resolve
-
-  def call(query, limit, resolve = false, account = nil)
+  def call(query, account, limit, options = {})
     @query   = query.strip
     @account = account
-    @limit   = limit
-    @resolve = resolve
+    @options = options
+    @limit   = limit.to_i
+    @offset  = options[:type].blank? ? 0 : options[:offset].to_i
+    @resolve = options[:resolve] || false
 
     default_results.tap do |results|
       if url_query?
         results.merge!(url_resource_results) unless url_resource.nil?
-      elsif query.present?
+      elsif @query.present?
         results[:accounts] = perform_accounts_search! if account_searchable?
         results[:statuses] = perform_statuses_search! if full_text_searchable?
         results[:hashtags] = perform_hashtags_search! if hashtag_searchable?
@@ -23,23 +23,46 @@ class SearchService < BaseService
   private
 
   def perform_accounts_search!
-    AccountSearchService.new.call(query, limit, account, resolve: resolve)
+    AccountSearchService.new.call(
+      @query,
+      @account,
+      limit: @limit,
+      resolve: @resolve,
+      offset: @offset
+    )
   end
 
   def perform_statuses_search!
-    statuses = StatusesIndex.filter(term: { searchable_by: account.id })
-                            .query(multi_match: { type: 'most_fields', query: query, operator: 'and', fields: %w(text text.stemmed) })
-                            .limit(limit)
-                            .objects
-                            .compact
+    definition = StatusesIndex.filter(term: { searchable_by: @account.id })
+                              .query(multi_match: { type: 'most_fields', query: @query, operator: 'and', fields: %w(text text.stemmed) })
+
+    if @options[:account_id].present?
+      definition = definition.filter(term: { account_id: @options[:account_id] })
+    end
+
+    if @options[:min_id].present? || @options[:max_id].present?
+      range      = {}
+      range[:gt] = @options[:min_id].to_i if @options[:min_id].present?
+      range[:lt] = @options[:max_id].to_i if @options[:max_id].present?
+      definition = definition.filter(range: { id: range })
+    end
+
+    results             = definition.limit(@limit).offset(@offset).objects.compact
+    account_ids         = results.map(&:account_id)
+    account_domains     = results.map(&:account_domain)
+    preloaded_relations = relations_map_for_account(@account, account_ids, account_domains)
 
-    statuses.reject { |status| StatusFilter.new(status, account).filtered? }
+    results.reject { |status| StatusFilter.new(status, @account, preloaded_relations).filtered? }
   rescue Faraday::ConnectionFailed
     []
   end
 
   def perform_hashtags_search!
-    Tag.search_for(query.gsub(/\A#/, ''), limit)
+    Tag.search_for(
+      @query.gsub(/\A#/, ''),
+      @limit,
+      @offset
+    )
   end
 
   def default_results
@@ -47,7 +70,7 @@ class SearchService < BaseService
   end
 
   def url_query?
-    query =~ /\Ahttps?:\/\//
+    @options[:type].blank? && @query =~ /\Ahttps?:\/\//
   end
 
   def url_resource_results
@@ -55,7 +78,7 @@ class SearchService < BaseService
   end
 
   def url_resource
-    @_url_resource ||= ResolveURLService.new.call(query, on_behalf_of: @account)
+    @_url_resource ||= ResolveURLService.new.call(@query, on_behalf_of: @account)
   end
 
   def url_resource_symbol
@@ -64,14 +87,37 @@ class SearchService < BaseService
 
   def full_text_searchable?
     return false unless Chewy.enabled?
-    !account.nil? && !((query.start_with?('#') || query.include?('@')) && !query.include?(' '))
+
+    statuses_search? && !@account.nil? && !((@query.start_with?('#') || @query.include?('@')) && !@query.include?(' '))
   end
 
   def account_searchable?
-    !(query.include?('@') && query.include?(' '))
+    account_search? && !(@query.include?('@') && @query.include?(' '))
   end
 
   def hashtag_searchable?
-    !query.include?('@')
+    hashtag_search? && !@query.include?('@')
+  end
+
+  def account_search?
+    @options[:type].blank? || @options[:type] == 'accounts'
+  end
+
+  def hashtag_search?
+    @options[:type].blank? || @options[:type] == 'hashtags'
+  end
+
+  def statuses_search?
+    @options[:type].blank? || @options[:type] == 'statuses'
+  end
+
+  def relations_map_for_account(account, account_ids, domains)
+    {
+      blocking: Account.blocking_map(account_ids, account.id),
+      blocked_by: Account.blocked_by_map(account_ids, account.id),
+      muting: Account.muting_map(account_ids, account.id),
+      following: Account.following_map(account_ids, account.id),
+      domain_blocking_by_domain: Account.domain_blocking_map_by_domain(domains, account.id),
+    }
   end
 end
diff --git a/app/services/subscribe_service.rb b/app/services/subscribe_service.rb
index 2893b5410358337dfff1cd854ba514f727fe8765..83fd64396a1057d981ed67ca6f7c2e506ca78aac 100644
--- a/app/services/subscribe_service.rb
+++ b/app/services/subscribe_service.rb
@@ -43,7 +43,7 @@ class SubscribeService < BaseService
   end
 
   def some_local_account
-    @some_local_account ||= Account.local.where(suspended: false).first
+    @some_local_account ||= Account.local.without_suspended.first
   end
 
   # Any response in the 3xx or 4xx range, except for 429 (rate limit)
diff --git a/app/services/suspend_account_service.rb b/app/services/suspend_account_service.rb
index 1bc2314de7156e802fe75c8d0139e00afb4147ea..5dd01da52582b3440aa675b3955b1c78b2d59a73 100644
--- a/app/services/suspend_account_service.rb
+++ b/app/services/suspend_account_service.rb
@@ -1,6 +1,8 @@
 # frozen_string_literal: true
 
 class SuspendAccountService < BaseService
+  include Payloadable
+
   ASSOCIATIONS_ON_SUSPEND = %w(
     account_pins
     active_relationships
@@ -41,6 +43,7 @@ class SuspendAccountService < BaseService
     @account = account
     @options = options
 
+    reject_follows!
     purge_user!
     purge_profile!
     purge_content!
@@ -48,6 +51,14 @@ class SuspendAccountService < BaseService
 
   private
 
+  def reject_follows!
+    return if @account.local? || !@account.activitypub?
+
+    ActivityPub::DeliveryWorker.push_bulk(Follow.where(account: @account)) do |follow|
+      [build_reject_json(follow), follow.target_account_id, follow.account.inbox_url]
+    end
+  end
+
   def purge_user!
     return if !@account.local? || @account.user.nil?
 
@@ -55,11 +66,12 @@ class SuspendAccountService < BaseService
       @account.user.destroy
     else
       @account.user.disable!
+      @account.user.invites.where(uses: 0).destroy_all
     end
   end
 
   def purge_content!
-    distribute_delete_actor! if @account.local?
+    distribute_delete_actor! if @account.local? && !@options[:skip_distribution]
 
     @account.statuses.reorder(nil).find_in_batches do |statuses|
       BatchedRemoveStatusService.new.call(statuses, skip_side_effects: @options[:destroy])
@@ -79,12 +91,12 @@ class SuspendAccountService < BaseService
 
     return if @options[:destroy]
 
-    @account.silenced         = false
-    @account.suspended        = true
+    @account.silenced_at      = nil
+    @account.suspended_at     = @options[:suspended_at] || Time.now.utc
     @account.locked           = false
     @account.display_name     = ''
     @account.note             = ''
-    @account.fields           = {}
+    @account.fields           = []
     @account.statuses_count   = 0
     @account.followers_count  = 0
     @account.following_count  = 0
@@ -102,22 +114,26 @@ class SuspendAccountService < BaseService
     ActivityPub::DeliveryWorker.push_bulk(delivery_inboxes) do |inbox_url|
       [delete_actor_json, @account.id, inbox_url]
     end
+
+    ActivityPub::LowPriorityDeliveryWorker.push_bulk(low_priority_delivery_inboxes) do |inbox_url|
+      [delete_actor_json, @account.id, inbox_url]
+    end
   end
 
   def delete_actor_json
-    return @delete_actor_json if defined?(@delete_actor_json)
-
-    payload = ActiveModelSerializers::SerializableResource.new(
-      @account,
-      serializer: ActivityPub::DeleteActorSerializer,
-      adapter: ActivityPub::Adapter
-    ).as_json
+    @delete_actor_json ||= Oj.dump(serialize_payload(@account, ActivityPub::DeleteActorSerializer, signer: @account))
+  end
 
-    @delete_actor_json = Oj.dump(ActivityPub::LinkedDataSignature.new(payload).sign!(@account))
+  def build_reject_json(follow)
+    Oj.dump(serialize_payload(follow, ActivityPub::RejectFollowSerializer))
   end
 
   def delivery_inboxes
-    Account.inboxes + Relay.enabled.pluck(:inbox_url)
+    @delivery_inboxes ||= @account.followers.inboxes + Relay.enabled.pluck(:inbox_url)
+  end
+
+  def low_priority_delivery_inboxes
+    Account.inboxes - delivery_inboxes
   end
 
   def associations_for_destruction
diff --git a/app/services/unblock_domain_service.rb b/app/services/unblock_domain_service.rb
index 946b6d465c3b18500ce7a41d4e6cb75e6e26b810..fc262a50ada223034602d078824ff55dba62ceb4 100644
--- a/app/services/unblock_domain_service.rb
+++ b/app/services/unblock_domain_service.rb
@@ -3,9 +3,9 @@
 class UnblockDomainService < BaseService
   attr_accessor :domain_block
 
-  def call(domain_block, retroactive)
+  def call(domain_block)
     @domain_block = domain_block
-    process_retroactive_updates if retroactive
+    process_retroactive_updates
     domain_block.destroy
   end
 
@@ -14,14 +14,20 @@ class UnblockDomainService < BaseService
   end
 
   def blocked_accounts
-    Account.where(domain: domain_block.domain)
+    scope = Account.by_domain_and_subdomains(domain_block.domain)
+
+    if domain_block.silence?
+      scope.where(silenced_at: @domain_block.created_at)
+    else
+      scope.where(suspended_at: @domain_block.created_at)
+    end
   end
 
   def update_options
-    { domain_block_impact => false }
+    { domain_block_impact => nil }
   end
 
   def domain_block_impact
-    domain_block.silence? ? :silenced : :suspended
+    domain_block.silence? ? :silenced_at : :suspended_at
   end
 end
diff --git a/app/services/unblock_service.rb b/app/services/unblock_service.rb
index 72fc5ab150d68702d953fd4efa495945b9bdacaa..95a858e9f59a8174502a40fe705ef9125ecdf1a3 100644
--- a/app/services/unblock_service.rb
+++ b/app/services/unblock_service.rb
@@ -1,6 +1,8 @@
 # frozen_string_literal: true
 
 class UnblockService < BaseService
+  include Payloadable
+
   def call(account, target_account)
     return unless account.blocking?(target_account)
 
@@ -20,11 +22,7 @@ class UnblockService < BaseService
   end
 
   def build_json(unblock)
-    ActiveModelSerializers::SerializableResource.new(
-      unblock,
-      serializer: ActivityPub::UndoBlockSerializer,
-      adapter: ActivityPub::Adapter
-    ).to_json
+    Oj.dump(serialize_payload(unblock, ActivityPub::UndoBlockSerializer))
   end
 
   def build_xml(block)
diff --git a/app/services/unfavourite_service.rb b/app/services/unfavourite_service.rb
index 2fda11bd660292be67c5eb99ad2960b4422bd3ab..dcc890b7de5f40e6fb3a8a439cf5af0dee31280c 100644
--- a/app/services/unfavourite_service.rb
+++ b/app/services/unfavourite_service.rb
@@ -1,6 +1,8 @@
 # frozen_string_literal: true
 
 class UnfavouriteService < BaseService
+  include Payloadable
+
   def call(account, status)
     favourite = Favourite.find_by!(account: account, status: status)
     favourite.destroy!
@@ -21,11 +23,7 @@ class UnfavouriteService < BaseService
   end
 
   def build_json(favourite)
-    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
-      favourite,
-      serializer: ActivityPub::UndoLikeSerializer,
-      adapter: ActivityPub::Adapter
-    ).as_json).sign!(favourite.account))
+    Oj.dump(serialize_payload(favourite, ActivityPub::UndoLikeSerializer))
   end
 
   def build_xml(favourite)
diff --git a/app/services/unfollow_service.rb b/app/services/unfollow_service.rb
index 95da2a667b32c03ba5a1be1a6da8acd2bfbd579e..17dc29735f9d5006fd7ece962c2c22b6d97de635 100644
--- a/app/services/unfollow_service.rb
+++ b/app/services/unfollow_service.rb
@@ -1,6 +1,8 @@
 # frozen_string_literal: true
 
 class UnfollowService < BaseService
+  include Payloadable
+
   # Unfollow and notify the remote user
   # @param [Account] source_account Where to unfollow from
   # @param [Account] target_account Which to unfollow
@@ -50,19 +52,11 @@ class UnfollowService < BaseService
   end
 
   def build_json(follow)
-    ActiveModelSerializers::SerializableResource.new(
-      follow,
-      serializer: ActivityPub::UndoFollowSerializer,
-      adapter: ActivityPub::Adapter
-    ).to_json
+    Oj.dump(serialize_payload(follow, ActivityPub::UndoFollowSerializer))
   end
 
   def build_reject_json(follow)
-    ActiveModelSerializers::SerializableResource.new(
-      follow,
-      serializer: ActivityPub::RejectFollowSerializer,
-      adapter: ActivityPub::Adapter
-    ).to_json
+    Oj.dump(serialize_payload(follow, ActivityPub::RejectFollowSerializer))
   end
 
   def build_xml(follow)
diff --git a/app/services/update_remote_profile_service.rb b/app/services/update_remote_profile_service.rb
index 68d36addfcaf12442568d3f8210768cb72c1e336..403395a0ddb1b0f620f61048f65b5ff17d99a71d 100644
--- a/app/services/update_remote_profile_service.rb
+++ b/app/services/update_remote_profile_service.rb
@@ -26,7 +26,7 @@ class UpdateRemoteProfileService < BaseService
     account.note         = remote_profile.note         || ''
     account.locked       = remote_profile.locked?
 
-    if !account.suspended? && !DomainBlock.find_by(domain: account.domain)&.reject_media?
+    if !account.suspended? && !DomainBlock.reject_media?(account.domain)
       if remote_profile.avatar.present?
         account.avatar_remote_url = remote_profile.avatar
       else
@@ -46,7 +46,7 @@ class UpdateRemoteProfileService < BaseService
   end
 
   def save_emojis
-    do_not_download = DomainBlock.find_by(domain: account.domain)&.reject_media?
+    do_not_download = DomainBlock.reject_media?(account.domain)
 
     return if do_not_download
 
diff --git a/app/services/verify_link_service.rb b/app/services/verify_link_service.rb
index c6557876137f778c0aefbebba8430b56d42e1421..878a2188dc30399090c42f98a52c34429e2b2ebf 100644
--- a/app/services/verify_link_service.rb
+++ b/app/services/verify_link_service.rb
@@ -10,7 +10,7 @@ class VerifyLinkService < BaseService
     return unless link_back_present?
 
     field.mark_verified!
-  rescue HTTP::Error, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError => e
+  rescue OpenSSL::SSL::SSLError, HTTP::Error, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError => e
     Rails.logger.debug "Error fetching link #{@url}: #{e}"
     nil
   end
diff --git a/app/services/vote_service.rb b/app/services/vote_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0eeb8fd56a95f5a6c2dbb87a9638037ba1b1ce27
--- /dev/null
+++ b/app/services/vote_service.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+class VoteService < BaseService
+  include Authorization
+  include Payloadable
+
+  def call(account, poll, choices)
+    authorize_with account, poll, :vote?
+
+    @account = account
+    @poll    = poll
+    @choices = choices
+    @votes   = []
+
+    ApplicationRecord.transaction do
+      @choices.each do |choice|
+        @votes << @poll.votes.create!(account: @account, choice: choice)
+      end
+    end
+
+    ActivityTracker.increment('activity:interactions')
+
+    if @poll.account.local?
+      distribute_poll!
+    else
+      deliver_votes!
+      queue_final_poll_check!
+    end
+  end
+
+  private
+
+  def distribute_poll!
+    return if @poll.hide_totals?
+    ActivityPub::DistributePollUpdateWorker.perform_in(3.minutes, @poll.status.id)
+  end
+
+  def queue_final_poll_check!
+    return unless @poll.expires?
+    PollExpirationNotifyWorker.perform_at(@poll.expires_at + 5.minutes, @poll.id)
+  end
+
+  def deliver_votes!
+    @votes.each do |vote|
+      ActivityPub::DeliveryWorker.perform_async(
+        build_json(vote),
+        @account.id,
+        @poll.account.inbox_url
+      )
+    end
+  end
+
+  def build_json(vote)
+    Oj.dump(serialize_payload(vote, ActivityPub::VoteSerializer))
+  end
+end
diff --git a/app/validators/blacklisted_email_validator.rb b/app/validators/blacklisted_email_validator.rb
index a2061fdd311069b06d0ff3444c3f911890d1ca86..0d01a1c47fb7fb842542a5d0981fcb547dd1d06b 100644
--- a/app/validators/blacklisted_email_validator.rb
+++ b/app/validators/blacklisted_email_validator.rb
@@ -2,7 +2,10 @@
 
 class BlacklistedEmailValidator < ActiveModel::Validator
   def validate(user)
+    return if user.valid_invitation?
+
     @email = user.email
+
     user.errors.add(:email, I18n.t('users.invalid_email')) if blocked_email?
   end
 
@@ -13,7 +16,7 @@ class BlacklistedEmailValidator < ActiveModel::Validator
   end
 
   def on_blacklist?
-    return true if EmailDomainBlock.block?(@email)
+    return true  if EmailDomainBlock.block?(@email)
     return false if Rails.configuration.x.email_domains_blacklist.blank?
 
     domains = Rails.configuration.x.email_domains_blacklist.gsub('.', '\.')
diff --git a/app/validators/domain_validator.rb b/app/validators/domain_validator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ae07f17980b1c894e52b78025c8c1d86112d44c1
--- /dev/null
+++ b/app/validators/domain_validator.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class DomainValidator < ActiveModel::EachValidator
+  def validate_each(record, attribute, value)
+    return if value.blank?
+
+    record.errors.add(attribute, I18n.t('domain_validator.invalid_domain')) unless compliant?(value)
+  end
+
+  private
+
+  def compliant?(value)
+    Addressable::URI.new.tap { |uri| uri.host = value }
+  rescue Addressable::URI::InvalidURIError
+    false
+  end
+end
diff --git a/app/validators/email_mx_validator.rb b/app/validators/email_mx_validator.rb
index 5b4c684b2c4b449ee98c8d693ce1b25cd5328701..96fbedcfcf9b813dccba10d44238a3b1f6226ddd 100644
--- a/app/validators/email_mx_validator.rb
+++ b/app/validators/email_mx_validator.rb
@@ -24,6 +24,7 @@ class EmailMxValidator < ActiveModel::Validator
 
       ([domain] + hostnames).uniq.each do |hostname|
         ips.concat(dns.getresources(hostname, Resolv::DNS::Resource::IN::A).to_a.map { |e| e.address.to_s })
+        ips.concat(dns.getresources(hostname, Resolv::DNS::Resource::IN::AAAA).to_a.map { |e| e.address.to_s })
       end
     end
 
diff --git a/app/validators/existing_username_validator.rb b/app/validators/existing_username_validator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b31d098273a7ee146bfcfd9c246f1e6fe629c6e4
--- /dev/null
+++ b/app/validators/existing_username_validator.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class ExistingUsernameValidator < ActiveModel::EachValidator
+  def validate_each(record, attribute, value)
+    return if value.blank?
+
+    if options[:multiple]
+      missing_usernames = value.split(',').map { |username| username.strip.gsub(/\A@/, '') }.map { |username| username unless Account.find_local(username) }.compact
+      record.errors.add(attribute, I18n.t('existing_username_validator.not_found_multiple', usernames: missing_usernames.join(', '))) if missing_usernames.any?
+    else
+      record.errors.add(attribute, I18n.t('existing_username_validator.not_found')) unless Account.find_local(value.strip.gsub(/\A@/, ''))
+    end
+  end
+end
diff --git a/app/validators/html_validator.rb b/app/validators/html_validator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1c9cd303cf46ab4d8f1f554a5f2b5e8047032bb3
--- /dev/null
+++ b/app/validators/html_validator.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class HtmlValidator < ActiveModel::EachValidator
+  ERROR_RE = /Opening and ending tag mismatch|Unexpected end tag/
+
+  def validate_each(record, attribute, value)
+    return if value.blank?
+
+    errors = html_errors(value)
+
+    record.errors.add(attribute, I18n.t('html_validator.invalid_markup', error: errors.first.to_s)) unless errors.empty?
+  end
+
+  private
+
+  def html_errors(str)
+    fragment = Nokogiri::HTML.fragment(options[:wrap_with] ? "<#{options[:wrap_with]}>#{str}</#{options[:wrap_with]}>" : str)
+    fragment.errors.select { |error| ERROR_RE =~ error.message }
+  end
+end
diff --git a/app/validators/poll_validator.rb b/app/validators/poll_validator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9d7321cad62966eea8ad85800952ed0cbc824b08
--- /dev/null
+++ b/app/validators/poll_validator.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class PollValidator < ActiveModel::Validator
+  MAX_OPTIONS      = 4
+  MAX_OPTION_CHARS = 25
+  MAX_EXPIRATION   = 1.month.freeze
+  MIN_EXPIRATION   = 5.minutes.freeze
+
+  def validate(poll)
+    current_time = Time.now.utc
+
+    poll.errors.add(:options, I18n.t('polls.errors.too_few_options')) unless poll.options.size > 1
+    poll.errors.add(:options, I18n.t('polls.errors.too_many_options', max: MAX_OPTIONS)) if poll.options.size > MAX_OPTIONS
+    poll.errors.add(:options, I18n.t('polls.errors.over_character_limit', max: MAX_OPTION_CHARS)) if poll.options.any? { |option| option.mb_chars.grapheme_length > MAX_OPTION_CHARS }
+    poll.errors.add(:options, I18n.t('polls.errors.duplicate_options')) unless poll.options.uniq.size == poll.options.size
+    poll.errors.add(:expires_at, I18n.t('polls.errors.duration_too_long')) if poll.expires_at.nil? || poll.expires_at - current_time > MAX_EXPIRATION
+    poll.errors.add(:expires_at, I18n.t('polls.errors.duration_too_short')) if poll.expires_at.present? && (poll.expires_at - current_time).ceil < MIN_EXPIRATION
+  end
+end
diff --git a/app/validators/vote_validator.rb b/app/validators/vote_validator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2e1818bdb94d3b557efaf726b02f0a6d7f03a90f
--- /dev/null
+++ b/app/validators/vote_validator.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class VoteValidator < ActiveModel::Validator
+  def validate(vote)
+    vote.errors.add(:base, I18n.t('polls.errors.expired')) if vote.poll.expired?
+
+    if vote.poll.multiple? && vote.poll.votes.where(account: vote.account, choice: vote.choice).exists?
+      vote.errors.add(:base, I18n.t('polls.errors.already_voted'))
+    elsif !vote.poll.multiple? && vote.poll.votes.where(account: vote.account).exists?
+      vote.errors.add(:base, I18n.t('polls.errors.already_voted'))
+    end
+  end
+end
diff --git a/app/views/about/_features.html.haml b/app/views/about/_features.html.haml
deleted file mode 100644
index 8fbc6b7607334ae839704962f6555263c7ccf3ff..0000000000000000000000000000000000000000
--- a/app/views/about/_features.html.haml
+++ /dev/null
@@ -1,25 +0,0 @@
-.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/about/_forms.html.haml b/app/views/about/_forms.html.haml
deleted file mode 100644
index 81f7173f7b1ffb8a4ef5107b9fbb34dc5874d9cf..0000000000000000000000000000000000000000
--- a/app/views/about/_forms.html.haml
+++ /dev/null
@@ -1,15 +0,0 @@
-- if @instance_presenter.open_registrations
-  = render 'registration'
-- else
-  = link_to t('auth.register_elsewhere'), 'https://joinmastodon.org', class: 'button button-primary'
-
-  .closed-registrations-message
-    - if @instance_presenter.closed_registrations_message.blank?
-      %p= t('about.closed_registrations')
-    - else
-      = @instance_presenter.closed_registrations_message.html_safe
-
-.separator-or
-  %span= t('auth.or')
-
-= link_to t('auth.login'), new_user_session_path, class: 'button button-alternative-2 webapp-btn'
diff --git a/app/views/about/_links.html.haml b/app/views/about/_links.html.haml
deleted file mode 100644
index f79c37e658b5c1ff7a8b438e778ceb0cbd0bfd3c..0000000000000000000000000000000000000000
--- a/app/views/about/_links.html.haml
+++ /dev/null
@@ -1,16 +0,0 @@
-.container-alt.links
-  .brand
-    = link_to root_url do
-      = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
-
-  %ul.nav
-    %li
-      - if user_signed_in?
-        = link_to t('settings.back'), root_url, class: 'webapp-btn'
-      - else
-        = link_to t('auth.login'), new_user_session_path, class: 'webapp-btn'
-    %li= link_to t('about.about_this'), about_more_path
-    %li
-      = link_to 'https://joinmastodon.org/' do
-        = "#{t('about.other_instances')}"
-        %i.fa.fa-external-link{ style: 'padding-left: 5px;' }
diff --git a/app/views/about/_login.html.haml b/app/views/about/_login.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..d286f0d3c6e2411c81759802373e7cc9fceff6e3
--- /dev/null
+++ b/app/views/about/_login.html.haml
@@ -0,0 +1,13 @@
+= simple_form_for(new_user, url: user_session_path) do |f|
+  .fields-group
+    - if use_seamless_external_login?
+      = f.input :email, placeholder: t('simple_form.labels.defaults.username_or_email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.username_or_email') }, hint: false
+    - else
+      = f.input :email, placeholder: t('simple_form.labels.defaults.email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }, hint: false
+
+    = f.input :password, placeholder: t('simple_form.labels.defaults.password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.password') }, hint: false
+
+  .actions
+    = f.button :button, t('auth.login'), type: :submit, class: 'button button-primary'
+
+  %p.hint.subtle-hint= link_to t('auth.trouble_logging_in'), new_user_password_path
diff --git a/app/views/about/_registration.html.haml b/app/views/about/_registration.html.haml
index ee4f8fe2e61d8994af7ce0888ff72d8981c2e146..ff32ec8c46caec1f8bb8cf6c541daea6de49c7b3 100644
--- a/app/views/about/_registration.html.haml
+++ b/app/views/about/_registration.html.haml
@@ -1,12 +1,28 @@
 = simple_form_for(new_user, url: user_registration_path) do |f|
-  = f.simple_fields_for :account do |account_fields|
-    = account_fields.input :username, wrapper: :with_label, autofocus: true, label: false, required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.username'), :autocomplete => 'off', placeholder: t('simple_form.labels.defaults.username') }, append: "@#{site_hostname}", hint: false
+  .simple_form__overlay-area
+    %p.lead= t('about.federation_hint_html', instance: content_tag(:strong, site_hostname))
 
-  = f.input :email, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email'), :autocomplete => 'off' }, hint: false
-  = f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password'), :autocomplete => 'off' }, hint: false
-  = f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_password'), :autocomplete => 'off' }, hint: false
+    .fields-group
+      = f.simple_fields_for :account do |account_fields|
+        = account_fields.input :username, wrapper: :with_label, label: false, required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.username'), :autocomplete => 'off', placeholder: t('simple_form.labels.defaults.username') }, append: "@#{site_hostname}", hint: false, disabled: closed_registrations?
 
-  .actions
-    = f.button :button, t('auth.register'), type: :submit, class: 'button button-primary'
+      = f.input :email, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email'), :autocomplete => 'off' }, hint: false, disabled: closed_registrations?
+      = f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password'), :autocomplete => 'off' }, hint: false, disabled: closed_registrations?
+      = f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_password'), :autocomplete => 'off' }, hint: false, disabled: closed_registrations?
 
-  %p.hint.subtle-hint=t('auth.agreement_html', rules_path: about_more_path, terms_path: terms_path)
+    - if approved_registrations?
+      .fields-group
+        = f.simple_fields_for :invite_request do |invite_request_fields|
+          = invite_request_fields.input :text, as: :text, wrapper: :with_block_label, required: false
+
+    .fields-group
+      = f.input :agreement, as: :boolean, wrapper: :with_label, label: t('auth.checkbox_agreement_html', rules_path: about_more_path, terms_path: terms_path), disabled: closed_registrations?
+
+    .actions
+      = f.button :button, sign_up_message, type: :submit, class: 'button button-primary', disabled: closed_registrations?
+
+    - if closed_registrations? && @instance_presenter.closed_registrations_message.present?
+      .simple_form__overlay-area__overlay
+        .simple_form__overlay-area__overlay__content.rich-formatting
+          .block-icon= fa_icon 'warning'
+          = @instance_presenter.closed_registrations_message.html_safe
diff --git a/app/views/about/more.html.haml b/app/views/about/more.html.haml
index f94c7c06f8ce05a00dcffb6404948c54f5251bb4..b248ed1d2300c28f4df6ed9059cb16217b7847b6 100644
--- a/app/views/about/more.html.haml
+++ b/app/views/about/more.html.haml
@@ -9,7 +9,7 @@
   .column-0
     .public-account-header.public-account-header--no-bar
       .public-account-header__image
-        = image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url || asset_pack_path('preview.jpg'), alt: @instance_presenter.site_title, class: 'parallax'
+        = image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url || asset_pack_path('media/images/preview.jpg'), alt: @instance_presenter.site_title, class: 'parallax'
 
   .column-1
     .landing-page__call-to-action{ dir: 'ltr' }
@@ -25,7 +25,7 @@
             %span= t 'about.status_count_after', count: @instance_presenter.status_count
         .row__mascot
           .landing-page__mascot
-            = image_tag @instance_presenter.mascot&.file&.url || asset_pack_path('elephant_ui_plane.svg'), alt: ''
+            = image_tag @instance_presenter.mascot&.file&.url || asset_pack_path('media/images/elephant_ui_plane.svg'), alt: ''
 
   .column-2
     .landing-page__information.contact-widget
diff --git a/app/views/about/show.html.haml b/app/views/about/show.html.haml
index f5a78665d3d84c0ea68ef2c981aa5278eecfdef9..f24f4e1957d91d5f8430e1f11e7dc8cab2c5509c 100644
--- a/app/views/about/show.html.haml
+++ b/app/views/about/show.html.haml
@@ -3,144 +3,78 @@
 
 - content_for :header_tags do
   %link{ rel: 'canonical', href: about_url }/
-  %script#initial-state{ type: 'application/json' }!= json_escape(@initial_state_json)
-  = javascript_pack_tag 'about', integrity: true, crossorigin: 'anonymous'
   = render partial: 'shared/og'
 
-.landing-page.alternative
-  .container
-    .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'
-
-      - else
-        .column-1.non-preview
-          .landing-page__forms
-            .brand
-              = link_to root_url do
-                = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
-
-            = 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{ dir: 'ltr' }
-            .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', count: @instance_presenter.user_count
-                .information-board__section
-                  %span= t 'about.status_count_before'
-                  %strong= number_with_delimiter @instance_presenter.status_count
-                  %span= t 'about.status_count_after', count: @instance_presenter.status_count
-              .row__mascot
-                .landing-page__mascot
-                  = image_tag @instance_presenter.mascot&.file&.url || asset_pack_path('elephant_ui_plane.svg'), alt: ''
-
-      - 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
-
-          .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
-              .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', count: @instance_presenter.user_count
-                .information-board__section
-                  %span= t 'about.status_count_before'
-                  %strong= number_with_delimiter @instance_presenter.status_count
-                  %span= t 'about.status_count_after', count: @instance_presenter.status_count
-              .row__mascot
-                .landing-page__mascot
-                  = image_tag @instance_presenter.mascot&.file&.url || asset_pack_path('elephant_ui_plane.svg'), alt: ''
-
-      - 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
-            .features-list
-              %div
-                %h3= t 'about.what_is_mastodon'
-                %p= t 'about.about_mastodon_html'
-              %div.contact
-                %h3= t 'about.administered_by'
-                = account_link_to(@instance_presenter.contact_account, link_to(t('about.learn_more'), about_more_path, class: 'button button-alternative'))
-
-            = render 'features'
-
-            .landing-page__features__action
-              = link_to t('about.learn_more'), 'https://joinmastodon.org/', class: 'button button-alternative'
-
-          .landing-page__footer
+.landing
+  .landing__brand
+    = link_to root_url, class: 'brand' do
+      = svg_logo_full
+      %span.brand__tagline=t 'about.tagline'
+
+  .landing__grid
+    .landing__grid__column.landing__grid__column-registration
+      .box-widget
+        = render 'registration'
+
+      .directory
+        - if Setting.profile_directory
+          .directory__tag
+            = optional_link_to Setting.profile_directory, explore_path do
+              %h4
+                = fa_icon 'address-book fw'
+                = t('about.discover_users')
+                %small= t('about.browse_directory')
+
+              .avatar-stack
+                - @instance_presenter.sample_accounts.each do |account|
+                  = image_tag current_account&.user&.setting_auto_play_gif ? account.avatar_original_url : account.avatar_static_url, width: 48, height: 48, alt: '', class: 'account__avatar'
+
+        - if Setting.timeline_preview
+          .directory__tag
+            = optional_link_to Setting.timeline_preview, public_timeline_path do
+              %h4
+                = fa_icon 'globe fw'
+                = t('about.see_whats_happening')
+                %small= t('about.browse_public_posts')
+
+        .directory__tag
+          = link_to 'https://joinmastodon.org/apps', target: '_blank', rel: 'noopener' do
+            %h4
+              = fa_icon 'tablet fw'
+              = t('about.get_apps')
+              %small= t('about.apps_platforms')
+
+    .landing__grid__column.landing__grid__column-login
+      .box-widget
+        = render 'login'
+
+      .hero-widget
+        .hero-widget__img
+          = image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url || asset_pack_path('media/images/preview.jpg'), alt: @instance_presenter.site_title
+
+        - if @instance_presenter.site_short_description.present?
+          .hero-widget__text
             %p
-              = link_to t('about.source_code'), @instance_presenter.source_url
-              = " (#{@instance_presenter.version_number})"
-
-      - else
-        .column-4.non-preview.landing-page__information
-          .landing-page__features
-            .features-list
-              %div
-                %h3= t 'about.what_is_mastodon'
-                %p= t 'about.about_mastodon_html'
-              %div.contact
-                %h3= t 'about.administered_by'
-                = account_link_to(@instance_presenter.contact_account, link_to(t('about.learn_more'), about_more_path, class: 'button button-alternative'))
-
-            = 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})"
-
-#modal-container
+              = @instance_presenter.site_short_description.html_safe.presence
+              = link_to about_more_path do
+                = t('about.learn_more')
+                = fa_icon 'angle-double-right'
+
+        .hero-widget__footer
+          .hero-widget__footer__column
+            %h4= t 'about.administered_by'
+
+            = account_link_to @instance_presenter.contact_account
+
+          .hero-widget__footer__column
+            %h4= t 'about.server_stats'
+
+            %div{ style: 'display: flex' }
+              .hero-widget__counter{ style: 'width: 50%' }
+                %strong= number_to_human @instance_presenter.user_count, strip_insignificant_zeros: true
+                %span= t 'about.user_count_after', count: @instance_presenter.user_count
+              .hero-widget__counter{ style: 'width: 50%' }
+                %strong= number_to_human @instance_presenter.active_user_count, strip_insignificant_zeros: true
+                %span
+                  = t 'about.active_count_after'
+                  %abbr{ title: t('about.active_footnote') } *
diff --git a/app/views/accounts/_bio.html.haml b/app/views/accounts/_bio.html.haml
index 2ea34a0485fa30e450bb93d142eca5f5040d914f..efc26d1366c5909529cf9e5f4610375a6558645e 100644
--- a/app/views/accounts/_bio.html.haml
+++ b/app/views/accounts/_bio.html.haml
@@ -1,7 +1,17 @@
+- proofs = account.identity_proofs.active
+- fields = account.fields
+
 .public-account-bio
-  - unless account.fields.empty?
+  - unless fields.empty? && proofs.empty?
     .account__header__fields
-      - account.fields.each do |field|
+      - proofs.each do |proof|
+        %dl
+          %dt= proof.provider.capitalize
+          %dd.verified
+            = link_to fa_icon('check'), proof.badge.proof_url, class: 'verified__mark', title: t('accounts.link_verified_on', date: l(proof.updated_at))
+            = link_to proof.provider_username, proof.badge.profile_url
+
+      - fields.each do |field|
         %dl
           %dt.emojify{ title: field.name }= Formatter.instance.format_field(account, field.name, custom_emojify: true)
           %dd{ title: field.value, class: custom_field_classes(field) }
@@ -9,6 +19,7 @@
               %span.verified__mark{ title: t('accounts.link_verified_on', date: l(field.verified_at)) }
                 = fa_icon 'check'
             = Formatter.instance.format_field(account, field.value, custom_emojify: true)
+
   = account_badge(account)
 
   - if account.note.present?
diff --git a/app/views/accounts/_header.html.haml b/app/views/accounts/_header.html.haml
index 370e7e470f50dc6aa3decb02695fbce3afa058a4..4ef9f94787e2b1f6e80fc7039cb3c4a9050a5643 100644
--- a/app/views/accounts/_header.html.haml
+++ b/app/views/accounts/_header.html.haml
@@ -3,7 +3,7 @@
     = image_tag (current_account&.user&.setting_auto_play_gif ? account.header_original_url : account.header_static_url), class: 'parallax'
   .public-account-header__bar
     = link_to short_account_url(account), class: 'avatar' do
-      = image_tag (current_account&.user&.setting_auto_play_gif ? account.avatar_original_url : account.avatar_static_url)
+      = image_tag (current_account&.user&.setting_auto_play_gif ? account.avatar_original_url : account.avatar_static_url), id: 'profile_page_avatar', data: {original: full_asset_url(account.avatar_original_url), static: full_asset_url(account.avatar_static_url), autoplay: current_account&.user&.setting_auto_play_gif}
     .public-account-header__tabs
       .public-account-header__tabs__name
         %h1
diff --git a/app/views/accounts/show.html.haml b/app/views/accounts/show.html.haml
index 0ee9dd7deda4dc53a78c899a0fc811b706498d41..8f8647536b1969ce81b8580efc92ae35a351e77f 100644
--- a/app/views/accounts/show.html.haml
+++ b/app/views/accounts/show.html.haml
@@ -5,7 +5,7 @@
   %meta{ name: 'description', content: account_description(@account) }/
 
   - if @account.user&.setting_noindex
-    %meta{ name: 'robots', content: 'noindex' }/
+    %meta{ name: 'robots', content: 'noindex, noarchive' }/
 
   %link{ rel: 'salmon', href: api_salmon_url(@account.id) }/
   %link{ rel: 'alternate', type: 'application/atom+xml', href: account_url(@account, format: 'atom') }/
@@ -33,10 +33,12 @@
         = active_link_to t('accounts.posts_with_replies'), short_account_with_replies_url(@account)
         = active_link_to t('accounts.media'), short_account_media_url(@account)
 
-      - if @statuses.empty?
+      - if user_signed_in? && @account.blocking?(current_account)
+        .nothing-here.nothing-here--under-tabs= t('accounts.unavailable')
+      - elsif @statuses.empty?
         = nothing_here 'nothing-here--under-tabs'
       - else
-        .activity-stream
+        .activity-stream.activity-stream--under-tabs
           - if params[:page].to_i.zero?
             = render partial: 'stream_entries/status', collection: @pinned_statuses, as: :status, locals: { pinned: true }
 
@@ -63,4 +65,17 @@
         - @endorsed_accounts.each do |account|
           = account_link_to account
 
+    - @account.featured_tags.order(statuses_count: :desc).each do |featured_tag|
+      .directory__tag{ class: params[:tag] == featured_tag.name ? 'active' : nil }
+        = link_to short_account_tag_path(@account, featured_tag.tag) do
+          %h4
+            = fa_icon 'hashtag'
+            = featured_tag.name
+            %small
+              - if featured_tag.last_status_at.nil?
+                = t('accounts.nothing_here')
+              - else
+                %time.formatted{ datetime: featured_tag.last_status_at.iso8601, title: l(featured_tag.last_status_at) }= l featured_tag.last_status_at
+          .trends__item__current= number_to_human featured_tag.statuses_count, strip_insignificant_zeros: true
+
     = render 'application/sidebar'
diff --git a/app/views/admin/accounts/_account.html.haml b/app/views/admin/accounts/_account.html.haml
index 1e1bb1812b0436666a3534444ce8aa8aa291d209..eba3ad804123bbd56363a8e980473aec022b811f 100644
--- a/app/views/admin/accounts/_account.html.haml
+++ b/app/views/admin/accounts/_account.html.haml
@@ -5,7 +5,7 @@
     %div{ style: 'margin: -2px 0' }= account_badge(account, all: true)
   %td
     - if account.user_current_sign_in_ip
-      %samp= account.user_current_sign_in_ip
+      %samp.ellipsized-ip{ title: account.user_current_sign_in_ip }= account.user_current_sign_in_ip
     - else
       \-
   %td
@@ -14,5 +14,9 @@
     - else
       \-
   %td
-    = table_link_to 'circle', t('admin.accounts.web'), web_path("accounts/#{account.id}")
-    = table_link_to 'globe', t('admin.accounts.public'), TagManager.instance.url_for(account)
+    - if account.local? && account.user_pending?
+      = table_link_to 'check', t('admin.accounts.approve'), approve_admin_account_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:approve, account.user)
+      = table_link_to 'times', t('admin.accounts.reject'), reject_admin_account_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:reject, account.user)
+    - else
+      = table_link_to 'circle', t('admin.accounts.web'), web_path("accounts/#{account.id}")
+      = table_link_to 'globe', t('admin.accounts.public'), TagManager.instance.url_for(account)
diff --git a/app/views/admin/accounts/index.html.haml b/app/views/admin/accounts/index.html.haml
index 91fddadf81d41edb6c626851a29a8b798b70c60a..7e9adb3fff3fd8fc8e8e77edcea3929aa9e49dd4 100644
--- a/app/views/admin/accounts/index.html.haml
+++ b/app/views/admin/accounts/index.html.haml
@@ -10,9 +10,10 @@
   .filter-subset
     %strong= t('admin.accounts.moderation.title')
     %ul
-      %li= filter_link_to t('admin.accounts.moderation.active'), silenced: nil, suspended: nil
-      %li= filter_link_to t('admin.accounts.moderation.silenced'), silenced: '1', suspended: nil
-      %li= filter_link_to t('admin.accounts.moderation.suspended'), suspended: '1', silenced: nil
+      %li= link_to safe_join([t('admin.accounts.moderation.pending'), "(#{number_with_delimiter(User.pending.count)})"], ' '), admin_pending_accounts_path
+      %li= filter_link_to t('admin.accounts.moderation.active'), silenced: nil, suspended: nil, pending: nil
+      %li= filter_link_to t('admin.accounts.moderation.silenced'), silenced: '1', suspended: nil, pending: nil
+      %li= filter_link_to t('admin.accounts.moderation.suspended'), suspended: '1', silenced: nil, pending: nil
   .filter-subset
     %strong= t('admin.accounts.role')
     %ul
@@ -26,8 +27,9 @@
         = hidden_field_tag key, params[key]
 
     - %i(username by_domain display_name email ip).each do |key|
-      .input.string.optional
-        = text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.accounts.#{key}")
+      - unless key == :by_domain && params[:remote].blank?
+        .input.string.optional
+          = text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.accounts.#{key}")
 
     .actions
       %button= t('admin.accounts.search')
diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml
index 280a834ba268d0ae2da9b188f1ee1b77dffe2c6c..7494c9fa2fd6d3a3be53f6e066e1583311f70054 100644
--- a/app/views/admin/accounts/show.html.haml
+++ b/app/views/admin/accounts/show.html.haml
@@ -37,6 +37,8 @@
           %span.red= t('admin.accounts.disabled')
         - elsif @account.local? && !@account.user&.confirmed?
           %span.neutral= t('admin.accounts.confirming')
+        - elsif @account.local? && !@account.user_approved?
+          %span.neutral= t('admin.accounts.pending')
         - else
           %span.neutral= t('admin.accounts.no_limits_imposed')
       .dashboard__counters__label= t 'admin.accounts.login_status'
@@ -95,7 +97,7 @@
             %td
               - if @account.user&.disabled?
                 = table_link_to 'unlock', t('admin.accounts.enable'), enable_admin_account_path(@account.id), method: :post if can?(:enable, @account.user)
-              - else
+              - elsif @account.user_approved?
                 = table_link_to 'lock', t('admin.accounts.disable'), new_admin_account_action_path(@account.id, type: 'disable') if can?(:disable, @account.user)
 
           %tr
@@ -144,28 +146,38 @@
         = link_to t('admin.accounts.reset_password'), admin_account_reset_path(@account.id), method: :create, class: 'button' if can?(:reset_password, @account.user)
         - if @account.user&.otp_required_for_login?
           = link_to t('admin.accounts.disable_two_factor_authentication'), admin_user_two_factor_authentication_path(@account.user.id), method: :delete, class: 'button' if can?(:disable_2fa, @account.user)
-        - unless @account.memorial?
+        - if !@account.memorial? && @account.user_approved?
           = link_to t('admin.accounts.memorialize'), memorialize_admin_account_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' if can?(:memorialize, @account)
       - else
         = link_to t('admin.accounts.redownload'), redownload_admin_account_path(@account.id), method: :post, class: 'button' if can?(:redownload, @account)
 
     %div{ style: 'float: left' }
-      - if @account.local?
+      - if @account.local? && @account.user_approved?
         = link_to t('admin.accounts.warn'), new_admin_account_action_path(@account.id, type: 'none'), class: 'button' if can?(:warn, @account)
       - if @account.silenced?
         = link_to t('admin.accounts.undo_silenced'), unsilence_admin_account_path(@account.id), method: :post, class: 'button' if can?(:unsilence, @account)
-      - else
+      - elsif !@account.local? || @account.user_approved?
         = link_to t('admin.accounts.silence'), new_admin_account_action_path(@account.id, type: 'silence'), class: 'button button--destructive' if can?(:silence, @account)
 
       - if @account.local?
+        - if @account.user_pending?
+          = link_to t('admin.accounts.approve'), approve_admin_account_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button' if can?(:approve, @account.user)
+          = link_to t('admin.accounts.reject'), reject_admin_account_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' if can?(:reject, @account.user)
+
         - unless @account.user_confirmed?
           = link_to t('admin.accounts.confirm'), admin_account_confirmation_path(@account.id), method: :post, class: 'button' if can?(:confirm, @account.user)
 
       - if @account.suspended?
         = link_to t('admin.accounts.undo_suspension'), unsuspend_admin_account_path(@account.id), method: :post, class: 'button' if can?(:unsuspend, @account)
-      - else
+      - elsif !@account.local? || @account.user_approved?
         = link_to t('admin.accounts.perform_full_suspension'), new_admin_account_action_path(@account.id, type: 'suspend'), class: 'button button--destructive' if can?(:suspend, @account)
 
+      - unless @account.local?
+        - if DomainBlock.where(domain: @account.domain).exists?
+          = link_to t('admin.domain_blocks.undo'), admin_instance_path(@account.domain), class: 'button'
+        - else
+          = link_to t('admin.domain_blocks.add_new'), new_admin_domain_block_path(_domain: @account.domain), class: 'button button--destructive'
+
   %hr.spacer/
 
   - unless @warnings.empty?
diff --git a/app/views/admin/action_logs/_action_log.html.haml b/app/views/admin/action_logs/_action_log.html.haml
index f059814bd618fcd421ab68e4cde9b4fd24d9f00b..a545e189ef6d8071769a85adc1c9f01cdc35d8a5 100644
--- a/app/views/admin/action_logs/_action_log.html.haml
+++ b/app/views/admin/action_logs/_action_log.html.haml
@@ -6,7 +6,7 @@
       .log-entry__title
         = t("admin.action_logs.actions.#{action_log.action}_#{action_log.target_type.underscore}", name: content_tag(:span, action_log.account.username, class: 'username'), target: content_tag(:span, log_target(action_log), class: 'target')).html_safe
       .log-entry__timestamp
-        %time= l action_log.created_at
+        %time.formatted{ datetime: action_log.created_at.iso8601 }
     .spacer
     .log-entry__icon
       = fa_icon icon_for_log(action_log)
diff --git a/app/views/admin/change_emails/show.html.haml b/app/views/admin/change_emails/show.html.haml
index 6febef9b1a811abdd045cf22b50cdaf6ded699d9..6ff0d785ed21c9a93512ad6379b79c9dd5d25d87 100644
--- a/app/views/admin/change_emails/show.html.haml
+++ b/app/views/admin/change_emails/show.html.haml
@@ -3,7 +3,7 @@
 
 = simple_form_for @user, url: admin_account_change_email_path(@account.id) do |f|
   .fields-group
-    = f.input :email, wrapper: :with_label, disabled: true, label: t('admin.accounts.change_email.current_email')
+    = f.input :email, wrapper: :with_label, hint: false, disabled: true, label: t('admin.accounts.change_email.current_email')
 
   .fields-group
     = f.input :unconfirmed_email, wrapper: :with_label, label: t('admin.accounts.change_email.new_email')
diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml
index fa3d70e9eddd4b45d5bd53ffedc55926c595f1e0..d448e386297e2e4492d438ccdccef0db41f291c3 100644
--- a/app/views/admin/dashboard/index.html.haml
+++ b/app/views/admin/dashboard/index.html.haml
@@ -40,35 +40,17 @@
       %h4= t 'admin.dashboard.features'
       %ul
         %li
-          = link_to t('admin.dashboard.feature_registrations'), edit_admin_settings_path
-          - if @registrations_enabled
-            %span.pull-right.positive-hint= fa_icon 'check fw'
-          - else
-            %span.pull-right.negative-hint= fa_icon 'times fw'
-        %li
-          = link_to t('admin.dashboard.feature_invites'), edit_admin_settings_path
-          - if @invites_enabled
-            %span.pull-right.positive-hint= fa_icon 'check fw'
-          - else
-            %span.pull-right.negative-hint= fa_icon 'times fw'
-        %li
-          = link_to t('admin.dashboard.feature_deletions'), edit_admin_settings_path
-          - if @deletions_enabled
-            %span.pull-right.positive-hint= fa_icon 'check fw'
-          - else
-            %span.pull-right.negative-hint= fa_icon 'times fw'
-        %li
-          = link_to t('admin.dashboard.feature_profile_directory'), edit_admin_settings_path
-          - if @profile_directory
-            %span.pull-right.positive-hint= fa_icon 'check fw'
-          - else
-            %span.pull-right.negative-hint= fa_icon 'times fw'
-        %li
-          = link_to t('admin.dashboard.feature_relay'), admin_relays_path
-          - if @relay_enabled
-            %span.pull-right.positive-hint= fa_icon 'check fw'
-          - else
-            %span.pull-right.negative-hint= fa_icon 'times fw'
+          = feature_hint(link_to(t('admin.dashboard.feature_registrations'), edit_admin_settings_path), @registrations_enabled)
+        %li
+          = feature_hint(link_to(t('admin.dashboard.feature_invites'), edit_admin_settings_path), @invites_enabled)
+        %li
+          = feature_hint(link_to(t('admin.dashboard.feature_deletions'), edit_admin_settings_path), @deletions_enabled)
+        %li
+          = feature_hint(link_to(t('admin.dashboard.feature_profile_directory'), edit_admin_settings_path), @profile_directory)
+        %li
+          = feature_hint(link_to(t('admin.dashboard.feature_timeline_preview'), edit_admin_settings_path), @timeline_preview)
+        %li
+          = feature_hint(link_to(t('admin.dashboard.feature_relay'), admin_relays_path), @relay_enabled)
 
   .dashboard__widgets__versions
     %div
@@ -103,47 +85,19 @@
       %h4= t 'admin.dashboard.config'
       %ul
         %li
-          = t('admin.dashboard.search')
-          - if @search_enabled
-            %span.pull-right.positive-hint= fa_icon 'check fw'
-          - else
-            %span.pull-right.negative-hint= fa_icon 'times fw'
-        %li
-          = t('admin.dashboard.single_user_mode')
-          - if @single_user_mode
-            %span.pull-right.positive-hint= fa_icon 'check fw'
-          - else
-            %span.pull-right.negative-hint= fa_icon 'times fw'
-        %li
-          LDAP
-          - if @ldap_enabled
-            %span.pull-right.positive-hint= fa_icon 'check fw'
-          - else
-            %span.pull-right.negative-hint= fa_icon 'times fw'
-        %li
-          CAS
-          - if @cas_enabled
-            %span.pull-right.positive-hint= fa_icon 'check fw'
-          - else
-            %span.pull-right.negative-hint= fa_icon 'times fw'
-        %li
-          SAML
-          - if @saml_enabled
-            %span.pull-right.positive-hint= fa_icon 'check fw'
-          - else
-            %span.pull-right.negative-hint= fa_icon 'times fw'
-        %li
-          PAM
-          - if @pam_enabled
-            %span.pull-right.positive-hint= fa_icon 'check fw'
-          - else
-            %span.pull-right.negative-hint= fa_icon 'times fw'
-        %li
-          = t 'admin.dashboard.hidden_service'
-          - if @hidden_service
-            %span.pull-right.positive-hint= fa_icon 'check fw'
-          - else
-            %span.pull-right.negative-hint= fa_icon 'times fw'
+          = feature_hint(t('admin.dashboard.search'), @search_enabled)
+        %li
+          = feature_hint(t('admin.dashboard.single_user_mode'), @single_user_mode)
+        %li
+          = feature_hint('LDAP', @ldap_enabled)
+        %li
+          = feature_hint('CAS', @cas_enabled)
+        %li
+          = feature_hint('SAML', @saml_enabled)
+        %li
+          = feature_hint('PAM', @pam_enabled)
+        %li
+          = feature_hint(t('admin.dashboard.hidden_service'), @hidden_service)
 
   .dashboard__widgets__trends
     %div
diff --git a/app/views/admin/domain_blocks/show.html.haml b/app/views/admin/domain_blocks/show.html.haml
index ea1929d44f74ed3bc929ab78fed20d3b5636f4a2..dca4dbac777f9302dd0ebbba1a6b7fd1fe82b042 100644
--- a/app/views/admin/domain_blocks/show.html.haml
+++ b/app/views/admin/domain_blocks/show.html.haml
@@ -3,18 +3,11 @@
 
 = simple_form_for @domain_block, url: admin_domain_block_path(@domain_block), method: :delete do |f|
 
-  - if (@domain_block.noop?)
-    = f.input :retroactive,
-      as: :hidden,
-      input_html: { :value => "0" }
-  - else
-    = f.input :retroactive,
-      as: :boolean,
-      wrapper: :with_label,
-      label: t(".retroactive.#{@domain_block.severity}"),
-      hint: t(:affected_accounts,
-        scope: [:admin, :domain_blocks, :show],
-        count: @domain_block.accounts_count)
+  - unless (@domain_block.noop?)
+    %p= t(".retroactive.#{@domain_block.severity}")
+    %p.hint= t(:affected_accounts,
+      scope: [:admin, :domain_blocks, :show],
+      count: @domain_block.affected_accounts_count)
 
   .actions
     = f.button :button, t('.undo'), type: :submit
diff --git a/app/views/admin/instances/index.html.haml b/app/views/admin/instances/index.html.haml
index ce35b5db4751ade39b32b4e7f17798b9cd611710..61e578409a4ae0478e01fe1dab17f030677c4712 100644
--- a/app/views/admin/instances/index.html.haml
+++ b/app/views/admin/instances/index.html.haml
@@ -11,6 +11,20 @@
   %div{ style: 'flex: 1 1 auto; text-align: right' }
     = link_to t('admin.domain_blocks.add_new'), new_admin_domain_block_path, class: 'button'
 
+= form_tag admin_instances_url, method: 'GET', class: 'simple_form' do
+  .fields-group
+    - Admin::FilterHelper::INSTANCES_FILTERS.each do |key|
+      - if params[key].present?
+        = hidden_field_tag key, params[key]
+
+    - %i(by_domain).each do |key|
+      .input.string.optional
+        = text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.instances.#{key}")
+
+    .actions
+      %button= t('admin.accounts.search')
+      = link_to t('admin.accounts.reset'), admin_instances_path, class: 'button negative'
+
 %hr.spacer/
 
 - @instances.each do |instance|
@@ -19,21 +33,22 @@
       %h4
         = instance.domain
         %small
-          = t('admin.instances.known_accounts', count: instance.accounts_count)
-
           - if instance.domain_block
+            - first_item = true
             - if !instance.domain_block.noop?
-              &bull;
               = t("admin.domain_blocks.severity.#{instance.domain_block.severity}")
+              - first_item = false
             - if instance.domain_block.reject_media?
-              &bull;
+              - unless first_item
+                &bull;
               = t('admin.domain_blocks.rejecting_media')
+              - first_item = false
             - if instance.domain_block.reject_reports?
-              &bull;
+              - unless first_item
+                &bull;
               = t('admin.domain_blocks.rejecting_reports')
-
-      .avatar-stack
-        - instance.cached_sample_accounts.each do |account|
-          = image_tag current_account&.user&.setting_auto_play_gif ? account.avatar_original_url : account.avatar_static_url, width: 48, height: 48, alt: '', class: 'account__avatar'
-
+          - else
+            = t('admin.accounts.no_limits_imposed')
+      - if instance.countable?
+        .trends__item__current{ title: t('admin.instances.known_accounts', count: instance.accounts_count) }= number_to_human instance.accounts_count, strip_insignificant_zeros: true
 = paginate paginated_instances
diff --git a/app/views/admin/invites/_invite.html.haml b/app/views/admin/invites/_invite.html.haml
index d7b6972863fb74d68749fa5567d49fc9d9f8ca01..e6ad9de34c9edc4d795d36093f51c12d513691a1 100644
--- a/app/views/admin/invites/_invite.html.haml
+++ b/app/views/admin/invites/_invite.html.haml
@@ -1,21 +1,30 @@
 %tr
+  %td
+    .input-copy
+      .input-copy__wrapper
+        %input{ type: :text, maxlength: '999', spellcheck: 'false', readonly: 'true', value: public_invite_url(invite_code: invite.code) }
+      %button{ type: :button }= t('generic.copy')
+
   %td
     .name-tag
       = image_tag invite.user.account.avatar.url(:original), alt: '', width: 16, height: 16, class: 'avatar'
       %span.username= invite.user.account.username
-  %td
-    = invite.uses
-    = " / #{invite.max_uses}" unless invite.max_uses.nil?
-  %td
-    - if invite.expired?
-      = t('invites.expired')
-    - else
+
+  - if invite.valid_for_use?
+    %td
+      = fa_icon 'user fw'
+      = invite.uses
+      = " / #{invite.max_uses}" unless invite.max_uses.nil?
+    %td
       - if invite.expires_at.nil?
         ∞
       - else
         %time.formatted{ datetime: invite.expires_at.iso8601, title: l(invite.expires_at) }
           = l invite.expires_at
-  %td= table_link_to 'link', public_invite_url(invite_code: invite.code), public_invite_url(invite_code: invite.code)
+  - else
+    %td{ colspan: 2 }
+      = t('invites.expired')
+
   %td
-    - if !invite.expired? && policy(invite).destroy?
+    - if invite.valid_for_use? && policy(invite).destroy?
       = table_link_to 'times', t('invites.delete'), admin_invite_path(invite), method: :delete
diff --git a/app/views/admin/invites/index.html.haml b/app/views/admin/invites/index.html.haml
index 42159e9f36750429856bfcba7de82aa8afb6ba66..ee6ba0f574255aea48bc229ced7d67d4f531268e 100644
--- a/app/views/admin/invites/index.html.haml
+++ b/app/views/admin/invites/index.html.haml
@@ -18,15 +18,15 @@
 
   %hr.spacer/
 
-.table-wrapper
-  %table.table
+.table-wrapper.simple_form
+  %table.table.table--invites
     %thead
       %tr
+        %th
         %th
         %th= t('invites.table.uses')
         %th= t('invites.table.expires_at')
         %th
-        %th
     %tbody
       = render @invites
 
diff --git a/app/views/admin/pending_accounts/_account.html.haml b/app/views/admin/pending_accounts/_account.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..7a9796a6741b96c2019ab7d4439810ebb5ff602e
--- /dev/null
+++ b/app/views/admin/pending_accounts/_account.html.haml
@@ -0,0 +1,16 @@
+.batch-table__row
+  %label.batch-table__row__select.batch-table__row__select--aligned.batch-checkbox
+    = f.check_box :account_ids, { multiple: true, include_hidden: false }, account.id
+  .batch-table__row__content.pending-account
+    .pending-account__header
+      = link_to admin_account_path(account.id) do
+        %strong= account.user_email
+        = "(@#{account.username})"
+      %br/
+      = account.user_current_sign_in_ip
+      •
+      = t 'admin.accounts.time_in_queue', time: time_ago_in_words(account.user&.created_at)
+
+    - if account.user&.invite_request&.text&.present?
+      .pending-account__body
+        %p= account.user&.invite_request&.text
diff --git a/app/views/admin/pending_accounts/index.html.haml b/app/views/admin/pending_accounts/index.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..7ce5b8213aeee97350d93f44f444c62dc8d9849e
--- /dev/null
+++ b/app/views/admin/pending_accounts/index.html.haml
@@ -0,0 +1,33 @@
+- content_for :page_title do
+  = t('admin.pending_accounts.title', count: User.pending.count)
+
+- content_for :header_tags do
+  = javascript_pack_tag 'admin', integrity: true, async: true, crossorigin: 'anonymous'
+
+= form_for(@form, url: batch_admin_pending_accounts_path) do |f|
+  = hidden_field_tag :page, params[:page] || 1
+
+  .batch-table
+    .batch-table__toolbar
+      %label.batch-table__toolbar__select.batch-checkbox-all
+        = check_box_tag :batch_checkbox_all, nil, false
+      .batch-table__toolbar__actions
+        = f.button safe_join([fa_icon('check'), t('admin.accounts.approve')]), name: :approve, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
+
+        = f.button safe_join([fa_icon('times'), t('admin.accounts.reject')]), name: :reject, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
+    .batch-table__body
+      - if @accounts.empty?
+        = nothing_here 'nothing-here--under-tabs'
+      - else
+        = render partial: 'account', collection: @accounts, locals: { f: f }
+
+= paginate @accounts
+
+%hr.spacer/
+
+%div{ style: 'overflow: hidden' }
+  %div{ style: 'float: right' }
+    = link_to t('admin.accounts.reject_all'), reject_all_admin_pending_accounts_path, method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive'
+
+  %div
+    = link_to t('admin.accounts.approve_all'), approve_all_admin_pending_accounts_path, method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button'
diff --git a/app/views/admin/settings/edit.html.haml b/app/views/admin/settings/edit.html.haml
index 7afa9ec3718df12ab521d70a448aeb0067595b01..a67e6a2c82300eb060defcfd6860a103a120e88c 100644
--- a/app/views/admin/settings/edit.html.haml
+++ b/app/views/admin/settings/edit.html.haml
@@ -2,12 +2,16 @@
   = t('admin.settings.title')
 
 = simple_form_for @admin_settings, url: admin_settings_path, html: { method: :patch } do |f|
+  = render 'shared/error_messages', object: @admin_settings
 
   .fields-group
     = f.input :site_title, wrapper: :with_label, label: t('admin.settings.site_title')
 
-  .fields-group
-    = f.input :theme, collection: Themes.instance.names, label_method: lambda { |theme| I18n.t("themes.#{theme}", default: theme) }, wrapper: :with_label, include_blank: false
+  .fields-row
+    .fields-row__column.fields-row__column-6.fields-group
+      = f.input :theme, collection: Themes.instance.names, label: t('simple_form.labels.defaults.setting_theme'), label_method: lambda { |theme| I18n.t("themes.#{theme}", default: theme) }, wrapper: :with_label, include_blank: false
+    .fields-row__column.fields-row__column-6.fields-group
+      = f.input :registrations_mode, collection: %w(open approved none), wrapper: :with_label, label: t('admin.settings.registrations_mode.title'), include_blank: false, label_method: lambda { |mode| I18n.t("admin.settings.registrations_mode.modes.#{mode}") }
 
   .fields-row
     .fields-row__column.fields-row__column-6.fields-group
@@ -47,9 +51,6 @@
   .fields-group
     = f.input :show_staff_badge, as: :boolean, wrapper: :with_label, label: t('admin.settings.show_staff_badge.title'), hint: t('admin.settings.show_staff_badge.desc_html')
 
-  .fields-group
-    = f.input :open_registrations, as: :boolean, wrapper: :with_label, label: t('admin.settings.registrations.open.title'), hint: t('admin.settings.registrations.open.desc_html')
-
   .fields-group
     = f.input :open_deletion, as: :boolean, wrapper: :with_label, label: t('admin.settings.registrations.deletion.title'), hint: t('admin.settings.registrations.deletion.desc_html')
 
diff --git a/app/views/admin_mailer/new_pending_account.text.erb b/app/views/admin_mailer/new_pending_account.text.erb
new file mode 100644
index 0000000000000000000000000000000000000000..a466ee2de74bbed4534c1ef8bd38ed56aea92a43
--- /dev/null
+++ b/app/views/admin_mailer/new_pending_account.text.erb
@@ -0,0 +1,12 @@
+<%= raw t('application_mailer.salutation', name: display_name(@me)) %>
+
+<%= raw t('admin_mailer.new_pending_account.body') %>
+
+<%= @account.user_email %> (@<%= @account.username %>)
+<%= @account.user_current_sign_in_ip %>
+<% if @account.user&.invite_request&.text.present? %>
+
+<%= quote_wrap(@account.user&.invite_request&.text) %>
+<% end %>
+
+<%= raw t('application_mailer.view')%> <%= admin_pending_accounts_url %>
diff --git a/app/views/application/_sidebar.html.haml b/app/views/application/_sidebar.html.haml
index 2ff14b2526fed39494e7f090143dc6f4ad080772..b5ce5845e3eb884c990a0e9a31ee6c5920df7d8a 100644
--- a/app/views/application/_sidebar.html.haml
+++ b/app/views/application/_sidebar.html.haml
@@ -1,6 +1,6 @@
 .hero-widget
   .hero-widget__img
-    = image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url || asset_pack_path('preview.jpg'), alt: @instance_presenter.site_title
+    = image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url || asset_pack_path('media/images/preview.jpg'), alt: @instance_presenter.site_title
 
   .hero-widget__text
     %p= @instance_presenter.site_short_description.html_safe.presence || @instance_presenter.site_description.html_safe.presence || t('about.generic_description', domain: site_hostname)
diff --git a/app/views/auth/registrations/new.html.haml b/app/views/auth/registrations/new.html.haml
index 72ce8e531fc322789a52f3b2dcd1343e83ea9cb0..b4a7cced55c69d6fab5164908d0bbe6ae050bac8 100644
--- a/app/views/auth/registrations/new.html.haml
+++ b/app/views/auth/registrations/new.html.haml
@@ -21,14 +21,21 @@
 
   .fields-group
     = f.input :password, wrapper: :with_label, label: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password'), :autocomplete => 'off' }
+
   .fields-group
     = f.input :password_confirmation, wrapper: :with_label, label: t('simple_form.labels.defaults.confirm_password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_password'), :autocomplete => 'off' }
 
+  - if approved_registrations? && !@invite.present?
+    .fields-group
+      = f.simple_fields_for :invite_request do |invite_request_fields|
+        = invite_request_fields.input :text, as: :text, wrapper: :with_block_label, required: false
+
   = f.input :invite_code, as: :hidden
 
-  %p.hint= t('auth.agreement_html', rules_path: about_more_path, terms_path: terms_path)
+  .fields-group
+    = f.input :agreement, as: :boolean, wrapper: :with_label, label: t('auth.checkbox_agreement_html', rules_path: about_more_path, terms_path: terms_path)
 
   .actions
-    = f.button :button, t('auth.register'), type: :submit
+    = f.button :button, @invite.present? ? t('auth.register') : sign_up_message, type: :submit
 
 .form-footer= render 'auth/shared/links'
diff --git a/app/views/auth/shared/_links.html.haml b/app/views/auth/shared/_links.html.haml
index 516c625a6b564cfe2877e77c377dab80802c1b8d..3c68ccd222086da4f0ffde12cfbc0a7a0fa5a718 100644
--- a/app/views/auth/shared/_links.html.haml
+++ b/app/views/auth/shared/_links.html.haml
@@ -3,7 +3,7 @@
     %li= link_to t('auth.login'), new_session_path(resource_name)
 
   - if devise_mapping.registerable? && controller_name != 'registrations'
-    %li= link_to t('auth.register'), open_registrations? ? new_registration_path(resource_name) : 'https://joinmastodon.org/#getting-started'
+    %li= link_to t('auth.register'), available_sign_up_path
 
   - if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations'
     %li= link_to t('auth.forgot_password'), new_password_path(resource_name)
diff --git a/app/views/follower_accounts/index.html.haml b/app/views/follower_accounts/index.html.haml
index 31dab68bf57c144a8eb4932e11cc83ac2df56a24..645dd2de17c730e6d9304dea519c398d4d8d63c6 100644
--- a/app/views/follower_accounts/index.html.haml
+++ b/app/views/follower_accounts/index.html.haml
@@ -9,6 +9,8 @@
 
 - if @account.user_hides_network?
   .nothing-here= t('accounts.network_hidden')
+- elsif user_signed_in? && @account.blocking?(current_account)
+  .nothing-here= t('accounts.unavailable')
 - elsif @follows.empty?
   = nothing_here
 - else
diff --git a/app/views/following_accounts/index.html.haml b/app/views/following_accounts/index.html.haml
index 8b49b529b4d91a159c0822d74d6f11d252d7b81a..17fe790188ca7d43eab04e285fe9db9975321f63 100644
--- a/app/views/following_accounts/index.html.haml
+++ b/app/views/following_accounts/index.html.haml
@@ -9,6 +9,8 @@
 
 - if @account.user_hides_network?
   .nothing-here= t('accounts.network_hidden')
+- elsif user_signed_in? && @account.blocking?(current_account)
+  .nothing-here= t('accounts.unavailable')
 - elsif @follows.empty?
   = nothing_here
 - else
diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml
index 6f3a6942e93d85a565cd830d500596304927eadc..4c7fac0b6ae3f7f5afb034211facec0addd74c2d 100644
--- a/app/views/home/index.html.haml
+++ b/app/views/home/index.html.haml
@@ -11,7 +11,7 @@
 
 .app-holder#mastodon{ data: { props: Oj.dump(default_props) } }
   %noscript
-    = image_tag asset_pack_path('logo.svg'), alt: 'Mastodon'
+    = image_pack_tag 'logo.svg', alt: 'Mastodon'
 
     %div
       = t('errors.noscript_html', apps_path: 'https://joinmastodon.org/apps')
diff --git a/app/views/invites/_invite.html.haml b/app/views/invites/_invite.html.haml
index 1c7ec311d244dbba902f5429c857fda51b85bd82..62799ca5be20ef8e9f22986199a85c6ea9bd9333 100644
--- a/app/views/invites/_invite.html.haml
+++ b/app/views/invites/_invite.html.haml
@@ -1,17 +1,25 @@
 %tr
   %td
-    = invite.uses
-    = " / #{invite.max_uses}" unless invite.max_uses.nil?
-  %td
-    - if invite.expired?
-      = t('invites.expired')
-    - else
+    .input-copy
+      .input-copy__wrapper
+        %input{ type: :text, maxlength: '999', spellcheck: 'false', readonly: 'true', value: public_invite_url(invite_code: invite.code) }
+      %button{ type: :button }= t('generic.copy')
+
+  - if invite.valid_for_use?
+    %td
+      = fa_icon 'user fw'
+      = invite.uses
+      = " / #{invite.max_uses}" unless invite.max_uses.nil?
+    %td
       - if invite.expires_at.nil?
         ∞
       - else
         %time.formatted{ datetime: invite.expires_at.iso8601, title: l(invite.expires_at) }
           = l invite.expires_at
-  %td= table_link_to 'link', public_invite_url(invite_code: invite.code), public_invite_url(invite_code: invite.code)
+  - else
+    %td{ colspan: 2 }
+      = t('invites.expired')
+
   %td
-    - if !invite.expired? && policy(invite).destroy?
+    - if invite.valid_for_use? && policy(invite).destroy?
       = table_link_to 'times', t('invites.delete'), invite_path(invite), method: :delete
diff --git a/app/views/invites/index.html.haml b/app/views/invites/index.html.haml
index fb827f6e6d0b55f331d09e6341d3105d3909b807..61420ab1e407970e14345717a4184bd7c7e38cae 100644
--- a/app/views/invites/index.html.haml
+++ b/app/views/invites/index.html.haml
@@ -8,12 +8,13 @@
 
   %hr.spacer/
 
-%table.table
-  %thead
-    %tr
-      %th= t('invites.table.uses')
-      %th= t('invites.table.expires_at')
-      %th
-      %th
-  %tbody
-    = render @invites
+.simple_form
+  %table.table.table--invites
+    %thead
+      %tr
+        %th
+        %th= t('invites.table.uses')
+        %th= t('invites.table.expires_at')
+        %th
+    %tbody
+      = render @invites
diff --git a/app/views/layouts/admin.html.haml b/app/views/layouts/admin.html.haml
index 6ce67d91e7059d4019f405ba93910a27e2a6904e..083f2fac7644dd78f66538c4f30b7555f797f434 100644
--- a/app/views/layouts/admin.html.haml
+++ b/app/views/layouts/admin.html.haml
@@ -6,7 +6,7 @@
     .sidebar-wrapper
       .sidebar
         = link_to root_path do
-          = image_tag asset_pack_path('logo.svg'), class: 'logo', alt: 'Mastodon'
+          = image_pack_tag 'logo.svg', class: 'logo', alt: 'Mastodon'
 
         = render_navigation
     .content-wrapper
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index d0f50c8e9bcfe32db8fe4af20ac893092b54acc3..b47112247dc0433837750e5a2bccc02cf303b116 100755
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -34,3 +34,7 @@
 
   %body{ class: body_classes }
     = content_for?(:content) ? yield(:content) : yield
+
+    %div{ style: 'display: none'}
+      = render file: Rails.root.join('app', 'javascript', 'images', 'logo_transparent.svg')
+      = render file: Rails.root.join('app', 'javascript', 'images', 'logo_full.svg')
diff --git a/app/views/layouts/auth.html.haml b/app/views/layouts/auth.html.haml
index eb8949f988aa146041c8d25fa4d371946ef156b2..585e246557a4de1dcef951c5a4e275a781facc72 100644
--- a/app/views/layouts/auth.html.haml
+++ b/app/views/layouts/auth.html.haml
@@ -6,7 +6,7 @@
     .logo-container
       %h1
         = link_to root_path do
-          = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
+          = svg_logo_full
 
     .form-container
       = render 'flashes'
diff --git a/app/views/layouts/error.html.haml b/app/views/layouts/error.html.haml
index 37359b89b95dc1eea11f04d69863ada25d676c78..25c85abf9e7964611d339bc9177af4eeac4c89fd 100644
--- a/app/views/layouts/error.html.haml
+++ b/app/views/layouts/error.html.haml
@@ -7,8 +7,11 @@
     %meta{ content: 'width=device-width,initial-scale=1', name: 'viewport' }/
     = stylesheet_pack_tag 'common', media: 'all'
     = stylesheet_pack_tag Setting.default_settings['theme'], media: 'all'
+    = javascript_pack_tag 'common', integrity: true, crossorigin: 'anonymous'
+    = javascript_pack_tag 'error', integrity: true, crossorigin: 'anonymous'
   %body.error
     .dialog
-      %img{ alt: Setting.default_settings['site_title'], src: '/oops.gif' }/
-      %div
+      .dialog__illustration
+        %img{ alt: Setting.default_settings['site_title'], src: '/oops.png' }/
+      .dialog__message
         %h1= yield :content
diff --git a/app/views/layouts/mailer.html.haml b/app/views/layouts/mailer.html.haml
index e401df10fd50a504cf557a5cdcd6ae98d9350c5f..343bcb265e2fa61a391bdd7d27e3820a11cd9545 100644
--- a/app/views/layouts/mailer.html.haml
+++ b/app/views/layouts/mailer.html.haml
@@ -24,7 +24,7 @@
                               %tr
                                 %td.column-cell
                                   = link_to root_url do
-                                    = image_tag full_pack_url('logo_full.png'), alt: 'Mastodon', height: 34, class: 'logo'
+                                    = image_tag full_pack_url('media/images/mailer/logo_full.png'), alt: 'Mastodon', height: 34, class: 'logo'
 
     = yield
 
@@ -46,7 +46,7 @@
                             %tbody
                               %td.column-cell
                                 %p= t 'about.hosted_on', domain: site_hostname
-                                %p= link_to t('application_mailer.notification_preferences'), settings_notifications_url
+                                %p= link_to t('application_mailer.notification_preferences'), settings_preferences_notifications_url
                               %td.column-cell.text-right
                                 = link_to root_url do
-                                  = image_tag full_pack_url('logo_transparent.png'), alt: 'Mastodon', height: 24
+                                  = image_tag full_pack_url('media/images/mailer/logo_transparent.png'), alt: 'Mastodon', height: 24
diff --git a/app/views/layouts/public.html.haml b/app/views/layouts/public.html.haml
index caccd5bb67f66a7875c351562d68f2a5ad60d1a6..2929ac599cce8b7762c78d51c2bf873225659033 100644
--- a/app/views/layouts/public.html.haml
+++ b/app/views/layouts/public.html.haml
@@ -3,23 +3,23 @@
 
 - content_for :content do
   .public-layout
-    .container
-      %nav.header
-        .nav-left
-          = link_to root_url, class: 'brand' do
-            = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
+    - unless @hide_navbar
+      .container
+        %nav.header
+          .nav-left
+            = link_to root_url, class: 'brand' do
+              = svg_logo_full
 
-          - if Setting.profile_directory
-            = link_to t('directories.directory'), explore_path, class: 'nav-link optional'
-          = link_to t('about.about_this'), about_more_path, class: 'nav-link optional'
-          = link_to t('about.apps'), 'https://joinmastodon.org/apps', class: 'nav-link optional'
-        .nav-center
-        .nav-right
-          - if user_signed_in?
-            = link_to t('settings.back'), root_url, class: 'nav-link nav-button webapp-btn'
-          - else
-            = link_to t('auth.login'), new_user_session_path, class: 'webapp-btn nav-link nav-button'
-            = link_to t('auth.register'), open_registrations? ? new_user_registration_path : 'https://joinmastodon.org/#getting-started', class: 'webapp-btn nav-link nav-button'
+            = link_to t('directories.directory'), explore_path, class: 'nav-link optional' if Setting.profile_directory
+            = link_to t('about.about_this'), about_more_path, class: 'nav-link optional'
+            = link_to t('about.apps'), 'https://joinmastodon.org/apps', class: 'nav-link optional'
+          .nav-center
+          .nav-right
+            - if user_signed_in?
+              = link_to t('settings.back'), root_url, class: 'nav-link nav-button webapp-btn'
+            - else
+              = link_to t('auth.login'), new_user_session_path, class: 'webapp-btn nav-link nav-button'
+              = link_to t('auth.register'), available_sign_up_path, class: 'webapp-btn nav-link nav-button'
 
     .container= yield
 
@@ -38,9 +38,7 @@
               %li= link_to t('about.api'), 'https://docs.joinmastodon.org/api/guidelines/'
           .column-2
             %h4= link_to t('about.what_is_mastodon'), 'https://joinmastodon.org/'
-
-            = link_to root_url, class: 'brand' do
-              = render file: Rails.root.join('app', 'javascript', 'images', 'logo_transparent.svg')
+            = link_to svg_logo, root_url, class: 'brand'
           .column-3
             %h4= site_hostname
             %ul
diff --git a/app/views/notification_mailer/favourite.html.haml b/app/views/notification_mailer/favourite.html.haml
index 7d1b494d0968f82b8259775c35feb50372f9182b..a715d615ce8ac5801432df999c0730dd04577b33 100644
--- a/app/views/notification_mailer/favourite.html.haml
+++ b/app/views/notification_mailer/favourite.html.haml
@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_grade.png'), alt:''
+                                      = image_tag full_pack_url('media/images/mailer/icon_grade.png'), alt:''
 
                               %h1= t 'notification_mailer.favourite.title'
                               %p.lead= t('notification_mailer.favourite.body', name: @account.acct)
diff --git a/app/views/notification_mailer/follow.html.haml b/app/views/notification_mailer/follow.html.haml
index 31a2b744540ade19b1739d26fc1fcb5fa16b695b..cd84f785847caabe426614fd66b03b4c0cf65969 100644
--- a/app/views/notification_mailer/follow.html.haml
+++ b/app/views/notification_mailer/follow.html.haml
@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_person_add.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_person_add.png'), alt: ''
 
                               %h1= t 'notification_mailer.follow.title'
                               %p.lead= t('notification_mailer.follow.body', name: @account.acct)
diff --git a/app/views/notification_mailer/follow_request.html.haml b/app/views/notification_mailer/follow_request.html.haml
index 44f1911c403a83e747dd994a2507eb7bb53b8cfa..a63e27a909e1fcaac211fa554ae8855fd4c30be2 100644
--- a/app/views/notification_mailer/follow_request.html.haml
+++ b/app/views/notification_mailer/follow_request.html.haml
@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_person_add.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_person_add.png'), alt: ''
 
                               %h1= t 'notification_mailer.follow_request.title'
                               %p.lead= t('notification_mailer.follow_request.body', name: @account.acct)
diff --git a/app/views/notification_mailer/mention.html.haml b/app/views/notification_mailer/mention.html.haml
index 479fed41ccdd50058b08b7c19412ac952ed39007..619873cfa3a34a870dc37e7d66ff6de194f3f4a6 100644
--- a/app/views/notification_mailer/mention.html.haml
+++ b/app/views/notification_mailer/mention.html.haml
@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_reply.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_reply.png'), alt: ''
 
                               %h1= t 'notification_mailer.mention.title'
                               %p.lead= t('notification_mailer.mention.body', name: @status.account.acct)
diff --git a/app/views/notification_mailer/reblog.html.haml b/app/views/notification_mailer/reblog.html.haml
index 85b202cf932693538b6072896e9ca2cb3daaaff3..a2811be23269472a7fad9e4957a541aad5c77615 100644
--- a/app/views/notification_mailer/reblog.html.haml
+++ b/app/views/notification_mailer/reblog.html.haml
@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_cached.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_cached.png'), alt: ''
 
                               %h1= t 'notification_mailer.reblog.title'
                               %p.lead= t('notification_mailer.reblog.body', name: @account.acct)
diff --git a/app/views/oauth/authorizations/show.html.haml b/app/views/oauth/authorizations/show.html.haml
index ad523600740527cb6d0fb3e00e032ef85801bf36..c3c9960d8acfd216603f7622757486a7483f3169 100644
--- a/app/views/oauth/authorizations/show.html.haml
+++ b/app/views/oauth/authorizations/show.html.haml
@@ -1,4 +1,7 @@
 .form-container
-  .flash-message
+  .flash-message.simple_form
     %p= t('doorkeeper.authorizations.show.title')
-    %input{ type: 'text', class: 'oauth-code', readonly: true, value: params[:code], onClick: 'select()' }
+    .input-copy
+      .input-copy__wrapper
+        %input{ type: 'text', class: 'oauth-code', spellcheck: 'false', readonly: true, value: params[:code] }
+      %button{ type: :button }= t('generic.copy')
diff --git a/app/views/public_timelines/show.html.haml b/app/views/public_timelines/show.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..913d5d855d2eb2e57d1daa20315775c158c7910f
--- /dev/null
+++ b/app/views/public_timelines/show.html.haml
@@ -0,0 +1,14 @@
+- content_for :page_title do
+  = t('about.see_whats_happening')
+
+- content_for :header_tags do
+  %meta{ name: 'robots', content: 'noindex' }/
+  %script#initial-state{ type: 'application/json' }!= json_escape(@initial_state_json)
+  = javascript_pack_tag 'about', integrity: true, crossorigin: 'anonymous'
+
+.page-header
+  %h1= t('about.see_whats_happening')
+  %p= t('about.browse_public_posts')
+
+#mastodon-timeline{ data: { props: Oj.dump(default_props) }}
+#modal-container
diff --git a/app/views/relationships/_account.html.haml b/app/views/relationships/_account.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..6c22deb515e26bcb02f6a2088854d705edd228fd
--- /dev/null
+++ b/app/views/relationships/_account.html.haml
@@ -0,0 +1,20 @@
+.batch-table__row
+  %label.batch-table__row__select.batch-table__row__select--aligned.batch-checkbox
+    = f.check_box :account_ids, { multiple: true, include_hidden: false }, account.id
+  .batch-table__row__content.batch-table__row__content--unpadded
+    %table.accounts-table
+      %tbody
+        %tr
+          %td= account_link_to account
+          %td.accounts-table__count.optional
+            = number_to_human account.statuses_count, strip_insignificant_zeros: true
+            %small= t('accounts.posts', count: account.statuses_count).downcase
+          %td.accounts-table__count.optional
+            = number_to_human account.followers_count, strip_insignificant_zeros: true
+            %small= t('accounts.followers', count: account.followers_count).downcase
+          %td.accounts-table__count
+            - if account.last_status_at.present?
+              %time.time-ago{ datetime: account.last_status_at.iso8601, title: l(account.last_status_at) }= l account.last_status_at
+            - else
+              \-
+            %small= t('accounts.last_active')
diff --git a/app/views/relationships/show.html.haml b/app/views/relationships/show.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..e6fff0ad68e94d0156d27e93365c0964262566ea
--- /dev/null
+++ b/app/views/relationships/show.html.haml
@@ -0,0 +1,57 @@
+- content_for :page_title do
+  = t('settings.relationships')
+
+- content_for :header_tags do
+  = javascript_pack_tag 'admin', integrity: true, async: true, crossorigin: 'anonymous'
+
+.filters
+  .filter-subset
+    %strong= t 'relationships.relationship'
+    %ul
+      %li= filter_link_to t('accounts.following', count: current_account.following_count), relationship: nil
+      %li= filter_link_to t('accounts.followers', count: current_account.followers_count), relationship: 'followed_by'
+      %li= filter_link_to t('relationships.mutual'), relationship: 'mutual'
+
+  .filter-subset
+    %strong= t 'relationships.status'
+    %ul
+      %li= filter_link_to t('generic.all'), status: nil
+      %li= filter_link_to t('relationships.primary'), status: 'primary'
+      %li= filter_link_to t('relationships.moved'), status: 'moved'
+
+  .filter-subset
+    %strong= t 'relationships.activity'
+    %ul
+      %li= filter_link_to t('generic.all'), activity: nil
+      %li= filter_link_to t('relationships.dormant'), activity: 'dormant'
+
+  .filter-subset
+    %strong= t 'generic.order_by'
+    %ul
+      %li= filter_link_to t('relationships.most_recent'), order: nil
+      %li= filter_link_to t('relationships.last_active'), order: 'active'
+
+= form_for(@form, url: relationships_path, method: :patch) do |f|
+  = hidden_field_tag :page, params[:page] || 1
+  = hidden_field_tag :relationship, params[:relationship]
+  = hidden_field_tag :status, params[:status]
+  = hidden_field_tag :activity, params[:activity]
+  = hidden_field_tag :order, params[:order]
+
+  .batch-table
+    .batch-table__toolbar
+      %label.batch-table__toolbar__select.batch-checkbox-all
+        = check_box_tag :batch_checkbox_all, nil, false
+      .batch-table__toolbar__actions
+        = f.button safe_join([fa_icon('user-times'), t('relationships.remove_selected_follows')]), name: :unfollow, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } unless followed_by_relationship?
+
+        = f.button safe_join([fa_icon('trash'), t('relationships.remove_selected_followers')]), name: :remove_from_followers, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } unless following_relationship?
+
+        = f.button safe_join([fa_icon('trash'), t('relationships.remove_selected_domains')]), name: :block_domains, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } if followed_by_relationship?
+    .batch-table__body
+      - if @accounts.empty?
+        = nothing_here 'nothing-here--under-tabs'
+      - else
+        = render partial: 'account', collection: @accounts, locals: { f: f }
+
+= paginate @accounts
diff --git a/app/views/remote_follow/new.html.haml b/app/views/remote_follow/new.html.haml
index 5cf6977ba17014fb4d3d156e41f1d1e129fcd66e..4e9601f6aa53b9d2aefea018ad091e68d1695451 100644
--- a/app/views/remote_follow/new.html.haml
+++ b/app/views/remote_follow/new.html.haml
@@ -1,6 +1,5 @@
 - content_for :header_tags do
-  - if @account.user&.setting_noindex
-    %meta{ name: 'robots', content: 'noindex' }/
+  %meta{ name: 'robots', content: 'noindex' }/
 
 .form-container
   .follow-prompt
@@ -18,4 +17,4 @@
 
     %p.hint.subtle-hint
       = t('remote_follow.reason_html', instance: site_hostname)
-      = t('remote_follow.no_account_html', sign_up_path: open_registrations? ? new_user_registration_path : 'https://joinmastodon.org/#getting-started')
+      = t('remote_follow.no_account_html', sign_up_path: available_sign_up_path)
diff --git a/app/views/remote_interaction/new.html.haml b/app/views/remote_interaction/new.html.haml
index a0b10681483d97e76221390acf558de7a83a8110..c8c08991f059b13075b0b7037b08b676447e3810 100644
--- a/app/views/remote_interaction/new.html.haml
+++ b/app/views/remote_interaction/new.html.haml
@@ -1,3 +1,6 @@
+- content_for :header_tags do
+  %meta{ name: 'robots', content: 'noindex' }/
+
 .form-container
   .follow-prompt
     %h2= t("remote_interaction.#{@interaction_type}.prompt")
@@ -18,4 +21,4 @@
 
     %p.hint.subtle-hint
       = t('remote_follow.reason_html', instance: site_hostname)
-      = t('remote_follow.no_account_html', sign_up_path: open_registrations? ? new_user_registration_path : 'https://joinmastodon.org/#getting-started')
+      = t('remote_follow.no_account_html', sign_up_path: available_sign_up_path)
diff --git a/app/views/settings/featured_tags/index.html.haml b/app/views/settings/featured_tags/index.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..5f69517f3af8bb5525ea9a93143cd35e0bd60b1d
--- /dev/null
+++ b/app/views/settings/featured_tags/index.html.haml
@@ -0,0 +1,27 @@
+- content_for :page_title do
+  = t('settings.featured_tags')
+
+= simple_form_for @featured_tag, url: settings_featured_tags_path do |f|
+  = render 'shared/error_messages', object: @featured_tag
+
+  .fields-group
+    = f.input :name, wrapper: :with_block_label, hint: safe_join([t('simple_form.hints.featured_tag.name'), safe_join(@most_used_tags.map { |tag| link_to("##{tag.name}", settings_featured_tags_path(featured_tag: { name: tag.name }), method: :post) }, ', ')], ' ')
+
+  .actions
+    = f.button :button, t('featured_tags.add_new'), type: :submit
+
+%hr.spacer/
+
+- @featured_tags.each do |featured_tag|
+  .directory__tag{ class: params[:tag] == featured_tag.name ? 'active' : nil }
+    %div
+      %h4
+        = fa_icon 'hashtag'
+        = featured_tag.name
+        %small
+          - if featured_tag.last_status_at.nil?
+            = t('accounts.nothing_here')
+          - else
+            %time{ datetime: featured_tag.last_status_at.iso8601, title: l(featured_tag.last_status_at) }= l featured_tag.last_status_at
+          = table_link_to 'trash', t('filters.index.delete'), settings_featured_tag_path(featured_tag), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') }
+      .trends__item__current= number_to_human featured_tag.statuses_count, strip_insignificant_zeros: true
diff --git a/app/views/settings/follower_domains/show.html.haml b/app/views/settings/follower_domains/show.html.haml
deleted file mode 100644
index f1687d4d2f176ed70c3ae28e99914ac56bee2168..0000000000000000000000000000000000000000
--- a/app/views/settings/follower_domains/show.html.haml
+++ /dev/null
@@ -1,34 +0,0 @@
-- content_for :page_title do
-  = t('settings.followers')
-
-= form_tag settings_follower_domains_path, method: :patch, class: 'table-form' do
-  - unless @account.locked?
-    .warning
-      %strong
-        = fa_icon('warning')
-        = t('followers.unlocked_warning_title')
-      = t('followers.unlocked_warning_html', lock_link: link_to(t('followers.lock_link'), settings_profile_url))
-
-  %p= t('followers.explanation_html')
-  %p= t('followers.true_privacy_html')
-
-  .table-wrapper
-    %table.table
-      %thead
-        %tr
-          %th
-          %th= t('followers.domain')
-          %th= t('followers.followers_count')
-      %tbody
-        - @domains.each do |domain|
-          %tr
-            %td
-              = check_box_tag 'select[]', domain.domain, false, disabled: !@account.locked? unless domain.domain.nil?
-            %td
-              %samp= domain.domain.presence || Rails.configuration.x.local_domain
-            %td= number_with_delimiter domain.accounts_from_domain
-
-  .action-pagination
-    .actions
-      = button_tag t('followers.purge'), type: :submit, class: 'button', disabled: !@account.locked?
-    = paginate @domains
diff --git a/app/views/settings/identity_proofs/_proof.html.haml b/app/views/settings/identity_proofs/_proof.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..524827ad749726f9e0231a5597e4b4bbe5b9482a
--- /dev/null
+++ b/app/views/settings/identity_proofs/_proof.html.haml
@@ -0,0 +1,20 @@
+%tr
+  %td
+    = link_to proof.badge.profile_url, class: 'name-tag' do
+      = image_tag proof.badge.avatar_url, width: 15, height: 15, alt: '', class: 'avatar'
+      %span.username
+        = proof.provider_username
+        %span= "(#{proof.provider.capitalize})"
+
+  %td
+    - if proof.live?
+      %span.positive-hint
+        = fa_icon 'check-circle fw'
+        = t('identity_proofs.active')
+    - else
+      %span.negative-hint
+        = fa_icon 'times-circle fw'
+        = t('identity_proofs.inactive')
+
+  %td
+    = table_link_to 'external-link', t('identity_proofs.view_proof'), proof.badge.proof_url if proof.badge.proof_url
diff --git a/app/views/settings/identity_proofs/index.html.haml b/app/views/settings/identity_proofs/index.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..d0ea03ecd0e9d53127218159d364f139fa1f97e8
--- /dev/null
+++ b/app/views/settings/identity_proofs/index.html.haml
@@ -0,0 +1,17 @@
+- content_for :page_title do
+  = t('settings.identity_proofs')
+
+%p= t('identity_proofs.explanation_html')
+
+- unless @proofs.empty?
+  %hr.spacer/
+
+  .table-wrapper
+    %table.table
+      %thead
+        %tr
+          %th= t('identity_proofs.identity')
+          %th= t('identity_proofs.status')
+          %th
+      %tbody
+        = render partial: 'settings/identity_proofs/proof', collection: @proofs, as: :proof
diff --git a/app/views/settings/identity_proofs/new.html.haml b/app/views/settings/identity_proofs/new.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..5e4e9895d167ba59bd80dfa4c6db46ee6421d66c
--- /dev/null
+++ b/app/views/settings/identity_proofs/new.html.haml
@@ -0,0 +1,36 @@
+- content_for :page_title do
+  = t('identity_proofs.authorize_connection_prompt')
+
+.form-container
+  .oauth-prompt
+    %h2= t('identity_proofs.authorize_connection_prompt')
+
+  = simple_form_for @proof, url: settings_identity_proofs_url, html: { method: :post } do |f|
+    = f.input :provider, as: :hidden
+    = f.input :provider_username, as: :hidden
+    = f.input :token, as: :hidden
+
+    = hidden_field_tag :user_agent, params[:user_agent]
+
+    .connection-prompt
+      .connection-prompt__row.connection-prompt__connection
+        .connection-prompt__column
+          = image_tag current_account.avatar.url(:original), size: 96, class: 'account__avatar'
+
+          %p= t('identity_proofs.i_am_html', username: content_tag(:strong,current_account.username), service: site_hostname)
+
+        .connection-prompt__column.connection-prompt__column-sep
+          = fa_icon 'link'
+
+        .connection-prompt__column
+          = image_tag @proof.badge.avatar_url, size: 96, class: 'account__avatar'
+
+          %p= t('identity_proofs.i_am_html', username: content_tag(:strong, @proof.provider_username), service: @proof.provider.capitalize)
+
+    .connection-prompt__post
+      = f.input :post_status, label: t('identity_proofs.publicize_checkbox'), as: :boolean, wrapper: :with_label, :input_html => { checked: true }
+
+      = f.input :status_text, as: :text, input_html: { value: t('identity_proofs.publicize_toot', username: @proof.provider_username, service: @proof.provider.capitalize, url: @proof.badge.proof_url), rows: 4 }
+
+    = f.button :button, t('identity_proofs.authorize'), type: :submit
+    = link_to t('simple_form.no'), settings_identity_proofs_url, class: 'button negative'
diff --git a/app/views/settings/imports/show.html.haml b/app/views/settings/imports/show.html.haml
index 4512fc714dc7e929470a26a65052a0f04086bd67..7bb4beb01c770de9b4b547d2858140231d653888 100644
--- a/app/views/settings/imports/show.html.haml
+++ b/app/views/settings/imports/show.html.haml
@@ -5,8 +5,11 @@
   .field-group
     = f.input :type, collection: Import.types.keys, wrapper: :with_block_label, include_blank: false, label_method: lambda { |type| I18n.t("imports.types.#{type}") }, hint: t('imports.preface')
 
-  .field-group
-    = f.input :data, wrapper: :with_block_label, hint: t('simple_form.hints.imports.data')
+  .fields-row
+    .fields-group.fields-row__column.fields-row__column-6
+      = f.input :data, wrapper: :with_block_label, hint: t('simple_form.hints.imports.data')
+    .fields-group.fields-row__column.fields-row__column-6
+      = f.input :mode, as: :radio_buttons, collection: Import::MODES, label_method: lambda { |mode| safe_join([I18n.t("imports.modes.#{mode}"), content_tag(:span, I18n.t("imports.modes.#{mode}_long"), class: 'hint')]) }, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'
 
   .actions
     = f.button :button, t('imports.upload'), type: :submit
diff --git a/app/views/settings/preferences/appearance/show.html.haml b/app/views/settings/preferences/appearance/show.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..10f0092647a42a7b6cfee888e071110e59bc55fe
--- /dev/null
+++ b/app/views/settings/preferences/appearance/show.html.haml
@@ -0,0 +1,41 @@
+- content_for :page_title do
+  = t('settings.appearance')
+
+= simple_form_for current_user, url: settings_preferences_appearance_path, html: { method: :put } do |f|
+  .fields-row
+    .fields-group.fields-row__column.fields-row__column-6
+      = f.input :locale, collection: I18n.available_locales, wrapper: :with_label, include_blank: false, label_method: lambda { |locale| human_locale(locale) }, selected: I18n.locale, hint: false
+    .fields-group.fields-row__column.fields-row__column-6
+      = f.input :setting_theme, collection: Themes.instance.names, label_method: lambda { |theme| I18n.t("themes.#{theme}", default: theme) }, wrapper: :with_label, include_blank: false, hint: false
+
+  %h4= t 'appearance.advanced_web_interface'
+
+  %p.hint= t 'appearance.advanced_web_interface_hint'
+
+  .fields-group
+    = f.input :setting_advanced_layout, as: :boolean, wrapper: :with_label, hint: false
+
+  %h4= t 'appearance.animations_and_accessibility'
+
+  .fields-group
+    = f.input :setting_auto_play_gif, as: :boolean, wrapper: :with_label, recommended: true
+    = f.input :setting_reduce_motion, as: :boolean, wrapper: :with_label
+    = f.input :setting_system_font_ui, as: :boolean, wrapper: :with_label
+
+  %h4= t 'appearance.confirmation_dialogs'
+
+  .fields-group
+    = f.input :setting_unfollow_modal, as: :boolean, wrapper: :with_label
+    = f.input :setting_boost_modal, as: :boolean, wrapper: :with_label
+    = f.input :setting_delete_modal, as: :boolean, wrapper: :with_label
+
+  %h4= t 'appearance.sensitive_content'
+
+  .fields-group
+    = f.input :setting_display_media, collection: ['default', 'show_all', 'hide_all'],label_method: lambda { |item| t("simple_form.hints.defaults.setting_display_media_#{item}") }, hint: false, as: :radio_buttons, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li', wrapper: :with_floating_label
+
+  .fields-group
+    = f.input :setting_expand_spoilers, as: :boolean, wrapper: :with_label
+
+  .actions
+    = f.button :button, t('generic.save_changes'), type: :submit
diff --git a/app/views/settings/notifications/show.html.haml b/app/views/settings/preferences/notifications/show.html.haml
similarity index 87%
rename from app/views/settings/notifications/show.html.haml
rename to app/views/settings/preferences/notifications/show.html.haml
index 8aaac043b711d013dfe2231c94fbda6718234542..acc646fc3482cd534bd4c93711df805f93af8fa1 100644
--- a/app/views/settings/notifications/show.html.haml
+++ b/app/views/settings/preferences/notifications/show.html.haml
@@ -1,7 +1,7 @@
 - content_for :page_title do
   = t('settings.notifications')
 
-= simple_form_for current_user, url: settings_notifications_path, html: { method: :put } do |f|
+= simple_form_for current_user, url: settings_preferences_notifications_path, html: { method: :put } do |f|
   = render 'shared/error_messages', object: current_user
 
   .fields-group
@@ -14,6 +14,7 @@
 
       - if current_user.staff?
         = ff.input :report, as: :boolean, wrapper: :with_label
+        = ff.input :pending_account, as: :boolean, wrapper: :with_label
 
   .fields-group
     = f.simple_fields_for :notification_emails, hash_to_object(current_user.settings.notification_emails) do |ff|
diff --git a/app/views/settings/preferences/other/show.html.haml b/app/views/settings/preferences/other/show.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..db7d806bc05445eed383840606b674be059d0b2a
--- /dev/null
+++ b/app/views/settings/preferences/other/show.html.haml
@@ -0,0 +1,37 @@
+- content_for :page_title do
+  = t('settings.preferences')
+
+= simple_form_for current_user, url: settings_preferences_other_path, html: { method: :put } do |f|
+  = render 'shared/error_messages', object: current_user
+
+  .fields-group
+    = f.input :setting_noindex, as: :boolean, wrapper: :with_label
+
+  .fields-group
+    = f.input :setting_hide_network, as: :boolean, wrapper: :with_label
+
+  .fields-group
+    = f.input :setting_aggregate_reblogs, as: :boolean, wrapper: :with_label, recommended: true
+
+  %h4= t 'preferences.posting_defaults'
+
+  .fields-row
+    .fields-group.fields-row__column.fields-row__column-6
+      = f.input :setting_default_privacy, collection: Status.selectable_visibilities, wrapper: :with_label, include_blank: false, label_method: lambda { |visibility| safe_join([I18n.t("statuses.visibilities.#{visibility}"), I18n.t("statuses.visibilities.#{visibility}_long")], ' - ') }, required: false, hint: false
+
+    .fields-group.fields-row__column.fields-row__column-6
+      = f.input :setting_default_language, collection: [nil] + filterable_languages.sort, wrapper: :with_label, label_method: lambda { |locale| locale.nil? ? I18n.t('statuses.language_detection') : human_locale(locale) }, required: false, include_blank: false, hint: false
+
+  .fields-group
+    = f.input :setting_default_sensitive, as: :boolean, wrapper: :with_label
+
+  .fields-group
+    = f.input :setting_show_application, as: :boolean, wrapper: :with_label, recommended: true
+
+  %h4= t 'preferences.public_timelines'
+
+  .fields-group
+    = f.input :chosen_languages, collection: filterable_languages.sort, wrapper: :with_block_label, include_blank: false, label_method: lambda { |locale| human_locale(locale) }, required: false, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'
+
+  .actions
+    = f.button :button, t('generic.save_changes'), type: :submit
diff --git a/app/views/settings/preferences/show.html.haml b/app/views/settings/preferences/show.html.haml
deleted file mode 100644
index a2c61c9a6810c1a1c1a59225fb9957ca7d1c51b9..0000000000000000000000000000000000000000
--- a/app/views/settings/preferences/show.html.haml
+++ /dev/null
@@ -1,60 +0,0 @@
-- content_for :page_title do
-  = t('settings.preferences')
-
-%ul.quick-nav
-  %li= link_to t('preferences.languages'), '#settings_languages'
-  %li= link_to t('preferences.publishing'), '#settings_publishing'
-  %li= link_to t('preferences.other'), '#settings_other'
-  %li= link_to t('preferences.web'), '#settings_web'
-
-= simple_form_for current_user, url: settings_preferences_path, html: { method: :put } do |f|
-  = render 'shared/error_messages', object: current_user
-
-  .fields-row#settings_languages
-    .fields-group.fields-row__column.fields-row__column-6
-      = f.input :locale, collection: I18n.available_locales, wrapper: :with_label, include_blank: false, label_method: lambda { |locale| human_locale(locale) }, selected: I18n.locale
-    .fields-group.fields-row__column.fields-row__column-6
-      = f.input :setting_default_language, collection: [nil] + filterable_languages.sort, wrapper: :with_label, label_method: lambda { |locale| locale.nil? ? I18n.t('statuses.language_detection') : human_locale(locale) }, required: false, include_blank: false
-
-  .fields-group
-    = f.input :chosen_languages, collection: filterable_languages.sort, wrapper: :with_block_label, include_blank: false, label_method: lambda { |locale| human_locale(locale) }, required: false, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'
-
-  %hr#settings_publishing/
-
-  .fields-group
-    = f.input :setting_default_privacy, collection: Status.selectable_visibilities, wrapper: :with_floating_label, include_blank: false, label_method: lambda { |visibility| safe_join([I18n.t("statuses.visibilities.#{visibility}"), content_tag(:span, I18n.t("statuses.visibilities.#{visibility}_long"), class: 'hint')]) }, required: false, as: :radio_buttons, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'
-
-    = f.input :setting_default_sensitive, as: :boolean, wrapper: :with_label
-
-  %hr#settings_other/
-
-  .fields-group
-    = f.input :setting_noindex, as: :boolean, wrapper: :with_label
-
-  .fields-group
-    = f.input :setting_hide_network, as: :boolean, wrapper: :with_label
-
-  %hr#settings_web/
-
-  .fields-row
-    .fields-group.fields-row__column.fields-row__column-6
-      = f.input :setting_theme, collection: Themes.instance.names, label_method: lambda { |theme| I18n.t("themes.#{theme}", default: theme) }, wrapper: :with_label, include_blank: false, hint: false
-    .fields-group.fields-row__column.fields-row__column-6
-      = f.input :setting_display_media, collection: ['default', 'show_all', 'hide_all'], wrapper: :with_label, include_blank: false, label_method: lambda { |item| t("simple_form.hints.defaults.setting_display_media_#{item}") }, hint: false
-
-  .fields-group
-    = f.input :setting_unfollow_modal, as: :boolean, wrapper: :with_label
-    = f.input :setting_boost_modal, as: :boolean, wrapper: :with_label
-    = f.input :setting_delete_modal, as: :boolean, wrapper: :with_label
-
-  .fields-group
-    = f.input :setting_aggregate_reblogs, as: :boolean, wrapper: :with_label
-
-  .fields-group
-    = f.input :setting_auto_play_gif, as: :boolean, wrapper: :with_label
-    = f.input :setting_expand_spoilers, as: :boolean, wrapper: :with_label
-    = f.input :setting_reduce_motion, as: :boolean, wrapper: :with_label
-    = f.input :setting_system_font_ui, as: :boolean, wrapper: :with_label
-
-  .actions
-    = f.button :button, t('generic.save_changes'), type: :submit
diff --git a/app/views/settings/profiles/show.html.haml b/app/views/settings/profiles/show.html.haml
index 932638dbe2faac6c07b81ebd1fd624501fe89a8a..28a417a563c40117bed2642dbee580fea95b815d 100644
--- a/app/views/settings/profiles/show.html.haml
+++ b/app/views/settings/profiles/show.html.haml
@@ -28,7 +28,7 @@
 
   - if Setting.profile_directory
     .fields-group
-      = f.input :discoverable, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.discoverable_html', min_followers: Account::MIN_FOLLOWERS_DISCOVERY, path: explore_path)
+      = f.input :discoverable, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.discoverable_html', min_followers: Account::MIN_FOLLOWERS_DISCOVERY, path: explore_path), recommended: true
 
   %hr.spacer/
 
diff --git a/app/views/shared/_og.html.haml b/app/views/shared/_og.html.haml
index 566e7d9366d36cc2823aa9d7e9a05d387e9ed105..fc12f89da582026e66a71308398bab72912c17c3 100644
--- a/app/views/shared/_og.html.haml
+++ b/app/views/shared/_og.html.haml
@@ -9,7 +9,7 @@
 = opengraph 'og:type', 'website'
 = opengraph 'og:title', @instance_presenter.site_title
 = opengraph 'og:description', description
-= opengraph 'og:image', full_asset_url(thumbnail&.file&.url || asset_pack_path('preview.jpg', protocol: :request))
+= opengraph 'og:image', full_asset_url(thumbnail&.file&.url || asset_pack_path('media/images/preview.jpg', protocol: :request))
 = opengraph 'og:image:width', thumbnail ? thumbnail.meta['width'] : '1200'
 = opengraph 'og:image:height', thumbnail ? thumbnail.meta['height'] : '630'
 = opengraph 'twitter:card', 'summary_large_image'
diff --git a/app/views/statuses/show.html.haml b/app/views/statuses/show.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..0f22d106b560c12a79a8f2cace6da89d93dfe445
--- /dev/null
+++ b/app/views/statuses/show.html.haml
@@ -0,0 +1,24 @@
+- content_for :page_title do
+  = t('statuses.title', name: display_name(@account), quote: truncate(@status.spoiler_text.presence || @status.text, length: 50, omission: '…', escape: false))
+
+- content_for :header_tags do
+  - if @account.user&.setting_noindex
+    %meta{ name: 'robots', content: 'noindex, noarchive' }/
+
+  %link{ rel: 'alternate', type: 'application/json+oembed', href: api_oembed_url(url: short_account_status_url(@account, @status), format: 'json') }/
+  %link{ rel: 'alternate', type: 'application/activity+json', href: ActivityPub::TagManager.instance.uri_for(@status) }/
+
+  = opengraph 'og:site_name', site_title
+  = opengraph 'og:type', 'article'
+  = opengraph 'og:title', "#{display_name(@account)} (@#{@account.local_username_and_domain})"
+  = opengraph 'og:url', short_account_status_url(@account, @status)
+
+  = render 'og_description', activity: @status
+  = render 'og_image', activity: @status, account: @account
+
+.grid
+  .column-0
+    .activity-stream.h-entry
+      = render partial: 'status', locals: { status: @status, include_threads: true }
+  .column-1
+    = render 'application/sidebar'
diff --git a/app/views/stream_entries/_detailed_status.html.haml b/app/views/stream_entries/_detailed_status.html.haml
index 27170d2c6388eca0627affc46d27ac390b4fa842..5049328b8f20dd3119623cafe47dfa4198c328a4 100644
--- a/app/views/stream_entries/_detailed_status.html.haml
+++ b/app/views/stream_entries/_detailed_status.html.haml
@@ -19,13 +19,17 @@
     - if status.spoiler_text?
       %p{ :style => ('margin-bottom: 0' unless current_account&.user&.setting_expand_spoilers) }<
         %span.p-summary> #{Formatter.instance.format_spoiler(status, autoplay: autoplay)}&nbsp;
-        %a.status__content__spoiler-link{ href: '#' }= t('statuses.show_more')
-    .e-content{ lang: status.language, style: "display: #{!current_account&.user&.setting_expand_spoilers && status.spoiler_text? ? 'none' : 'block'}; direction: #{rtl_status?(status) ? 'rtl' : 'ltr'}" }= Formatter.instance.format(status, custom_emojify: true, autoplay: autoplay)
+        %button.status__content__spoiler-link= t('statuses.show_more')
+    .e-content{ lang: status.language, style: "display: #{!current_account&.user&.setting_expand_spoilers && status.spoiler_text? ? 'none' : 'block'}; direction: #{rtl_status?(status) ? 'rtl' : 'ltr'}" }
+      = Formatter.instance.format(status, custom_emojify: true, autoplay: autoplay)
+      - if status.preloadable_poll
+        = react_component :poll, disabled: true, poll: ActiveModelSerializers::SerializableResource.new(status.preloadable_poll, serializer: REST::PollSerializer, scope: current_user, scope_name: :current_user).as_json do
+          = render partial: 'stream_entries/poll', locals: { status: status, poll: status.preloadable_poll, autoplay: autoplay }
 
   - if !status.media_attachments.empty?
-    - if status.media_attachments.first.video?
+    - if status.media_attachments.first.audio_or_video?
       - video = status.media_attachments.first
-      = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: !current_account&.user&.show_all_media? && status.sensitive? || current_account&.user&.hide_all_media?, width: 670, height: 380, detailed: true, inline: true, alt: video.description do
+      = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), blurhash: video.blurhash, sensitive: !current_account&.user&.show_all_media? && status.sensitive? || current_account&.user&.hide_all_media?, width: 670, height: 380, detailed: true, inline: true, alt: video.description do
         = render partial: 'stream_entries/attachment_list', locals: { attachments: status.media_attachments }
     - else
       = react_component :media_gallery, height: 380, sensitive: !current_account&.user&.show_all_media? && status.sensitive? || current_account&.user&.hide_all_media?, standalone: true, 'autoPlayGif': current_account&.user&.setting_auto_play_gif || autoplay, 'reduceMotion': current_account&.user&.setting_reduce_motion, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json } do
@@ -39,7 +43,7 @@
     = link_to TagManager.instance.url_for(status), class: 'detailed-status__datetime u-url u-uid', target: stream_link_target, rel: 'noopener' do
       %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
     ·
-    - if status.application
+    - if status.application && @account.user&.setting_show_application
       - if status.application.website.blank?
         %strong.detailed-status__application= status.application.name
       - else
diff --git a/app/views/stream_entries/_og_image.html.haml b/app/views/stream_entries/_og_image.html.haml
index e1b977da369f2f8be09399e9a4d6ff89ec7e7b86..67f9274b6ffb016cdd7f5c956f0e7407300e2673 100644
--- a/app/views/stream_entries/_og_image.html.haml
+++ b/app/views/stream_entries/_og_image.html.haml
@@ -7,6 +7,8 @@
       - unless media.file.meta.nil?
         = opengraph 'og:image:width', media.file.meta.dig('original', 'width')
         = opengraph 'og:image:height', media.file.meta.dig('original', 'height')
+      - if media.description.present?
+        = opengraph 'og:image:alt', media.description
     - elsif media.video? || media.gifv?
       - player_card = true
       = opengraph 'og:image', full_asset_url(media.file.url(:small))
diff --git a/app/views/stream_entries/_poll.html.haml b/app/views/stream_entries/_poll.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..ba34890dfee5e46b95940fa8e5a32599a80bd86f
--- /dev/null
+++ b/app/views/stream_entries/_poll.html.haml
@@ -0,0 +1,27 @@
+- show_results = (user_signed_in? && poll.voted?(current_account)) || poll.expired?
+
+.poll
+  %ul
+    - poll.loaded_options.each do |option|
+      %li
+        - if show_results
+          - percent = poll.votes_count > 0 ? 100 * option.votes_count / poll.votes_count : 0
+          %span.poll__chart{ style: "width: #{percent}%" }
+
+          %label.poll__text><
+            %span.poll__number= percent.round
+            = Formatter.instance.format_poll_option(status, option, autoplay: autoplay)
+        - else
+          %label.poll__text><
+            %span.poll__input{ class: poll.multiple? ? 'checkbox' : nil}><
+            = Formatter.instance.format_poll_option(status, option, autoplay: autoplay)
+  .poll__footer
+    - unless show_results
+      %button.button.button-secondary{ disabled: true }
+        = t('statuses.poll.vote')
+
+    %span= t('statuses.poll.total_votes', count: poll.votes_count)
+
+    - unless poll.expires_at.nil?
+      ·
+      %span= l poll.expires_at
diff --git a/app/views/stream_entries/_simple_status.html.haml b/app/views/stream_entries/_simple_status.html.haml
index b0b6e80c89bf7176ce307dedba60cda16f2a661d..0b924f72fb9d3b39586c1c5da1305f54b5fd48f6 100644
--- a/app/views/stream_entries/_simple_status.html.haml
+++ b/app/views/stream_entries/_simple_status.html.haml
@@ -23,13 +23,17 @@
     - if status.spoiler_text?
       %p{ :style => ('margin-bottom: 0' unless current_account&.user&.setting_expand_spoilers) }<
         %span.p-summary> #{Formatter.instance.format_spoiler(status, autoplay: autoplay)}&nbsp;
-        %a.status__content__spoiler-link{ href: '#' }= t('statuses.show_more')
-    .e-content{ lang: status.language, style: "display: #{!current_account&.user&.setting_expand_spoilers && status.spoiler_text? ? 'none' : 'block'}; direction: #{rtl_status?(status) ? 'rtl' : 'ltr'}" }= Formatter.instance.format(status, custom_emojify: true, autoplay: autoplay)
+        %button.status__content__spoiler-link= t('statuses.show_more')
+    .e-content{ lang: status.language, style: "display: #{!current_account&.user&.setting_expand_spoilers && status.spoiler_text? ? 'none' : 'block'}; direction: #{rtl_status?(status) ? 'rtl' : 'ltr'}" }
+      = Formatter.instance.format(status, custom_emojify: true, autoplay: autoplay)
+      - if status.preloadable_poll
+        = react_component :poll, disabled: true, poll: ActiveModelSerializers::SerializableResource.new(status.preloadable_poll, serializer: REST::PollSerializer, scope: current_user, scope_name: :current_user).as_json do
+          = render partial: 'stream_entries/poll', locals: { status: status, poll: status.preloadable_poll, autoplay: autoplay }
 
   - if !status.media_attachments.empty?
-    - if status.media_attachments.first.video?
+    - if status.media_attachments.first.audio_or_video?
       - video = status.media_attachments.first
-      = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: !current_account&.user&.show_all_media? && status.sensitive? || current_account&.user&.hide_all_media?, width: 610, height: 343, inline: true, alt: video.description do
+      = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), blurhash: video.blurhash, sensitive: !current_account&.user&.show_all_media? && status.sensitive? || current_account&.user&.hide_all_media?, width: 610, height: 343, inline: true, alt: video.description do
         = render partial: 'stream_entries/attachment_list', locals: { attachments: status.media_attachments }
     - else
       = react_component :media_gallery, height: 343, sensitive: !current_account&.user&.show_all_media? && status.sensitive? || current_account&.user&.hide_all_media?, 'autoPlayGif': current_account&.user&.setting_auto_play_gif || autoplay, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json } do
diff --git a/app/views/stream_entries/show.html.haml b/app/views/stream_entries/show.html.haml
index 0e81c4f6853f6756772246d043d3855174bad39c..1a6567512493a6f6f678e9fbf2aba884c4aeba4d 100644
--- a/app/views/stream_entries/show.html.haml
+++ b/app/views/stream_entries/show.html.haml
@@ -3,7 +3,7 @@
 
 - content_for :header_tags do
   - if @account.user&.setting_noindex
-    %meta{ name: 'robots', content: 'noindex' }/
+    %meta{ name: 'robots', content: 'noindex, noarchive' }/
 
   %link{ rel: 'alternate', type: 'application/atom+xml', href: account_stream_entry_url(@account, @stream_entry, format: 'atom') }/
   %link{ rel: 'alternate', type: 'application/json+oembed', href: api_oembed_url(url: account_stream_entry_url(@account, @stream_entry), format: 'json') }/
diff --git a/app/views/tags/show.html.haml b/app/views/tags/show.html.haml
index 18de48eea2cc9201efcb992cc6fe1a3a4acb93ce..cf42468224fa801c3c3e0b94092ef0b551d40ba9 100644
--- a/app/views/tags/show.html.haml
+++ b/app/views/tags/show.html.haml
@@ -2,6 +2,7 @@
   = "##{@tag.name}"
 
 - content_for :header_tags do
+  %meta{ name: 'robots', content: 'noindex' }/
   %link{ rel: 'alternate', type: 'application/rss+xml', href: tag_url(@tag, format: 'rss') }/
 
   %script#initial-state{ type: 'application/json' }!= json_escape(@initial_state_json)
diff --git a/app/views/user_mailer/backup_ready.html.haml b/app/views/user_mailer/backup_ready.html.haml
index d5a4b8b48b68b814310450668ef1a66401945fcf..85140b08be3b4ec114c83bbbc59ff09867881e47 100644
--- a/app/views/user_mailer/backup_ready.html.haml
+++ b/app/views/user_mailer/backup_ready.html.haml
@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_file_download.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_file_download.png'), alt: ''
 
                               %h1= t 'user_mailer.backup_ready.title'
 
diff --git a/app/views/user_mailer/confirmation_instructions.html.haml b/app/views/user_mailer/confirmation_instructions.html.haml
index f75f7529a8f2286c19862413fe387f1695ec3356..39a83faff833d6a6a2140cc2751ab65f1b2c8213 100644
--- a/app/views/user_mailer/confirmation_instructions.html.haml
+++ b/app/views/user_mailer/confirmation_instructions.html.haml
@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_email.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_email.png'), alt: ''
 
                               %h1= t 'devise.mailer.confirmation_instructions.title'
 
@@ -36,7 +36,7 @@
                         %tbody
                           %tr
                             %td.column-cell.text-center
-                              %p= t 'devise.mailer.confirmation_instructions.explanation', host: site_hostname
+                              %p= t @resource.approved? ? 'devise.mailer.confirmation_instructions.explanation' : 'devise.mailer.confirmation_instructions.explanation_when_pending', host: site_hostname
 
 %table.email-table{ cellspacing: 0, cellpadding: 0 }
   %tbody
diff --git a/app/views/user_mailer/confirmation_instructions.text.erb b/app/views/user_mailer/confirmation_instructions.text.erb
index 65b4626c669d07a0c3a738ae58d058ea0e8ce83a..aad91cd9d6a341fc64e73009cf61f073cf21b8c1 100644
--- a/app/views/user_mailer/confirmation_instructions.text.erb
+++ b/app/views/user_mailer/confirmation_instructions.text.erb
@@ -2,7 +2,7 @@
 
 ===
 
-<%= t 'devise.mailer.confirmation_instructions.explanation', host: site_hostname %>
+<%= t @resource.approved? ? 'devise.mailer.confirmation_instructions.explanation' : 'devise.mailer.confirmation_instructions.explanation_when_pending', host: site_hostname %>
 
 => <%= confirmation_url(@resource, confirmation_token: @token, redirect_to_app: @resource.created_by_application ? 'true' : nil) %>
 
diff --git a/app/views/user_mailer/email_changed.html.haml b/app/views/user_mailer/email_changed.html.haml
index 0802aaf968c608082316d4591a001e002cb44b3d..7e91e87ad102ec776788774783ab94caacb14de9 100644
--- a/app/views/user_mailer/email_changed.html.haml
+++ b/app/views/user_mailer/email_changed.html.haml
@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_email.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_email.png'), alt: ''
 
                               %h1= t 'devise.mailer.email_changed.title'
                               %p.lead= t 'devise.mailer.email_changed.explanation'
diff --git a/app/views/user_mailer/password_change.html.haml b/app/views/user_mailer/password_change.html.haml
index 26314a21793b23c075d33544abfa53ac3cc9fcb9..559abf027c9f67b2dbba2987c95e1319c5a7a0b3 100644
--- a/app/views/user_mailer/password_change.html.haml
+++ b/app/views/user_mailer/password_change.html.haml
@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_lock_open.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_lock_open.png'), alt: ''
 
                               %h1= t 'devise.mailer.password_change.title'
                               %p.lead= t 'devise.mailer.password_change.explanation'
diff --git a/app/views/user_mailer/reconfirmation_instructions.html.haml b/app/views/user_mailer/reconfirmation_instructions.html.haml
index e3be8e295e65f2403e4e0a9eb98e98071abe9e41..7f10ba94fddfcbbb7a818e24bb328b9bbaf7466a 100644
--- a/app/views/user_mailer/reconfirmation_instructions.html.haml
+++ b/app/views/user_mailer/reconfirmation_instructions.html.haml
@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_email.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_email.png'), alt: ''
 
                               %h1= t 'devise.mailer.reconfirmation_instructions.title'
                               %p.lead= t 'devise.mailer.reconfirmation_instructions.explanation'
diff --git a/app/views/user_mailer/reset_password_instructions.html.haml b/app/views/user_mailer/reset_password_instructions.html.haml
index 5d9ce6a7534a0ce71a6283b2f573b7e8e46917ac..eeed38c9e4ecab5dea00b30e0cf191906d7dc9d9 100644
--- a/app/views/user_mailer/reset_password_instructions.html.haml
+++ b/app/views/user_mailer/reset_password_instructions.html.haml
@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_lock_open.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_lock_open.png'), alt: ''
 
                               %h1= t 'devise.mailer.reset_password_instructions.title'
                               %p.lead= t 'devise.mailer.reset_password_instructions.explanation'
diff --git a/app/views/user_mailer/warning.html.haml b/app/views/user_mailer/warning.html.haml
index c5e1f5a289832833a7722588dc886068358f6a37..72ea5e5d28f935650c2f886fcdceda46d2ac8a56 100644
--- a/app/views/user_mailer/warning.html.haml
+++ b/app/views/user_mailer/warning.html.haml
@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_warning.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_warning.png'), alt: ''
 
                               %h1= t "user_mailer.warning.title.#{@warning.action}"
 
diff --git a/app/views/user_mailer/welcome.html.haml b/app/views/user_mailer/welcome.html.haml
index 4a5788bf6e507674e734701bf05232f4decc3b2a..1f75ff48ae453457002a0df887749e569d00ff66 100644
--- a/app/views/user_mailer/welcome.html.haml
+++ b/app/views/user_mailer/welcome.html.haml
@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_done.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_done.png'), alt: ''
 
                               %h1= t 'user_mailer.welcome.title', name: @resource.account.username
                               %p.lead= t 'user_mailer.welcome.explanation'
diff --git a/app/workers/activitypub/delivery_worker.rb b/app/workers/activitypub/delivery_worker.rb
index f9c385ea3e20ab77f7a5ef4ebeaed47e4b497d23..00b5c6b7e7fac89174b41afa455236b930669932 100644
--- a/app/workers/activitypub/delivery_worker.rb
+++ b/app/workers/activitypub/delivery_worker.rb
@@ -51,7 +51,7 @@ class ActivityPub::DeliveryWorker
   end
 
   def response_error_unsalvageable?(response)
-    (400...500).cover?(response.code) && response.code != 429
+    response.code == 501 || ((400...500).cover?(response.code) && ![401, 408, 429].include?(response.code))
   end
 
   def failure_tracker
diff --git a/app/workers/activitypub/distribute_poll_update_worker.rb b/app/workers/activitypub/distribute_poll_update_worker.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1e87fa4bf2a784966773e3aeb654ad84cb45fed3
--- /dev/null
+++ b/app/workers/activitypub/distribute_poll_update_worker.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+class ActivityPub::DistributePollUpdateWorker
+  include Sidekiq::Worker
+  include Payloadable
+
+  sidekiq_options queue: 'push', unique: :until_executed, retry: 0
+
+  def perform(status_id)
+    @status  = Status.find(status_id)
+    @account = @status.account
+
+    return unless @status.preloadable_poll
+
+    ActivityPub::DeliveryWorker.push_bulk(inboxes) do |inbox_url|
+      [payload, @account.id, inbox_url]
+    end
+
+    relay! if relayable?
+  rescue ActiveRecord::RecordNotFound
+    true
+  end
+
+  private
+
+  def relayable?
+    @status.public_visibility?
+  end
+
+  def inboxes
+    return @inboxes if defined?(@inboxes)
+
+    @inboxes = [@status.mentions, @status.reblogs, @status.preloadable_poll.votes].flat_map do |relation|
+      relation.includes(:account).map do |record|
+        record.account.preferred_inbox_url if !record.account.local? && record.account.activitypub?
+      end
+    end
+
+    @inboxes.concat(@account.followers.inboxes) unless @status.direct_visibility?
+    @inboxes.uniq!
+    @inboxes.compact!
+    @inboxes
+  end
+
+  def payload
+    @payload ||= Oj.dump(serialize_payload(@status, ActivityPub::UpdatePollSerializer, signer: @account))
+  end
+
+  def relay!
+    ActivityPub::DeliveryWorker.push_bulk(Relay.enabled.pluck(:inbox_url)) do |inbox_url|
+      [payload, @account.id, inbox_url]
+    end
+  end
+end
diff --git a/app/workers/activitypub/distribution_worker.rb b/app/workers/activitypub/distribution_worker.rb
index d83f017000896eb9dc0f9320f65a1db544da839d..11b6a611108606b6bd9f91e368cd05cec62d8db4 100644
--- a/app/workers/activitypub/distribution_worker.rb
+++ b/app/workers/activitypub/distribution_worker.rb
@@ -2,6 +2,7 @@
 
 class ActivityPub::DistributionWorker
   include Sidekiq::Worker
+  include Payloadable
 
   sidekiq_options queue: 'push'
 
@@ -41,20 +42,8 @@ class ActivityPub::DistributionWorker
                  end
   end
 
-  def signed_payload
-    Oj.dump(ActivityPub::LinkedDataSignature.new(unsigned_payload).sign!(@account))
-  end
-
-  def unsigned_payload
-    ActiveModelSerializers::SerializableResource.new(
-      @status,
-      serializer: ActivityPub::ActivitySerializer,
-      adapter: ActivityPub::Adapter
-    ).as_json
-  end
-
   def payload
-    @payload ||= @status.distributable? ? signed_payload : Oj.dump(unsigned_payload)
+    @payload ||= Oj.dump(serialize_payload(@status, ActivityPub::ActivitySerializer, signer: @account))
   end
 
   def relay!
diff --git a/app/workers/activitypub/fetch_replies_worker.rb b/app/workers/activitypub/fetch_replies_worker.rb
new file mode 100644
index 0000000000000000000000000000000000000000..54d98f228ba73fc6946ce60515f97a71d9682899
--- /dev/null
+++ b/app/workers/activitypub/fetch_replies_worker.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class ActivityPub::FetchRepliesWorker
+  include Sidekiq::Worker
+  include ExponentialBackoff
+
+  sidekiq_options queue: 'pull', retry: 3
+
+  def perform(parent_status_id, replies_uri)
+    ActivityPub::FetchRepliesService.new.call(Status.find(parent_status_id), replies_uri)
+  rescue ActiveRecord::RecordNotFound
+    true
+  end
+end
diff --git a/app/workers/activitypub/low_priority_delivery_worker.rb b/app/workers/activitypub/low_priority_delivery_worker.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a141b8f7809da12688c438932d98b8def0e3fa26
--- /dev/null
+++ b/app/workers/activitypub/low_priority_delivery_worker.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+
+class ActivityPub::LowPriorityDeliveryWorker < ActivityPub::DeliveryWorker
+  sidekiq_options queue: 'pull', retry: 8, dead: false
+end
diff --git a/app/workers/activitypub/processing_worker.rb b/app/workers/activitypub/processing_worker.rb
index a8a3ebf0f56987c433c8ccc67d7bfe45543318e9..05139f616db9688890ffa638eb2faf554fdb16cf 100644
--- a/app/workers/activitypub/processing_worker.rb
+++ b/app/workers/activitypub/processing_worker.rb
@@ -6,6 +6,8 @@ class ActivityPub::ProcessingWorker
   sidekiq_options backtrace: true
 
   def perform(account_id, body, delivered_to_account_id = nil)
-    ActivityPub::ProcessCollectionService.new.call(body, Account.find(account_id), override_timestamps: true, delivered_to_account_id: delivered_to_account_id)
+    ActivityPub::ProcessCollectionService.new.call(body, Account.find(account_id), override_timestamps: true, delivered_to_account_id: delivered_to_account_id, delivery: true)
+  rescue ActiveRecord::RecordInvalid => e
+    Rails.logger.debug "Error processing incoming ActivityPub object: #{e}"
   end
 end
diff --git a/app/workers/activitypub/reply_distribution_worker.rb b/app/workers/activitypub/reply_distribution_worker.rb
index d8fea6c4e5cafacbca0fc15f10373ce44ab0edb7..1ff8a657e8391912609afeafd9a4ee7b27b700b3 100644
--- a/app/workers/activitypub/reply_distribution_worker.rb
+++ b/app/workers/activitypub/reply_distribution_worker.rb
@@ -5,6 +5,7 @@
 
 class ActivityPub::ReplyDistributionWorker
   include Sidekiq::Worker
+  include Payloadable
 
   sidekiq_options queue: 'push'
 
@@ -27,19 +28,7 @@ class ActivityPub::ReplyDistributionWorker
     @inboxes ||= @account.followers.inboxes
   end
 
-  def signed_payload
-    Oj.dump(ActivityPub::LinkedDataSignature.new(unsigned_payload).sign!(@status.account))
-  end
-
-  def unsigned_payload
-    ActiveModelSerializers::SerializableResource.new(
-      @status,
-      serializer: ActivityPub::ActivitySerializer,
-      adapter: ActivityPub::Adapter
-    ).as_json
-  end
-
   def payload
-    @payload ||= @status.distributable? ? signed_payload : Oj.dump(unsigned_payload)
+    @payload ||= Oj.dump(serialize_payload(@status, ActivityPub::ActivitySerializer, signer: @status.account))
   end
 end
diff --git a/app/workers/activitypub/update_distribution_worker.rb b/app/workers/activitypub/update_distribution_worker.rb
index b9e5ff064f2e532ec1eb8b2c79eb6867badfab1d..3a207f0719c616c3d8a56b97e490b7ba5b54a751 100644
--- a/app/workers/activitypub/update_distribution_worker.rb
+++ b/app/workers/activitypub/update_distribution_worker.rb
@@ -2,6 +2,7 @@
 
 class ActivityPub::UpdateDistributionWorker
   include Sidekiq::Worker
+  include Payloadable
 
   sidekiq_options queue: 'push'
 
@@ -27,14 +28,6 @@ class ActivityPub::UpdateDistributionWorker
   end
 
   def signed_payload
-    @signed_payload ||= Oj.dump(ActivityPub::LinkedDataSignature.new(payload).sign!(@account, sign_with: @options[:sign_with]))
-  end
-
-  def payload
-    @payload ||= ActiveModelSerializers::SerializableResource.new(
-      @account,
-      serializer: ActivityPub::UpdateSerializer,
-      adapter: ActivityPub::Adapter
-    ).as_json
+    @signed_payload ||= Oj.dump(serialize_payload(@account, ActivityPub::UpdateSerializer, signer: @account, sign_with: @options[:sign_with]))
   end
 end
diff --git a/app/workers/concerns/exponential_backoff.rb b/app/workers/concerns/exponential_backoff.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f2b931e33128f7deafc23987493431c71df67c2d
--- /dev/null
+++ b/app/workers/concerns/exponential_backoff.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module ExponentialBackoff
+  extend ActiveSupport::Concern
+
+  included do
+    sidekiq_retry_in do |count|
+      15 + 10 * (count**4) + rand(10 * (count**4))
+    end
+  end
+end
diff --git a/app/workers/distribution_worker.rb b/app/workers/distribution_worker.rb
index f423d43ae58df1cccd560153b368e7f6e4c78e03..4e20ef31bfc0155054d74f86f316ca83aa688722 100644
--- a/app/workers/distribution_worker.rb
+++ b/app/workers/distribution_worker.rb
@@ -4,7 +4,13 @@ class DistributionWorker
   include Sidekiq::Worker
 
   def perform(status_id)
-    FanOutOnWriteService.new.call(Status.find(status_id))
+    RedisLock.acquire(redis: Redis.current, key: "distribute:#{status_id}") do |lock|
+      if lock.acquired?
+        FanOutOnWriteService.new.call(Status.find(status_id))
+      else
+        raise Mastodon::RaceConditionError
+      end
+    end
   rescue ActiveRecord::RecordNotFound
     true
   end
diff --git a/app/workers/fetch_reply_worker.rb b/app/workers/fetch_reply_worker.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f7aa25e815b23638c160ecf500ae7d9718d52b64
--- /dev/null
+++ b/app/workers/fetch_reply_worker.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+class FetchReplyWorker
+  include Sidekiq::Worker
+  include ExponentialBackoff
+
+  sidekiq_options queue: 'pull', retry: 3
+
+  def perform(child_url)
+    FetchRemoteStatusService.new.call(child_url)
+  end
+end
diff --git a/app/workers/import/relationship_worker.rb b/app/workers/import/relationship_worker.rb
index 1dd8bf8fbb104cd570233e1fd99a861a3b4ffdb7..616da6da92417f2f77823723a20fc4815fcac782 100644
--- a/app/workers/import/relationship_worker.rb
+++ b/app/workers/import/relationship_worker.rb
@@ -5,19 +5,26 @@ class Import::RelationshipWorker
 
   sidekiq_options queue: 'pull', retry: 8, dead: false
 
-  def perform(account_id, target_account_uri, relationship)
+  def perform(account_id, target_account_uri, relationship, options = {})
     from_account   = Account.find(account_id)
     target_account = ResolveAccountService.new.call(target_account_uri)
+    options.symbolize_keys!
 
     return if target_account.nil?
 
     case relationship
     when 'follow'
-      FollowService.new.call(from_account, target_account.acct)
+      FollowService.new.call(from_account, target_account, options)
+    when 'unfollow'
+      UnfollowService.new.call(from_account, target_account)
     when 'block'
       BlockService.new.call(from_account, target_account)
+    when 'unblock'
+      UnblockService.new.call(from_account, target_account)
     when 'mute'
-      MuteService.new.call(from_account, target_account)
+      MuteService.new.call(from_account, target_account, options)
+    when 'unmute'
+      UnmuteService.new.call(from_account, target_account)
     end
   rescue ActiveRecord::RecordNotFound
     true
diff --git a/app/workers/import_worker.rb b/app/workers/import_worker.rb
index aeb221cf688ec958bbceebed1c7cf21d8e32de41..dfa71b29ec011ab7a47d79735c6aeddebead3ce0 100644
--- a/app/workers/import_worker.rb
+++ b/app/workers/import_worker.rb
@@ -1,44 +1,14 @@
 # frozen_string_literal: true
 
-require 'csv'
-
 class ImportWorker
   include Sidekiq::Worker
 
   sidekiq_options queue: 'pull', retry: false
 
-  attr_reader :import
-
   def perform(import_id)
-    @import = Import.find(import_id)
-
-    Import::RelationshipWorker.push_bulk(import_rows) do |row|
-      [@import.account_id, row.first, relationship_type]
-    end
-
-    @import.destroy
-  end
-
-  private
-
-  def import_contents
-    Paperclip.io_adapters.for(@import.data).read
-  end
-
-  def relationship_type
-    case @import.type
-    when 'following'
-      'follow'
-    when 'blocking'
-      'block'
-    when 'muting'
-      'mute'
-    end
-  end
-
-  def import_rows
-    rows = CSV.new(import_contents).reject(&:blank?)
-    rows = rows.take(FollowLimitValidator.limit_for_account(@import.account)) if @import.type == 'following'
-    rows
+    import = Import.find(import_id)
+    ImportService.new.call(import)
+  ensure
+    import&.destroy
   end
 end
diff --git a/app/workers/poll_expiration_notify_worker.rb b/app/workers/poll_expiration_notify_worker.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e08f0c2496fa7d13ec538195df5074916ae1359d
--- /dev/null
+++ b/app/workers/poll_expiration_notify_worker.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+class PollExpirationNotifyWorker
+  include Sidekiq::Worker
+
+  sidekiq_options unique: :until_executed
+
+  def perform(poll_id)
+    poll = Poll.find(poll_id)
+
+    # Notify poll owner and remote voters
+    if poll.local?
+      ActivityPub::DistributePollUpdateWorker.perform_async(poll.status.id)
+      NotifyService.new.call(poll.account, poll)
+    end
+
+    # Notify local voters
+    poll.votes.includes(:account).map(&:account).select(&:local?).each do |account|
+      NotifyService.new.call(account, poll)
+    end
+  rescue ActiveRecord::RecordNotFound
+    true
+  end
+end
diff --git a/app/workers/scheduler/feed_cleanup_scheduler.rb b/app/workers/scheduler/feed_cleanup_scheduler.rb
index cd22734180572c8bd6151f00df95d6220af415de..bf5e20757007d893913d077021256eb03ceba062 100644
--- a/app/workers/scheduler/feed_cleanup_scheduler.rb
+++ b/app/workers/scheduler/feed_cleanup_scheduler.rb
@@ -2,6 +2,7 @@
 
 class Scheduler::FeedCleanupScheduler
   include Sidekiq::Worker
+  include Redisable
 
   sidekiq_options unique: :until_executed, retry: 0
 
@@ -57,8 +58,4 @@ class Scheduler::FeedCleanupScheduler
   def feed_manager
     FeedManager.instance
   end
-
-  def redis
-    Redis.current
-  end
 end
diff --git a/app/workers/thread_resolve_worker.rb b/app/workers/thread_resolve_worker.rb
index c18a778d555e472ccb8009907202db66e6f17431..8bba9ca75e668fa969fb4aed127215c5a7244224 100644
--- a/app/workers/thread_resolve_worker.rb
+++ b/app/workers/thread_resolve_worker.rb
@@ -2,13 +2,10 @@
 
 class ThreadResolveWorker
   include Sidekiq::Worker
+  include ExponentialBackoff
 
   sidekiq_options queue: 'pull', retry: 3
 
-  sidekiq_retry_in do |count|
-    15 + 10 * (count**4) + rand(10 * (count**4))
-  end
-
   def perform(child_status_id, parent_url)
     child_status  = Status.find(child_status_id)
     parent_status = FetchRemoteStatusService.new.call(parent_url)
diff --git a/app/workers/web/push_notification_worker.rb b/app/workers/web/push_notification_worker.rb
index 8e8a359735674ea753a6b0fed60b5ab71f90cf9a..90104397581aacdcf9f21c58f518c1849bc2c6e0 100644
--- a/app/workers/web/push_notification_worker.rb
+++ b/app/workers/web/push_notification_worker.rb
@@ -3,7 +3,7 @@
 class Web::PushNotificationWorker
   include Sidekiq::Worker
 
-  sidekiq_options backtrace: true
+  sidekiq_options backtrace: true, retry: 5
 
   def perform(subscription_id, notification_id)
     subscription = ::Web::PushSubscription.find(subscription_id)
diff --git a/bin/webpack b/bin/webpack
index 465832722c9810c7b0dce67fdc1dacd6d8add213..008ecb22f7c7d4daadc1b67acf2a1c974bb30729 100755
--- a/bin/webpack
+++ b/bin/webpack
@@ -12,4 +12,8 @@ require "bundler/setup"
 
 require "webpacker"
 require "webpacker/webpack_runner"
-Webpacker::WebpackRunner.run(ARGV)
+
+APP_ROOT = File.expand_path("..", __dir__)
+Dir.chdir(APP_ROOT) do
+  Webpacker::WebpackRunner.run(ARGV)
+end
diff --git a/bin/webpack-dev-server b/bin/webpack-dev-server
index faa69f078005c888e213e79159787b7a5e1015d1..a931a9b7fc26c5c5d619ee5165734b77b99e8dc2 100755
--- a/bin/webpack-dev-server
+++ b/bin/webpack-dev-server
@@ -12,4 +12,8 @@ require "bundler/setup"
 
 require "webpacker"
 require "webpacker/dev_server_runner"
-Webpacker::DevServerRunner.run(ARGV)
+
+APP_ROOT = File.expand_path("..", __dir__)
+Dir.chdir(APP_ROOT) do
+  Webpacker::DevServerRunner.run(ARGV)
+end
diff --git a/boxfile.yml b/boxfile.yml
index 9368a7d9dbcd8da6cc6526ac89827e6e43098b0f..08526a57c918e9c09d4c56c87faeaa551b26ec29 100644
--- a/boxfile.yml
+++ b/boxfile.yml
@@ -64,8 +64,9 @@ deploy.config:
       - |-
           if [[ "${ES_ENABLED}" != "false" ]]
           then
-            bundle exec rake chewy:deploy
+            bin/tootctl search deploy
           fi
+      - bin/tootctl cache clear
 
 
 web.web:
@@ -120,77 +121,6 @@ worker.sidekiq:
       - public/system
 
 
-worker.cron_only:
-  start: sleep 365d
-
-  writable_dirs:
-    - tmp
-
-  log_watch:
-    rake: 'log/production.log'
-
-  network_dirs:
-    data.storage:
-      - public/system
-
-  cron:
-    # 20:00 (8 pm), server time: send out the daily digest emails to everyone
-    # who opted to receive one
-    - id: send_digest_emails
-      schedule: '00 20 * * *'
-      command: 'bundle exec rake mastodon:emails:digest'
-
-    # 00:10 (ten past midnight), server time: remove local copies of remote
-    # users' media once they are older than a certain age (use NUM_DAYS evar to
-    # change this from the default of 7 days)
-    - id: clear_remote_media
-      schedule: '10 00 * * *'
-      command: 'bundle exec rake mastodon:media:remove_remote'
-
-    # 00:20 (twenty past midnight), server time: remove subscriptions to remote
-    # users that nobody follows locally (anymore)
-    - id: clear_unfollowed_subs
-      schedule: '20 00 * * *'
-      command: 'bundle exec rake mastodon:push:clear'
-
-    # 00:30 (half past midnight), server time: update local copies of remote
-    # users' avatars to match whatever they currently have set on their profile
-    - id: update_remote_avatars
-      schedule: '30 00 * * *'
-      command: 'bundle exec rake mastodon:media:redownload_avatars'
-
-    ############################################################################
-    # This task is one you might want to enable, or might not. It keeps disk
-    # usage low, but makes "shadow bans" (scenarios where the user is silenced,
-    # but not intended to be made aware that the silencing has occurred) much
-    # more difficult to put in place, as users would then notice their media is
-    # vanishing on a regular basis. Enable it if you aren't worried about users
-    # knowing they've been silenced (on the instance level), and want to save
-    # disk space. Leave it disabled otherwise.
-    ############################################################################
-    # # 00:00 (midnight), server time: remove media posted by silenced users
-    # - id: clear_silenced_media
-    #   schedule: '00 00 * * *'
-    #   command: 'bundle exec rake mastodon:media:remove_silenced'
-
-    ############################################################################
-    # The following two tasks can be uncommented to automatically open and close
-    # registrations on a schedule. The format of 'schedule' is a standard cron
-    # time expression: minute hour day month day-of-week; search for "cron
-    # time expressions" for more info on how to set these up. The examples here
-    # open registration only from 8 am to 4 pm, server time.
-    ############################################################################
-    # # 08:00 (8 am), server time: open registrations so new users can join
-    # - id: open_registrations
-    #   schedule: '00 08 * * *'
-    #   command: 'bundle exec rake mastodon:settings:open_registrations'
-    #
-    # # 16:00 (4 pm), server time: close registrations so new users *can't* join
-    # - id: close_registrations
-    #   schedule: '00 16 * * *'
-    #   command: 'bundle exec rake mastodon:settings:close_registrations'
-
-
 data.db:
   image: nanobox/postgresql:9.6
 
diff --git a/config/application.rb b/config/application.rb
index b4a39b5c8a6014b6245eadb4207c1c083613fded..f49deffbb6d4e14b78c5c10ff5087fe4a2e403e6 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -10,6 +10,7 @@ require_relative '../app/lib/exceptions'
 require_relative '../lib/paperclip/lazy_thumbnail'
 require_relative '../lib/paperclip/gif_transcoder'
 require_relative '../lib/paperclip/video_transcoder'
+require_relative '../lib/paperclip/type_corrector'
 require_relative '../lib/mastodon/snowflake'
 require_relative '../lib/mastodon/version'
 require_relative '../lib/devise/ldap_authenticatable'
@@ -40,6 +41,7 @@ module Mastodon
       :ar,
       :ast,
       :bg,
+      :bn,
       :ca,
       :co,
       :cs,
@@ -53,8 +55,10 @@ module Mastodon
       :fa,
       :fi,
       :fr,
+      :ga,
       :gl,
       :he,
+      :hi,
       :hr,
       :hu,
       :hy,
@@ -63,7 +67,11 @@ module Mastodon
       :it,
       :ja,
       :ka,
+      :kk,
       :ko,
+      :lt,
+      :lv,
+      :ms,
       :nl,
       :no,
       :oc,
@@ -74,6 +82,7 @@ module Mastodon
       :ru,
       :sk,
       :sl,
+      :sq,
       :sr,
       :'sr-Latn',
       :sv,
@@ -105,6 +114,9 @@ module Mastodon
       Doorkeeper::AuthorizationsController.layout 'modal'
       Doorkeeper::AuthorizedApplicationsController.layout 'admin'
       Doorkeeper::Application.send :include, ApplicationExtension
+      Devise::FailureApp.send :include, AbstractController::Callbacks
+      Devise::FailureApp.send :include, HttpAcceptLanguage::EasyAccess
+      Devise::FailureApp.send :include, Localized
     end
   end
 end
diff --git a/config/brakeman.ignore b/config/brakeman.ignore
index 58fb243da4589610d1da8f126ea2ad65b228ae78..7e3828f7e017d2e6fba0b18fb1399f0a819a9433 100644
--- a/config/brakeman.ignore
+++ b/config/brakeman.ignore
@@ -1,5 +1,25 @@
 {
   "ignored_warnings": [
+    {
+      "warning_type": "Mass Assignment",
+      "warning_code": 105,
+      "fingerprint": "0117d2be5947ea4e4fbed9c15f23c6615b12c6892973411820c83d079808819d",
+      "check_name": "PermitAttributes",
+      "message": "Potentially dangerous key allowed for mass assignment",
+      "file": "app/controllers/api/v1/search_controller.rb",
+      "line": 30,
+      "link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/",
+      "code": "params.permit(:type, :offset, :min_id, :max_id, :account_id)",
+      "render_path": null,
+      "location": {
+        "type": "method",
+        "class": "Api::V1::SearchController",
+        "method": "search_params"
+      },
+      "user_input": ":account_id",
+      "confidence": "High",
+      "note": ""
+    },
     {
       "warning_type": "SQL Injection",
       "warning_code": 0,
@@ -20,25 +40,6 @@
       "confidence": "High",
       "note": ""
     },
-    {
-      "warning_type": "Cross-Site Scripting",
-      "warning_code": 4,
-      "fingerprint": "0adbe361b91afff22ba51e5fc2275ec703cc13255a0cb3eecd8dab223ab9f61e",
-      "check_name": "LinkToHref",
-      "message": "Potentially unsafe model attribute in link_to href",
-      "file": "app/views/admin/accounts/show.html.haml",
-      "line": 167,
-      "link": "https://brakemanscanner.org/docs/warning_types/link_to_href",
-      "code": "link_to(Account.find(params[:id]).inbox_url, Account.find(params[:id]).inbox_url)",
-      "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":18,"file":"app/controllers/admin/accounts_controller.rb"}],
-      "location": {
-        "type": "template",
-        "template": "admin/accounts/show"
-      },
-      "user_input": "Account.find(params[:id]).inbox_url",
-      "confidence": "Weak",
-      "note": ""
-    },
     {
       "warning_type": "SQL Injection",
       "warning_code": 0,
@@ -46,7 +47,7 @@
       "check_name": "SQL",
       "message": "Possible SQL injection",
       "file": "app/models/status.rb",
-      "line": 84,
+      "line": 87,
       "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
       "code": "result.joins(\"INNER JOIN statuses_tags t#{id} ON t#{id}.status_id = statuses.id AND t#{id}.tag_id = #{id}\")",
       "render_path": null,
@@ -59,44 +60,6 @@
       "confidence": "Weak",
       "note": ""
     },
-    {
-      "warning_type": "Cross-Site Scripting",
-      "warning_code": 4,
-      "fingerprint": "1fc29c578d0c89bf13bd5476829d272d54cd06b92ccf6df18568fa1f2674926e",
-      "check_name": "LinkToHref",
-      "message": "Potentially unsafe model attribute in link_to href",
-      "file": "app/views/admin/accounts/show.html.haml",
-      "line": 173,
-      "link": "https://brakemanscanner.org/docs/warning_types/link_to_href",
-      "code": "link_to(Account.find(params[:id]).shared_inbox_url, Account.find(params[:id]).shared_inbox_url)",
-      "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":18,"file":"app/controllers/admin/accounts_controller.rb"}],
-      "location": {
-        "type": "template",
-        "template": "admin/accounts/show"
-      },
-      "user_input": "Account.find(params[:id]).shared_inbox_url",
-      "confidence": "Weak",
-      "note": ""
-    },
-    {
-      "warning_type": "Cross-Site Scripting",
-      "warning_code": 4,
-      "fingerprint": "2129d4c1e63a351d28d8d2937ff0b50237809c3df6725c0c5ef82b881dbb2086",
-      "check_name": "LinkToHref",
-      "message": "Potentially unsafe model attribute in link_to href",
-      "file": "app/views/admin/accounts/show.html.haml",
-      "line": 75,
-      "link": "https://brakemanscanner.org/docs/warning_types/link_to_href",
-      "code": "link_to(Account.find(params[:id]).url, Account.find(params[:id]).url)",
-      "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":18,"file":"app/controllers/admin/accounts_controller.rb"}],
-      "location": {
-        "type": "template",
-        "template": "admin/accounts/show"
-      },
-      "user_input": "Account.find(params[:id]).url",
-      "confidence": "Weak",
-      "note": ""
-    },
     {
       "warning_type": "Mass Assignment",
       "warning_code": 105,
@@ -104,7 +67,7 @@
       "check_name": "PermitAttributes",
       "message": "Potentially dangerous key allowed for mass assignment",
       "file": "app/controllers/admin/reports_controller.rb",
-      "line": 80,
+      "line": 56,
       "link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/",
       "code": "params.permit(:account_id, :resolved, :target_account_id)",
       "render_path": null,
@@ -127,7 +90,7 @@
       "line": 4,
       "link": "https://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
       "code": "render(action => Admin::ActionLog.page(params[:page]), {})",
-      "render_path": [{"type":"controller","class":"Admin::ActionLogsController","method":"index","line":7,"file":"app/controllers/admin/action_logs_controller.rb"}],
+      "render_path": [{"type":"controller","class":"Admin::ActionLogsController","method":"index","line":7,"file":"app/controllers/admin/action_logs_controller.rb","rendered":{"name":"admin/action_logs/index","file":"/home/eugr/Projects/mastodon/app/views/admin/action_logs/index.html.haml"}}],
       "location": {
         "type": "template",
         "template": "admin/action_logs/index"
@@ -143,7 +106,7 @@
       "check_name": "Redirect",
       "message": "Possible unprotected redirect",
       "file": "app/controllers/remote_interaction_controller.rb",
-      "line": 20,
+      "line": 21,
       "link": "https://brakemanscanner.org/docs/warning_types/redirect/",
       "code": "redirect_to(RemoteFollow.new(resource_params).interact_address_for(Status.find(params[:id])))",
       "render_path": null,
@@ -156,25 +119,6 @@
       "confidence": "High",
       "note": ""
     },
-    {
-      "warning_type": "Cross-Site Scripting",
-      "warning_code": 4,
-      "fingerprint": "64b5b2a02ede9c2b3598881eb5a466d63f7d27fe0946aa00d570111ec7338d2e",
-      "check_name": "LinkToHref",
-      "message": "Potentially unsafe model attribute in link_to href",
-      "file": "app/views/admin/accounts/show.html.haml",
-      "line": 176,
-      "link": "https://brakemanscanner.org/docs/warning_types/link_to_href",
-      "code": "link_to(Account.find(params[:id]).followers_url, Account.find(params[:id]).followers_url)",
-      "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":18,"file":"app/controllers/admin/accounts_controller.rb"}],
-      "location": {
-        "type": "template",
-        "template": "admin/accounts/show"
-      },
-      "user_input": "Account.find(params[:id]).followers_url",
-      "confidence": "Weak",
-      "note": ""
-    },
     {
       "warning_type": "Dynamic Render Path",
       "warning_code": 15,
@@ -185,7 +129,7 @@
       "line": 3,
       "link": "https://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
       "code": "render(action => \"stream_entries/#{Account.find_local!(params[:account_username]).statuses.find(params[:id]).stream_entry.activity_type.downcase}\", { Account.find_local!(params[:account_username]).statuses.find(params[:id]).stream_entry.activity_type.downcase.to_sym => Account.find_local!(params[:account_username]).statuses.find(params[:id]).stream_entry.activity, :centered => true, :autoplay => ActiveModel::Type::Boolean.new.cast(params[:autoplay]) })",
-      "render_path": [{"type":"controller","class":"StatusesController","method":"embed","line":59,"file":"app/controllers/statuses_controller.rb"}],
+      "render_path": [{"type":"controller","class":"StatusesController","method":"embed","line":63,"file":"app/controllers/statuses_controller.rb","rendered":{"name":"stream_entries/embed","file":"/home/eugr/Projects/mastodon/app/views/stream_entries/embed.html.haml"}}],
       "location": {
         "type": "template",
         "template": "stream_entries/embed"
@@ -201,7 +145,7 @@
       "check_name": "SQL",
       "message": "Possible SQL injection",
       "file": "app/models/status.rb",
-      "line": 89,
+      "line": 92,
       "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
       "code": "result.joins(\"LEFT OUTER JOIN statuses_tags t#{id} ON t#{id}.status_id = statuses.id AND t#{id}.tag_id = #{id}\")",
       "render_path": null,
@@ -214,25 +158,6 @@
       "confidence": "Weak",
       "note": ""
     },
-    {
-      "warning_type": "Cross-Site Scripting",
-      "warning_code": 4,
-      "fingerprint": "82f7b0d09beb3ab68e0fa16be63cedf4e820f2490326e9a1cec05761d92446cd",
-      "check_name": "LinkToHref",
-      "message": "Potentially unsafe model attribute in link_to href",
-      "file": "app/views/admin/accounts/show.html.haml",
-      "line": 149,
-      "link": "https://brakemanscanner.org/docs/warning_types/link_to_href",
-      "code": "link_to(Account.find(params[:id]).salmon_url, Account.find(params[:id]).salmon_url)",
-      "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":18,"file":"app/controllers/admin/accounts_controller.rb"}],
-      "location": {
-        "type": "template",
-        "template": "admin/accounts/show"
-      },
-      "user_input": "Account.find(params[:id]).salmon_url",
-      "confidence": "Weak",
-      "note": ""
-    },
     {
       "warning_type": "Dynamic Render Path",
       "warning_code": 15,
@@ -243,7 +168,7 @@
       "line": 45,
       "link": "https://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
       "code": "render(action => filtered_custom_emojis.eager_load(:local_counterpart).page(params[:page]), {})",
-      "render_path": [{"type":"controller","class":"Admin::CustomEmojisController","method":"index","line":11,"file":"app/controllers/admin/custom_emojis_controller.rb"}],
+      "render_path": [{"type":"controller","class":"Admin::CustomEmojisController","method":"index","line":11,"file":"app/controllers/admin/custom_emojis_controller.rb","rendered":{"name":"admin/custom_emojis/index","file":"/home/eugr/Projects/mastodon/app/views/admin/custom_emojis/index.html.haml"}}],
       "location": {
         "type": "template",
         "template": "admin/custom_emojis/index"
@@ -279,10 +204,10 @@
       "check_name": "Render",
       "message": "Render path contains parameter value",
       "file": "app/views/admin/accounts/index.html.haml",
-      "line": 67,
+      "line": 47,
       "link": "https://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
       "code": "render(action => filtered_accounts.page(params[:page]), {})",
-      "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"index","line":12,"file":"app/controllers/admin/accounts_controller.rb"}],
+      "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"index","line":12,"file":"app/controllers/admin/accounts_controller.rb","rendered":{"name":"admin/accounts/index","file":"/home/eugr/Projects/mastodon/app/views/admin/accounts/index.html.haml"}}],
       "location": {
         "type": "template",
         "template": "admin/accounts/index"
@@ -298,7 +223,7 @@
       "check_name": "Redirect",
       "message": "Possible unprotected redirect",
       "file": "app/controllers/media_controller.rb",
-      "line": 10,
+      "line": 14,
       "link": "https://brakemanscanner.org/docs/warning_types/redirect/",
       "code": "redirect_to(MediaAttachment.attached.find_by!(:shortcode => ((params[:id] or params[:medium_id]))).file.url(:original))",
       "render_path": null,
@@ -311,25 +236,6 @@
       "confidence": "High",
       "note": ""
     },
-    {
-      "warning_type": "Cross-Site Scripting",
-      "warning_code": 4,
-      "fingerprint": "bb0ad5c4a42e06e3846c2089ff5269c17f65483a69414f6ce65eecf2bb11fab7",
-      "check_name": "LinkToHref",
-      "message": "Potentially unsafe model attribute in link_to href",
-      "file": "app/views/admin/accounts/show.html.haml",
-      "line": 138,
-      "link": "https://brakemanscanner.org/docs/warning_types/link_to_href",
-      "code": "link_to(Account.find(params[:id]).remote_url, Account.find(params[:id]).remote_url)",
-      "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":18,"file":"app/controllers/admin/accounts_controller.rb"}],
-      "location": {
-        "type": "template",
-        "template": "admin/accounts/show"
-      },
-      "user_input": "Account.find(params[:id]).remote_url",
-      "confidence": "Weak",
-      "note": ""
-    },
     {
       "warning_type": "Redirect",
       "warning_code": 18,
@@ -350,25 +256,6 @@
       "confidence": "High",
       "note": ""
     },
-    {
-      "warning_type": "Cross-Site Scripting",
-      "warning_code": 4,
-      "fingerprint": "e04aafe1e06cf8317fb6ac0a7f35783e45aa1274272ee6eaf28d39adfdad489b",
-      "check_name": "LinkToHref",
-      "message": "Potentially unsafe model attribute in link_to href",
-      "file": "app/views/admin/accounts/show.html.haml",
-      "line": 170,
-      "link": "https://brakemanscanner.org/docs/warning_types/link_to_href",
-      "code": "link_to(Account.find(params[:id]).outbox_url, Account.find(params[:id]).outbox_url)",
-      "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":18,"file":"app/controllers/admin/accounts_controller.rb"}],
-      "location": {
-        "type": "template",
-        "template": "admin/accounts/show"
-      },
-      "user_input": "Account.find(params[:id]).outbox_url",
-      "confidence": "Weak",
-      "note": ""
-    },
     {
       "warning_type": "Mass Assignment",
       "warning_code": 105,
@@ -376,7 +263,7 @@
       "check_name": "PermitAttributes",
       "message": "Potentially dangerous key allowed for mass assignment",
       "file": "app/controllers/api/v1/reports_controller.rb",
-      "line": 37,
+      "line": 36,
       "link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/",
       "code": "params.permit(:account_id, :comment, :forward, :status_ids => ([]))",
       "render_path": null,
@@ -399,7 +286,7 @@
       "line": 23,
       "link": "https://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
       "code": "render(partial => \"stream_entries/#{Account.find_local!(params[:account_username]).statuses.find(params[:id]).stream_entry.activity_type.downcase}\", { :locals => ({ Account.find_local!(params[:account_username]).statuses.find(params[:id]).stream_entry.activity_type.downcase.to_sym => Account.find_local!(params[:account_username]).statuses.find(params[:id]).stream_entry.activity, :include_threads => true }) })",
-      "render_path": [{"type":"controller","class":"StatusesController","method":"show","line":30,"file":"app/controllers/statuses_controller.rb"}],
+      "render_path": [{"type":"controller","class":"StatusesController","method":"show","line":34,"file":"app/controllers/statuses_controller.rb","rendered":{"name":"stream_entries/show","file":"/home/eugr/Projects/mastodon/app/views/stream_entries/show.html.haml"}}],
       "location": {
         "type": "template",
         "template": "stream_entries/show"
@@ -409,6 +296,6 @@
       "note": ""
     }
   ],
-  "updated": "2018-10-20 23:24:45 +1300",
-  "brakeman_version": "4.2.1"
+  "updated": "2019-02-21 02:30:29 +0100",
+  "brakeman_version": "4.4.0"
 }
diff --git a/config/database.yml b/config/database.yml
index 82e560515c872a2ec0be9c03d2843707ce0180b8..c10bff6b2e6da96c935715f65c75283f4f50fea3 100644
--- a/config/database.yml
+++ b/config/database.yml
@@ -3,6 +3,7 @@ default: &default
   pool: <%= ENV["DB_POOL"] || ENV['MAX_THREADS'] || 5 %>
   timeout: 5000
   encoding: unicode
+  sslmode: <%= ENV['DB_SSLMODE'] || "prefer" %>
 
 development:
   <<: *default
@@ -31,3 +32,4 @@ production:
   host: <%= ENV['DB_HOST'] || 'localhost' %>
   port: <%= ENV['DB_PORT'] || 5432 %>
   prepared_statements: <%= ENV['PREPARED_STATEMENTS'] || 'true' %>
+
diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml
index eec8b6dbecd657b5e2adc3031d8ae63f4b21b180..bc5a05f4a57b7afaff35d9ec70102f96fc54d618 100644
--- a/config/i18n-tasks.yml
+++ b/config/i18n-tasks.yml
@@ -35,11 +35,8 @@ ignore_missing:
   - 'activemodel.errors.*'
   - 'activerecord.attributes.*'
   - 'activerecord.errors.*'
-  - '{devise,pagination,doorkeeper}.*'
+  - '{pagination,doorkeeper}.*'
   - '{date,datetime,time,number}.*'
-  - 'simple_form.{yes,no}'
-  - 'simple_form.{placeholders,hints,labels}.*'
-  - 'simple_form.{error_notification,required}.:'
   - 'errors.messages.*'
   - 'activerecord.errors.models.doorkeeper/*'
   - 'sessions.{browsers,platforms}.*'
@@ -54,7 +51,7 @@ ignore_unused:
   - 'activerecord.errors.*'
   - '{devise,pagination,doorkeeper}.*'
   - '{date,datetime,time,number}.*'
-  - 'simple_form.{yes,no}'
+  - 'simple_form.{yes,no,recommended}'
   - 'simple_form.{placeholders,hints,labels}.*'
   - 'simple_form.{error_notification,required}.:'
   - 'errors.messages.*'
diff --git a/config/initializers/active_model_serializers.rb b/config/initializers/active_model_serializers.rb
index 0e69e1d96c408ded0bb5d4d08a5b132408709771..329a5fb2c3a005688bdf9a5e023815008a62f974 100644
--- a/config/initializers/active_model_serializers.rb
+++ b/config/initializers/active_model_serializers.rb
@@ -3,3 +3,22 @@ ActiveModelSerializers.config.tap do |config|
 end
 
 ActiveSupport::Notifications.unsubscribe(ActiveModelSerializers::Logging::RENDER_EVENT)
+
+class ActiveModel::Serializer::Reflection
+  # We monkey-patch this method so that when we include associations in a serializer,
+  # the nested serializers can send information about used contexts upwards back to
+  # the root. We do this via instance_options because the nesting can be dynamic.
+  def build_association(parent_serializer, parent_serializer_options, include_slice = {})
+    serializer = options[:serializer]
+
+    parent_serializer_options.merge!(named_contexts: serializer._named_contexts, context_extensions: serializer._context_extensions) if serializer.respond_to?(:_named_contexts)
+
+    association_options = {
+      parent_serializer: parent_serializer,
+      parent_serializer_options: parent_serializer_options,
+      include_slice: include_slice,
+    }
+
+    ActiveModel::Serializer::Association.new(self, association_options)
+  end
+end
diff --git a/config/initializers/doorkeeper.rb b/config/initializers/doorkeeper.rb
index 367eead6a40ebd27044459a116bd12d795694c8c..914b3c0010d34be00ffcf07a1c500b633b1b3920 100644
--- a/config/initializers/doorkeeper.rb
+++ b/config/initializers/doorkeeper.rb
@@ -80,7 +80,13 @@ Doorkeeper.configure do
                   :'read:search',
                   :'read:statuses',
                   :follow,
-                  :push
+                  :push,
+                  :'admin:read',
+                  :'admin:read:accounts',
+                  :'admin:read:reports',
+                  :'admin:write',
+                  :'admin:write:accounts',
+                  :'admin:write:reports'
 
   # Change the way client credentials are retrieved from the request object.
   # By default it retrieves first from the `HTTP_AUTHORIZATION` header, then
diff --git a/config/initializers/instrumentation.rb b/config/initializers/instrumentation.rb
deleted file mode 100644
index 8483f2be2e4caf502fe10dc12298eb32b514442d..0000000000000000000000000000000000000000
--- a/config/initializers/instrumentation.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-instrumentation_hostname = ENV.fetch('INSTRUMENTATION_HOSTNAME') { 'localhost' }
-
-ActiveSupport::Notifications.subscribe(/process_action.action_controller/) do |*args|
-  event      = ActiveSupport::Notifications::Event.new(*args)
-  controller = event.payload[:controller]
-  action     = event.payload[:action]
-  format     = event.payload[:format] || 'all'
-  format     = 'all' if format == '*/*'
-  status     = event.payload[:status]
-  key        = "#{controller}.#{action}.#{format}.#{instrumentation_hostname}"
-
-  ActiveSupport::Notifications.instrument :performance, action: :measure, measurement: "#{key}.total_duration", value: event.duration
-  ActiveSupport::Notifications.instrument :performance, action: :measure, measurement: "#{key}.db_time", value: event.payload[:db_runtime]
-  ActiveSupport::Notifications.instrument :performance, action: :measure, measurement: "#{key}.view_time", value: event.payload[:view_runtime]
-  ActiveSupport::Notifications.instrument :performance, measurement: "#{key}.status.#{status}"
-end
diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb
index 254e751d42ea93f4d3f98a9638ae25cbeb22b66f..e8d7697a1145a16af255803f72de4bf6e6315313 100644
--- a/config/initializers/omniauth.rb
+++ b/config/initializers/omniauth.rb
@@ -14,7 +14,7 @@ Devise.setup do |config|
     cas_options[:host] = ENV['CAS_HOST'] if ENV['CAS_HOST']
     cas_options[:port] = ENV['CAS_PORT'] if ENV['CAS_PORT']
     cas_options[:ssl] = ENV['CAS_SSL'] == 'true' if ENV['CAS_SSL']
-    cas_options[:validate_url] = ENV['CAS_VALIDATE_URL'] if ENV['CAS_VALIDATE_URL']
+    cas_options[:service_validate_url] = ENV['CAS_VALIDATE_URL'] if ENV['CAS_VALIDATE_URL']
     cas_options[:callback_url] = ENV['CAS_CALLBACK_URL'] if ENV['CAS_CALLBACK_URL']
     cas_options[:logout_url] = ENV['CAS_LOGOUT_URL'] if ENV['CAS_LOGOUT_URL']
     cas_options[:login_url] = ENV['CAS_LOGIN_URL'] if ENV['CAS_LOGIN_URL']
diff --git a/config/initializers/rack_attack.rb b/config/initializers/rack_attack.rb
index 35302e37b1be76c7d35291fc31342a98af09b97f..24ba16ae36f5463d796a0345371c81fb29991e99 100644
--- a/config/initializers/rack_attack.rb
+++ b/config/initializers/rack_attack.rb
@@ -13,6 +13,10 @@ class Rack::Attack
       )
     end
 
+    def remote_ip
+      @remote_ip ||= (@env["action_dispatch.remote_ip"] || ip).to_s
+    end
+
     def authenticated_user_id
       authenticated_token&.resource_owner_id
     end
@@ -28,6 +32,10 @@ class Rack::Attack
     def web_request?
       !api_request?
     end
+
+    def paging_request?
+      params['page'].present? || params['min_id'].present? || params['max_id'].present? || params['since_id'].present?
+    end
   end
 
   PROTECTED_PATHS = %w(
@@ -42,27 +50,47 @@ class Rack::Attack
   # (blocklist & throttles are skipped)
   Rack::Attack.safelist('allow from localhost') do |req|
     # Requests are allowed if the return value is truthy
-    req.ip == '127.0.0.1' || req.ip == '::1'
+    req.remote_ip == '127.0.0.1' || req.remote_ip == '::1'
   end
 
   throttle('throttle_authenticated_api', limit: 300, period: 5.minutes) do |req|
-    req.api_request? && req.authenticated_user_id
+    req.authenticated_user_id if req.api_request?
   end
 
-  throttle('throttle_unauthenticated_api', limit: 7_500, period: 5.minutes) do |req|
-    req.ip if req.api_request?
+  throttle('throttle_unauthenticated_api', limit: 300, period: 5.minutes) do |req|
+    req.remote_ip if req.api_request? && req.unauthenticated?
   end
 
-  throttle('throttle_media', limit: 30, period: 30.minutes) do |req|
+  throttle('throttle_api_media', limit: 30, period: 30.minutes) do |req|
     req.authenticated_user_id if req.post? && req.path.start_with?('/api/v1/media')
   end
 
+  throttle('throttle_media_proxy', limit: 30, period: 30.minutes) do |req|
+    req.remote_ip if req.path.start_with?('/media_proxy')
+  end
+
   throttle('throttle_api_sign_up', limit: 5, period: 30.minutes) do |req|
-    req.ip if req.post? && req.path == '/api/v1/accounts'
+    req.remote_ip if req.post? && req.path == '/api/v1/accounts'
+  end
+
+  # Throttle paging, as it is mainly used for public pages and AP collections
+  throttle('throttle_authenticated_paging', limit: 300, period: 15.minutes) do |req|
+    req.authenticated_user_id if req.paging_request?
+  end
+
+  throttle('throttle_unauthenticated_paging', limit: 300, period: 15.minutes) do |req|
+    req.remote_ip if req.paging_request? && req.unauthenticated?
+  end
+
+  API_DELETE_REBLOG_REGEX = /\A\/api\/v1\/statuses\/[\d]+\/unreblog/.freeze
+  API_DELETE_STATUS_REGEX = /\A\/api\/v1\/statuses\/[\d]+/.freeze
+
+  throttle('throttle_api_delete', limit: 30, period: 30.minutes) do |req|
+    req.authenticated_user_id if (req.post? && req.path =~ API_DELETE_REBLOG_REGEX) || (req.delete? && req.path =~ API_DELETE_STATUS_REGEX)
   end
 
   throttle('protected_paths', limit: 25, period: 5.minutes) do |req|
-    req.ip if req.post? && req.path =~ PROTECTED_PATHS_REGEX
+    req.remote_ip if req.post? && req.path =~ PROTECTED_PATHS_REGEX
   end
 
   self.throttled_response = lambda do |env|
diff --git a/config/initializers/rack_attack_logging.rb b/config/initializers/rack_attack_logging.rb
index 2ddbfb99ce8c7a41f23bbbc7a4039a605cc7a376..c30bd8a64314193d6de8b4b2c46e30d58614d0a2 100644
--- a/config/initializers/rack_attack_logging.rb
+++ b/config/initializers/rack_attack_logging.rb
@@ -1,4 +1,6 @@
-ActiveSupport::Notifications.subscribe('rack.attack') do |_name, _start, _finish, _request_id, req|
+ActiveSupport::Notifications.subscribe(/rack_attack/) do |_name, _start, _finish, _request_id, payload|
+  req = payload[:request]
+
   next unless [:throttle, :blacklist].include? req.env['rack.attack.match_type']
   Rails.logger.info("Rate limit hit (#{req.env['rack.attack.match_type']}): #{req.ip} #{req.request_method} #{req.fullpath}")
 end
diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb
index 386ede654c62d26395a6dd1dde9e2fd3f2f4381f..96452681955e2d507bf8f463220709e0d80d0138 100644
--- a/config/initializers/simple_form.rb
+++ b/config/initializers/simple_form.rb
@@ -8,7 +8,16 @@ module AppendComponent
   end
 end
 
+module RecommendedComponent
+  def recommended(wrapper_options = nil)
+    return unless options[:recommended]
+    options[:label_text] = ->(raw_label_text, _required_label_text, _label_present) { safe_join([raw_label_text, ' ', content_tag(:span, I18n.t('simple_form.recommended'), class: 'recommended')]) }
+    nil
+  end
+end
+
 SimpleForm.include_component(AppendComponent)
+SimpleForm.include_component(RecommendedComponent)
 
 SimpleForm.setup do |config|
   # Wrappers are used by the form builder to generate a
@@ -65,6 +74,7 @@ SimpleForm.setup do |config|
     b.use :html5
 
     b.wrapper tag: :div, class: :label_input do |ba|
+      ba.optional :recommended
       ba.use :label
 
       ba.wrapper tag: :div, class: :label_input__wrapper do |bb|
diff --git a/config/initializers/statsd.rb b/config/initializers/statsd.rb
index ce83fd9de2d484aec51dbcc223081d427559a3de..93ea1d1e4a7d1fbacb2300da4427b7cc2098ab3b 100644
--- a/config/initializers/statsd.rb
+++ b/config/initializers/statsd.rb
@@ -3,10 +3,10 @@
 if ENV['STATSD_ADDR'].present?
   host, port = ENV['STATSD_ADDR'].split(':')
 
-  statsd = ::Statsd.new(host, port)
-  statsd.namespace = ENV.fetch('STATSD_NAMESPACE') { ['Mastodon', Rails.env].join('.') }
+  $statsd = ::Statsd.new(host, port)
+  $statsd.namespace = ENV.fetch('STATSD_NAMESPACE') { ['Mastodon', Rails.env].join('.') }
 
-  ::NSA.inform_statsd(statsd) do |informant|
+  ::NSA.inform_statsd($statsd) do |informant|
     informant.collect(:action_controller, :web)
     informant.collect(:active_record, :db)
     informant.collect(:active_support_cache, :cache)
diff --git a/config/initializers/stoplight.rb b/config/initializers/stoplight.rb
index 1bd4ee6e7cdf0aee51c4eef7854e1a47ab47a2ae..7384b2e9a6ba7dda373471c9340eaabfd1601714 100644
--- a/config/initializers/stoplight.rb
+++ b/config/initializers/stoplight.rb
@@ -1,3 +1,4 @@
 require 'stoplight'
 
 Stoplight::Light.default_data_store = Stoplight::DataStore::Redis.new(Redis.current)
+Stoplight::Light.default_notifiers  = [Stoplight::Notifier::Logger.new(Rails.logger)]
diff --git a/config/initializers/twitter_regex.rb b/config/initializers/twitter_regex.rb
index 0e8f5bfeb47353d1c151e8917f03650e000067b6..0ddbbee9828bfdcfefb1e28964d27df3ab28bef9 100644
--- a/config/initializers/twitter_regex.rb
+++ b/config/initializers/twitter_regex.rb
@@ -1,7 +1,7 @@
 module Twitter
   class Regex
-    REGEXEN[:valid_general_url_path_chars] = /[^\p{White_Space}\(\)\?]/iou
-    REGEXEN[:valid_url_path_ending_chars] = /[^\p{White_Space}\(\)\?!\*';:=\,\.\$%\[\]~&\|@]|(?:#{REGEXEN[:valid_url_balanced_parens]})/iou
+    REGEXEN[:valid_general_url_path_chars] = /[^\p{White_Space}<>\(\)\?]/iou
+    REGEXEN[:valid_url_path_ending_chars] = /[^\p{White_Space}\(\)\?!\*"'「」<>;:=\,\.\$%\[\]~&\|@]|(?:#{REGEXEN[:valid_url_balanced_parens]})/iou
     REGEXEN[:valid_url_balanced_parens] = /
       \(
         (?:
diff --git a/config/locales/activerecord.ar.yml b/config/locales/activerecord.ar.yml
index 68c7fe939695d02605b5df38d2ffd45470b90681..2b39ee156225ef05c43b40e05b0fdae3a2190cdd 100644
--- a/config/locales/activerecord.ar.yml
+++ b/config/locales/activerecord.ar.yml
@@ -1,6 +1,10 @@
 ---
 ar:
   activerecord:
+    attributes:
+      poll:
+        expires_at: آخر أجل
+        options: الخيارات
     errors:
       models:
         account:
diff --git a/config/locales/activerecord.bg.yml b/config/locales/activerecord.bg.yml
new file mode 100644
index 0000000000000000000000000000000000000000..d0e375da96f10971c15d25ff3e8579573a9e6405
--- /dev/null
+++ b/config/locales/activerecord.bg.yml
@@ -0,0 +1 @@
+bg:
diff --git a/config/locales/activerecord.bn.yml b/config/locales/activerecord.bn.yml
new file mode 100644
index 0000000000000000000000000000000000000000..152c698290639f4688cdb5184962daafc705fc52
--- /dev/null
+++ b/config/locales/activerecord.bn.yml
@@ -0,0 +1 @@
+bn:
diff --git a/config/locales/activerecord.ca.yml b/config/locales/activerecord.ca.yml
index 39f6839aa42f1d461b6d408006596da5992044bd..2795a6b33815a0916805a97b5c4d8a778da86a9a 100644
--- a/config/locales/activerecord.ca.yml
+++ b/config/locales/activerecord.ca.yml
@@ -1,6 +1,10 @@
 ---
 ca:
   activerecord:
+    attributes:
+      poll:
+        expires_at: Data límit
+        options: Opcions
     errors:
       models:
         account:
diff --git a/config/locales/activerecord.co.yml b/config/locales/activerecord.co.yml
index af28d108fd4463a471847bc4bbebdc3c72b96bcd..0a9a936ddf283e53a345cb6fc1f0f8f792473219 100644
--- a/config/locales/activerecord.co.yml
+++ b/config/locales/activerecord.co.yml
@@ -1,6 +1,10 @@
 ---
 co:
   activerecord:
+    attributes:
+      poll:
+        expires_at: Fine
+        options: Scelte
     errors:
       models:
         account:
diff --git a/config/locales/activerecord.cs.yml b/config/locales/activerecord.cs.yml
index 838dee15f89339d1c1b2dd11b644c08758717a9f..57240a19e123c5f8005d19b29d93b81f4ac57e1b 100644
--- a/config/locales/activerecord.cs.yml
+++ b/config/locales/activerecord.cs.yml
@@ -1,6 +1,10 @@
 ---
 cs:
   activerecord:
+    attributes:
+      poll:
+        expires_at: Uzávěrka
+        options: Volby
     errors:
       models:
         account:
diff --git a/config/locales/activerecord.cy.yml b/config/locales/activerecord.cy.yml
index 26553012472a326d374bbb34085d653f1f8c41f6..19547df986a48c5a4338158cc1b2335376b7282a 100644
--- a/config/locales/activerecord.cy.yml
+++ b/config/locales/activerecord.cy.yml
@@ -1,6 +1,10 @@
 ---
 cy:
   activerecord:
+    attributes:
+      poll:
+        expires_at: Terfyn
+        options: Dewisiadau
     errors:
       models:
         account:
diff --git a/config/locales/activerecord.de.yml b/config/locales/activerecord.de.yml
index 7d09856d7e4236791a76f9ecb5f8cd682129e3eb..46a48d234b7bb98689688977e3be193eba341094 100644
--- a/config/locales/activerecord.de.yml
+++ b/config/locales/activerecord.de.yml
@@ -1,6 +1,10 @@
 ---
 de:
   activerecord:
+    attributes:
+      poll:
+        expires_at: Frist
+        options: Wahlmöglichkeiten
     errors:
       models:
         account:
@@ -10,4 +14,4 @@ de:
         status:
           attributes:
             reblog:
-              taken: des Status existiert schon
+              taken: des Beitrags existiert schon
diff --git a/config/locales/activerecord.el.yml b/config/locales/activerecord.el.yml
index 86672b21d0ed4de373ac4c239cabbf94c1ea6115..36e5f508d49ea1402f8b5e3e3f23dad33a4b5766 100644
--- a/config/locales/activerecord.el.yml
+++ b/config/locales/activerecord.el.yml
@@ -1,6 +1,10 @@
 ---
 el:
   activerecord:
+    attributes:
+      poll:
+        expires_at: Προθεσμία
+        options: Επιλογές
     errors:
       models:
         account:
diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml
index 428aaf7273457271a849312eff52e67a8cd225bf..8533418cc69e7f3ac34afb6d191803e8d0280b18 100644
--- a/config/locales/activerecord.en.yml
+++ b/config/locales/activerecord.en.yml
@@ -1,6 +1,10 @@
 ---
 en:
   activerecord:
+    attributes:
+      poll:
+        expires_at: Deadline
+        options: Choices
     errors:
       models:
         account:
diff --git a/config/locales/activerecord.eo.yml b/config/locales/activerecord.eo.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f8a3cf18bfddcf20938c4942b434c973c63a8ef5
--- /dev/null
+++ b/config/locales/activerecord.eo.yml
@@ -0,0 +1,17 @@
+---
+eo:
+  activerecord:
+    attributes:
+      poll:
+        expires_at: Limdato
+        options: Elektoj
+    errors:
+      models:
+        account:
+          attributes:
+            username:
+              invalid: nur leteroj, ciferoj kaj substrekoj
+        status:
+          attributes:
+            reblog:
+              taken: de statuso jam ekzistas
diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml
index d18b1683477ffa46e610203901ef88d3e7581d68..f40e6c36132b1e227a261ccb87a6d1a1abdf5e95 100644
--- a/config/locales/activerecord.es.yml
+++ b/config/locales/activerecord.es.yml
@@ -1,12 +1,16 @@
 ---
 es:
   activerecord:
+    attributes:
+      poll:
+        expires_at: Vencimiento
+        options: Opciones
     errors:
       models:
         account:
           attributes:
             username:
-              invalid: solo letras, números y guiones bajos
+              invalid: sólo letras, números y guiones bajos
         status:
           attributes:
             reblog:
diff --git a/config/locales/activerecord.eu.yml b/config/locales/activerecord.eu.yml
index 64c8bc04e6e9bc6473d14c4051c19d569a034868..235738f2283c2510cf02a75a2e05ce2037d74ff8 100644
--- a/config/locales/activerecord.eu.yml
+++ b/config/locales/activerecord.eu.yml
@@ -1,6 +1,10 @@
 ---
 eu:
   activerecord:
+    attributes:
+      poll:
+        expires_at: Epemuga
+        options: Aukerak
     errors:
       models:
         account:
diff --git a/config/locales/activerecord.fa.yml b/config/locales/activerecord.fa.yml
index 1cd50eec7973fe1680c1011320ec3697f5b3244b..d3b01a158556ea296fce96e8b434b6899f4d9f31 100644
--- a/config/locales/activerecord.fa.yml
+++ b/config/locales/activerecord.fa.yml
@@ -1,6 +1,10 @@
 ---
 fa:
   activerecord:
+    attributes:
+      poll:
+        expires_at: مهلت
+        options: گزینه‌ها
     errors:
       models:
         account:
diff --git a/config/locales/activerecord.fi.yml b/config/locales/activerecord.fi.yml
new file mode 100644
index 0000000000000000000000000000000000000000..2b2ffd121a27f6e62e1563903674e54944859ce3
--- /dev/null
+++ b/config/locales/activerecord.fi.yml
@@ -0,0 +1,13 @@
+---
+fi:
+  activerecord:
+    attributes:
+      poll:
+        expires_at: Määräaika
+        options: Vaihtoehdot
+    errors:
+      models:
+        account:
+          attributes:
+            username:
+              invalid: Vain kirjaimia, numeroita ja alleviivoja
diff --git a/config/locales/activerecord.fr.yml b/config/locales/activerecord.fr.yml
index c4b04c73ada70f803fce8886d11d9d569e4275ca..e26e0259230e1aea219ae103784ba4cffe4beb5e 100644
--- a/config/locales/activerecord.fr.yml
+++ b/config/locales/activerecord.fr.yml
@@ -1,6 +1,10 @@
 ---
 fr:
   activerecord:
+    attributes:
+      poll:
+        expires_at: Date butoir
+        options: Choix
     errors:
       models:
         account:
diff --git a/config/locales/activerecord.gl.yml b/config/locales/activerecord.gl.yml
index e3813145451ef4d1ca8bf5c157e62e86d5c50321..0bc27502ca6f953c36e44ab88bdd312ba26f1d65 100644
--- a/config/locales/activerecord.gl.yml
+++ b/config/locales/activerecord.gl.yml
@@ -1,6 +1,10 @@
 ---
 gl:
   activerecord:
+    attributes:
+      poll:
+        expires_at: Caducidade
+        options: Opcións
     errors:
       models:
         account:
diff --git a/config/locales/activerecord.hr.yml b/config/locales/activerecord.hr.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f67f33c7e0cfcce80b0d9e2a044068a78a531865
--- /dev/null
+++ b/config/locales/activerecord.hr.yml
@@ -0,0 +1 @@
+hr:
diff --git a/config/locales/activerecord.hu.yml b/config/locales/activerecord.hu.yml
new file mode 100644
index 0000000000000000000000000000000000000000..bbc18bc33cb2ba3052fd09971182dd2d5c5a864f
--- /dev/null
+++ b/config/locales/activerecord.hu.yml
@@ -0,0 +1,13 @@
+---
+hu:
+  activerecord:
+    attributes:
+      poll:
+        expires_at: Határidő
+        options: Lehetőségek
+    errors:
+      models:
+        account:
+          attributes:
+            username:
+              invalid: csak betűk, számok vagy alávonás
diff --git a/config/locales/activerecord.hy.yml b/config/locales/activerecord.hy.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c406540162aa8f9ae59ae2d79f75097ce1af0c26
--- /dev/null
+++ b/config/locales/activerecord.hy.yml
@@ -0,0 +1 @@
+hy:
diff --git a/config/locales/activerecord.io.yml b/config/locales/activerecord.io.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c63dc0e8d9470cde51d7473e8284be7623ca0677
--- /dev/null
+++ b/config/locales/activerecord.io.yml
@@ -0,0 +1 @@
+io:
diff --git a/config/locales/activerecord.it.yml b/config/locales/activerecord.it.yml
index 4cec9fb63cd6a98ab3d587e9af0fce0645cc59fd..70afdaef192d1a72acfe25c1b982d1db3f8e9f86 100644
--- a/config/locales/activerecord.it.yml
+++ b/config/locales/activerecord.it.yml
@@ -1,12 +1,16 @@
 ---
 it:
   activerecord:
+    attributes:
+      poll:
+        expires_at: Scadenza
+        options: Scelte
     errors:
       models:
         account:
           attributes:
             username:
-              invalid: solo lettere, numeri e trattino basso
+              invalid: solo lettere, numeri e trattini bassi
         status:
           attributes:
             reblog:
diff --git a/config/locales/activerecord.ja.yml b/config/locales/activerecord.ja.yml
index 7bc4fc3081373f2984407d55e6a907c689fa59eb..8b0eefb1221db82e22d26f79d9c87906ef81fa14 100644
--- a/config/locales/activerecord.ja.yml
+++ b/config/locales/activerecord.ja.yml
@@ -2,15 +2,16 @@
 ja:
   activerecord:
     attributes:
-      user:
-        email: メールアドレス
+      poll:
+        expires_at: 期限
+        options: é …ç›®
     errors:
       models:
         account:
           attributes:
             username:
-              invalid: アルファベット・数値・アンダーバー(_)で入力してください
+              invalid: アルファベット・数字・アンダーバーの組み合わせで入力してください
         status:
           attributes:
             reblog:
-              taken: のブーストはすでに存在します
+              taken: は既にブーストされています
diff --git a/config/locales/activerecord.kk.yml b/config/locales/activerecord.kk.yml
new file mode 100644
index 0000000000000000000000000000000000000000..fba2e60549c78456d866d498760f567bd0dcfea5
--- /dev/null
+++ b/config/locales/activerecord.kk.yml
@@ -0,0 +1,17 @@
+---
+kk:
+  activerecord:
+    attributes:
+      poll:
+        expires_at: Дедлайн
+        options: Таңдаулар
+    errors:
+      models:
+        account:
+          attributes:
+            username:
+              invalid: тек әріптер, сандар және асты сызылған таңбалар
+        status:
+          attributes:
+            reblog:
+              taken: жазбасы бұрыннан бар
diff --git a/config/locales/activerecord.ko.yml b/config/locales/activerecord.ko.yml
new file mode 100644
index 0000000000000000000000000000000000000000..3c081269a6574a917380172289a2d9fd1d4b9a03
--- /dev/null
+++ b/config/locales/activerecord.ko.yml
@@ -0,0 +1,17 @@
+---
+ko:
+  activerecord:
+    attributes:
+      poll:
+        expires_at: 마감 기한
+        options: 선택
+    errors:
+      models:
+        account:
+          attributes:
+            username:
+              invalid: 영문자, 숫자, _만 사용 가능
+        status:
+          attributes:
+            reblog:
+              taken: 이미 게시물이 존재합니다
diff --git a/config/locales/activerecord.lt.yml b/config/locales/activerecord.lt.yml
new file mode 100644
index 0000000000000000000000000000000000000000..6c5cb837ac8c136ddd4d85ef0a39145c386d62af
--- /dev/null
+++ b/config/locales/activerecord.lt.yml
@@ -0,0 +1 @@
+lt:
diff --git a/config/locales/activerecord.lv.yml b/config/locales/activerecord.lv.yml
new file mode 100644
index 0000000000000000000000000000000000000000..1be0eabc091569fadd234dc415e9a399b26e32c1
--- /dev/null
+++ b/config/locales/activerecord.lv.yml
@@ -0,0 +1 @@
+lv:
diff --git a/config/locales/activerecord.ms.yml b/config/locales/activerecord.ms.yml
new file mode 100644
index 0000000000000000000000000000000000000000..2925688a0330ed791a036a41ffcb8fc31c75352f
--- /dev/null
+++ b/config/locales/activerecord.ms.yml
@@ -0,0 +1 @@
+ms:
diff --git a/config/locales/activerecord.nl.yml b/config/locales/activerecord.nl.yml
index eeabab34aa3b6566ee3b3b0b5d123f2fb38b5c76..a9bcb33fa8a9e71a87b6c80ba4b86922b34e4f98 100644
--- a/config/locales/activerecord.nl.yml
+++ b/config/locales/activerecord.nl.yml
@@ -1,6 +1,10 @@
 ---
 nl:
   activerecord:
+    attributes:
+      poll:
+        expires_at: Deadline
+        options: Keuzes
     errors:
       models:
         account:
diff --git a/config/locales/activerecord.oc.yml b/config/locales/activerecord.oc.yml
index cdf0fa0acc18ac6ef40c3d03cccf5ac8451efe1f..1157d97694cdd249cac5ba4bca2d5845c2621374 100644
--- a/config/locales/activerecord.oc.yml
+++ b/config/locales/activerecord.oc.yml
@@ -1,6 +1,10 @@
 ---
 oc:
   activerecord:
+    attributes:
+      poll:
+        expires_at: Data limita
+        options: Opcions
     errors:
       models:
         account:
diff --git a/config/locales/activerecord.pl.yml b/config/locales/activerecord.pl.yml
index bd8e40a6a77f6d94acbe66c36fadaf4c0f337b6b..f10420ec727603b35fdf9930d38744753e9404b1 100644
--- a/config/locales/activerecord.pl.yml
+++ b/config/locales/activerecord.pl.yml
@@ -2,8 +2,9 @@
 pl:
   activerecord:
     attributes:
-      user:
-        email: adres e-mail
+      poll:
+        expires_at: Ostateczny termin
+        options: Opcje
     errors:
       models:
         account:
diff --git a/config/locales/activerecord.pt-BR.yml b/config/locales/activerecord.pt-BR.yml
index d2519fe905beaa22118bf34ba16636c23352d7f0..85150c1e75a7fc7ef4e1cd4d2d52d8e7182d0a1c 100644
--- a/config/locales/activerecord.pt-BR.yml
+++ b/config/locales/activerecord.pt-BR.yml
@@ -1,6 +1,10 @@
 ---
 pt-BR:
   activerecord:
+    attributes:
+      poll:
+        expires_at: Expira em
+        options: Escolhas
     errors:
       models:
         account:
diff --git a/config/locales/activerecord.ro.yml b/config/locales/activerecord.ro.yml
new file mode 100644
index 0000000000000000000000000000000000000000..79dbaa871cae8753fe261033b12cd507f3536ad9
--- /dev/null
+++ b/config/locales/activerecord.ro.yml
@@ -0,0 +1 @@
+ro:
diff --git a/config/locales/activerecord.ru.yml b/config/locales/activerecord.ru.yml
index 2a2d62a7ef57e04954a3b42a64a847bbf65d6984..d4529428a4cccb1ad3c2fb38a58b54e2805ea4b4 100644
--- a/config/locales/activerecord.ru.yml
+++ b/config/locales/activerecord.ru.yml
@@ -1,6 +1,10 @@
 ---
 ru:
   activerecord:
+    attributes:
+      poll:
+        expires_at: Крайний срок
+        options: Варианты
     errors:
       models:
         account:
diff --git a/config/locales/activerecord.sk.yml b/config/locales/activerecord.sk.yml
index 9ae71fa9aa4d095af49de23bf3b7328761a6a5b0..eb8d75d48d7bfb46fb33ec454388a5ff84a1896e 100644
--- a/config/locales/activerecord.sk.yml
+++ b/config/locales/activerecord.sk.yml
@@ -1,6 +1,10 @@
 ---
 sk:
   activerecord:
+    attributes:
+      poll:
+        expires_at: Trvá do
+        options: Voľby
     errors:
       models:
         account:
@@ -10,4 +14,4 @@ sk:
         status:
           attributes:
             reblog:
-              taken: status už existuje
+              taken: príspevku už existuje
diff --git a/config/locales/activerecord.sl.yml b/config/locales/activerecord.sl.yml
index d98e3b676b95a21e975ae317ae5695c809648d3b..1df1095796432a61eea51d819faaf32cf413386c 100644
--- a/config/locales/activerecord.sl.yml
+++ b/config/locales/activerecord.sl.yml
@@ -1,6 +1,10 @@
 ---
 sl:
   activerecord:
+    attributes:
+      poll:
+        expires_at: Rok
+        options: Izbire
     errors:
       models:
         account:
diff --git a/config/locales/activerecord.sq.yml b/config/locales/activerecord.sq.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e52345978ee0dd6418ef4a4729dacff0856e8972
--- /dev/null
+++ b/config/locales/activerecord.sq.yml
@@ -0,0 +1,13 @@
+---
+sq:
+  activerecord:
+    errors:
+      models:
+        account:
+          attributes:
+            username:
+              invalid: vetëm shkronja, numra dhe nënvija
+        status:
+          attributes:
+            reblog:
+              taken: e gjendjes ekziston tashmë
diff --git a/config/locales/activerecord.ta.yml b/config/locales/activerecord.ta.yml
new file mode 100644
index 0000000000000000000000000000000000000000..4320953ce2ab23ded9cc319b3002dfc1bc13903a
--- /dev/null
+++ b/config/locales/activerecord.ta.yml
@@ -0,0 +1 @@
+ta:
diff --git a/config/locales/activerecord.te.yml b/config/locales/activerecord.te.yml
new file mode 100644
index 0000000000000000000000000000000000000000..34c54f18f624c6d89026a04bd92ebc0df9c63e48
--- /dev/null
+++ b/config/locales/activerecord.te.yml
@@ -0,0 +1 @@
+te:
diff --git a/config/locales/activerecord.th.yml b/config/locales/activerecord.th.yml
index 2a41f4bce52816f5b30d5cfca2e6553ad2bd5408..6719422a25b40411a235cf4bf217fca70db6a107 100644
--- a/config/locales/activerecord.th.yml
+++ b/config/locales/activerecord.th.yml
@@ -1,13 +1,17 @@
 ---
 th:
   activerecord:
+    attributes:
+      poll:
+        expires_at: กำหนดเวลาสิ้นสุด
+        options: ทางเลือก
     errors:
       models:
         account:
           attributes:
             username:
-              invalid: only letters, numbers and underscores
+              invalid: ตัวอักษร, ตัวเลข และขีดล่างเท่านั้น
         status:
           attributes:
             reblog:
-              taken: of status already exists
+              taken: มีสถานะอยู่แล้ว
diff --git a/config/locales/activerecord.tr.yml b/config/locales/activerecord.tr.yml
new file mode 100644
index 0000000000000000000000000000000000000000..1cc2d98760a7522c4d42458c590a7a8d8d2a436d
--- /dev/null
+++ b/config/locales/activerecord.tr.yml
@@ -0,0 +1,13 @@
+---
+tr:
+  activerecord:
+    errors:
+      models:
+        account:
+          attributes:
+            username:
+              invalid: sadece harfler, sayılar ve alt çizgiler
+        status:
+          attributes:
+            reblog:
+              taken: durum zaten var
diff --git a/config/locales/activerecord.zh-CN.yml b/config/locales/activerecord.zh-CN.yml
index 8628d6677b926ac62e1e301738e5a8d6e5a5196f..8d2ddfd1408bc53b4548df7289aabf65e6651751 100644
--- a/config/locales/activerecord.zh-CN.yml
+++ b/config/locales/activerecord.zh-CN.yml
@@ -1,6 +1,10 @@
 ---
 zh-CN:
   activerecord:
+    attributes:
+      poll:
+        expires_at: 截止时间
+        options: 选项
     errors:
       models:
         account:
diff --git a/config/locales/activerecord.zh-TW.yml b/config/locales/activerecord.zh-TW.yml
new file mode 100644
index 0000000000000000000000000000000000000000..cb82c0526113b986978e7a8f16024f9075f98428
--- /dev/null
+++ b/config/locales/activerecord.zh-TW.yml
@@ -0,0 +1 @@
+zh-TW:
diff --git a/config/locales/activerecord.zh_Hant.yml b/config/locales/activerecord.zh_Hant.yml
new file mode 100644
index 0000000000000000000000000000000000000000..730ab3a5114b06c5035e99308a57f6e6f7d37091
--- /dev/null
+++ b/config/locales/activerecord.zh_Hant.yml
@@ -0,0 +1,15 @@
+zh_Hant:
+  activerecord:
+    attributes:
+      status:
+        owned_poll: 投票
+    errors:
+      models:
+        account:
+          attributes:
+            username:
+              invalid: 只允許使用字母、數字和底線
+        status:
+          attributes:
+            reblog:
+              taken: 的嘟文已經存在
diff --git a/config/locales/ar.yml b/config/locales/ar.yml
index 9d31e48407d7feb24efd29368db8c76f6323e26f..eb6a5ef06c321c4f8a71f14eded723cf74a53705 100644
--- a/config/locales/ar.yml
+++ b/config/locales/ar.yml
@@ -2,33 +2,27 @@
 ar:
   about:
     about_hashtag_html: هذه تبويقات متاحة للجمهور تحتوي على الكلمات الدلالية <strong>#%{hashtag}</strong>. يمكنك التفاعل معها إن كان لديك حساب في أي مكان على الفديفرس.
-    about_mastodon_html: ماستدون شبكة إجتماعية مبنية على أسُس بروتوكولات برمجيات الويب الحرة و مفتوحة المصدر. و هو لامركزي تمامًا كالبريد الإلكتروني.
+    about_mastodon_html: ماستدون شبكة اجتماعية مبنية على أسُس بروتوكولات برمجيات الويب الحرة و مفتوحة المصدر. و هو لامركزي تمامًا كالبريد الإلكتروني.
     about_this: عن مثيل الخادوم هذا
-    administered_by: 'يُديره :'
+    active_count_after: نشط
+    administered_by: 'يُديره:'
     api: واجهة برمجة التطبيقات
     apps: تطبيقات الأجهزة المحمولة
-    closed_registrations: التسجيلات في مثيل الخادوم هذا مُغلقة حاليًا. غير أنه بامكانك العثور على خادم آخر لإنشاء حسابك و مِن ثم النفاذ إلى نفس الشبكة مِن هناك.
     contact: للتواصل معنا
     contact_missing: لم يتم تعيينه
     contact_unavailable: غير متوفر
+    discover_users: اكتشف مستخدِمين
     documentation: الدليل
     extended_description_html: |
       <h3>مكان جيد للقواعد</h3>
       <p>لم يتم بعد إدخال الوصف الطويل.</p>
-    features:
-      humane_approach_body: تعلُّمًا مِن فشل الشبكات الأخرى، غاية ماستدون هي بلوغ الخيارات الأخلاقية في التصميم لمُحارَبة إسائة إستعمال شبكات التواصل الإجتماعية.
-      humane_approach_title: أسلوب يُعيد الإعتبار للفَرد
-      not_a_product_body: ماستدون ليس شبكة تجارية. لا يحتوي على إعلانات و لا يقوم باستغلال البيانات و لا هو بِبُستان مُسيَّج. لا تحكم فيه وليس له أية هيئةٍ مركزيةٍ.
-      not_a_product_title: إنك فرد و لست سلعة
-      real_conversation_body: يُمكنكم التعبير عن آرائكم بكل حرية بفضل 65535 حرف و انتقاء دقيق للمحتوى و الوسائط بفضل أدوات التحذير التي هي بين أيديكم.
-      real_conversation_title: مبني لتحقيق تواصل حقيقي
-      within_reach_body: إبقوا على اتصال دائم بأصدقائكم حيثما كانوا عبر عدة تطبيقات لنظام آي أواس و أندرويد و عدة منصات أخرى بفضل واجهة برمجية للتطبيقات و بيئة صديقة للتطوير.
-      within_reach_title: في مُتناوَل يدك دائمًا
     generic_description: "%{domain} هو سيرفر من بين سيرفرات الشبكة"
+    get_apps: جرّب تطبيقا على الموبايل
     hosted_on: ماستدون مُستضاف على %{domain}
     learn_more: تعلم المزيد
-    other_instances: خوادم أخرى
     privacy_policy: سياسة الخصوصية
+    see_whats_happening: اطّلع على ما يجري
+    server_stats: 'إحصائيات الخادم:'
     source_code: الشفرة المصدرية
     status_count_after:
       few: منشورات
@@ -38,6 +32,7 @@ ar:
       two: منشورات
       zero: منشورات
     status_count_before: نشروا
+    tagline: اتبع أصدقائك وصديقاتك واكتشف آخرين وأخريات
     terms: شروط الخدمة
     user_count_after:
       few: مستخدمين
@@ -49,8 +44,8 @@ ar:
     user_count_before: يستضيف
     what_is_mastodon: ما هو ماستدون ؟
   accounts:
-    choices_html: 'توصيات %{name} :'
-    follow: إتبع
+    choices_html: 'توصيات %{name}:'
+    follow: اتبع
     followers:
       few: متابِعون
       many: متابِعون
@@ -63,9 +58,9 @@ ar:
     last_active: آخر نشاط
     link_verified_on: تم التحقق مِن مالك هذا الرابط بتاريخ %{date}
     media: الوسائط
-    moved_html: "%{name} إنتقلَ إلى %{new_profile_link} :"
+    moved_html: "%{name} إنتقلَ إلى %{new_profile_link}:"
     network_hidden: إنّ المعطيات غير متوفرة
-    nothing_here: لا يوجد أي شيء هنا !
+    nothing_here: لا يوجد أي شيء هنا!
     people_followed_by: الأشخاص الذين يتبعهم %{name}
     people_who_follow: الأشخاص الذين يتبعون %{name}
     pin_errors:
@@ -79,27 +74,30 @@ ar:
       zero: تبويقات
     posts_tab_heading: تبويقات
     posts_with_replies: التبويقات و الردود
-    reserved_username: إسم المستخدم محجوز
+    reserved_username: اسم المستخدم محجوز
     roles:
       admin: المدير
       bot: روبوت
       moderator: مُشرِف
+    unavailable: الحساب غير متوفر
     unfollow: إلغاء المتابعة
   admin:
     account_actions:
-      action: تنفيذ الاجراء
+      action: تنفيذ الإجراء
       title: اتخاذ إجراء إشراف على %{acct}
     account_moderation_notes:
-      create: إترك ملاحظة
-      created_msg: تم إنشاء ملاحظة الإشراف بنجاح !
+      create: اترك ملاحظة
+      created_msg: تم إنشاء ملاحظة الإشراف بنجاح!
       delete: حذف
-      destroyed_msg: تم تدمير ملاحظة الإشراف بنجاح !
+      destroyed_msg: تم تدمير ملاحظة الإشراف بنجاح!
     accounts:
+      approve: صادِق عليه
+      approve_all: الموافقة على الكل
       are_you_sure: متأكد ؟
       avatar: الصورة الرمزية
       by_domain: النطاق
       change_email:
-        changed_msg: تم تعديل عنوان البريد الإلكتروني الخاص بالحساب بنجاح !
+        changed_msg: تم تعديل عنوان البريد الإلكتروني الخاص بالحساب بنجاح!
         current_email: عنوان البريد الإلكتروني الحالي
         label: تعديل عنوان البريد الإلكتروني
         new_email: عنوان البريد الإلكتروني الجديد
@@ -113,7 +111,7 @@ ar:
       disable: تعطيل
       disable_two_factor_authentication: تعطيل المصادقة بخطوتين
       disabled: معطَّل
-      display_name: عرض الإسم
+      display_name: عرض الاسم
       domain: النطاق
       edit: تعديل
       email: البريد الإلكتروني
@@ -140,15 +138,18 @@ ar:
       moderation:
         active: نشِط
         all: الكل
+        pending: قيد المراجعة
         silenced: تم كتمه
         suspended: مُجَمَّد
         title: الإشراف
       moderation_notes: ملاحظات الإشراف
       most_recent_activity: آخر نشاط حديث
       most_recent_ip: أحدث عنوان إيبي
+      no_account_selected: لم يطرأ أي تغيير على أي حساب بما أنه لم يتم اختيار أي واحد
       no_limits_imposed: مِن دون حدود مشروطة
       not_subscribed: غير مشترك
       outbox_url: رابط صندوق الصادر
+      pending: في انتظار المراجعة
       perform_full_suspension: تعليق الحساب
       profile_url: رابط الملف الشخصي
       promote: ترقية
@@ -156,15 +157,17 @@ ar:
       public: عمومي
       push_subscription_expires: انتهاء الاشتراك ”PuSH“
       redownload: تحديث الصفحة الشخصية
+      reject: ارفض
+      reject_all: ارفض الكل
       remove_avatar: حذف الصورة الرمزية
       remove_header: حذف الرأسية
       resend_confirmation:
         already_confirmed: هذا المستخدم مؤكد بالفعل
-        send: أعد إرسال رسالة البريد الالكتروني الخاصة بالتأكيد
+        send: أعد إرسال رسالة البريد الإلكتروني الخاصة بالتأكيد
         success: تم إرسال رسالة التأكيد بنجاح!
       reset: إعادة التعيين
       reset_password: إعادة ضبط كلمة السر
-      resubscribe: إعادة الإشتراك
+      resubscribe: إعادة الاشتراك
       role: الصلاحيات
       roles:
         admin: مدير
@@ -176,18 +179,19 @@ ar:
       shared_inbox_url: رابط الصندوق المُشترَك للبريد الوارد
       show:
         created_reports: البلاغات التي أنشأها هذا الحساب
-        targeted_reports: الشكاوي التي أُنشِأت مِن طرف الآخَرين
+        targeted_reports: الشكاوى التي أُنشِأت مِن طرف الآخَرين
       silence: كتم
       silenced: تم كتمه
       statuses: المنشورات
       subscribe: اشترك
       suspended: تم تعليقه
+      time_in_queue: في قائمة الانتظار %{time}
       title: الحسابات
       unconfirmed_email: البريد الإلكتروني غير مؤكد
       undo_silenced: رفع الصمت
       undo_suspension: إلغاء تعليق الحساب
       unsubscribe: إلغاء الاشتراك
-      username: إسم المستخدم
+      username: اسم المستخدم
       warn: تحذير
       web: الويب
     action_logs:
@@ -195,6 +199,7 @@ ar:
         assigned_to_self_report: قام %{name} بتعيين التقرير %{target} لأنفسهم
         change_email_user: غيّر %{name} عنوان البريد الإلكتروني للمستخدم %{target}
         confirm_user: "%{name} قد قام بتأكيد عنوان البريد الإلكتروني لـ %{target}"
+        create_account_warning: قام %{name} بإرسال تحذير إلى %{target}
         create_custom_emoji: "%{name} قام برفع إيموجي جديد %{target}"
         create_domain_block: "%{name} قام بحجب نطاق %{target}"
         create_email_domain_block: "%{name} قد قام بحظر نطاق البريد الإلكتروني %{target}"
@@ -203,7 +208,7 @@ ar:
         destroy_domain_block: "%{name} قام بإلغاء الحجب عن النطاق %{target}"
         destroy_email_domain_block: قام %{name} بإضافة نطاق البريد الإلكتروني %{target} إلى اللائحة البيضاء
         destroy_status: لقد قام %{name} بحذف منشور %{target}
-        disable_2fa_user: "%{name} لقد قام  بتعطيل ميزة المصادقة بخطوتين للمستخدم %{target}"
+        disable_2fa_user: "%{name} لقد قام بتعطيل ميزة المصادقة بخطوتين للمستخدم %{target}"
         disable_custom_emoji: "%{name} قام بتعطيل الإيموجي %{target}"
         disable_user: "%{name} لقد قام بتعطيل تسجيل الدخول للمستخدِم %{target}"
         enable_custom_emoji: "%{name} قام بتنشيط الإيموجي %{target}"
@@ -228,9 +233,9 @@ ar:
       copied_msg: تم إنشاء نسخة محلية للإيموجي بنجاح
       copy: نسخ
       copy_failed_msg: فشلت عملية إنشاء نسخة محلية لهذا الإيموجي
-      created_msg: تم إنشاء الإيموجي بنجاح !
+      created_msg: تم إنشاء الإيموجي بنجاح!
       delete: حذف
-      destroyed_msg: تمت عملية تدمير الإيموجي بنجاح !
+      destroyed_msg: تمت عملية تدمير الإيموجي بنجاح!
       disable: تعطيل
       disabled_msg: تمت عملية تعطيل ذلك الإيموجي بنجاح
       emoji: إيموجي
@@ -245,8 +250,8 @@ ar:
       shortcode_hint: على الأقل حرفين، و فقط رموز أبجدية عددية و أسطر سفلية
       title: الإيموجي الخاصة
       unlisted: غير مدرج
-      update_failed_msg: تعذرت عملية تحذيث ذاك الإيموجي
-      updated_msg: تم تحديث الإيموجي بنجاح !
+      update_failed_msg: تعذرت عملية تحديث ذاك الإيموجي
+      updated_msg: تم تحديث الإيموجي بنجاح!
       upload: رفع
     dashboard:
       backlog: الأعمال المتراكمة
@@ -256,9 +261,10 @@ ar:
       feature_profile_directory: دليل الحسابات
       feature_registrations: التسجيلات
       feature_relay: المُرحّل الفديرالي
+      feature_timeline_preview: معاينة الخيط الزمني
       features: الميّزات
       hidden_service: الفيديرالية مع الخدمات الخفية
-      open_reports: فتح الشكاوي
+      open_reports: فتح الشكاوى
       recent_users: أحدث المستخدِمين
       search: البحث النصي الكامل
       single_user_mode: وضع المستخدِم الأوحد
@@ -296,8 +302,8 @@ ar:
           many: "%{count} حسابات معنية في قاعدة البيانات"
           one: حساب واحد معني في قاعدة البيانات
           other: "%{count} حسابات معنية في قاعدة البيانات"
-          two: حسابات معنية في قاعدة البيانات
-          zero: حسابات معنية في قاعدة البيانات
+          two: "%{count} حسابات معنية في قاعدة البيانات"
+          zero: "%{count} حسابات معنية في قاعدة البيانات"
         retroactive:
           silence: إلغاء الكتم عن كافة الحسابات المتواجدة على هذا النطاق
           suspend: إلغاء التعليق المفروض على كافة حسابات هذا النطاق
@@ -318,6 +324,8 @@ ar:
       back_to_account: العودة إلى الحساب
       title: "%{acct} مُتابِعون"
     instances:
+      by_domain: النطاق
+      delivery_available: التسليم متوفر
       known_accounts:
         few: "%{count} حسابات معروفة"
         many: "%{count} حسابات معروفة"
@@ -327,6 +335,7 @@ ar:
         zero: "%{count} حسابات معروفة"
       moderation:
         all: كافتها
+        limited: محدود
         title: الإشراف
       title: الفديرالية
       total_blocked_by_us: المحجوبة مِن طرفنا
@@ -342,13 +351,15 @@ ar:
         expired: المنتهي صلاحيتها
         title: التصفية
       title: الدعوات
+    pending_accounts:
+      title: الحسابات المعلقة (%{count})
     relays:
       add_new: إضافة مُرحّل جديد
       delete: حذف
       disable: تعطيل
       disabled: مُعطَّل
       enable: تشغيل
-      enable_hint: عندما تقوم بتنشيط هذه الميزة، سوف يشترك خادومك في جميع التبويقات القادمة مِن هذا المُرحِّل و سيشرع كذلك بإرسال كافة التبويقات العمومية إليه.
+      enable_hint: عندما تقوم بتنشيط هذه الميزة، سوف يشترك خادومكم في جميع التبويقات القادمة مِن هذا المُرحِّل و سيشرع كذلك بإرسال كافة التبويقات العمومية إليه.
       enabled: مُشغَّل
       inbox_url: رابط المُرحّل
       pending: في انتظار تسريح المُرحِّل
@@ -370,14 +381,14 @@ ar:
       comment:
         none: لا شيء
       created_at: ذكرت
-      mark_as_resolved: إعتبار الشكوى كمحلولة
-      mark_as_unresolved: علام كغير محلولة
+      mark_as_resolved: اعتبار الشكوى كمحلولة
+      mark_as_unresolved: علم كغير محلولة
       notes:
         create: اضف ملاحظة
         create_and_resolve: الحل مع ملاحظة
         create_and_unresolve: إعادة فتح مع ملاحظة
         delete: حذف
-        placeholder: قم بوصف الإجراءات التي تم اتخاذها أو أي تحديثات أخرى ذات علاقة …
+        placeholder: قم بوصف الإجراءات التي تم اتخاذها أو أي تحديثات أخرى ذات علاقة...
       reopen: إعادة فتح الشكوى
       report: 'الشكوى #%{id}'
       reported_account: حساب مُبلّغ عنه
@@ -385,20 +396,20 @@ ar:
       resolved: معالجة
       resolved_msg: تم حل تقرير بنجاح!
       status: الحالة
-      title: الشكاوي
+      title: الشكاوى
       unassign: إلغاء تعيين
       unresolved: غير معالجة
       updated_at: محدث
     settings:
       activity_api_enabled:
-        desc_html: عدد المنشورات المحلية و المستخدمين النشطين و التسجيلات الأسبوعية الجديدة
+        desc_html: عدد المنشورات المحلية و المستخدمين الناشطين و التسجيلات الأسبوعية الجديدة
         title: نشر مُجمل الإحصائيات عن نشاط المستخدمين
       bootstrap_timeline_accounts:
         desc_html: افصل بين أسماء المستخدمين المتعددة بواسطة الفاصلة. استعمل الحسابات المحلية والمفتوحة فقط. الافتراضي عندما تكون فارغة كل المسؤولين المحليين.
-        title: الإشتراكات الإفتراضية للمستخدمين الجدد
+        title: الاشتراكات الافتراضية للمستخدمين الجدد
       contact_information:
         email: البريد الإلكتروني المهني
-        username: الإتصال بالمستخدِم
+        username: الاتصال بالمستخدِم
       custom_css:
         desc_html: يقوم بتغيير المظهر بواسطة سي أس أس يُحمَّل على كافة الصفحات
         title: سي أس أس مخصص
@@ -406,7 +417,7 @@ ar:
         desc_html: معروض على الصفحة الأولى. لا يقل عن 600 × 100 بكسل. عند عدم التعيين ، تعود الصورة إلى النسخة المصغرة على سبيل المثال
         title: الصورة الرأسية
       peers_api_enabled:
-        desc_html: أسماء النطاقات التي إلتقى بها مثيل الخادوم على البيئة الموحَّدة فيديفرس
+        desc_html: أسماء النطاقات التي التقى بها مثيل الخادوم على البيئة الموحَّدة فديفرس
         title: نشر عدد مثيلات الخوادم التي تم مصادفتها
       preview_sensitive_media:
         desc_html: روابط المُعَاينة على مواقع الويب الأخرى ستقوم بعرض صُوَر مصغّرة حتى و إن كانت الوسائط حساسة
@@ -424,12 +435,13 @@ ar:
         min_invite_role:
           disabled: لا أحد
           title: المستخدِمون المصرح لهم لإرسال الدعوات
-        open:
-          desc_html: السماح للجميع بإنشاء حساب
-          title: فتح التسجيل
+      registrations_mode:
+        modes:
+          none: لا أحد يمكنه إنشاء حساب
+          open: يمكن للجميع إنشاء حساب
+        title: طريقة إنشاء الحسابات
       show_known_fediverse_at_about_page:
-        desc_html: عند التثبت ، سوف تظهر toots من جميع fediverse المعروفة على عرض مسبق. وإلا فإنه سيعرض فقط toots المحلية.
-        title: إظهار الفيديفرس الموحَّد في خيط المُعايَنة
+        title: إظهار الفديفرس الموحَّد في خيط المُعايَنة
       show_staff_badge:
         desc_html: عرض شارة الموظفين على صفحة المستخدم
         title: إظهار شارة الموظفين
@@ -440,17 +452,17 @@ ar:
         desc_html: مكان جيد لمدونة قواعد السلوك والقواعد والإرشادات وغيرها من الأمور التي تحدد حالتك. يمكنك استخدام علامات HTML
         title: الوصف المُفصّل للموقع
       site_short_description:
-        desc_html: يتم عرضه في لوحة جانبية و في البيانات الوصفية. قم بوصف ماستدون و ما يميز هذا السيرفر عن الآخرين في فقرة موجزة. إن تركت الحقل فارغا فسوف يتم عرض الوصف الإفتراضي لمثيل الخادوم.
+        desc_html: يتم عرضه في لوحة جانبية و في البيانات الوصفية. قم بوصف ماستدون و ما يميز هذا السيرفر عن الآخرين في فقرة موجزة. إن تركت الحقل فارغا فسوف يتم عرض الوصف الافتراضي لمثيل الخادوم.
         title: مقدمة وصفية قصيرة عن مثيل الخادوم
       site_terms:
         desc_html: يمكنك كتابة سياسة الخصوصية الخاصة بك ، شروط الخدمة أو غيرها من القوانين. يمكنك استخدام علامات HTML
         title: شروط الخدمة المخصصة
-      site_title: إسم مثيل الخادم
+      site_title: اسم مثيل الخادم
       thumbnail:
         desc_html: يستخدم للعروض السابقة عبر Open Graph و API. 1200x630px موصى به
         title: الصورة الرمزية المصغرة لمثيل الخادوم
       timeline_preview:
-        desc_html: عرض الخيط العمومي على صفحة الإستقبال
+        desc_html: عرض الخيط العمومي على صفحة الاستقبال
         title: مُعاينة الخيط العام
       title: إعدادات الموقع
     statuses:
@@ -471,7 +483,6 @@ ar:
       confirmed: مؤكَّد
       expires_in: تنتهي مدة صلاحيتها في
       last_delivery: آخر إيداع
-      title: WebSub
       topic: الموضوع
     tags:
       accounts: الحسابات
@@ -489,15 +500,20 @@ ar:
       edit_preset: تعديل نموذج التحذير
       title: إدارة نماذج التحذير
   admin_mailer:
+    new_pending_account:
+      subject: حساب جديد في انتظار مراجعة على %{instance} (%{username})
     new_report:
       body: قام %{reporter} بالإبلاغ عن %{target}
       body_remote: أبلغ شخص ما من %{domain} عن %{target}
       subject: تقرير جديد ل%{instance} (#%{id})
+  appearance:
+    advanced_web_interface: واجهة الويب المتقدمة
+    confirmation_dialogs: نوافذ التأكيد
+    sensitive_content: محتوى حساس
   application_mailer:
     notification_preferences: تعديل خيارات البريد الإلكتروني
     salutation: "%{name}،"
-    settings: 'تغيير تفضيلات البريد الإلكتروني : %{link}'
-    view: 'View:'
+    settings: 'تغيير تفضيلات البريد الإلكتروني: %{link}'
     view_profile: عرض الملف الشخصي
     view_status: عرض المنشور
   applications:
@@ -506,11 +522,12 @@ ar:
     invalid_url: إن الرابط المقدم غير صالح
     regenerate_token: إعادة توليد رمز النفاذ
     token_regenerated: تم إعادة إنشاء الرمز الوصول بنجاح
-    warning: كن حذرا مع هذه البيانات. لا تقم أبدا بمشاركتها مع الآخَرين !
+    warning: كن حذرا مع هذه البيانات. لا تقم أبدا بمشاركتها مع الآخَرين!
     your_token: رمز نفاذك
   auth:
-    agreement_html: بمجرد النقر على "التسجيل" أسفله، فإنك تُصرِّح قبول <a href="%{rules_path}">قواعد مثيل الخادوم</a> و <a href="%{terms_path}">شروط الخدمة التي نوفرها لك</a>.
+    apply_for_account: اطلب دعوة
     change_password: الكلمة السرية
+    checkbox_agreement_html: أوافق على <a href="%{rules_path}" target="_blank">قواعد الخادم</a> و <a href="%{terms_path}" target="_blank">شروط الخدمة</a>
     confirm_email: تأكيد عنوان البريد الإلكتروني
     delete_account: حذف حساب
     delete_account_html: إن كنت ترغب في حذف حسابك يُمكنك <a href="%{path}">المواصلة هنا</a>. سوف يُطلَبُ منك التأكيد قبل الحذف.
@@ -519,25 +536,25 @@ ar:
     invalid_reset_password_token: رمز إعادة تعيين كلمة المرور غير صالح أو منتهي الصلاحية. يرجى طلب واحد جديد.
     login: تسجيل الدخول
     logout: خروج
-    migrate_account: الإنتقال إلى حساب آخر
+    migrate_account: الانتقال إلى حساب آخر
     migrate_account_html: إن كنت ترغب في تحويل هذا الحساب نحو حساب آخَر، يُمكِنُك <a href="%{path}">إعداده هنا</a>.
-    or: أو
     or_log_in_with: أو قم بتسجيل الدخول بواسطة
     providers:
       cas: CAS
       saml: SAML
     register: إنشاء حساب
-    register_elsewhere: التسجيل على خادوم آخَر
+    registration_closed: لا يقبل %{instance} استقبال أعضاء جدد
     resend_confirmation: إعادة إرسال تعليمات التأكيد
     reset_password: إعادة تعيين كلمة المرور
     security: الأمان
     set_new_password: إدخال كلمة مرور جديدة
+    trouble_logging_in: هل صادفتكم مشكلة في الولوج؟
   authorize_follow:
     already_following: أنت تتابع بالفعل هذا الحساب
     error: يا للأسف، وقع هناك خطأ إثر عملية البحث عن الحساب عن بعد
-    follow: إتبع
-    follow_request: 'لقد قمت بإرسال طلب متابعة إلى :'
-    following: 'مرحى ! أنت الآن تتبع :'
+    follow: اتبع
+    follow_request: 'لقد قمت بإرسال طلب متابعة إلى:'
+    following: 'مرحى! أنت الآن تتبع:'
     post_follow:
       close: أو يمكنك إغلاق هذه النافذة.
       return: عرض الملف الشخصي للمستخدم
@@ -558,7 +575,7 @@ ar:
       x_months: "%{count} شه"
       x_seconds: "%{count}Ø«"
   deletes:
-    bad_password_msg: محاولة جيدة يا هاكرز ! كلمة السر خاطئة
+    bad_password_msg: محاولة جيدة يا هاكرز! كلمة السر خاطئة
     confirm_password: قم بإدخال كلمتك السرية الحالية للتحقق من هويتك
     proceed: حذف حساب
     success_msg: تم حذف حسابك بنجاح
@@ -580,27 +597,32 @@ ar:
     '404': إنّ الصفحة التي تبحث عنها لا وجود لها أصلا.
     '410': إنّ الصفحة التي تبحث عنها لم تعد موجودة.
     '422':
-      content: فشل التحقق الآمن. ربما منعتَ كعكات الكوكيز ؟
+      content: فشل التحقق الآمن. ربما منعتَ كعكات الكوكيز؟
       title: فشِل التحقق الآمن
     '429': طلبات كثيرة جدا
     '500':
       content: نحن متأسفون، لقد حدث خطأ ما مِن جانبنا.
       title: هذه الصفحة خاطئة
     noscript_html: يرجى تفعيل الجافا سكريبت لاستخدام تطبيق الويب لماستدون، أو عِوض ذلك قوموا بتجريب إحدى <a href="%{apps_path}">التطبيقات الأصلية</a> الدّاعمة لماستدون على منصّتكم.
+  existing_username_validator:
+    not_found_multiple: تعذر العثور على %{usernames}
   exports:
     archive_takeout:
       date: التاريخ
       download: تنزيل نسخة لحسابك
       hint_html: بإمكانك طلب نسخة كاملة لـ <strong>كافة تبويقاتك و الوسائط التي قمت بنشرها</strong>. البيانات المُصدَّرة ستكون محفوظة على شكل نسق ActivityPub و باستطاعتك قراءتها بأي برنامج يدعم هذا النسق. يُمكنك طلب نسخة كل 7 أيام.
-      in_progress: عملية جمع نسخة لبيانات حسابك جارية …
+      in_progress: عملية جمع نسخة لبيانات حسابك جارية...
       request: طلب نسخة لحسابك
       size: الحجم
     blocks: قمت بحظر
     csv: CSV
+    domain_blocks: النطاقات المحظورة
     follows: أنت تتبع
     lists: القوائم
     mutes: قُمتَ بكتم
     storage: ذاكرة التخزين
+  featured_tags:
+    add_new: إضافة واحد
   filters:
     contexts:
       home: الخيط الزمني الرئيسي
@@ -617,22 +639,15 @@ ar:
       title: عوامل التصفية
     new:
       title: إضافة عامل تصفية جديد
-  followers:
-    domain: النطاق
-    followers_count: عدد المتابِعين
-    lock_link: قم بتجميد حسابك
-    purge: تنحية من بين متابعيك
-    success: جارية عملية حظر المتابِعين بسلاسة من %{count} نطاقات أخرى ...
-    true_privacy_html: تذكر دائمًا أنّ <strong>الخصوصية التامة لا يمكن بلوغها إلّا بالتعمية و التشفير من طرف إلى آخَر</strong>.
-    unlocked_warning_html: يمكن لأي كان متابعة حسابك و الإطلاع مباشرة على تبويقاتك. إستخدِم %{lock_link} لمُعاينة أو رفض طلبات المتابِعين الجُدُد.
-    unlocked_warning_title: إنّ حسابك غير مقفل
   footer:
     developers: المطورون
-    more: المزيد …
+    more: المزيد…
     resources: الموارد
   generic:
-    changes_saved_msg: تم حفظ التعديلات بنجاح !
+    all: الكل
+    changes_saved_msg: تم حفظ التعديلات بنجاح!
     copy: نسخ
+    order_by: ترتيب بحسب
     save_changes: حفظ التغييرات
     validation_errors:
       few: هناك شيء ما ليس على ما يرام! يُرجى مراجعة الأخطاء الـ %{count} أدناه
@@ -641,18 +656,35 @@ ar:
       other: هناك شيء ما ليس على ما يرام! يُرجى مراجعة الأخطاء الـ %{count} أدناه
       two: هناك شيء ما ليس على ما يرام! يُرجى مراجعة الأخطاء الـ %{count} أدناه
       zero: هناك شيء ما ليس على ما يرام! يُرجى مراجعة الأخطاء الـ %{count} أدناه
+  identity_proofs:
+    active: نشط
+    authorize: نعم ، قم بترخيصه
+    authorize_connection_prompt: هل تريد ترخيص هذا الاتصال المشفّر؟
+    i_am_html: أنا %{username} على %{service}.
+    identity: الهوية
+    inactive: ليس نشطا
+    publicize_checkbox: 'وقم بتبويق هذا:'
+    publicize_toot: 'متحقق منه! أنا %{username} على %{service}: %{url}'
+    status: حالة التحقق
+    view_proof: عرض الدليل
   imports:
+    modes:
+      merge: دمج
+      merge_long: الإبقاء علي التسجيلات الحالية وإضافة الجديدة
+      overwrite: إعادة الكتابة
+      overwrite_long: استبدال التسجيلات الحالية بالجديدة
     preface: بإمكانك استيراد بيانات قد قُمتَ بتصديرها مِن مثيل خادوم آخَر، كقوائم المستخدِمين الذين كنتَ تتابِعهم أو قُمتَ بحظرهم.
     success: تم تحميل بياناتك بنجاح وسيتم معالجتها في الوقت المناسب
     types:
       blocking: قائمة المحظورين
+      domain_blocking: قائمة النطاقات المحظورة
       following: قائمة المستخدمين المتبوعين
       muting: قائمة الكتم
     upload: تحميل
   in_memoriam_html: في ذكرى.
   invites:
     delete: تعطيل
-    expired: إنتهت صلاحيتها
+    expired: انتهت صلاحيتها
     expires_in:
       '1800': 30 دقيقة
       '21600': 6 ساعات
@@ -662,14 +694,14 @@ ar:
       '86400': يوم واحد
     expires_in_prompt: أبدا
     generate: توليد
-    invited_by: 'تمت دعوتك من طرف :'
+    invited_by: 'تمت دعوتك من طرف:'
     max_uses:
       few: "%{count} استخدامات"
       many: "%{count} استخدامات"
       one: استخدام واحد
       other: "%{count} استخدامات"
-      two: استخدامات
-      zero: استخدامات
+      two: "%{count} استخدامات"
+      zero: "%{count} استخدامات"
     max_uses_prompt: بلا حدود
     prompt: توليد و مشاركة روابط للسماح للآخَرين بالنفاذ إلى مثيل الخادوم هذا
     table:
@@ -685,16 +717,16 @@ ar:
       too_many: لا يمكن إرفاق أكثر من 4 ملفات
   migrations:
     acct: username@domain للحساب الجديد
-    currently_redirecting: 'تم تحويل رابط ملفك الشخصي إلى :'
+    currently_redirecting: 'تم تحويل رابط ملفك الشخصي إلى:'
     proceed: حفظ
-    updated_msg: تم تحديث إعدادات ترحيل حسابك بنجاح !
+    updated_msg: تم تحديث إعدادات ترحيل حسابك بنجاح!
   moderation:
     title: الإشراف
   notification_mailer:
     digest:
       action: معاينة كافة الإشعارات
-      body: هذا هو مُلَخَّص الرسائل التي فاتتك وذلك منذ آخر زيارة لك في  %{since}
-      mention: "%{name} أشار إليك في :"
+      body: هذا هو مُلَخَّص الرسائل التي فاتتك وذلك منذ آخر زيارة لك في %{since}
+      mention: "%{name} أشار إليك في:"
       new_followers_summary:
         few: رائع، لقد قام بمتابَعتك %{count} مُتابِعون جُدد أثناء فترة غيابك عن ماستدون!
         many: رائع، لقد قام بمتابَعتك %{count} مُتابِعون جُدد أثناء فترة غيابك عن ماستدون!
@@ -707,29 +739,29 @@ ar:
         many: "%{count} إشعارات جديدة منذ آخر زيارة لك إلى \U0001F418"
         one: "إشعار واحد 1 منذ آخر زيارة لك لـ \U0001F418"
         other: "%{count} إشعارات جديدة منذ آخر زيارة لك إلى \U0001F418"
-        two: "إشعارات جديدة منذ آخر زيارة لك إلى \U0001F418"
-        zero: "إشعارات جديدة منذ آخر زيارة لك إلى \U0001F418"
-      title: أثناء فترة غيابك …
+        two: "%{count} إشعارات جديدة منذ آخر زيارة لك إلى \U0001F418"
+        zero: "%{count} إشعارات جديدة منذ آخر زيارة لك إلى \U0001F418"
+      title: أثناء فترة غيابك...
     favourite:
-      body: 'أُعجب %{name} بمنشورك :'
+      body: 'أُعجب %{name} بمنشورك:'
       subject: أُعجِب %{name} بمنشورك
       title: مفضّلة جديدة
     follow:
-      body: "%{name} من متتبعيك الآن !"
+      body: "%{name} من متتبعيك الآن!"
       subject: "%{name} من متتبعيك الآن"
       title: متابِع جديد
     follow_request:
       action: إدارة طلبات المتابَعة
       body: طلب %{name} متابعتك
-      subject: 'متابع مُعلّق : %{name}'
+      subject: 'متابع مُعلّق: %{name}'
       title: طلب متابَعة جديد
     mention:
       action: الرد
-      body: 'أشار إليك %{name} في :'
+      body: 'أشار إليك %{name} في:'
       subject: لقد قام %{name} بذِكرك
       title: إشارة جديدة
     reblog:
-      body: 'قام %{name} بترقية منشورك :'
+      body: 'قام %{name} بترقية منشورك:'
       subject: قام %{name} بترقية منشورك
       title: ترقية جديدة
   number:
@@ -737,29 +769,55 @@ ar:
       decimal_units:
         format: "%n%u"
         units:
-          billion: B
-          million: M
+          billion: بل
+          million: ملي
           quadrillion: كواد
           thousand: ألف
-          trillion: T
-          unit: ''
+          trillion: ترل
   pagination:
     newer: الأحدَث
     next: التالي
     older: الأقدَم
     prev: السابق
     truncate: Ùˆ
+  polls:
+    errors:
+      already_voted: لقد قمت بالتصويت على استطلاع الرأي هذا مِن قبل
+      duplicate_options: يحتوي على عناصر مكررة
+      duration_too_short: مبكّر جدا
+      expired: لقد انتهى استطلاع الرأي
   preferences:
-    languages: اللغات
     other: إعدادات أخرى
-    publishing: النشر
-    web: الويب
+    posting_defaults: التفضيلات الافتراضية لنشر التبويقات
+    public_timelines: الخيوط الزمنية العامة
+  relationships:
+    activity: نشاط الحساب
+    dormant: في سبات
+    last_active: آخر نشاط
+    most_recent: الأحدث
+    moved: هاجر
+    primary: رئيسي
+    relationship: العلاقة
+    remove_selected_domains: احذف كافة المتابِعين القادمين مِن النطاقات المختارة
+    remove_selected_followers: احذف المتابِعين الذين قمت باختيارهم
+    remove_selected_follows: الغي متابعة المستخدمين الذين اخترتهم
+    status: حالة الحساب
   remote_follow:
     acct: قم بإدخال عنوان حسابك username@domain الذي من خلاله تود النشاط
     missing_resource: تعذر العثور على رابط التحويل المطلوب الخاص بحسابك
     no_account_html: أليس عندك حساب بعدُ ؟ يُمْكنك <a href='%{sign_up_path}' target='_blank'>التسجيل مِن هنا</a>
     proceed: أكمل المتابعة
-    prompt: 'إنك  بصدد متابعة :'
+    prompt: 'إنك بصدد متابعة:'
+  remote_interaction:
+    favourite:
+      proceed: المواصلة إلى المفضلة
+      prompt: 'ترغب في إضافة هذا التبويق إلى مفضلتك:'
+    reblog:
+      proceed: المواصلة إلى الترقية
+      prompt: 'ترغب في ترقية هذا التبويق:'
+    reply:
+      proceed: المواصلة إلى الرد
+      prompt: 'ترغب في الرد على هذا التبويق:'
   remote_unfollow:
     error: خطأ
     title: العنوان
@@ -777,7 +835,7 @@ ar:
       generic: متصفح مجهول
       ie: إنترنت إكسبلورر
       micro_messenger: مايكرو ميسنجر
-      nokia: متصفح  Nokia S40 Ovi
+      nokia: متصفح Nokia S40 Ovi
       opera: أوبرا
       otter: أوتر
       phantom_js: فانتوم جي آس
@@ -787,7 +845,7 @@ ar:
       weibo: وايبو
     current_session: الجلسة الحالية
     description: "%{browser} على %{platform}"
-    explanation: ها هي قائمة مُتصفِّحات الويب  التي تستخدِم حاليًا حساب ماستدون الخاص بك.
+    explanation: ها هي قائمة مُتصفِّحات الويب التي تستخدِم حاليًا حساب ماستدون الخاص بك.
     ip: عنوان الإيبي
     platforms:
       adobe_air: أدوبي إيير
@@ -806,39 +864,44 @@ ar:
     revoke_success: تم إبطال الجلسة بنجاح
     title: الجلسات
   settings:
+    account: الحساب
+    account_settings: إعدادات الحساب
+    appearance: المظهر
     authorized_apps: التطبيقات المرخص لها
     back: عودة إلى ماستدون
     delete: حذف الحسابات
     development: التطوير
     edit_profile: تعديل الملف الشخصي
     export: تصدير البيانات
-    followers: المتابِعون المُرَخّصون
-    import: إستيراد
+    featured_tags: الوسوم الشائعة
+    identity_proofs: دلائل الهوية
+    import: استيراد
+    import_and_export: استيراد وتصدير
     migrate: تهجير الحساب
     notifications: الإخطارات
     preferences: التفضيلات
-    settings: الإعدادات
+    profile: الملف الشخصي
+    relationships: المتابِعون والمتابَعون
     two_factor_authentication: المُصادقة بخُطوَتَيْن
-    your_apps: تطبيقاتك
   statuses:
     attached:
-      description: 'مُرفَق : %{attached}'
+      description: 'مُرفَق: %{attached}'
       image:
         few: "%{count} صور"
         many: "%{count} صور"
         one: صورة %{count}
         other: "%{count} صور"
-        two: صور
-        zero: صور
+        two: "%{count} صورة"
+        zero: "%{count} صورة"
       video:
         few: "%{count} فيديوهات"
         many: "%{count} فيديوهات"
         one: فيديو %{count}
         other: "%{count} فيديوهات"
-        two: فيديوهات
-        zero: فيديوهات
+        two: "%{count} فيديوهات"
+        zero: "%{count} فيديوهات"
     boosted_from_html: تم إعادة ترقيته مِن %{acct_link}
-    content_warning: 'تحذير عن المحتوى : %{warning}'
+    content_warning: 'تحذير عن المحتوى: %{warning}'
     disallowed_hashtags:
       few: 'يحتوي على وسوم غير مسموح بها: %{tags}'
       many: 'يحتوي على وسوم غير مسموح بها: %{tags}'
@@ -847,18 +910,20 @@ ar:
       two: 'يحتوي على وسوم غير مسموح بها: %{tags}'
       zero: 'يحتوي على وسوم غير مسموح بها: %{tags}'
     language_detection: اكتشاف اللغة تلقائيا
-    open_in_web: إفتح في الويب
+    open_in_web: افتح في الويب
     over_character_limit: تم تجاوز حد الـ %{max} حرف المسموح بها
     pin_errors:
       limit: لقد بلغت الحد الأقصى للتبويقات المدبسة
       ownership: لا يمكن تدبيس تبويق نشره شخص آخر
       private: لا يمكن تدبيس تبويق لم يُنشر للعامة
       reblog: لا يمكن تثبيت ترقية
+    poll:
+      vote: صوّت
     show_more: أظهر المزيد
     sign_in_to_participate: قم بتسجيل الدخول للمشاركة في هذه المحادثة
-    title: '%{name} : "%{quote}"'
+    title: '%{name}: "%{quote}"'
     visibilities:
-      private: إعرض فقط لمتتبعيك
+      private: اعرض فقط لمتتبعيك
       private_long: إعرضه لمتتبعيك فقط
       public: للعامة
       public_long: يمكن للجميع رؤيته
@@ -871,13 +936,9 @@ ar:
   terms:
     title: شروط الخدمة وسياسة الخصوصية على %{instance}
   themes:
-    contrast: تباين عالٍ
-    default: ماستدون
+    contrast: ماستدون (تباين عالٍ)
+    default: ماستدون (داكن)
     mastodon-light: ماستدون (فاتح)
-  time:
-    formats:
-      default: "%b %d, %Y, %H:%M"
-      month: "%b %Y"
   two_factor_authentication:
     code_hint: قم بإدخال الرمز المُوَلّد عبر تطبيق المصادقة للتأكيد
     description_html: في حال تفعيل <strong>المصادقة بخطوتين </strong>، فتسجيل الدخول يتطلب منك أن يكون بحوزتك هاتفك النقال قصد توليد الرمز الذي سيتم إدخاله.
@@ -885,50 +946,52 @@ ar:
     enable: تفعيل
     enabled: نظام المصادقة بخطوتين مُفعَّل
     enabled_success: تم تفعيل المصادقة بخطوتين بنجاح
-    generate_recovery_codes: توليد رموز الإسترجاع
+    generate_recovery_codes: توليد رموز الاسترجاع
     instructions_html: "<strong>قم بمسح رمز الكيو آر عبر Google Authenticator أو أي تطبيق TOTP على جهازك</strong>. من الآن فصاعدا سوف يقوم ذاك التطبيق بتوليد رموز يجب عليك إدخالها عند تسجيل الدخول."
-    lost_recovery_codes: تُمكّنك رموز الإسترجاع الإحتاطية مِن استرجاع النفاذ إلى حسابك في حالة فقدان جهازك المحمول. إن ضاعت منك هذه الرموز فبإمكانك إعادة توليدها مِن هنا و إبطال الرموز القديمة.
-    manual_instructions: 'في حالة تعذّر مسح رمز الكيو آر أو طُلب منك إدخال يدوي، يُمْكِنك إدخال هذا النص السري على التطبيق :'
-    recovery_codes: النسخ الإحتياطي لرموز الإسترجاع
-    recovery_codes_regenerated: تم إعادة توليد رموز الإسترجاع الإحتياطية بنجاح
+    lost_recovery_codes: تُمكّنك رموز الاسترجاع الاحتياطية مِن استرجاع النفاذ إلى حسابك في حالة فقدان جهازك المحمول. إن ضاعت منك هذه الرموز فبإمكانك إعادة توليدها مِن هنا و إبطال الرموز القديمة.
+    manual_instructions: 'في حالة تعذّر مسح رمز الكيو آر أو طُلب منك إدخال يدوي، يُمْكِنك إدخال هذا النص السري على التطبيق:'
+    recovery_codes: النسخ الاحتياطي لرموز الاسترجاع
+    recovery_codes_regenerated: تم إعادة توليد رموز الاسترجاع الاحتياطية بنجاح
     setup: تنشيط
-    wrong_code: الرمز الذي أدخلته غير صالح ! تحقق من صحة الوقت على الخادم و الجهاز ؟
+    wrong_code: الرمز الذي أدخلته غير صالح! تحقق من صحة الوقت على الخادم و الجهاز؟
   user_mailer:
     backup_ready:
-      explanation: لقد قمت بطلب نسخة كاملة لحسابك على ماستدون. إنها متوفرة الآن للتنزيل !
+      explanation: لقد قمت بطلب نسخة كاملة لحسابك على ماستدون. إنها متوفرة الآن للتنزيل!
       subject: نسخة بيانات حسابك جاهزة للتنزيل
       title: المغادرة بأرشيف الحساب
     warning:
       review_server_policies: مراجعة شروط السيرفر
       subject:
         disable: تم تجميد حسابك %{acct}
+        none: تحذير إلى %{acct}
+        suspend: لقد تم تعليق حسابك %{acct}
       title:
         disable: الحساب مُجمَّد
         none: تحذير
         suspend: الحساب مُعلَّق
     welcome:
       edit_profile_action: تهيئة الملف الشخصي
-      edit_profile_step: يُمكنك·كي تخصيص ملفك الشخصي عن طريق تحميل صورة رمزية ورأسية و بتعديل  إسمك·كي العلني وأكثر. و إن أردت·تي معاينة المتابِعين و المتابعات الجُدد قبيل السماح لهم·ن بمتابَعتك فيمكنك·كي تأمين حسابك·كي.
-      explanation: ها هي بعض النصائح قبل بداية الإستخدام
+      edit_profile_step: يُمكنك·كي تخصيص ملفك الشخصي عن طريق تحميل صورة رمزية ورأسية و بتعديل اسمك·كي العلني وأكثر. و إن أردت·تي معاينة المتابِعين و المتابعات الجُدد قبيل السماح لهم·ن بمتابَعتك فيمكنك·كي تأمين حسابك·كي.
+      explanation: ها هي بعض النصائح قبل بداية الاستخدام
       final_action: اشرَع في النشر
       final_step: |-
-        يمكنك الشروع في النشر في الحين ! حتى و إن لم كنت لا تمتلك متابِعين بعدُ، يمكن للآخرين الإطلاع على منشوراتك الموجهة للجمهور على الخيط المحلي أو إن قمت باستخدام وسوم.
-        إبدأ بتقديم نفسك باستعمال وسم #introductions.
+        يمكنك الشروع في النشر في الحين! حتى و إن لم كنت لا تمتلك متابِعين بعدُ، يمكن للآخرين الإطلاع على منشوراتك الموجهة للجمهور على الخيط العام المحلي أو إن قمت باستخدام وسوم.
+        ابدأ بتقديم نفسك باستعمال وسم #introductions.
       full_handle: عنوانك الكامل
       full_handle_hint: هذا هو ما يجب تقديمه لأصدقائك قصد أن يكون بإمكانهم متابَعتك أو مُراسَلتك حتى و إن كانت حساباتهم على خوادم أخرى.
       review_preferences_action: تعديل التفضيلات
       subject: أهلًا بك على ماستدون
       tip_federated_timeline: الخيط الزمني الفديرالي هو بمثابة شبه نظرة شاملة على شبكة ماستدون. غير أنه لا يشمل إلا على الأشخاص المتابَعين مِن طرف جيرانك و جاراتك، لذا فهذا الخيط لا يعكس كافة الشبكة برُمّتها.
-      tip_following: أنت تتبع تلقائيا مديري و مديرات الخادم. للعثور على أشخاص مميزين أو قد تهمك حساباتهم بإمكانك الإطلاع على الخيوط المحلية و كذا الفدرالية.
-      tip_local_timeline: الخيط الزمني المحلي هو بمثابة نظرة سريعة على الأشخاص المتواجدين على %{instance} يمكن اعتبارهم كجيرانك وجاراتك الأقرب إليك!
+      tip_following: أنت تتبع تلقائيا مديري و مديرات الخادم. للعثور على أشخاص مميزين أو قد تهمك حساباتهم بإمكانك الإطلاع على الخيوط العامة المحلية و كذا الفدرالية.
+      tip_local_timeline: الخيط العام المحلي هو بمثابة نظرة سريعة على الأشخاص المتواجدين على %{instance} يمكن اعتبارهم كجيرانك وجاراتك الأقرب إليك!
       tips: نصائح
-      title: أهلاً بك، %{name} !
+      title: أهلاً بك، %{name}!
   users:
     follow_limit_reached: لا يمكنك متابعة أكثر مِن %{limit} أشخاص
     invalid_email: عنوان البريد الإلكتروني غير صالح
     invalid_otp_token: رمز المصادقة بخطوتين غير صالح
-    otp_lost_help_html: إن فقدتَهُما ، يمكنك الإتصال بـ %{email}
+    otp_lost_help_html: إن فقدتَهُما ، يمكنك الاتصال بـ %{email}
     seamless_external_login: لقد قمت بتسجيل الدخول عبر خدمة خارجية، إنّ إعدادات الكلمة السرية و البريد الإلكتروني غير متوفرة.
-    signed_in_as: 'تم تسجيل دخولك بصفة :'
+    signed_in_as: 'تم تسجيل دخولك بصفة:'
   verification:
     verification: التحقق
diff --git a/config/locales/ast.yml b/config/locales/ast.yml
index 78ad796a00de762fb3d46587924d5d852e875a83..ec545ca5786f965aa5998258571b1b3707c11129 100644
--- a/config/locales/ast.yml
+++ b/config/locales/ast.yml
@@ -4,7 +4,6 @@ ast:
     about_mastodon_html: Mastodon ye una rede social basada en protocolos abiertos y software de códigu llibre. Ye descentralizada, como'l corréu electrónicu.
     about_this: Tocante a
     administered_by: 'Alministráu por:'
-    api: API
     contact: Contautu
     contact_missing: Nun s'afitó
     contact_unavailable: N/D
@@ -12,16 +11,9 @@ ast:
     extended_description_html: |
       <h3>Un llugar bonu pa les regles</h3>
       <p>Entá nun se configuró la descripción estendida.</p>
-    features:
-      humane_approach_title: Una visión más humana
-      not_a_product_body: Mastodon nun ye una rede comercial, nun hai anuncios, nun recueye datos o nun pon muries a xardinos. Nin siquier tien una autoridá central.
-      not_a_product_title: Yes una persona, non un productu
-      real_conversation_title: Fechu pa conversaciones de verdá
-      within_reach_title: Siempres al algame
     hosted_on: Mastodon ta agospiáu en %{domain}
     learn_more: Deprendi más
     source_code: Códigu fonte
-    status_count_after: estaos
     status_count_before: Que crearon
     terms: Términos del serviciu
     user_count_after:
@@ -39,10 +31,6 @@ ast:
     nothing_here: "¡Equí nun hai nada!"
     people_followed_by: Persones a les que sigue %{name}
     people_who_follow: Persones que siguen a %{name}
-    posts:
-      one: Toot
-      other: Toots
-    posts_tab_heading: Toots
     posts_with_replies: Toots y rempuestes
     reserved_username: El nome d'usuariu ta acutáu
     roles:
@@ -50,12 +38,10 @@ ast:
   admin:
     accounts:
       are_you_sure: "¿De xuru?"
-      avatar: Avatar
       by_domain: Dominiu
       domain: Dominiu
       email: Corréu
       followers: Siguidores
-      ip: IP
       location:
         local: Llocal
         title: Allugamientu
@@ -70,7 +56,6 @@ ast:
       statuses: Estaos
       title: Cuentes
       username: Nome d'usuariu
-      web: Web
     action_logs:
       actions:
         create_domain_block: "%{name} bloquió'l dominiu %{target}"
@@ -87,7 +72,6 @@ ast:
       features: Carauterístiques
       hidden_service: Federación con servicios anubríos
       recent_users: Usuarios recientes
-      software: Software
       total_users: usuarios en total
       week_interactions: interaiciones d'esta selmana
       week_users_new: usuarios d'esta selmana
@@ -117,19 +101,14 @@ ast:
       title: Axustes del sitiu
     statuses:
       failed_to_execute: Fallu al executar
-    subscriptions:
-      title: WebSub
     title: Alministración
   admin_mailer:
     new_report:
       body_remote: Daquién dende %{domain} informó de %{target}
-  application_mailer:
-    salutation: "%{name},"
   applications:
     invalid_url: La URL apurrida nun ye válida
     warning: Ten curiáu con estos datos, ¡enxamás nun los compartas con naide!
   auth:
-    agreement_html: Faciendo clic en «Aniciar sesión» aceutes siguir <a href="%{rules_path}"> les regles de la instancia</a> y <a href="%{terms_path}">los nuesos términos del serviciu</a>.
     change_password: Contraseña
     delete_account: Desaniciu de la cuenta
     delete_account_html: Si deseyes desaniciar la to cuenta, pues <a href="%{path}">siguir equí</a>. Va pidísete la confirmación.
@@ -137,11 +116,7 @@ ast:
     login: Aniciar sesión
     migrate_account: Mudase a otra cuenta
     migrate_account_html: Si deseyes redirixir esta cuenta a otra, pues <a href="%{path}"> configuralo equí</a>.
-    providers:
-      cas: CAS
-      saml: SAML
     register: Rexistrase
-    register_elsewhere: Rexistrase n'otru sirvidor
     security: Seguranza
   authorize_follow:
     already_following: Yá tas siguiendo a esta cuenta
@@ -170,6 +145,7 @@ ast:
       content: Falló la verificación de seguranza. ¿Tas bloquiando les cookies?
       title: Falló la verificación de seguranza
     '429': Ficiéronse milenta solicitúes
+    '500': 
   exports:
     archive_takeout:
       date: Data
@@ -177,7 +153,6 @@ ast:
       request: Solicitar l'archivu
       size: Tamañu
     blocks: Xente que bloquiesti
-    csv: CSV
     follows: Xente que sigues
     mutes: Xente que silenciesti
   filters:
@@ -189,10 +164,6 @@ ast:
       title: Peñeres
     new:
       title: Amestar una peñera nueva
-  followers:
-    domain: Dominiu
-    followers_count: Númberu de siguidores
-    purge: Desaniciar de los siguidores
   generic:
     changes_saved_msg: "¡Los cambeos guardáronse con ésitu!"
     save_changes: Guardar cambeos
@@ -235,8 +206,6 @@ ast:
     digest:
       body: Equí hai un resume de los mensaxes que nun viesti dende la última visita'l %{since}
       mention: "%{name} mentóte en:"
-      subject:
-        other: "%{count} avisos nuevos dende la última visita \U0001F418"
     follow:
       body: "¡Agora %{name} ta siguiéndote!"
       title: Siguidor nuevu
@@ -251,16 +220,8 @@ ast:
       body: "%{name} compartió'l to estáu:"
       subject: "%{name} compartió'l to estáu"
       title: Compartición nueva de toot
-  number:
-    human:
-      decimal_units:
-        format: "%n%u"
   pagination:
     next: Siguiente
-  preferences:
-    languages: Llingües
-    publishing: Espublización
-    web: Web
   remote_follow:
     acct: Introduz el nome_usuariu@dominiu dende'l que lo quies facer
     no_account_html: "¿Nun tienes una cuenta? Pues <a href='%{sign_up_path}' target='_blank'>rexistrate equí</a>"
@@ -271,49 +232,20 @@ ast:
   sessions:
     browser: Restolador
     browsers:
-      alipay: Alipay
-      blackberry: Blackberry
-      chrome: Chrome
-      edge: Microsoft Edge
-      electron: Electron
-      firefox: Firefox
       generic: Restolador desconocíu
-      ie: Internet Explorer
-      micro_messenger: MicroMessenger
-      opera: Opera
-      otter: Otter
-      phantom_js: PhantomJS
-      qq: QQ Browser
-      safari: Safari
-      uc_browser: UCBrowser
-      weibo: Weibo
     current_session: Sesión actual
     description: "%{browser} en %{platform}"
-    ip: IP
     platforms:
-      adobe_air: Adobe Air
-      android: Android
-      blackberry: Blackberry
-      chrome_os: ChromeOS
-      firefox_os: Firefox OS
-      ios: iOS
-      linux: Linux
-      mac: Mac
       other: plataforma desconocida
-      windows: Windows
-      windows_mobile: Windows Mobile
-      windows_phone: Windows Phone
     title: Sesiones
   settings:
     authorized_apps: Aplicaciones autorizaes
     back: Volver a Mastodon
     edit_profile: Edición del perfil
     export: Esportación de datos
-    followers: Siguidores autorizaos
     import: Importación
     notifications: Avisos
     preferences: Preferencies
-    settings: Axustes
     two_factor_authentication: Autenticación en dos pasos
   statuses:
     attached:
diff --git a/config/locales/bg.yml b/config/locales/bg.yml
index 4de5b1e22a34866ceb7a2e44094971ed8b4bcaea..e11340542fddec96cdf836bca27db8c8b236d27e 100644
--- a/config/locales/bg.yml
+++ b/config/locales/bg.yml
@@ -3,22 +3,16 @@ bg:
   about:
     about_mastodon_html: Mastodon е <em>безплатен</em> сървър с <em>отворен код</em> за социални мрежи. Като <em>децентрализирана</em> алтернатива на комерсиалните платформи, той позволява избягването на риска от монополизация на твоята комуникация от единични компании. Изберете си сървър, на който се доверявате, и ще можете да контактувате с всички останали. Всеки може да пусне Mastodon и лесно да вземе участие в <em>социалната мрежа</em>.
     about_this: За тази инстанция
-    closed_registrations: В момента регистрациите за тази инстанция са затворени.
     contact: За контакти
-    other_instances: Други инстанции
     source_code: Програмен код
-    status_count_after: публикации
     status_count_before: Написали
-    user_count_after: потребители
     user_count_before: Дом на
   accounts:
     follow: Последвай
-    followers: Последователи
     following: Следва
     nothing_here: Тук няма никого!
     people_followed_by: Хора, които %{name} следва
     people_who_follow: Хора, които следват %{name}
-    posts: Публикации
     unfollow: Не следвай
   application_mailer:
     settings: 'Промяна на предпочитанията за e-mail: %{link}'
@@ -53,15 +47,20 @@ bg:
       x_minutes: "%{count} мин"
       x_months: "%{count} м"
       x_seconds: "%{count} сек"
+  errors:
+    '403': You don't have permission to view this page.
+    '404': The page you are looking for isn't here.
+    '410': The page you were looking for doesn't exist here anymore.
+    '422': 
+    '429': Throttled
+    '500': 
   exports:
     blocks: Вашите блокирания
-    csv: CSV
     follows: Вашите следвания
     storage: Съхранение на мултимедия
   generic:
     changes_saved_msg: Успешно запазване на промените!
     save_changes: Запази промените
-    validation_errors: Нещо все още не е наред! Моля, прегледай грешките по-долу
   imports:
     preface: Можеш да импортираш някои данни, като например всички хора, които следваш или блокираш в акаунта си на тази инстанция, от файлове, създадени чрез експорт в друга инстанция.
     success: Твоите данни бяха успешно качени и ще бъдат обработени впоследствие
@@ -69,6 +68,14 @@ bg:
       blocking: Списък на блокираните
       following: Списък на последователите
     upload: Качване
+  invites:
+    expires_in:
+      '1800': 30 minutes
+      '21600': 6 hours
+      '3600': 1 hour
+      '43200': 12 hours
+      '604800': 1 week
+      '86400': 1 day
   media_attachments:
     validations:
       images_and_video: Не мога да прикача видеоклип към публикация, която вече съдържа изображения
@@ -98,17 +105,6 @@ bg:
     reblog:
       body: 'Твоята публикация беше споделена от %{name}:'
       subject: "%{name} сподели публикацията ти"
-  number:
-    human:
-      decimal_units:
-        format: "%n%u"
-        units:
-          billion: B
-          million: M
-          quadrillion: Q
-          thousand: K
-          trillion: T
-          unit: ''
   pagination:
     next: Напред
     prev: Назад
@@ -124,7 +120,6 @@ bg:
     export: Експортиране на данни
     import: Импортиране
     preferences: Предпочитания
-    settings: Настройки
     two_factor_authentication: Двустепенно удостоверяване
   statuses:
     open_in_web: Отвори в уеб
diff --git a/config/locales/bn.yml b/config/locales/bn.yml
new file mode 100644
index 0000000000000000000000000000000000000000..b3eb0bd624a6874bef540e85eeb401640c4072c1
--- /dev/null
+++ b/config/locales/bn.yml
@@ -0,0 +1,158 @@
+---
+bn:
+  about:
+    about_hashtag_html: এগুলো প্রকাশ্য লেখা যার হ্যাশট্যাগ <strong>#%{hashtag}</strong>। আপনি এগুলোর ব্যবহার বা সাথে যুক্ত হতে পারবেন যদি আপনার যুক্তবিশ্বের কোথাও নিবন্ধন থেকে থাকে।
+    about_mastodon_html: মাস্টাডন উন্মুক্ত ইন্টারনেটজালের নিয়ম এবং স্বাধীন ও মুক্ত উৎসের সফটওয়্যারের ভিত্তিতে তৈরী একটি সামাজিক যোগাযোগ মাধ্যম। এটি ইমেইলের মত বিকেন্দ্রীভূত।
+    about_this: কি
+    active_count_after: চালু
+    active_footnote: মাসিক সক্রিয় ব্যবহারকারী
+    administered_by: 'পরিচালনা করছেন:'
+    api: সফটওয়্যার তৈরীর নিয়ম (API)
+    apps: মোবাইল অ্যাপ
+    apps_platforms: মাস্টাডন আইওএস, এন্ড্রোইড বা অন্য মাধ্যমে ব্যবহার করুন
+    browse_directory: একটি ব্যবহারকারীদের তালিকা দেখুন এবং পছন্দ অনুসারে খুজুন
+    browse_public_posts: মাস্টাডনে নতুন প্রকাশ্য লেখাগুলো সরাসরি দেখুন
+    contact: যোগাযোগ
+    contact_missing: নেই
+    contact_unavailable: প্রযোজ্য নয়
+    discover_users: ব্যবহারকারীদের দেখুন
+    documentation: ব্যবহারবিলি
+    extended_description_html: |
+      <h3>নিয়মের জন্য উপযুক্ত জায়গা</h3>
+      <p>বিস্তারিত বিবরণ এখনো যুক্ত করা হয়নি</p>
+    federation_hint_html: "%{instance}তে একটা নিবন্ধন থাকলে আপনি যেকোনো মাস্টাডন বা এধরণের অন্যান্য সার্ভারের মানুষের সাথে যুক্ত হতে পারবেন ।"
+    generic_description: নেটওয়ার্কের ভেতরে %{domain} একটি সার্ভার
+    get_apps: মোবাইল এপ্প একটা ব্যবহার করতে পারেন
+    hosted_on: এই মাস্টাডনটি আছে %{domain} এ
+    learn_more: বিস্তারিত জানুন
+    privacy_policy: গোপনীয়তা নীতি
+    see_whats_happening: কী কী হচ্ছে দেখুন
+    server_stats: 'সার্ভারের অবস্থা:'
+    source_code: আসল তৈরীপত্র
+    status_count_after:
+      one: অবস্থা
+      other: স্থিতিগুলি
+    status_count_before: কে লিখেছে
+    tagline: পরিচিতজনদের সাথে যুক্ত হন এবং নতুনদের সাথে পরিচিত হন
+    terms: ব্যবহারের শর্তাবলী
+    user_count_after:
+      one: ব্যবহারকারী
+      other: জনের
+    user_count_before: বাসা
+    what_is_mastodon: মাস্টাডনটি কি ?
+  accounts:
+    choices_html: "%{name} বাছাই:"
+    follow: যুক্ত
+    followers:
+      one: যুক্ত আছে
+      other: যারা যুক্ত হয়েছে
+    following: যুক্ত করা
+    joined: যোগদান হয় %{date}
+    last_active: শেষ সক্রিয় ছিল
+    link_verified_on: এই লিংকের মালিকানা শেষ চেক করা হয়  %{date} তারিখে
+    media: ছবি বা ভিডিও
+    moved_html: "%{name} চলে গেছে %{new_profile_link} তে:"
+    network_hidden: এই তথ্যটি নেই
+    nothing_here: এখানে কিছুই নেই!
+    people_followed_by: "%{name} যাদেরকে অনুসরণ করে"
+    people_who_follow: যারা %{name} কে অনুসরণ করে
+    pin_errors:
+      following: সমর্থন করতে অনুসরণ থাকা লাগবে
+    posts:
+      one: লেখা
+      other: লেখাগুলো
+    posts_tab_heading: লেখাগুলো
+    posts_with_replies: লেখা এবং মতামত
+    reserved_username: নামটি সংরক্ষিত
+    roles:
+      admin: পরিচালক
+      bot: রোবট
+      moderator: পরিচালক
+    unavailable: প্রোফাইল অনুপলব্ধ
+    unfollow: অনুসরণ বাদ
+  admin:
+    account_actions:
+      action: করা
+      title: 'প্রশাসনা করুন এর উপর : %{acct}'
+    account_moderation_notes:
+      create: কিছু লিখুন
+      created_msg: প্রশাসনবস্তুত লেখাটি সঠিকভাবে তৈরী হয়েছে!
+      delete: মুছে ফেলা
+      destroyed_msg: প্রশাসনবস্তুত লেখাটি সঠিকভাবে মুছে ফেলা হয়েছে!
+    accounts:
+      approve: অনুমোদন দিন
+      approve_all: প্রত্যেক কে অনুমতি দিন
+      are_you_sure: আপনি কি নিশ্চিত ?
+      avatar: অবতার
+      by_domain: ওয়েবসাইট/কার্যক্ষেত্র
+      change_email:
+        changed_msg: নিবন্ধনের ইমেইল সঠিকভাবে পরিবর্তন হয়েছে!
+        current_email: এখনকার ইমেইল
+        label: ইমেইল পরিবর্তন
+        new_email: নতুন ইমেইল
+        submit: ইমেইল পরিবর্তন
+        title: "%{username} এর ইমেইল পরিবর্তন"
+      confirm: নিশ্চিত করুন
+      confirmed: নিশ্চিত হয়েছে
+      confirming: নিশ্চিত করা হচ্ছে
+      deleted: মুছে ফেলা হয়েছে
+      demote: নিচের পদে দিন
+      disable: বন্ধ করুন
+      disable_two_factor_authentication: দুই পদ্ধতির প্রমাণীকরণ(2FA) বন্ধ করুন
+      disabled: বন্ধ করা হয়েছে
+      display_name: দেখানোর জন্য নাম
+      domain: ওয়েবসাইট/কার্যক্ষেত্র
+      edit: বদলান
+      email: ইমেইল
+      email_status: ইমেইলের অবস্থা
+      enable: চালু করুন
+      enabled: চালু করুন
+      feed_url: সম্মিলিত(feed) লিংক
+      followers: অনুসরকারীরা
+      followers_url: অনুসরণকারীদের লিংক
+      follows: অনুসরণ করে
+      header: শিরোলেখা
+      inbox_url: চিঠি পাওয়ার বক্স লিংক
+      invited_by: আমন্ত্রণ করেছে
+      ip: আইপি(IP)
+      joined: যোগ দিয়েছে
+      location:
+        all: সব
+        local: স্থানীয়
+        remote: দূরবর্তী
+        title: জায়গা
+      login_status: নিবন্ধনধারীভাবে প্রবেশের অবস্থা
+      media_attachments: ছবি/ভিডিও যুক্ত
+      memorialize: স্মরণিকা বানান
+      moderation:
+        active: চালু
+        all: সব
+        pending: অপেক্ষিত আছে
+        silenced: নীরব করা হয়েছে
+        suspended: স্থগিত করা হয়েছে
+        title: প্রশাসনা
+      moderation_notes: প্রশাসনের কিছু লেখা
+      most_recent_activity: সর্বশেষ কার্যক্রম
+      most_recent_ip: সর্বশেষ আইপি(IP)
+      no_limits_imposed: কোন সীমা আরোপ করা নেই
+      not_subscribed: সাবস্ক্রাইব নেই
+      outbox_url: চিঠি পাঠানোর বাক্স লিংক
+      pending: পয্র্যবেক্ষণের অপেক্ষায় আছে
+      perform_full_suspension: বাতিল করা
+  errors:
+    '403': You don't have permission to view this page.
+    '404': The page you are looking for isn't here.
+    '410': The page you were looking for doesn't exist here anymore.
+    '422': 
+    '429': Throttled
+    '500': 
+  invites:
+    expires_in:
+      '1800': 30 minutes
+      '21600': 6 hours
+      '3600': 1 hour
+      '43200': 12 hours
+      '604800': 1 week
+      '86400': 1 day
+  verification:
+    verification: সত্যতা নির্ধারণ
diff --git a/config/locales/ca.yml b/config/locales/ca.yml
index 9b76d184b8fb2ef4c37aa9b942d5da27c20bdbeb..a5d96cc1caa55f6e83f680e01ab29d057a645abc 100644
--- a/config/locales/ca.yml
+++ b/config/locales/ca.yml
@@ -4,36 +4,36 @@ ca:
     about_hashtag_html: Aquests són toots públics etiquetats amb <strong>#%{hashtag}</strong>. Pots interactuar amb ells si tens un compte a qualsevol lloc del fediverse.
     about_mastodon_html: Mastodon és una xarxa social basada en protocols web oberts i en programari lliure i de codi obert. Està descentralitzat com el correu electrònic.
     about_this: Quant a
+    active_count_after: actiu
+    active_footnote: Usuaris actius mensuals (UAM)
     administered_by: 'Administrat per:'
     api: API
-    apps: Apps mòbil
-    closed_registrations: Actualment, el registre està tancat en aquesta instància. Malgrat això! Pots trobar una altra instància per fer-te un compte i obtenir accés a la mateixa xarxa des d'allà.
+    apps: Apps mòbils
+    apps_platforms: Utilitza Mastodon des de iOS, Android i altres plataformes
+    browse_directory: Navega per el directori de perfils i filtra segons interessos
+    browse_public_posts: Navega per una transmissió en directe de publicacions públiques a Mastodon
     contact: Contacte
     contact_missing: No configurat
     contact_unavailable: N/D
+    discover_users: Descobreix usuaris
     documentation: Documentació
     extended_description_html: |
       <h3>Un bon lloc per les regles</h3>
       <p>Encara no s'ha configurat la descripció ampliada.</p>
-    features:
-      humane_approach_body: Aprenent dels errors d'altres xarxes, Mastodon té com a objectiu fer eleccions ètiques de disseny per a combatre el mal ús de les xarxes socials.
-      humane_approach_title: Un enfocament més humà
-      not_a_product_body: Mastodon no és una xarxa comercial. Sense publicitat, sense mineria de dades, sense jardins emmurallats. No hi ha cap autoritat central.
-      not_a_product_title: Ets una persona, no un producte
-      real_conversation_body: Amb 65535 caràcters a la teva disposició i suport per a continguts granulars i avisos multimèdia, pots expressar-te de la manera que vulguis.
-      real_conversation_title: Construït per a converses reals
-      within_reach_body: Diverses aplicacions per a iOS, Android i altres plataformes gràcies a un ecosistema API amable amb el desenvolupador, et permet mantenir-te al dia amb els amics en qualsevol lloc..
-      within_reach_title: Sempre a l'abast
+    federation_hint_html: Amb un compte de %{instance} podràs seguir persones de qualsevol servidor Mastodon i altres.
     generic_description: "%{domain} és un servidor a la xarxa"
+    get_apps: Prova una aplicació mòbil
     hosted_on: Mastodon allotjat a %{domain}
     learn_more: Més informació
-    other_instances: Altres instàncies
     privacy_policy: Política de privacitat
+    see_whats_happening: Mira què està passant
+    server_stats: 'Estadístiques del servidor:'
     source_code: Codi font
     status_count_after:
-      one: estat
-      other: estats
+      one: toot
+      other: toots
     status_count_before: Que han escrit
+    tagline: Segueix els teus amics i descobreix-ne de nous
     terms: Termes del servei
     user_count_after:
       one: usuari
@@ -68,6 +68,7 @@ ca:
       admin: Administrador
       bot: Bot
       moderator: Moderador
+    unavailable: Perfil inaccessible
     unfollow: Deixa de seguir
   admin:
     account_actions:
@@ -79,6 +80,8 @@ ca:
       delete: Suprimeix
       destroyed_msg: Nota de moderació destruïda amb èxit!
     accounts:
+      approve: Aprova
+      approve_all: Aprova'ls tots
       are_you_sure: N'estàs segur?
       avatar: Avatar
       by_domain: Domini
@@ -124,15 +127,18 @@ ca:
       moderation:
         active: Actiu
         all: Tot
+        pending: Pendent
         silenced: Silenciat
         suspended: Suspès
         title: Moderació
       moderation_notes: Notes de moderació
       most_recent_activity: Activitat més recent
       most_recent_ip: IP més recent
+      no_account_selected: No s'han canviat els comptes perque no s'han seleccionat
       no_limits_imposed: Sense límits imposats
       not_subscribed: No subscrit
       outbox_url: URL de la bústia de sortida
+      pending: Revisió pendent
       perform_full_suspension: Suspèn
       profile_url: URL del perfil
       promote: Promociona
@@ -140,12 +146,14 @@ ca:
       public: Públic
       push_subscription_expires: La subscripció PuSH expira
       redownload: Actualitza el perfil
+      reject: Rebutja
+      reject_all: Rebutja'ls tots
       remove_avatar: Eliminar avatar
       remove_header: Treu la capçalera
       resend_confirmation:
-        already_confirmed: Este usuario ya está confirmado
+        already_confirmed: Aquest usuari ja està confirmat
         send: Reenviar el correu electrònic de confirmació
-        success: "¡Correo electrónico de confirmación enviado con éxito!"
+        success: Correu electrònic de confirmació enviat amb èxit!
       reset: Reinicialitza
       reset_password: Restableix la contrasenya
       resubscribe: Torna a subscriure
@@ -166,6 +174,7 @@ ca:
       statuses: Estats
       subscribe: Subscriu
       suspended: Suspès
+      time_in_queue: Esperant en la cua %{time}
       title: Comptes
       unconfirmed_email: Correu electrònic sense confirmar
       undo_silenced: Deixa de silenciar
@@ -201,7 +210,7 @@ ca:
         resolve_report: "%{name} ha resolt l'informe %{target}"
         silence_account: "%{name} ha silenciat el compte de %{target}"
         suspend_account: "%{name} ha suspès el compte de %{target}"
-        unassigned_report: "%{name} ha des-assignat  l'informe %{target}"
+        unassigned_report: "%{name} ha des-assignat l'informe %{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 actualitzat l'emoji %{target}"
@@ -241,6 +250,7 @@ ca:
       feature_profile_directory: Directori de perfils
       feature_registrations: Registres
       feature_relay: Relay de la Federació
+      feature_timeline_preview: Vista previa de línia de temps
       features: Característiques
       hidden_service: Federació amb serveis ocults
       open_reports: informes oberts
@@ -260,6 +270,7 @@ ca:
       created_msg: El bloqueig de domini ara s'està processant
       destroyed_msg: El bloqueig de domini s'ha desfet
       domain: Domini
+      existing_domain_block_html: Ja has imposat uns limits més estrictes a %{name}, l'hauries de <a href="%{unblock_url}">desbloquejar-lo</a> primer.
       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.
@@ -289,7 +300,7 @@ ca:
         undo: Desfés
       undo: Desfés el bloqueig del domini
     email_domain_blocks:
-      add_new: Afegeix
+      add_new: Afegir nou
       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
@@ -302,6 +313,7 @@ ca:
       back_to_account: Tornar al compte
       title: Seguidors de %{acct}
     instances:
+      by_domain: Domini
       delivery_available: El lliurament està disponible
       known_accounts:
         one: "%{count} compte conegut"
@@ -311,10 +323,10 @@ ca:
         limited: Limitades
         title: Moderació
       title: Federació
-      total_blocked_by_us: Bloquejades per nosaltres
-      total_followed_by_them: Seguides per ells
-      total_followed_by_us: Seguides per nosaltres
-      total_reported: Informes sobre elles
+      total_blocked_by_us: Bloquejats per nosaltres
+      total_followed_by_them: Seguits per ells
+      total_followed_by_us: Seguits per nosaltres
+      total_reported: Informes sobre ells
       total_storage: Adjunts multimèdia
     invites:
       deactivate_all: Desactiva-ho tot
@@ -324,6 +336,8 @@ ca:
         expired: Caducat
         title: Filtre
       title: Convida
+    pending_accounts:
+      title: Comptes pendents (%{count})
     relays:
       add_new: Afegiu un nou relay
       delete: Esborra
@@ -331,7 +345,7 @@ ca:
       disable: Inhabilita
       disabled: Desactivat
       enable: Activat
-      enable_hint: Una vegada habilitat, el teu servidor es subscriurà a tots els toots públics d'aquest relay i començarà a enviar-hi tots els toots públics d'aquest servidor.
+      enable_hint: Una vegada habilitat el teu servidor es subscriurà a tots els toots públics d'aquest relay i començarà a enviar-hi tots els toots públics d'aquest servidor.
       enabled: Activat
       inbox_url: URL del Relay
       pending: S'està esperant l'aprovació del relay
@@ -380,20 +394,20 @@ ca:
         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
+        email: Introdueix una adreça de correu electrònic pública
         username: Nom d'usuari del contacte
       custom_css:
         desc_html: Modifica l'aspecte amb CSS carregat a cada pàgina
         title: CSS personalitzat
       hero:
-        desc_html: Es mostra en pàgina frontal. Recomanat 600x100px al menys. Si no es configura es mostrarà el de la instància
+        desc_html: Es mostra en pàgina frontal. Recomanat al menys 600x100px. Si no es configura es mostrarà el del servidor
         title: Imatge d’heroi
       mascot:
         desc_html: Es mostra a diverses pàgines. Es recomana com a mínim 293 × 205px. Si no està configurat, torna a la mascota predeterminada
         title: Imatge de la mascota
       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
+        desc_html: Els noms de domini que aquest servidor ha trobat al fedivers
+        title: Publica la llista de servidors descoberts
       preview_sensitive_media:
         desc_html: Les visualitzacions prèvies d'enllaços d'altres llocs web mostraran una miniatura encara que els mitjans de comunicació estiguin marcats com a sensibles
         title: Mostra els mitjans sensibles a les previsualitzacions d'OpenGraph
@@ -410,9 +424,12 @@ ca:
         min_invite_role:
           disabled: Ningú
           title: Permet les invitacions de
-        open:
-          desc_html: Permet que qualsevol pugui crear un compte
-          title: Registre obert
+      registrations_mode:
+        modes:
+          approved: Es requereix l’aprovació per registrar-se
+          none: Ningú no pot registrar-se
+          open: Qualsevol pot registrar-se
+        title: Mode de registres
       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
@@ -421,20 +438,20 @@ ca:
         title: Mostra insígnia de personal
       site_description:
         desc_html: Paràgraf introductori a la pàgina principal i en etiquetes meta. Pots utilitzar etiquetes HTML, en particular <code>&lt;a&gt;</code> i <code>&lt;em&gt;</code>.
-        title: Descripció de la instància
+        title: Descripció del servidor
       site_description_extended:
-        desc_html: Un bon lloc per al codi de conducta, regles, directrius i altres coses que distingeixen la vostra instància. Pots utilitzar etiquetes HTML
+        desc_html: Un bon lloc per al codi de conducta, regles, directrius i altres coses que distingeixen el teu servidor. Pots utilitzar etiquetes HTML
         title: Descripció ampliada del lloc
       site_short_description:
-        desc_html: Es mostra a la barra lateral i a metaetiquetes. Descriu en un únic paràgraf què és Mastodon i què fa que aquest servidor sigui especial. Si està buit, s'estableix per defecte la descripció de la instància.
-        title: Descripció curta de l’instància
+        desc_html: Es mostra a la barra lateral i a metaetiquetes. Descriu en un únic paràgraf què és Mastodon i què fa que aquest servidor sigui especial. Si està buit, s'estableix per defecte la descripció del servidor.
+        title: Descripció curta del servidor
       site_terms:
         desc_html: Pots escriure la teva pròpia política de privadesa, els termes del servei o d'altres normes legals. Pots utilitzar etiquetes HTML
         title: Termes del servei personalitzats
-      site_title: Nom de la instància
+      site_title: Nom del servidor
       thumbnail:
         desc_html: S'utilitza per obtenir visualitzacions prèvies a través d'OpenGraph i API. Es recomana 1200x630px
-        title: Miniatura de la Instància
+        title: Miniatura del servidor
       timeline_preview:
         desc_html: Mostra la línia de temps pública a la pàgina inicial
         title: Vista prèvia de la línia de temps
@@ -475,10 +492,19 @@ ca:
       edit_preset: Edita l'avís predeterminat
       title: Gestiona les configuracions predefinides dels avisos
   admin_mailer:
+    new_pending_account:
+      body: A continuació trobaràs els detalls del compte nou. Pots aprovar o rebutjar aquest registre.
+      subject: Nou compte per a revisar a %{instance} (%{username})
     new_report:
       body: "%{reporter} ha informat de %{target}"
       body_remote: Algú des de el domini %{domain} ha informat sobre %{target}
       subject: Informe nou per a %{instance} (#%{id})
+  appearance:
+    advanced_web_interface: Interfície web avançada
+    advanced_web_interface_hint: 'Si vols fer ús de tota l''amplada de la teva pantalla, l''interfície web avançada et permet configurar diverses columnes per a veure molta més informació al mateix temps: Inici, notificacions, línia de temps federada i qualsevol número de llistes i etiquetes.'
+    animations_and_accessibility: Animacions i accessibilitat
+    confirmation_dialogs: Diàlegs de confirmació
+    sensitive_content: Contingut sensible
   application_mailer:
     notification_preferences: Canvia les preferències de correu
     salutation: "%{name},"
@@ -495,8 +521,9 @@ ca:
     warning: Aneu amb compte amb aquestes dades. No les compartiu mai amb ningú!
     your_token: El teu identificador d'accés
   auth:
-    agreement_html: Al fer clic en "Registre" acceptes respectar <a href="%{rules_path}">els nostres termes del servei</a> i <a href="%{terms_path}">la nostra política de privadesa</a>.
+    apply_for_account: Demana una invitació
     change_password: Contrasenya
+    checkbox_agreement_html: Estic d'acord amb les <a href="%{rules_path}" target="_blank">normes del servidor</a> i <a href="%{terms_path}" target="_blank"> els termes del servei</a>
     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ó.
@@ -506,18 +533,18 @@ ca:
     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>.
-    or: o
+    migrate_account_html: Si vols redirigir aquest compte a un altre diferent, el pots <a href="%{path}">configurar aquí</a>.
     or_log_in_with: O inicia sessió amb
     providers:
       cas: CAS
       saml: SAML
     register: Registre
-    register_elsewhere: Registra't en un altre servidor
+    registration_closed: "%{instance} no accepta nous membres"
     resend_confirmation: Torna a enviar el correu de confirmació
     reset_password: Restableix la contrasenya
     security: Seguretat
     set_new_password: Estableix una contrasenya nova
+    trouble_logging_in: Problemes per iniciar la sessió?
   authorize_follow:
     already_following: Ja estàs seguint aquest compte
     error: Malauradament, ha ocorregut un error cercant el compte remot
@@ -536,7 +563,7 @@ ca:
       about_x_years: "%{count} anys"
       almost_x_years: "%{count}anys"
       half_a_minute: Ara mateix
-      less_than_x_minutes: "%{count}m"
+      less_than_x_minutes: fa %{count} minuts
       less_than_x_seconds: Ara mateix
       over_x_years: "%{count} anys"
       x_days: "%{count} dies"
@@ -549,7 +576,7 @@ ca:
     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: 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_html: Només és garantida l'eliminació del contingut d'aquest servidor en particular. 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
   directories:
     directory: Directori de perfils
@@ -563,7 +590,7 @@ ca:
       other: "%{count} gent"
   errors:
     '403': No tens permís per a veure aquesta pàgina.
-    '404': La pàgina que estàs cercant no existeix.
+    '404': La pàgina que estàs cercant no és aquí.
     '410': La pàgina que estàs cercant ja no existeix.
     '422':
       content: La verificació de seguretat ha fallat. Tens les galetes blocades?
@@ -573,11 +600,14 @@ ca:
       content: Ho sentim, però alguna cosa ha fallat a la nostra banda.
       title: Aquesta pàgina no es correcta
     noscript_html: Per a utilitzar Mastodon, activa el JavaScript. També pots provar una de les <a href="%{apps_path}"> aplicacions natives</a> de Mastodon per a la vostra plataforma.
+  existing_username_validator:
+    not_found: no s'ha pogut trobar cap usuari local amb aquest nom d'usuari
+    not_found_multiple: no s'ha pogut trobar %{usernames}
   exports:
     archive_takeout:
       date: Data
       download: Descarrega l’arxiu
-      hint_html: Pots sol·licitar un arxiu dels teus <strong>toots i els fitxers multimèdia pujats</strong>. Les dades exportades tindran el format ActivityPub, llegible per qualsevol programari compatible. Pots sol·licitar un arxiu cada 7 dies.
+      hint_html: Pots sol·licitar un arxiu dels teus <strong>toots i dels fitxers multimèdia pujats</strong>. Les dades exportades tindran el format ActivityPub, llegible per qualsevol programari compatible. Pots sol·licitar un arxiu cada 7 dies.
       in_progress: Compilant el teu arxiu...
       request: Sol·licita el teu arxiu
       size: Tamany
@@ -588,6 +618,10 @@ ca:
     lists: Llistes
     mutes: Persones silenciades
     storage: Emmagatzematge
+  featured_tags:
+    add_new: Afegir nova
+    errors:
+      limit: Ja has mostrat la quantitat màxima d'etiquetes
   filters:
     contexts:
       home: Línia de temps Inici
@@ -604,36 +638,52 @@ ca:
       title: Filtres
     new:
       title: Afegir nou filtre
-  followers:
-    domain: Domini
-    explanation_html: Si desitges garantir la privacitat de les teves publicacions, has de ser conscient de qui t'està seguint. <strong> Les publicacions privades es lliuren a totes les instàncies on tens seguidors </strong>. És possible que vulguis revisar-los i eliminar seguidors si no confies en que la teva privacitat sigui respectada pel personal o el programari d'aquestes instàncies.
-    followers_count: Nombre de seguidors
-    lock_link: Bloca el teu compte
-    purge: Elimina dels seguidors
-    success:
-      one: En el procés de bloqueig suau de seguidors d'un domini...
-      other: En el procés de bloqueig suau de seguidors de %{count} dominis...
-    true_privacy_html: Considera que <strong>la autèntica privacitat només es pot aconseguir amb xifratge d'extrem a extrem</strong>.
-    unlocked_warning_html: Tothom pot seguir-te per a veure inmediatament les teves publicacions privades. %{lock_link} per poder revisar i rebutjar seguidors.
-    unlocked_warning_title: El teu compte no està blocat
   footer:
     developers: Desenvolupadors
     more: Més…
     resources: Recursos
   generic:
+    all: Tot
     changes_saved_msg: Els canvis s'han desat correctament!
     copy: Copia
+    order_by: Ordena per
     save_changes: Desa els canvis
     validation_errors:
       one: Alguna cosa no va bé! Si us plau, revisa l'error
       other: Alguna cosa no va bé! Si us plau, revisa %{count} errors més a baix
+  html_validator:
+    invalid_markup: 'conté HTML markup no vàlid: %{error}'
+  identity_proofs:
+    active: Actiu
+    authorize: Sí, autoritza
+    authorize_connection_prompt: Autoritzar aquesta connexió criptogràfica?
+    errors:
+      failed: Ha fallat la connexió criptogràfica. Torna-ho a provar des de %{provider}.
+      keybase:
+        invalid_token: Els tokens de Keybase són hashs de signatures i han de tenir 66 caràcters hexadecimals
+        verification_failed: Keybase no reconeix aquest token com a signatura del usuari de Keybase %{kb_username}. Si us plau prova des de Keybase.
+      wrong_user: No es pot crear una prova per a %{proving} mentre es connectava com a %{current}. Inicia sessió com a %{proving} i prova de nou.
+    explanation_html: Aquí pots connectar criptogràficament les teves altres identitats com ara el teu perfil de Keybase. Això permet que altres persones t'envïin missatges xifrats i confiar en el contingut que els hi envies.
+    i_am_html: Sóc %{username} a %{service}.
+    identity: Identitat
+    inactive: Inactiu
+    publicize_checkbox: 'I tooteja això:'
+    publicize_toot: 'Està provat! Sóc %{username} a %{service}: %{url}'
+    status: Estat de verificació
+    view_proof: Veure la prova
   imports:
-    preface: Pots importar algunes dades, com ara totes les persones que estàs seguint o blocant, en el teu compte en aquesta instància, des de fitxers exportats en una altra instància.
+    modes:
+      merge: Fusionar
+      merge_long: Mantenir els registres existents i afegir-ne de nous
+      overwrite: Sobreescriu
+      overwrite_long: Reemplaça els registres actuals amb els nous
+    preface: Pots importar algunes les dades que has exportat des d'un altre servidor, com ara el llistat de les persones que estàs seguint o bloquejant.
     success: Les dades s'han rebut correctament i es processaran en breu
     types:
       blocking: Llista de blocats
+      domain_blocking: Llistat de dominis bloquejats
       following: Llista de seguits
-      muting: Llista d'apagats
+      muting: Llista de silenciats
     upload: Carregar
   in_memoriam_html: En Memòria.
   invites:
@@ -653,7 +703,7 @@ ca:
       one: 1 ús
       other: "%{count} usos"
     max_uses_prompt: Sense limit
-    prompt: Genera i comparteix enllaços amb altres persones per donar accés a aquesta instància
+    prompt: Genera i comparteix enllaços amb altres persones per donar accés a aquest servidor
     table:
       expires_at: Caduca
       uses: Usos
@@ -716,18 +766,39 @@ ca:
           quadrillion: Q
           thousand: m
           trillion: T
-          unit: " "
   pagination:
     newer: Més recent
     next: Endavant
     older: Més vell
     prev: Enrere
     truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: Ja has votat en aquesta enquesta
+      duplicate_options: conté opcions duplicades
+      duration_too_long: està massa lluny en el futur
+      duration_too_short: és massa aviat
+      expired: L'enquesta ja ha finalitzat
+      over_character_limit: no pot ser superior a %{max} caràcters cadascun
+      too_few_options: ha de tenir més d'una opció
+      too_many_options: no pot contenir més de %{max} opcions
   preferences:
-    languages: Llengues
     other: Altre
-    publishing: Publicació
-    web: Web
+    posting_defaults: Valors predeterminats de publicació
+    public_timelines: Línies de temps públiques
+  relationships:
+    activity: Activitat del compte
+    dormant: Inactiu
+    last_active: Darrer actiu
+    most_recent: Més recent
+    moved: Mogut
+    mutual: Mútua
+    primary: Primari
+    relationship: Relació
+    remove_selected_domains: Elimina tots els seguidors dels dominis seleccionats
+    remove_selected_followers: Elimina els seguidors seleccionats
+    remove_selected_follows: Deixa de seguir als usuaris seleccionats
+    status: Estat del compte
   remote_follow:
     acct: Escriu el teu usuari@domini des del qual vols seguir
     missing_resource: No s'ha pogut trobar la URL de redirecció necessaria per al compte
@@ -795,20 +866,25 @@ ca:
     revoke_success: S'ha revocat la sessió amb èxit
     title: Sessions
   settings:
+    account: Compte
+    account_settings: Ajustos del compte
+    appearance: Aparènça
     authorized_apps: Aplicacions autoritzades
-    back: Torna a l'inici
+    back: Torna a Mastodon
     delete: Eliminació del compte
     development: Desenvolupament
     edit_profile: Editar perfil
-    export: Exportar informació
-    followers: Seguidors autoritzats
+    export: Exportar dades
+    featured_tags: Etiquetes destacades
+    identity_proofs: Proves d'identitat
     import: Importar
+    import_and_export: Importar i exportar
     migrate: Migració del compte
     notifications: Notificacions
     preferences: Preferències
-    settings: Configuració
+    profile: Perfil
+    relationships: Seguits i seguidors
     two_factor_authentication: Autenticació de dos factors
-    your_apps: Les teves aplicacions
   statuses:
     attached:
       description: 'Adjunt: %{attached}'
@@ -828,9 +904,14 @@ ca:
     over_character_limit: Límit de caràcters de %{max} superat
     pin_errors:
       limit: Ja has fixat el màxim nombre de toots
-      ownership: El toot d'algú altre no es pot fixar
+      ownership: No es pot fixar el toot d'algú altre
       private: No es pot fixar el toot no públic
       reblog: No es pot fixar un impuls
+    poll:
+      total_votes:
+        one: "%{count} vot"
+        other: "%{count} vots"
+      vote: Vota
     show_more: Mostrar més
     sign_in_to_participate: Inicia la sessió per participar a la conversa
     title: '%{name}: "%{quote}"'
@@ -847,14 +928,14 @@ ca:
     sensitive_content: Contingut sensible
   terms:
     body_html: |
-      <h2>Privacy Policy</h2>
+      <h2>Política de Privacitat</h2>
       <h3 id="collect">Quina informació recollim?</h3>
 
       <ul>
-        <li><em>Informació bàsica del compte</em>: Si et registres en aquest servidor, se´t pot demanar que introdueixis un nom d'usuari, una adreça de correu electrònic i una contrasenya. També pots introduir informació de perfil addicional, com ara un nom de visualització i una biografia, i carregar una imatge de perfil i de capçalera. El nom d'usuari, el nom de visualització, la biografia, la imatge de perfil i la imatge de capçalera sempre apareixen públicament.</li>
-        <li><em>Publicacions, seguiment i altra informació pública</em>: La llista de persones que segueixes s'enumeren públicament i el mateix passa amb els teus seguidors. Quan envies un missatge, la data i l'hora s'emmagatzemen, així com l'aplicació que va enviar el missatge. Els missatges poden contenir multimèdia, com ara imatges i vídeos. Els toots públics i no llistats estan disponibles públicament. En quan tinguis un toot en el teu perfil, aquest també és informació pública. Les teves entrades es lliuren als teus seguidors que en alguns casos significa que es lliuren a diferents servidors en els quals s'hi emmagatzemen còpies. Quan suprimeixes publicacions, també es lliuraran als teus seguidors. L'acció d'impulsar o marcar com a favorit una publicació sempre és pública.</li>
-        <li><em>Toots directes i per a només seguidors</em>: Totes les publicacions s'emmagatzemen i processen al servidor. Els toots per a només seguidors només es lliuren als teus seguidors i als usuaris que s'esmenten en ells i els toots directes només es lliuren als usuaris esmentats. En alguns casos, significa que es lliuren a diferents servidors i s'hi emmagatzemen còpies. Fem un esforç de bona fe per limitar l'accés a aquestes publicacions només a les persones autoritzades, però és possible que altres servidors no ho facin. Per tant, és important revisar els servidors als quals pertanyen els teus seguidors. Pots canviar la opció de aprovar o rebutjar els nous seguidors manualment a la configuració.  <em>Tingues en compte que els operadors del servidor i qualsevol servidor receptor poden visualitzar aquests missatges</em> i els destinataris poden fer una captura de pantalla, copiar-los o tornar-los a compartir.  <em>No comparteixis cap informació perillosa a Mastodon.</em></li>
-        <li><em>IPs i altres metadades</em>: Quan inicies sessió registrem l'adreça IP en que l'has iniciat, així com el nom de l'aplicació o navegador. Totes les sessions registrades estan disponibles per a la teva revisió i revocació a la configuració. L'última adreça IP utilitzada s'emmagatzema durant un màxim de 12 mesos. També podrem conservar els registres que inclouen l'adreça IP de cada sol·licitud al nostre servidor.</li>
+      <li><em>Informació bàsica del compte</em>: Si et registres en aquest servidor, se´t pot demanar que introdueixis un nom d'usuari, una adreça de correu electrònic i una contrasenya. També pots introduir informació de perfil addicional, com ara un nom de visualització i una biografia, i carregar una imatge de perfil i de capçalera. El nom d'usuari, el nom de visualització, la biografia, la imatge de perfil i la imatge de capçalera sempre apareixen públicament.</li>
+      <li><em>Publicacions, seguiment i altra informació pública</em>: La llista de persones que segueixes s'enumeren públicament i el mateix passa amb els teus seguidors. Quan envies un missatge, la data i l'hora s'emmagatzemen, així com l'aplicació que va enviar el missatge. Els missatges poden contenir multimèdia, com ara imatges i vídeos. Els toots públics i no llistats estan disponibles públicament. En quan tinguis un toot en el teu perfil, aquest també és informació pública. Les teves entrades es lliuren als teus seguidors que en alguns casos significa que es lliuren a diferents servidors en els quals s'hi emmagatzemen còpies. Quan suprimeixes publicacions, també es lliuraran als teus seguidors. L'acció d'impulsar o marcar com a favorit una publicació sempre és pública.</li>
+      <li><em>Toots directes i per a només seguidors</em>: Totes les publicacions s'emmagatzemen i processen al servidor. Els toots per a només seguidors només es lliuren als teus seguidors i als usuaris que s'esmenten en ells i els toots directes només es lliuren als usuaris esmentats. En alguns casos, significa que es lliuren a diferents servidors i s'hi emmagatzemen còpies. Fem un esforç de bona fe per limitar l'accés a aquestes publicacions només a les persones autoritzades, però és possible que altres servidors no ho facin. Per tant, és important revisar els servidors als quals pertanyen els teus seguidors. Pots canviar la opció de aprovar o rebutjar els nous seguidors manualment a la configuració. <em>Tingues en compte que els operadors del servidor i qualsevol servidor receptor poden visualitzar aquests missatges</em> i els destinataris poden fer una captura de pantalla, copiar-los o tornar-los a compartir. <em>No comparteixis cap informació perillosa a Mastodon.</em></li>
+      <li><em>IPs i altres metadades</em>: Quan inicies sessió registrem l'adreça IP en que l'has iniciat, així com el nom de l'aplicació o navegador. Totes les sessions registrades estan disponibles per a la teva revisió i revocació a la configuració. L'última adreça IP utilitzada s'emmagatzema durant un màxim de 12 mesos. També podrem conservar els registres que inclouen l'adreça IP de cada sol·licitud al nostre servidor.</li>
       </ul>
 
       <hr class="spacer" />
@@ -864,9 +945,9 @@ ca:
       <p>Qualsevol de la informació que recopilem de tu es pot utilitzar de la manera següent:</p>
 
       <ul>
-        <li>Per proporcionar la funcionalitat bàsica de Mastodon. Només pots interactuar amb el contingut d'altres persones i publicar el teu propi contingut quan hàgis iniciat la sessió. Per exemple, pots seguir altres persones per veure les publicacions combinades a la teva pròpia línia de temps personalitzada.</li>
-        <li>Per ajudar a la moderació de la comunitat, per exemple comparar la teva adreça IP amb altres conegudes per determinar l'evasió de prohibicions o altres infraccions.</li>
-        <li>L'adreça electrònica que ens proporciones pot utilitzar-se per enviar-te informació, notificacions sobre altres persones que interactuen amb el teu contingut o t'envien missatges, i per respondre a les consultes i / o altres sol·licituds o preguntes.</li>
+      <li>Per proporcionar la funcionalitat bàsica de Mastodon. Només pots interactuar amb el contingut d'altres persones i publicar el teu propi contingut quan hàgis iniciat la sessió. Per exemple, pots seguir altres persones per veure les publicacions combinades a la teva pròpia línia de temps personalitzada.</li>
+      <li>Per ajudar a la moderació de la comunitat, per exemple comparar la teva adreça IP amb altres conegudes per determinar l'evasió de prohibicions o altres infraccions.</li>
+      <li>L'adreça electrònica que ens proporciones pot utilitzar-se per enviar-te informació, notificacions sobre altres persones que interactuen amb el teu contingut o t'envien missatges, i per respondre a les consultes i / o altres sol·licituds o preguntes.</li>
       </ul>
 
       <hr class="spacer" />
@@ -882,8 +963,8 @@ ca:
       <p>Farem un esforç de bona fe per:</p>
 
       <ul>
-        <li>Conservar els registres del servidor que continguin l'adreça IP de totes les sol·licituds que rebi, tenint em compte que aquests registres es mantenen no més de 90 dies.</li>
-        <li>Conservar les adreces IP associades als usuaris registrats no més de 12 mesos.</li>
+      <li>Conservar els registres del servidor que continguin l'adreça IP de totes les sol·licituds que rebi, tenint em compte que aquests registres es mantenen no més de 90 dies.</li>
+      <li>Conservar les adreces IP associades als usuaris registrats no més de 12 mesos.</li>
       </ul>
 
       <p>Pots sol·licitar i descarregar un arxiu del teu contingut incloses les publicacions, els fitxers adjunts multimèdia, la imatge de perfil i la imatge de capçalera.</p>
@@ -924,14 +1005,14 @@ ca:
 
       <p>Si decidim canviar la nostra política de privadesa, publicarem aquests canvis en aquesta pàgina.</p>
 
-      <p> Aquest document és CC-BY-SA. Actualitzat per darrera vegada el 7 de Març del 2018.</p>
+      <p>Aquest document és CC-BY-SA. Actualitzat per darrera vegada el 7 de Març del 2018.</p>
 
       <p>Originalment adaptat des del <a href="https://github.com/discourse/discourse">Discourse privacy policy</a>.</p>
     title: "%{instance} Condicions del servei i política de privadesa"
   themes:
-    contrast: Alt contrast
-    default: Mastodon
-    mastodon-light: Mastodon (clar)
+    contrast: Mastodon (Alt contrast)
+    default: Mastodon (Fosc)
+    mastodon-light: Mastodon (Clar)
   time:
     formats:
       default: "%b %d, %Y, %H:%M"
@@ -976,11 +1057,11 @@ ca:
     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 blocar el teu compte.
-      explanation: Aquests són alguns consells per començar
+      explanation: Aquests són alguns consells per a 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.'
       full_handle: El teu nom d'usuari sencer
-      full_handle_hint: Això és el que has de dir als teus amics perquè puguin enviar-te missatges o seguir-te des d'una altra instància.
+      full_handle_hint: Això és el que has de dir als teus amics perquè puguin enviar-te missatges o seguir-te des d'un altre servidor.
       review_preferences_action: Canviar preferències
       review_preferences_step: Assegura't d'establir les teves preferències, com ara els correus electrònics que vols rebre o el nivell de privadesa per defecte que t'agradaria que tinguin les teves entrades. Si no tens malaltia de moviment, pots optar per habilitar la reproducció automàtica de GIF.
       subject: Benvingut/da a Mastodon
diff --git a/config/locales/co.yml b/config/locales/co.yml
index d27875d91ff1a90f35900337afe23d364316bc48..b3d14fdb538a194969c0b39a2dd5faab9214c729 100644
--- a/config/locales/co.yml
+++ b/config/locales/co.yml
@@ -4,36 +4,36 @@ co:
     about_hashtag_html: Quessi sò statuti pubblichi taggati cù <strong>#%{hashtag}</strong>. Pudete interagisce cù elli sì voi avete un contu in qualche parte di u fediverse.
     about_mastodon_html: Mastodon ghjè una rete suciale custruita incù prutucolli web aperti è lugiziali liberi. Hè decentralizatu cumu l’e-mail.
     about_this: À prupositu
+    active_count_after: attivi
+    active_footnote: Utilizatori Attivi Mensili (UAM)
     administered_by: 'Amministratu da:'
     api: API
     apps: Applicazione per u telefuninu
-    closed_registrations: Pè avà, l’arregistramenti sò chjosi nant’à st’istanza. Mà pudete truvà un’altr’istanza per fà un contu è avè accessu à listessa reta da quallà.
+    apps_platforms: Utilizà Mastodon dapoi à iOS, Android è altre piattaforme
+    browse_directory: Navigà un'annuariu di i prufili è filtra per interessi
+    browse_public_posts: Navigà un flussu di i statuti publichi nant'à Mastodon
     contact: Cuntattu
     contact_missing: Mancante
     contact_unavailable: Micca dispunibule
+    discover_users: Scopre utilizatori
     documentation: Ducumentazione
     extended_description_html: |
       <h3>Una bona piazza per e regule</h3>
       <p>A descrizzione stesa ùn hè micca stata riempiuta.</p>
-    features:
-      humane_approach_body: Mastodon hà amparatu da i sbagli di l’altre rete suciale, è prova à fà scelte di cuncezzione più etiche per luttà contr’à l’abusu di i media suciali.
-      humane_approach_title: Una mentalità più umana
-      not_a_product_body: Mastodon ùn hè micca una rete cummerciale. Micca pubblicità, micca pruspizzione di dati, micca ambienti chjosi, è micca auturità centrale.
-      not_a_product_title: Site una parsona, micca un pruduttu
-      real_conversation_body: Cù 65535 caratteri dispunibuli, diffusione persunalizata di u cuntinutu è avertimenti per media sensibili, pudete cumunicà cum’è voi vulete.
-      real_conversation_title: Fattu per una vera cunversazione
-      within_reach_body: Parechje app per iOS, Android è altre piattaforme, create cù un sistemu d’API accessibile à i prugrammatori, vi permettenu d’avè accessu à i vostri amichi senza prublemi.
-      within_reach_title: Sempre accessibile
+    federation_hint_html: Cù un contu nant'à %{instance} puderete siguità ghjente da tutti i servori Mastodon è ancu più d'altri.
     generic_description: "%{domain} hè un servore di a rete"
+    get_apps: Pruvà un'applicazione di telefuninu
     hosted_on: Mastodon allughjatu nant’à %{domain}
     learn_more: Amparà di più
-    other_instances: Lista di l’istanze
     privacy_policy: Pulitica di vita privata
+    see_whats_happening: Vede cio chì si passa
+    server_stats: 'Statistiche di u servore:'
     source_code: Codice di fonte
     status_count_after:
       one: statutu
       other: statuti
     status_count_before: chì anu pubblicatu
+    tagline: Siguità amichi è scopre ancu di più altri
     terms: Cundizione di u serviziu
     user_count_after:
       one: utilizatore
@@ -68,6 +68,7 @@ co:
       admin: Amministratore
       bot: Bot
       moderator: Muderatore
+    unavailable: Prufile micca dispunibule
     unfollow: Ùn siguità più
   admin:
     account_actions:
@@ -79,6 +80,8 @@ co:
       delete: Toglie
       destroyed_msg: Nota di muderazione sguassata!
     accounts:
+      approve: Appruvà
+      approve_all: Appruvà tuttu
       are_you_sure: Site sicuru·a?
       avatar: Ritrattu di prufile
       by_domain: Duminiu
@@ -124,15 +127,18 @@ co:
       moderation:
         active: Attivu
         all: Tutti
+        pending: In attesa
         silenced: Silenzati
         suspended: Suspesi
         title: Muderazione
       moderation_notes: Note di muderazione
       most_recent_activity: Attività più ricente
       most_recent_ip: IP più ricente
+      no_account_selected: Nisun contu hè statu cambiatu postu ch'ùn c'eranu micca selezziunati
       no_limits_imposed: Nisuna limita imposta
       not_subscribed: Micca abbunatu
       outbox_url: URL di l’outbox
+      pending: In attesa di rivista
       perform_full_suspension: Suspende
       profile_url: URL di u prufile
       promote: Prumove
@@ -140,13 +146,15 @@ co:
       public: Pubblicu
       push_subscription_expires: Spirata di l’abbunamentu PuSH
       redownload: Mette à ghjornu u prufile
+      reject: Righjittà
+      reject_all: Righjittà tutti
       remove_avatar: Toglie l’avatar
       remove_header: Toglie l'intistatura
       resend_confirmation:
         already_confirmed: St’utilizatore hè digià cunfirmatu
         send: Rimandà un’e-mail di cunfirmazione
         success: L’e-mail di cunfirmazione hè statu mandatu!
-      reset: Reset
+      reset: Riinizializà
       reset_password: Riinizializà a chjave d’accessu
       resubscribe: Riabbunassi
       role: Auturizazione
@@ -166,6 +174,7 @@ co:
       statuses: Statuti
       subscribe: Abbunassi
       suspended: Suspesu
+      time_in_queue: 'Attesa in fila: %{time}'
       title: Conti
       unconfirmed_email: E-mail micca cunfirmatu
       undo_silenced: Ùn silenzà più
@@ -241,6 +250,7 @@ co:
       feature_profile_directory: Annuariu di i prufili
       feature_registrations: Arregistramenti
       feature_relay: Ripetitore di federazione
+      feature_timeline_preview: Vista di a linea pubblica
       features: Funziunalità
       hidden_service: Federazione cù servizii piattati
       open_reports: signalamenti aperti
@@ -249,7 +259,7 @@ co:
       single_user_mode: Modu utilizatore unicu
       software: Lugiziale
       space: Usu di u spaziu
-      title: Dashboard
+      title: Quatru di strumenti
       total_users: utilizatori in tutale
       trends: Tindenze
       week_interactions: interazzione sta settimana
@@ -260,6 +270,7 @@ co:
       created_msg: U blucchime di u duminiu hè attivu
       destroyed_msg: U blucchime di u duminiu ùn hè più attivu
       domain: Duminiu
+      existing_domain_block_html: Avete digià impostu limite più strette nant'à %{name}, duvete <a href="%{unblock_url}">sbluccallu</a> primu.
       new:
         create: Creà un blucchime
         hint: U blucchime di duminiu ùn impedirà micca a creazione di conti indè a database, mà metudi di muderazione specifiche saranu applicati.
@@ -283,8 +294,8 @@ co:
           one: Un contu tuccatu indè a database
           other: "%{count} conti tuccati indè a database"
         retroactive:
-          silence: Ùn silenzà più i conti nant’à stu duminiu
-          suspend: Ùn suspende più i conti nant’à stu duminiu
+          silence: Ùn silenzà più i conti affettati di stu duminiu
+          suspend: Ùn suspende più i conti affettati di stu duminiu
         title: Ùn bluccà più u duminiu %{domain}
         undo: Annullà
       undo: Annullà u blucchime di duminiu
@@ -302,6 +313,7 @@ co:
       back_to_account: Rivene à u Contu
       title: Abbunati à %{acct}
     instances:
+      by_domain: Duminiu
       delivery_available: Rimessa dispunibule
       known_accounts:
         one: "%{count} contu cunnisciutu"
@@ -324,6 +336,8 @@ co:
         expired: Spirati
         title: Filtrà
       title: Invitazione
+    pending_accounts:
+      title: Conti in attesa (%{count})
     relays:
       add_new: Aghjustà un ripetitore
       delete: Sguassà
@@ -386,14 +400,14 @@ co:
         desc_html: Mudificà l'apparenza cù CSS caricatu nant'à ogni pagina
         title: CSS persunalizatu
       hero:
-        desc_html: Affissatu nant’a pagina d’accolta. Ricumandemu almenu 600x100px. S’ellu ùn hè micca definiti, a vignetta di l’istanza sarà usata
+        desc_html: Affissatu nant’a pagina d’accolta. Ricumandemu almenu 600x100px. S’ellu ùn hè micca definiti, a vignetta di u servore sarà usata
         title: Ritrattu di cuprendula
       mascot:
         desc_html: Affissata nant'à parechje pagine. Almenu 293x205px ricumandatu. S'ella hè lasciata viota, a mascotta predefinita sarà utilizata
         title: Ritrattu di a mascotta
       peers_api_enabled:
-        desc_html: Indirizzi st’istanza hà vistu indè u fediverse
-        title: Pubblicà a lista d’istanza cunnisciute
+        desc_html: Indirizzi web stu servore hà vistu indè u fediverse
+        title: Pubblicà a lista di servori cunnisciuti
       preview_sensitive_media:
         desc_html: E priviste di i ligami nant'à l'altri siti mustreranu una vignetta ancu s'ellu hè marcatu cum'è sensibile u media
         title: Vede media sensibili in e viste OpenGraph
@@ -410,9 +424,12 @@ co:
         min_invite_role:
           disabled: Nisunu
           title: Auturizà l’invitazione da
-        open:
-          desc_html: Auturizà tuttu u mondu à creà un contu quì
-          title: Apre l’arregistramenti
+      registrations_mode:
+        modes:
+          approved: Apprubazione necessaria per arregistrassi
+          none: Nimu ùn pò arregistrassi
+          open: Tutt'ognunu pò arregistrassi
+        title: Modu d'arregistramenti
       show_known_fediverse_at_about_page:
         desc_html: Quandu ghjè selezziunatu, statuti di tuttu l’istanze cunnisciute saranu affissati indè a vista di e linee. Altrimente soli i statuti lucali saranu mustrati.
         title: Vedde tuttu u fediverse cunnisciutu nant’a vista di e linee
@@ -421,20 +438,20 @@ co:
         title: Mustrà un badge staff
       site_description:
         desc_html: Paragrafu di prisentazione nant’a pagina d’accolta. Parlate di cio chì rende stu servore speziale, o d'altre cose impurtante. Pudete fà usu di marchi HTML, in particulare <code>&lt;a&gt;</code> è <code>&lt;em&gt;</code>.
-        title: Discrizzione di l’istanza
+        title: Discrizzione di u servore
       site_description_extended:
         desc_html: Una bona piazza per e regule, infurmazione è altre cose chì l’utilizatori duverìanu sapè. Pudete fà usu di marchi HTML
         title: Discrizzione stesa di u situ
       site_short_description:
-        desc_html: Mustratu indè a barra laterala è i tag meta. Spiegate quale hè Mastodon è ciò chì rende u vostru servore speciale in un paragrafu. S'ella hè lasciata viota, a discrizzione di l'istanza sarà utilizata.
-        title: Descrizzione corta di l'istanza
+        desc_html: Mustratu indè a barra laterala è i tag meta. Spiegate quale hè Mastodon è ciò chì rende u vostru servore speciale in un paragrafu. S'ella hè lasciata viota, a discrizzione di u servore sarà utilizata.
+        title: Descrizzione corta di u servore
       site_terms:
         desc_html: Quì pudete scrive e vostre regule di cunfidenzialità, cundizione d’usu o altre menzione legale. Pudete fà usu di marchi HTML
         title: Termini persunalizati
-      site_title: Nome di l’istanza
+      site_title: Nome di u servore
       thumbnail:
         desc_html: Utilizatu per viste cù OpenGraph è l’API. Ricumandemu 1200x630px
-        title: Vignetta di l’istanza
+        title: Vignetta di u servore
       timeline_preview:
         desc_html: Vede a linea pubblica nant’a pagina d’accolta
         title: Vista di e linee
@@ -475,10 +492,19 @@ co:
       edit_preset: Cambià a preselezzione d'avertimentu
       title: Amministrà e preselezzione d'avertimentu
   admin_mailer:
+    new_pending_account:
+      body: I ditagli di u novu contu sò quì sottu. Pudete appruvà o righjittà a dumanda.
+      subject: Novu contu in attesa di rivista nant'à %{instance} (%{username})
     new_report:
       body: "%{reporter} hà palisatu %{target}"
       body_remote: Qualch’unu da %{domain} hà palisatu %{target}
       subject: Novu signalamentu nant’à %{instance} (#%{id})
+  appearance:
+    advanced_web_interface: Interfaccia web avanzata
+    advanced_web_interface_hint: 'S''è voi vulete fà usu di a larghezza sana di u vostru screnu, l''interfaccia web avanzata vi permette di cunfigurà parechje culonne sfarente per vede tutta l''infurmazione chì vulete vede in listessu tempu: Accolta, nutificazione, linea pubblica, è tutti l''hashtag è liste chì vulete.'
+    animations_and_accessibility: Animazione è accessibilità
+    confirmation_dialogs: Pop-up di cunfirmazione
+    sensitive_content: Cuntinutu sensibile
   application_mailer:
     notification_preferences: Cambià e priferenze e-mail
     salutation: "%{name},"
@@ -495,8 +521,9 @@ co:
     warning: Abbadate à quessi dati. Ùn i date à nisunu!
     your_token: Rigenerà a fiscia d’accessu
   auth:
-    agreement_html: Cliccà "Arregistrassi" quì sottu vole dì chì site d’accunsentu per siguità <a href="%{rules_path}">e regule di l’istanza</a> è <a href="%{terms_path}">e cundizione d’usu</a>.
+    apply_for_account: Dumandà un'invitazione
     change_password: Chjave d’accessu
+    checkbox_agreement_html: Sò d'accunsentu cù e <a href="%{rules_path}" target="_blank">regule di u servore</a> è i <a href="%{terms_path}" target="_blank">termini di u serviziu</a>
     confirm_email: Cunfirmà l’e-mail
     delete_account: Sguassà u contu
     delete_account_html: S’è voi vulete toglie u vostru contu <a href="%{path}">ghjè quì</a>. Duverete cunfirmà a vostra scelta.
@@ -507,17 +534,17 @@ co:
     logout: Scunnettassi
     migrate_account: Cambià di contu
     migrate_account_html: S’è voi vulete riindirizà stu contu versu un’altru, <a href="%{path}">ghjè pussibule quì</a>.
-    or: o
     or_log_in_with: O cunnettatevi cù
     providers:
       cas: CAS
       saml: SAML
     register: Arregistrassi
-    register_elsewhere: Arregistrassi altrò
+    registration_closed: "%{instance} ùn accetta micca novi socii"
     resend_confirmation: Rimandà l’istruzzioni di cunfirmazione
     reset_password: Cambià a chjave d’accessu
     security: Sicurità
     set_new_password: Creà una nova chjave d’accessu
+    trouble_logging_in: Difficultà per cunnettavi?
   authorize_follow:
     already_following: Site digià abbunatu·a à stu contu
     error: Peccatu, c’hè statu un prublemu ricercandu u contu
@@ -531,17 +558,17 @@ co:
     title: Siguità %{acct}
   datetime:
     distance_in_words:
-      about_x_hours: "%{count}h"
-      about_x_months: "%{count}mo"
-      about_x_years: "%{count}y"
-      almost_x_years: "%{count}y"
+      about_x_hours: "%{count}o"
+      about_x_months: "%{count}Me"
+      about_x_years: "%{count}A"
+      almost_x_years: "%{count}A"
       half_a_minute: Avà
       less_than_x_minutes: "%{count}m"
       less_than_x_seconds: Avà
-      over_x_years: "%{count}y"
-      x_days: "%{count}d"
+      over_x_years: "%{count}A"
+      x_days: "%{count}ghj"
       x_minutes: "%{count}m"
-      x_months: "%{count}mo"
+      x_months: "%{count}Me"
       x_seconds: "%{count}s"
   deletes:
     bad_password_msg: È nò! Sta chjave ùn hè curretta
@@ -549,19 +576,22 @@ co:
     description_html: U contu sarà deattivatu è u cuntenutu sarà sguassatu di manera <strong>permanente è irreversibile</strong>. Ùn sarà micca pussibule piglià stu cugnome torna per evità l’impusture.
     proceed: Sguassà u contu
     success_msg: U vostru contu hè statu sguassatu
-    warning_html: Pudete esse sicuru·a solu chì u cuntenutu sarà sguassatu di st’istanza. S’ellu hè statu spartutu in altrò, sarà forse sempre quallà.
+    warning_html: Pudete esse sicuru·a solu chì u cuntenutu sarà sguassatu di stu servore. S’ellu hè statu spartutu in altrò, sarà forse sempre quallà. I servori scunettati è quelli ch'ùn sò più abbunati à e vostre pubblicazione ùn anu micca da mette à ghjornu e so database.
     warning_title: Dispunibilità di i cuntenuti sparsi
   directories:
     directory: Annuariu di i prufili
+    enabled: Site inscrittu·a indè l'annuariu.
+    enabled_but_waiting: Avete sceltu d'esse inscrittu·a indè l'annuariu, mà ùn avete micca ancu u numeru minimale d'abbunati (%{min_followers}) per esse listatu·a.
     explanation: Scopre utilizatori à partesi di i so centri d'interessu
     explore_mastodon: Scopre à %{title}
+    how_to_enable: Ùn site micca ancu inscrittu·a indè l'annuariu. Pudete inscrive vi quì sottu. Utilizate qualchi hashtag indè a vostra biugrafia per esse listatu·a indè tag specifichi!
     people:
       one: "%{count} persona"
       other: "%{count} persone"
   errors:
     '403': Ùn site micca auturizatu·a à vede sta pagina.
-    '404': Sta pagina ùn esiste micca.
-    '410': Sta pagina ùn esiste più.
+    '404': Sta pagina ùn esiste micca quì.
+    '410': Sta pagina ùn esiste più quì.
     '422':
       content: C’hè statu un prublemu cù a verificazione di sicurità. Forse bluccate cookies?
       title: Fiascu di verificazione
@@ -570,11 +600,14 @@ co:
       content: Scusate, mà c’hè statu un prublemu cù u nostru servore.
       title: Sta pagina ùn hè curretta
     noscript_html: Mastodon nant’à u web hà bisognu di JavaScript per funziunà. Pudete ancu pruvà <a href="%{apps_path}">l’applicazione native</a> per a vostra piattaforma.
+  existing_username_validator:
+    not_found: ùn si pudeva micca truvà un'utilizatore lucale cù stu cugnome
+    not_found_multiple: ùn si pudeva micca truvà %{usernames}
   exports:
     archive_takeout:
       date: Data
       download: Scaricà l’archiviu
-      hint_html: Pudete dumandà un’archiviu di i vostri <strong>statuti è media caricati</strong>. I dati saranu in u furmattu ActivityPub è pudarenu esse letti da tutti i lugiziali chì u supportanu.
+      hint_html: Pudete dumandà un’archiviu di i vostri <strong>statuti è media caricati</strong>. I dati saranu in u furmattu ActivityPub è pudarenu esse letti da tutti i lugiziali chì u supportanu. Pudete richiede un'archiviu ogni 7 ghjorni.
       in_progress: Cumpilazione di l’archiviu...
       request: Dumandà u vostr’archiviu
       size: Pesu
@@ -585,6 +618,10 @@ co:
     lists: Liste
     mutes: Piattate
     storage: I vostri media
+  featured_tags:
+    add_new: Aghjustà novu
+    errors:
+      limit: Avete digià messu in mostra u numeru massimale di hashtag
   filters:
     contexts:
       home: Accolta
@@ -601,34 +638,50 @@ co:
       title: Filtri
     new:
       title: Aghjustà un novu filtru
-  followers:
-    domain: Duminiu
-    explanation_html: Per assicuravi di a cunfidenzialità di i vostri statuti, duvete avè primura di quale vi seguita. <strong>I vostri statuti privati sò mandati à tutte l’istanze induve avete abbunati</strong>. Pensate à u vostru livellu di cunfidenza in i so amministratori.
-    followers_count: Numeru d’abbunati
-    lock_link: Rendete u contu privatu
-    purge: Toglie di a lista d’abbunati
-    success:
-      one: Suppressione di l’abbunati d’un duminiu...
-      other: Suppressione di l’abbunati da %{count} duminii...
-    true_privacy_html: Ùn vi scurdate chì <strong>una vera cunfidenzialità pò solu esse ottenuta cù crittografia da un capu à l’altru</strong>.
-    unlocked_warning_html: Tuttu u mondu pò seguitavi è vede i vostri statuti privati. %{lock_link}  per pudè cunfirmà o righjittà abbunamenti.
-    unlocked_warning_title: U vostru contu hè pubblicu
   footer:
     developers: Sviluppatori
     more: Di più…
     resources: Risorze
   generic:
+    all: Tuttu
     changes_saved_msg: Cambiamenti salvati!
     copy: Cupià
+    order_by: Urdinà da
     save_changes: Salvà e mudificazione
     validation_errors:
       one: Qualcosa ùn và bè! Verificate u prublemu quì sottu
       other: Qualcosa ùn và bè! Verificate %{count} prublemi quì sottu
+  html_validator:
+    invalid_markup: 'cuntene codice HTML invalidu: %{error}'
+  identity_proofs:
+    active: Attiva
+    authorize: Ié, auturizà
+    authorize_connection_prompt: Auturizà sta cunnessione crittograffica?
+    errors:
+      failed: A cunnessione crittograffica s'hè fiascata. Ripruvate da %{provider}.
+      keybase:
+        invalid_token: E fiscie Keybase sò hash di firme è duvenu fà 66 caratteri esadecimali (0-9 A-F)
+        verification_failed: Keybase ùn ricunosce micca sta fiscia cum'una firma di l'utilizatore Keybase %{kb_username}. Ripruvate da Keybase.
+      wrong_user: Ùn si pò micca creà una prova per %{proving} mentre chì site cunnettatu·a cum'è %{current}. Cunnettatevi cum'è %{proving} è ripruvate.
+    explanation_html: Quì pudete cunnettà crittografficamente e vostre altre identità, cum'è per esempiu un prufile Keybase. Quessu permette à d'altre persone di mandà vi missaghji crittati, è d'affiducià i cuntinuti chì mandate.
+    i_am_html: Sò %{username} nant'à %{service}.
+    identity: Identità
+    inactive: Inattiva
+    publicize_checkbox: 'È mandà stu statutu:'
+    publicize_toot: 'Hè pruvata! Sò %{username} nant’à %{service}: %{url}'
+    status: Statutu di a verificazione
+    view_proof: Vede a prova
   imports:
-    preface: Pudete impurtà certi dati cumu e persone chì seguitate o bluccate nant’à u vostru contu nant’à st’istanza à partesi di fugliali creati nant’à un’altr’istanza.
+    modes:
+      merge: Unisce
+      merge_long: Cunservà i dati esistenti è aghjustà i novi
+      overwrite: Soprascrive
+      overwrite_long: Rimpiazzà i dati esistenti cù i novi
+    preface: Pudete impurtà certi dati, cumu e persone chì seguitate o bluccate nant’à u vostru contu, nant’à stu servore à partesi di fugliali creati nant’à un’altru.
     success: I vostri dati sò stati impurtati è saranu trattati da quì à pocu
     types:
       blocking: Persone chì bluccate
+      domain_blocking: Lista di blucchimi di duminiu
       following: Persone chì seguitate
       muting: Persone chì piattate
     upload: Impurtà
@@ -650,7 +703,7 @@ co:
       one: 1 usu
       other: "%{count} usi"
     max_uses_prompt: Micca limita
-    prompt: Create è spartete ligami cù altre parsone per dà accessu à l’istanza
+    prompt: Create è spartete ligami cù altre parsone per dà accessu à u servore
     table:
       expires_at: Spira
       uses: Utiliza
@@ -713,18 +766,39 @@ co:
           quadrillion: P
           thousand: K
           trillion: T
-          unit: ''
   pagination:
     newer: Più ricente
     next: Dopu
     older: Più vechju
     prev: Nanzu
     truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: Avete digià vutatu nant'à stu scandagliu
+      duplicate_options: cuntene uzzione doppie
+      duration_too_long: hè troppu luntanu indè u futuru
+      duration_too_short: hè troppu prossimu
+      expired: U scandagliu hè digià finitu
+      over_character_limit: ùn ponu micca esse più longhi chè %{max} caratteri
+      too_few_options: deve avè più d'un'uzzione
+      too_many_options: ùn pò micca avè più di %{max} uzzione
   preferences:
-    languages: Lingue
     other: Altre
-    publishing: Pubblicazione
-    web: Web
+    posting_defaults: Paramettri predefiniti
+    public_timelines: Linee pubbliche
+  relationships:
+    activity: Attività di u contu
+    dormant: Inattivu
+    last_active: Ultima attività
+    most_recent: Più ricente
+    moved: Spiazzatu
+    mutual: Mutuale
+    primary: Primariu
+    relationship: Rilazione
+    remove_selected_domains: Toglie tutti l'abbunati da i dumini selezziunati
+    remove_selected_followers: Toglie l'abbunati selezziunati
+    remove_selected_follows: Ùn siguità più l'utilizatori selezziunati
+    status: Statutu di u contu
   remote_follow:
     acct: Entrate u vostru cugnome@istanza da induve vulete siguità stu contu
     missing_resource: Ùn avemu pussutu à truvà l’indirizzu di ridirezzione
@@ -792,20 +866,25 @@ co:
     revoke_success: Sessione rivucata
     title: Sessioni
   settings:
+    account: Contu
+    account_settings: Parametri di u contu
+    appearance: Apparenza
     authorized_apps: Applicazione auturizate
     back: Ritornu nant’à Mastodon
     delete: Suppressione di u contu
     development: Sviluppu
     edit_profile: Mudificà u prufile
     export: Spurtazione d’infurmazione
-    followers: Abbunati auturizati
+    featured_tags: Hashtag in vista
+    identity_proofs: Prove d'identità
     import: Impurtazione
+    import_and_export: Impurtazione è spurtazione
     migrate: Migrazione di u contu
     notifications: Nutificazione
     preferences: Priferenze
-    settings: Parametri
+    profile: Prufile
+    relationships: Abbunamenti è abbunati
     two_factor_authentication: Identificazione à dui fattori
-    your_apps: E vostre applicazione
   statuses:
     attached:
       description: 'Aghjuntu: %{attached}'
@@ -828,6 +907,11 @@ co:
       ownership: Pudete puntarulà solu unu di i vostri propii statuti
       private: Ùn pudete micca puntarulà un statutu ch’ùn hè micca pubblicu
       reblog: Ùn pudete micca puntarulà una spartera
+    poll:
+      total_votes:
+        one: "%{count} votu"
+        other: "%{count} voti"
+      vote: Vutà
     show_more: Vede di più
     sign_in_to_participate: Cunnettatevi per participà à a cunversazione
     title: '%{name}: "%{quote}"'
@@ -848,10 +932,10 @@ co:
       <h3 id="collect">Quelles informations collectons-nous ?</h3>
 
       <ul>
-        <li><em>Informations de base sur votre compte</em> : Si vous vous inscrivez sur ce serveur, il vous sera demandé de rentrer un identifiant, une adresse électronique et un mot de passe. Vous pourrez également ajouter des informations additionnelles sur votre profil, telles qu’un nom public et une biographie, ainsi que téléverser une image de profil et une image d’en-tête. Vos identifiant, nom public, biographie, image de profil et image d’en-tête seront toujours affichés publiquement.</li>
+      <li><em>Informations de base sur votre compte</em> : Si vous vous inscrivez sur ce serveur, il vous sera demandé de rentrer un identifiant, une adresse électronique et un mot de passe. Vous pourrez également ajouter des informations additionnelles sur votre profil, telles qu’un nom public et une biographie, ainsi que téléverser une image de profil et une image d’en-tête. Vos identifiant, nom public, biographie, image de profil et image d’en-tête seront toujours affichés publiquement.</li>
       <li><em>Posts, liste d’abonnements et autres informations publiques</em> : La liste de vos abonnements ainsi que la liste de vos abonné·e·s sont publiques. Quand vous postez un message, la date et l’heure d’envoi ainsi que le nom de l’application utilisée pour sa transmission sont enregistré·e·s. Des médias, tels que des images ou des vidéos, peuvent être joints aux messages. Les posts publics et non listés sont affichés publiquement. Quand vous mettez en avant un post sur votre profil, ce post est également affiché publiquement. Vos messages sont délivrés à vos abonné·e·s, ce qui, dans certains cas, signifie qu’ils sont délivrés à des serveurs tiers et que ces derniers en stockent une copie. Quand vous supprimer un post, il est probable que vos abonné·e·s en soient informé·e·s. Partager un message ou le marquer comme favori est toujours une action publique.</li>
-        <li><em>Posts directs et abonné·e·s uniquement</em> : Tous les posts sont stockés et traités par le serveur. Les messages abonné·e·s uniquement ne sont transmis qu’à vos abonné·e·s et aux personnes mentionnées dans le corps du message, tandis que les messages directs ne sont transmis qu’aux personnes mentionnées. Dans certains cas, cela signifie qu’ils sont délivrés à des serveurs tiers et que ces derniers en stockent une copie. Nous faisons un effort de bonne fois pour en limiter l’accès uniquement aux personnes autorisées, mais ce n’est pas nécessairement le cas des autres serveurs. Il est donc très important que vous vérifiiez les serveurs auxquels appartiennent vos abonné·e·s. Il vous est possible d’activer une option dans les paramètres afin d’approuver et de rejeter manuellement les nouveaux·lles abonné·e·s. <em>Gardez s’il-vous-plaît en mémoire que les opérateur·rice·s du serveur ainsi que celles et ceux de n’importe quel serveur récepteur peuvent voir ces messages</em> et qu’il est possible pour les destinataires de faire des captures d’écran, de copier et plus généralement de repartager ces messages. <em>Ne partager aucune information sensible à l’aide de Mastodon.</em></li>
-        <li><em>IP et autres métadonnées</em> : Quand vous vous connectez, nous enregistrons votre adresse IP ainsi que le nom de votre navigateur web. Toutes les sessions enregistrées peuvent être consultées dans les paramètres, afin que vous puissiez les surveiller et éventuellement les révoquer. La dernière adresse IP utilisée est conservée pour une durée de 12 mois. Nous sommes également susceptibles de conserver les journaux du serveur, ce qui inclut l’adresse IP de chaque requête reçue.</li>
+      <li><em>Posts directs et abonné·e·s uniquement</em> : Tous les posts sont stockés et traités par le serveur. Les messages abonné·e·s uniquement ne sont transmis qu’à vos abonné·e·s et aux personnes mentionnées dans le corps du message, tandis que les messages directs ne sont transmis qu’aux personnes mentionnées. Dans certains cas, cela signifie qu’ils sont délivrés à des serveurs tiers et que ces derniers en stockent une copie. Nous faisons un effort de bonne fois pour en limiter l’accès uniquement aux personnes autorisées, mais ce n’est pas nécessairement le cas des autres serveurs. Il est donc très important que vous vérifiiez les serveurs auxquels appartiennent vos abonné·e·s. Il vous est possible d’activer une option dans les paramètres afin d’approuver et de rejeter manuellement les nouveaux·lles abonné·e·s. <em>Gardez s’il-vous-plaît en mémoire que les opérateur·rice·s du serveur ainsi que celles et ceux de n’importe quel serveur récepteur peuvent voir ces messages</em> et qu’il est possible pour les destinataires de faire des captures d’écran, de copier et plus généralement de repartager ces messages. <em>Ne partager aucune information sensible à l’aide de Mastodon.</em></li>
+      <li><em>IP et autres métadonnées</em> : Quand vous vous connectez, nous enregistrons votre adresse IP ainsi que le nom de votre navigateur web. Toutes les sessions enregistrées peuvent être consultées dans les paramètres, afin que vous puissiez les surveiller et éventuellement les révoquer. La dernière adresse IP utilisée est conservée pour une durée de 12 mois. Nous sommes également susceptibles de conserver les journaux du serveur, ce qui inclut l’adresse IP de chaque requête reçue.</li>
       </ul>
 
       <hr class="spacer" />
@@ -861,9 +945,9 @@ co:
       <p>Toutes les informations que nous collectons sur vous peuvent être utilisées d’une des manières suivantes :</p>
 
       <ul>
-        <li>Pour vous fournir les fonctionnalités de base de Mastodon. Vous ne pouvez interagir avec le contenu des autres et poster votre propre contenu que lorsque vous êtes connecté·e. Par exemple, vous pouvez vous abonner à plusieurs autres comptes pour voir l’ensemble de leurs posts dans votre fil d’accueil personnalisé.</li>
-        <li>Pour aider à la modération de la communauté, par exemple, comparer votre adresse IP à d’autres afin de déterminer si un bannissement a été contourné ou si une autre violation aux règles a été commise.</li>
-        <li>L’adresse électronique que vous nous avez fournie peut être utilisée pour vous envoyez des informations, des notifications lorsque d’autres personnes interagissent avec votre contenu ou vous envoient des messages, pour répondre à des demandes de votre part ainsi que pour tout autres requêtes ou questions.</li>
+      <li>Pour vous fournir les fonctionnalités de base de Mastodon. Vous ne pouvez interagir avec le contenu des autres et poster votre propre contenu que lorsque vous êtes connecté·e. Par exemple, vous pouvez vous abonner à plusieurs autres comptes pour voir l’ensemble de leurs posts dans votre fil d’accueil personnalisé.</li>
+      <li>Pour aider à la modération de la communauté, par exemple, comparer votre adresse IP à d’autres afin de déterminer si un bannissement a été contourné ou si une autre violation aux règles a été commise.</li>
+      <li>L’adresse électronique que vous nous avez fournie peut être utilisée pour vous envoyez des informations, des notifications lorsque d’autres personnes interagissent avec votre contenu ou vous envoient des messages, pour répondre à des demandes de votre part ainsi que pour tout autres requêtes ou questions.</li>
       </ul>
 
       <hr class="spacer" />
@@ -879,8 +963,8 @@ co:
       <p>Nous ferons un effort de bonne foi :</p>
 
       <ul>
-        <li>Pour ne pas conserver plus de 90 jours les journaux systèmes contenant les adresses IP de toutes les requêtes reçues par ce serveur.</li>
-        <li>Pour ne pas conserver plus de 12 mois les adresses IP associées aux utilisateur·ice·s enregistré·e·s.</li>
+      <li>Pour ne pas conserver plus de 90 jours les journaux systèmes contenant les adresses IP de toutes les requêtes reçues par ce serveur.</li>
+      <li>Pour ne pas conserver plus de 12 mois les adresses IP associées aux utilisateur·ice·s enregistré·e·s.</li>
       </ul>
 
       <p>Vous pouvez demander une archive de votre contenu, incluant vos posts, vos médias joints, votre image de profil et votre image d’en-tête.</p>
@@ -926,9 +1010,9 @@ co:
       <p>Originellement adapté de la <a href="https://github.com/discourse/discourse">politique de confidentialité de Discourse</a>.</p>
     title: Termini d’usu è di cunfidenzialità per %{instance}
   themes:
-    contrast: Cuntrastu altu
-    default: Mastodon
-    mastodon-light: Mastodon (chjaru)
+    contrast: Mastodon (Cuntrastu altu)
+    default: Mastodon (Scuru)
+    mastodon-light: Mastodon (Chjaru)
   time:
     formats:
       default: "%d %b %Y, %H:%M"
diff --git a/config/locales/cs.yml b/config/locales/cs.yml
index 424ec3dab65fa0a4f14bf76b68506dfb7e34a3ca..0735a86981afa95f6d4bdba9ea7a5f1c91ab653a 100644
--- a/config/locales/cs.yml
+++ b/config/locales/cs.yml
@@ -1,44 +1,46 @@
 ---
 cs:
   about:
-    about_hashtag_html: Tohle jsou veřejné tooty označené hashtagem <strong>#%{hashtag}</strong>. Pokud máte účet kdekoliv na fediverse, můžete s nimi interagovat.
+    about_hashtag_html: Tohle jsou veřejné tooty označené hashtagem <strong>#%{hashtag}</strong>. Pokud máte účet kdekoliv ve fedivesmíru, můžete s nimi interagovat.
     about_mastodon_html: Mastodon je sociální síť založená na otevřených webových protokolech a svobodném, otevřeném softwaru. Je decentralizovaná jako e-mail.
-    about_this: O této instanci
-    administered_by: 'Instanci spravuje:'
+    about_this: O tomto serveru
+    active_count_after: aktivních
+    active_footnote: Měsíční aktivní uživatelé (MAU)
+    administered_by: 'Server spravuje:'
     api: API
     apps: Mobilní aplikace
-    closed_registrations: Registrace na této instanci jsou momentálně uzavřené. Ale pozor! Můžete si najít jinou instanci, vytvořit si na ní účet a získat z ní přístup do naprosto stejné sítě.
+    apps_platforms: Používejte Mastodon z iOS, Androidu a jiných platforem
+    browse_directory: Prozkoumejte adresář profilů a filtrujte dle zájmů
+    browse_public_posts: Prozkoumejte živý proud veřejných příspěvků na Mastodonu
     contact: Kontakt
     contact_missing: Nenastaveno
     contact_unavailable: Neuvedeno
+    discover_users: Objevujte uživatele
     documentation: Dokumentace
     extended_description_html: |
       <h3>Dobré místo pro pravidla</h3>
       <p>Rozšířený popis ještě nebyl nastaven.</p>
-    features:
-      humane_approach_body: Mastodon se učí z chyb jiných sociálních sítí a volením etických rozhodnutí při designu se snaží bojovat s jejich zneužíváním.
-      humane_approach_title: Lidštější přístup
-      not_a_product_body: Mastodon není komerční síť. Žádné reklamy, žádné dolování dat, žádné hranice. Žádná centrální autorita.
-      not_a_product_title: Jste osoba, ne produkt
-      real_conversation_body: S 500 znaky k vaší dispozici a podporou pro varování o obsahu a médiích se můžete vyjadřovat tak, jak chcete.
-      real_conversation_title: Vytvořen pro opravdovou konverzaci
-      within_reach_body: Několik aplikací pro iOS, Android a jiné platformy vám díky jednoduchému API ekosystému dovolují držet krok s vašimi přáteli, ať už jste kdekoliv.
-      within_reach_title: Vždy v dosahu
+    federation_hint_html: S účtem na %{instance} můžete sledovat lidi na jakémkoliv serveru Mastodon a jiných službách.
     generic_description: "%{domain} je jedním ze serverů v síti"
-    hosted_on: Instance Mastodon na adrese %{domain}
+    get_apps: Vyzkoušejte mobilní aplikaci
+    hosted_on: Mastodon na adrese %{domain}
     learn_more: Zjistit více
-    other_instances: Seznam instancí
     privacy_policy: Zásady soukromí
+    see_whats_happening: Podívejte se, co se děje
+    server_stats: 'Statistika serveru:'
     source_code: Zdrojový kód
     status_count_after:
-      few: příspěvky
-      one: příspěvek
-      other: příspěvků
+      few: tooty
+      many: tootů
+      one: toot
+      other: tootů
     status_count_before: Kteří napsali
+    tagline: Sledujte své přátele a objevujte nové
     terms: Podmínky používání
     user_count_after:
-      few: uživatelů
-      one: uživatele
+      few: uživatelé
+      many: uživatelů
+      one: uživatel
       other: uživatelů
     user_count_before: Domov
     what_is_mastodon: Co je Mastodon?
@@ -46,15 +48,16 @@ cs:
     choices_html: 'Volby uživatele %{name}:'
     follow: Sledovat
     followers:
-      few: Sledovatelé
-      one: Sledovatel
-      other: Sledovatelů
+      few: Sledující
+      many: Sledujících
+      one: Sledující
+      other: Sledujících
     following: Sledovaných
     joined: Připojil/a se v %{date}
     last_active: naposledy aktivní
     link_verified_on: Vlastnictví tohoto odkazu bylo zkontrolováno %{date}
     media: Média
-    moved_html: 'Účet %{name} byl přesunut na %{new_profile_link}:'
+    moved_html: "%{name} se přesunul/a na %{new_profile_link}:"
     network_hidden: Tato informace není k dispozici
     nothing_here: Tady nic není!
     people_followed_by: Lidé, které sleduje %{name}
@@ -63,6 +66,7 @@ cs:
       following: Musíte již sledovat osobu, kterou chcete podpořit
     posts:
       few: Tooty
+      many: Tootů
       one: Toot
       other: Tootů
     posts_tab_heading: Tooty
@@ -72,17 +76,20 @@ cs:
       admin: Administrátor
       bot: Robot
       moderator: Moderátor
+    unavailable: Profil nedostupný
     unfollow: Přestat sledovat
   admin:
     account_actions:
       action: Vykonat akci
-      title: Vykonat moderační akci pro účet %{acct}
+      title: Vykonat moderátorskou akci pro účet %{acct}
     account_moderation_notes:
       create: Zanechat poznámku
-      created_msg: Poznámka moderátora byla úspěšně vytvořena!
+      created_msg: Moderátorská poznámka byla úspěšně vytvořena!
       delete: Smazat
-      destroyed_msg: Poznámka moderátora byla úspěšně zničena!
+      destroyed_msg: Moderátorská poznámka byla úspěšně zničena!
     accounts:
+      approve: Schválit
+      approve_all: Schválit vše
       are_you_sure: Jste si jistý/á?
       avatar: Avatar
       by_domain: Doména
@@ -109,16 +116,16 @@ cs:
       enable: Povolit
       enabled: Povoleno
       feed_url: URL proudu
-      followers: Sledovatelé
-      followers_url: URL sledovatelů
+      followers: Sledující
+      followers_url: URL sledujících
       follows: Sledovaní
-      header: Hlavička
-      inbox_url: URL přijatých zpráv
+      header: Záhlaví
+      inbox_url: URL příchozí schránky
       invited_by: Pozván/a uživatelem
-      ip: IP
+      ip: IP adresa
       joined: Připojil/a se
       location:
-        all: Vše
+        all: Všechny
         local: Místní
         remote: Vzdálené
         title: Umístění
@@ -128,15 +135,18 @@ cs:
       moderation:
         active: Aktivní
         all: Vše
+        pending: Čekající
         silenced: Utišen/a
         suspended: Pozastaven/a
-        title: Moderace
-      moderation_notes: Moderační poznámky
+        title: Moderování
+      moderation_notes: Moderátorské poznámky
       most_recent_activity: Nejnovější aktivita
       most_recent_ip: Nejnovější IP
+      no_account_selected: Nebyl změněn žádný účet, neboť žádný nebyl zvolen
       no_limits_imposed: Nejsou nastavena žádná omezení
       not_subscribed: Neodebírá
-      outbox_url: URL odchozích zpráv
+      outbox_url: URL odchozí schránky
+      pending: Čeká na posouzení
       perform_full_suspension: Pozastavit
       profile_url: URL profilu
       promote: Povýšit
@@ -144,32 +154,35 @@ cs:
       public: Veřejný
       push_subscription_expires: Odebírání PuSH expiruje
       redownload: Obnovit profil
+      reject: Zamítnout
+      reject_all: Zamítnout vše
       remove_avatar: Odstranit avatar
-      remove_header: Odstranit hlavičku
+      remove_header: Odstranit záhlaví
       resend_confirmation:
         already_confirmed: Tento uživatel je již potvrzen
         send: Znovu odeslat potvrzovací e-mail
         success: Potvrzovací e-mail byl úspěšně odeslán!
-      reset: Resetovat
+      reset: Obnovit
       reset_password: Obnovit heslo
       resubscribe: Znovu odebírat
       role: Oprávnění
       roles:
         admin: Administrátor
         moderator: Moderátor
-        staff: Personál
+        staff: Člen personálu
         user: Uživatel
       salmon_url: URL Salmon
       search: Hledat
-      shared_inbox_url: URL sdílených přijatých zpráv
+      shared_inbox_url: URL sdílené příchozí schránky
       show:
         created_reports: Vytvořená nahlášení
         targeted_reports: Nahlášeni ostatními
       silence: Utišit
       silenced: Utišen/a
-      statuses: Příspěvky
+      statuses: Tooty
       subscribe: Odebírat
       suspended: Pozastaven/a
+      time_in_queue: Čeká ve frontě %{time}
       title: Účty
       unconfirmed_email: Nepotvrzený e-mail
       undo_silenced: Zrušit utišení
@@ -191,8 +204,8 @@ cs:
         destroy_custom_emoji: "%{name} zničil/a emoji %{target}"
         destroy_domain_block: "%{name} odblokoval/a doménu %{target}"
         destroy_email_domain_block: "%{name} odebral/a e-mailovou doménu %{target} z černé listiny"
-        destroy_status: "%{name} odstranil/a příspěvek uživatele %{target}"
-        disable_2fa_user: "%{name} vypnul/a požadavek pro dvoufaktorovou autentikaci pro uživatele %{target}"
+        destroy_status: "%{name} odstranil/a toot uživatele %{target}"
+        disable_2fa_user: "%{name} vypnul/a dvoufázové ověřování pro uživatele %{target}"
         disable_custom_emoji: "%{name} zakázal/a emoji %{target}"
         disable_user: "%{name} zakázal/a přihlašování pro uživatele %{target}"
         enable_custom_emoji: "%{name} povolil/a emoji %{target}"
@@ -201,7 +214,7 @@ cs:
         promote_user: "%{name} povýšil/a uživatele %{target}"
         remove_avatar_user: "%{name} odstranil/a avatar uživatele %{target}"
         reopen_report: "%{name} znovuotevřel/a nahlášení %{target}"
-        reset_password_user: "%{name} resetoval/a heslo uživatele %{target}"
+        reset_password_user: "%{name} obnovil/a heslo uživatele %{target}"
         resolve_report: "%{name} vyřešil/a nahlášení %{target}"
         silence_account: "%{name} utišil/a účet uživatele %{target}"
         suspend_account: "%{name} pozastavil/a účet uživatele %{target}"
@@ -209,8 +222,8 @@ cs:
         unsilence_account: "%{name} odtišil/a účet uživatele %{target}"
         unsuspend_account: "%{name} zrušil/a pozastavení účtu uživatele %{target}"
         update_custom_emoji: "%{name} aktualizoval/a emoji %{target}"
-        update_status: "%{name} aktualizoval/a příspěvek uživatele %{target}"
-      deleted_status: "(smazaný příspěvek)"
+        update_status: "%{name} aktualizoval/a toot uživatele %{target}"
+      deleted_status: "(smazaný toot)"
       title: Záznam auditu
     custom_emojis:
       by_domain: Doména
@@ -225,15 +238,15 @@ cs:
       emoji: Emoji
       enable: Povolit
       enabled_msg: Emoji bylo úspěšně povoleno
-      image_hint: PNG až do 50KB
-      listed: Uvedené
+      image_hint: PNG až do 50 KB
+      listed: Uvedeno
       new:
         title: Přidat nové vlastní emoji
       overwrite: Přepsat
       shortcode: Zkratka
       shortcode_hint: Alespoň 2 znaky, pouze alfanumerické znaky a podtržítka
       title: Vlastní emoji
-      unlisted: Neuvedené
+      unlisted: Neuvedeno
       update_failed_msg: Nebylo možné aktualizovat toto emoji
       updated_msg: Emoji úspěšně aktualizováno!
       upload: Nahrát
@@ -245,6 +258,7 @@ cs:
       feature_profile_directory: Adresář profilů
       feature_registrations: Registrace
       feature_relay: Federovací most
+      feature_timeline_preview: Náhled časové osy
       features: Vlastnosti
       hidden_service: Federace se skrytými službami
       open_reports: otevřená hlášení
@@ -264,9 +278,10 @@ cs:
       created_msg: Blokace domény se právě vyřizuje
       destroyed_msg: Blokace domény byla zrušena
       domain: Doména
+      existing_domain_block_html: Pro účet %{name} jste již nastavil/a přísnější omezení, musíte jej nejdříve <a href="%{unblock_url}">odblokovat</a>.
       new:
         create: Vytvořit blokaci
-        hint: Blokace domény nezakáže vytváření účtových záznamů v databázi, ale bude na tyto účty zpětně a automaticky aplikovat specifické metody moderace.
+        hint: Blokace domény nezakáže vytváření záznamů účtů v databázi, ale bude na tyto účty zpětně a automaticky aplikovat specifické metody moderování.
         severity:
           desc_html: Funkce <strong>Utišit</strong> zneviditelní příspěvky z účtu komukoliv, kdo jej nesleduje. Funkce <strong>Pozastavit</strong> odstraní všechen obsah, média a profilová data účtu. Pro pouhé odmítnutí mediálních souborů použijte funkci <strong>Žádné</strong>.
           noop: Žádné
@@ -274,22 +289,23 @@ cs:
           suspend: Pozastavit
         title: Nová doménová blokace
       reject_media: Odmítat mediální soubory
-      reject_media_hint: Odstraní lokálně uložené soubory a odmítne jejich stažení v budoucnosti. Nepodstatné pro pozastavení
+      reject_media_hint: Odstraní lokálně uložené mediální soubory a odmítne jejich stahování v budoucnosti. Nepodstatné pro pozastavení
       reject_reports: Odmítat nahlášení
       reject_reports_hint: Ignorovat všechna nahlášení pocházející z této domény. Nepodstatné pro pozastavení
       rejecting_media: odmítají se mediální soubory
       rejecting_reports: odmítají se nahlášení
       severity:
-        silence: utišené
-        suspend: pozastavené
+        silence: utišeno
+        suspend: pozastaveno
       show:
         affected_accounts:
           few: "%{count} účty v databázi byly ovlivněny"
+          many: "%{count} účtů v databázi bylo ovlivněno"
           one: Jeden účet v databázi byl ovlivněn
           other: "%{count} účtů v databázi bylo ovlivněno"
         retroactive:
-          silence: Odtišit všechny existující účty z této domény
-          suspend: Zrušit pozastavení všech existujících účtů z této domény
+          silence: Odtišit existující ovlivněné účty z této domény
+          suspend: Zrušit pozastavení existujících ovlivněných účtů z této domény
         title: Zrušit blokaci domény %{domain}
         undo: Odvolat
       undo: Odvolat blokaci domény
@@ -301,39 +317,43 @@ cs:
       domain: Doména
       new:
         create: Přidat doménu
-        title: Nový e-mail pro zablokování
+        title: Nová položka pro černou listinu e-mailů
       title: Černá listina e-mailů
     followers:
       back_to_account: Zpět na účet
-      title: Sledovatelé uživatele %{acct}
+      title: Sledující uživatele %{acct}
     instances:
+      by_domain: Doména
       delivery_available: Doručení je k dispozici
       known_accounts:
         few: "%{count} známé účty"
+        many: "%{count} známých účtů"
         one: "%{count} známý účet"
         other: "%{count} známých účtů"
       moderation:
-        all: Vše
+        all: Všechny
         limited: Omezené
-        title: Moderace
+        title: Moderování
       title: Federace
       total_blocked_by_us: Blokované námi
-      total_followed_by_them: Sledované jím
+      total_followed_by_them: Sledované jimi
       total_followed_by_us: Sledované námi
-      total_reported: Nahlášení o něm
+      total_reported: Nahlášení o nich
       total_storage: Mediální přílohy
     invites:
       deactivate_all: Deaktivovat vše
       filter:
-        all: Vše
+        all: Všechny
         available: Dostupné
         expired: Vypršelé
         title: Filtrovat
       title: Pozvánky
+    pending_accounts:
+      title: Čekající účty (%{count})
     relays:
       add_new: Přidat nový most
       delete: Smazat
-      description_html: "<strong>Federovací most</strong> je přechodný server, který vyměňuje velká množství veřejných tootů mezi servery, které z něj odebírají a poblikují na něj. <strong>Může pomoci malým a středně velkým serverům objevovat obsah z fediverse</strong>, což by jinak vyžadovalo, aby místní uživatelé manuálně sledovali jiné lidi na vzdálených serverech."
+      description_html: "<strong>Federovací most</strong> je přechodný server, který vyměňuje velká množství veřejných tootů mezi servery, které z něj odebírají a publikují na něj. <strong>Může pomoci malým a středně velkým serverům objevovat obsah z fedivesmíru</strong>, což by jinak vyžadovalo, aby místní uživatelé manuálně sledovali jiné lidi na vzdálených serverech."
       disable: Zakázat
       disabled: Zakázáno
       enable: Povolit
@@ -366,7 +386,7 @@ cs:
         create_and_resolve: Vyřešit s poznámkou
         create_and_unresolve: Znovu otevřít s poznámkou
         delete: Smazat
-        placeholder: Popište, jaké akce byly vykonány, nebo jakékoliv jiné související aktuality...
+        placeholder: Popište, jaké akce byly vykonány, nebo jakékoliv jiné související aktuality…
       reopen: Znovu otevřít nahlášení
       report: 'Nahlásit #%{id}'
       reported_account: Nahlášený účet
@@ -380,26 +400,26 @@ cs:
       updated_at: Aktualizováno
     settings:
       activity_api_enabled:
-        desc_html: Počty lokálně publikovaných příspěvků, aktivních uživatelů a nových registrací, v týdenních intervalech
+        desc_html: Počty lokálně publikovaných tootů, aktivních uživatelů a nových registrací, v týdenních intervalech
         title: Publikovat hromadné statistiky o uživatelské aktivitě
       bootstrap_timeline_accounts:
-        desc_html: Je-li uživatelskch jmen více, oddělujte je čárkami. Lze zadat pouze místní a odemknuté účty. Je-li tohle prázdné, jsou výchozí hodnotou všichni místní administrátoři.
+        desc_html: Je-li uživatelských jmen více, oddělujte je čárkami. Lze zadat pouze místní a odemknuté účty. Je-li tohle prázdné, jsou výchozí hodnotou všichni místní administrátoři.
         title: Výchozí sledovaní pro nové uživatele
       contact_information:
         email: Pracovní e-mail
-        username: Uživatelské jméno kontaktu
+        username: Uživatelské jméno pro kontaktování
       custom_css:
         desc_html: Pozměnit vzhled pomocí šablony CSS načtené na každé stránce
         title: Vlastní CSS
       hero:
-        desc_html: Zobrazuje se na hlavní stránce. Doporučuje se rozlišení alespoň 600x100 px. Pokud toto není nastaveno, bude zobrazena miniatura instance
+        desc_html: Zobrazuje se na hlavní stránce. Doporučuje se rozlišení alespoň 600x100 px. Pokud toto není nastaveno, bude zobrazena miniatura serveru
         title: Hlavní obrázek
       mascot:
         desc_html: Zobrazuje se na hlavní stránce. Doporučuje se rozlišení alespoň 293x205 px. Pokud toto není nastaveno, bude zobrazen výchozí maskot
         title: Obrázek maskota
       peers_api_enabled:
-        desc_html: Domény, na které tato instance narazila ve fediverse
-        title: Zveřejnit seznam objevených instancí
+        desc_html: Domény, na které tento server narazil ve fedivesmíru
+        title: Zveřejnit seznam objevených serverů
       preview_sensitive_media:
         desc_html: Náhledy odkazů na jiných stránkách budou zobrazeny i pokud jsou media označena jako citlivá
         title: Zobrazovat v náhledech OpenGraph i citlivá média
@@ -416,31 +436,34 @@ cs:
         min_invite_role:
           disabled: Nikdo
           title: Povolit pozvánky od
-        open:
-          desc_html: Dovolit každému vytvořit si účet
-          title: Zpřístupnit registraci
+      registrations_mode:
+        modes:
+          approved: Pro registraci je vyžadováno schválení
+          none: Nikdo se nemůže registrovat
+          open: Kdokoliv se může registrovat
+        title: Režim registrací
       show_known_fediverse_at_about_page:
-        desc_html: Je-li toto zapnuto, zobrazí se v náhledu tooty ze všech známých serverů na fediverse. Jinak budou zobrazeny pouze místní tooty.
-        title: Zobrazit celou známou fediverse na náhledu časové osy
+        desc_html: Je-li tohle zapnuto, zobrazí se v náhledu tooty z celého známého fedivesmíru. Jinak budou zobrazeny pouze místní tooty.
+        title: Zobrazit na náhledu časové osy celý známý fedivesmír
       show_staff_badge:
         desc_html: Zobrazit na stránce uživatele odznak člena personálu
         title: Zobrazit odznak personálu
       site_description:
-        desc_html: Úvodní odstavec na hlavní straně. Popište, díky čemu je tento server Mastodon zvláštní, a cokoliv jiného, co je důležité. Můžete zde používat HTML značky, hlavně <code>&lt;a&gt;</code> a <code>&lt;em&gt;</code>.
-        title: Popis instance
+        desc_html: Úvodní odstavec v API. Popište, díky čemu je tento server Mastodon zvláštní, a cokoliv jiného, co je důležité. Můžete zde používat HTML značky, hlavně <code>&lt;a&gt;</code> a <code>&lt;em&gt;</code>.
+        title: Popis serveru
       site_description_extended:
-        desc_html: Dobré místo pro vaše pravidla, pokyny a jiné věci, které vaši instanci odlišují od ostatních. Lze použít HTML značky
-        title: Vlastní doplňující informace
+        desc_html: Dobré místo pro vaše pravidla, pokyny a jiné věci, které váš server odlišují od ostatních. Lze použít HTML značky
+        title: Vlastní rozšířené informace
       site_short_description:
-        desc_html: Zobrazen v postranním panelu a meta značkách. Popište, co je Mastodon a díky čemu je tento server zvláštní v jediném odstavci. Je-li tohle prázdné, zobrazí se popis instance.
-        title: Krátký popis instance
+        desc_html: Zobrazen v postranním panelu a meta značkách. Popište, co je Mastodon a díky čemu je tento server zvláštní v jediném odstavci.
+        title: Krátký popis serveru
       site_terms:
         desc_html: Můžete si napsat vlastní zásady soukromí, podmínky používání či jiné legality. Můžete použít HTML značky
         title: Vlastní podmínky používání
-      site_title: Název instance
+      site_title: Název serveru
       thumbnail:
         desc_html: Používáno pro náhledy přes OpenGraph a API. Doporučuje se rozlišení 1200x630px
-        title: Miniatura instance
+        title: Miniatura serveru
       timeline_preview:
         desc_html: Zobrazit na hlavní straně veřejnou časovou osu
         title: Náhled časové osy
@@ -448,15 +471,15 @@ cs:
     statuses:
       back_to_account: Zpět na stránku účtu
       batch:
-        delete: Vymazat
+        delete: Smazat
         nsfw_off: Označit, že není citlivý
         nsfw_on: Označit jako citlivý
       failed_to_execute: Nepodařilo se vykonat
       media:
         title: Média
       no_media: Žádná média
-      no_status_selected: Nebyly změněny žádné příspěvky, neboť žádné nebyly vybrány
-      title: Příspěvky účtu
+      no_status_selected: Nebyly změněny žádné tooty, neboť žádné nebyly vybrány
+      title: Tooty účtu
       with_media: S médii
     subscriptions:
       callback_url: Zpáteční URL
@@ -478,20 +501,29 @@ cs:
       add_new: Přidat nové
       delete: Smazat
       edit: Upravit
-      edit_preset: Upravit přednastavení pro varování
-      title: Spravovat přednastavení pro varování
+      edit_preset: Upravit předlohu pro varování
+      title: Spravovat předlohy pro varování
   admin_mailer:
+    new_pending_account:
+      body: Detaily nového účtu jsou uvedeny níže. Můžete tento požadavek schválit nebo zamítnout.
+      subject: Nový účet čekající na posouzení na %{instance} (%{username})
     new_report:
       body: "%{reporter} nahlásil/a uživatele %{target}"
       body_remote: Někdo z %{domain} nahlásil uživatele %{target}
       subject: Nové nahlášení pro %{instance} (#%{id})
+  appearance:
+    advanced_web_interface: Pokročilé webové rozhraní
+    advanced_web_interface_hint: 'Chcete-li využít celé šířky vaší obrazovky, dovolí vám pokročilé webové rozhraní nastavit si mnoho různých sloupců, takže můžete vidět ve stejnou chvíli tolik informací, kolik chcete: domovskou časovou osu, oznámení, federovanou časovou osu a libovolný počet seznamů a hashtagů.'
+    animations_and_accessibility: Animace a přístupnost
+    confirmation_dialogs: Potvrzovací dialogy
+    sensitive_content: Citlivý obsah
   application_mailer:
     notification_preferences: Změnit volby e-mailu
     salutation: "%{name},"
     settings: 'Změnit volby e-mailu: %{link}'
     view: 'Zobrazit:'
     view_profile: Zobrazit profil
-    view_status: Zobrazit příspěvek
+    view_status: Zobrazit toot
   applications:
     created: Aplikace úspěšně vytvořena
     destroyed: Aplikace úspěšně smazána
@@ -501,29 +533,30 @@ cs:
     warning: Buďte s těmito daty velmi opatrní. Nikdy je s nikým nesdílejte!
     your_token: Váš přístupový token
   auth:
-    agreement_html: Kliknutím na tlačítko „Registrovat“ souhlasíte s následováním <a href="%{rules_path}">pravidel této instance</a> a <a href="%{terms_path}">našich podmínek používání</a>.
+    apply_for_account: Vyžádat si pozvánku
     change_password: Heslo
+    checkbox_agreement_html: Souhlasím s <a href="%{rules_path}" target="_blank">pravidly serveru</a> a <a href="%{terms_path}" target="_blank">podmínkami používání</a>
     confirm_email: Potvrdit e-mail
     delete_account: Odstranit účet
     delete_account_html: Chcete-li odstranit svůj účet, <a href="%{path}">pokračujte zde</a>. Budete požádán/a o potvrzení.
     didnt_get_confirmation: Neobdržel/a jste pokyny pro potvrzení?
     forgot_password: Zapomněl/a jste heslo?
-    invalid_reset_password_token: Token na obnovu hesla je buď neplatný, nebo vypršel. Prosím vyžádejte si nový.
+    invalid_reset_password_token: Token pro obnovení hesla je buď neplatný, nebo vypršel. Prosím vyžádejte si nový.
     login: Přihlásit
     logout: Odhlásit
     migrate_account: Přesunout se na jiný účet
     migrate_account_html: Chcete-li přesměrovat tento účet na jiný, můžete to <a href="%{path}">nastavit zde</a>.
-    or: nebo
     or_log_in_with: Nebo se přihlaste pomocí
     providers:
       cas: CAS
       saml: SAML
     register: Registrovat
-    register_elsewhere: Registrovat na jiném serveru
+    registration_closed: "%{instance} nepřijímá nové členy"
     resend_confirmation: Znovu odeslat pokyny pro potvrzení
     reset_password: Obnovit heslo
     security: Zabezpečení
     set_new_password: Nastavit nové heslo
+    trouble_logging_in: Problémy s přihlašováním?
   authorize_follow:
     already_following: Tento účet již sledujete
     error: Při hledání vzdáleného účtu bohužel nastala chyba
@@ -555,37 +588,41 @@ cs:
     description_html: Tímto <strong>trvale a nenávratně</strong> odstraníte obsah z vašeho účtu a deaktivujete ho. Vaše uživatelské jméno zůstane rezervované pro zabránění budoucím napodobováním.
     proceed: Odstranit účet
     success_msg: Váš účet byl úspěšně odstraněn
-    warning_html: Pouze vymazání obsahu z této konkrétní instance je zaručeno. Obsah, který byl široce sdílen, po sobě pravděpodobně zanechá stopy. U offline serverů a serverů, které vaše aktualizace již neodebírají, nebudou databáze aktualizovány.
+    warning_html: Pouze vymazání obsahu z tohoto konkrétního serveru je zaručeno. Obsah, který byl široce sdílen, po sobě pravděpodobně zanechá stopy. U offline serverů a serverů, které vaše aktualizace již neodebírají, nebudou databáze aktualizovány.
     warning_title: Dostupnost rozšířeného obsahu
   directories:
     directory: Adresář profilů
     enabled: Aktuálně jste v adresáři uveden/a.
-    enabled_but_waiting: Přihlásil/a jste se k uvedení v adresáři, ale ještě nemáte minimální počet sledovatelů (%{min_followers}) pro uvedení.
+    enabled_but_waiting: Přihlásil/a jste se k uvedení v adresáři, ale ještě nemáte minimální počet sledujících (%{min_followers}) pro uvedení.
     explanation: Objevujte uživatele podle jejich zájmů
     explore_mastodon: Prozkoumejte %{title}
     how_to_enable: Aktuálně nejste přihlášen/a do adresáře. Přihlásit se můžete níže. Použijte ve svém popisu profilu hashtagy, abyste mohl/a být uveden/a pod konkrétními hashtagy!
     people:
       few: "%{count} lidé"
+      many: "%{count} lidí"
       one: "%{count} člověk"
       other: "%{count} lidí"
   errors:
     '403': Nemáte povolení zobrazit tuto stránku.
-    '404': Stránka, kterou hledáte, neexistuje.
-    '410': Stránka, kterou hledáte, již neexistuje.
+    '404': Stránka, kterou hledáte, tu není.
+    '410': Stránka, kterou hledáte, tu již neexistuje.
     '422':
-      content: Bezpečnostní ověření selhalo. Neblokujete cookoes?
+      content: Bezpečnostní ověření selhalo. Neblokujete cookies?
       title: Bezpečnostní ověření selhalo
     '429': Příliš mnoho požadavků
     '500':
-      content: Omlouváme se, ale něco se pokazilo u nás.
+      content: Omlouváme se, ale něco se u nás pokazilo.
       title: Tato stránka není správná
     noscript_html: Pro použití webové aplikace Mastodon prosím povolte JavaScript. Nebo zkuste jednu z <a href="%{apps_path}">nativních aplikací</a> pro Mastodon pro vaši platformu.
+  existing_username_validator:
+    not_found: nelze najít místního uživatele s tímto uživatelským jménem
+    not_found_multiple: nelze najít %{usernames}
   exports:
     archive_takeout:
       date: Datum
       download: Stáhnout svůj archiv
-      hint_html: Můžete si vyžádat archiv vašich <strong>tootů a nahraných médií</strong>. Exportovaná data budou ve formátu ActivityPub a budou čitelné kterýmkoliv kompatibilním softwarem. Archiv si můžete vyžádat každých 7 dní.
-      in_progress: Kompiluji váš archiv...
+      hint_html: Můžete si vyžádat archiv vašich <strong>tootů a nahraných médií</strong>. Exportovaná data budou ve formátu ActivityPub a budou čitelná kterýmkoliv kompatibilním softwarem. Archiv si můžete vyžádat každých 7 dní.
+      in_progress: Kompiluji váš archiv…
       request: Vyžádat svůj archiv
       size: Velikost
     blocks: Blokujete
@@ -593,13 +630,17 @@ cs:
     domain_blocks: Blokace domén
     follows: Sledujete
     lists: Seznamy
-    mutes: Ignorujete
+    mutes: Skryl/a jste
     storage: Paměť médií
+  featured_tags:
+    add_new: Přidat nový
+    errors:
+      limit: Již jste zvýraznil/a maximální počet hashtagů
   filters:
     contexts:
       home: Domovská časová osa
       notifications: Oznámení
-      public: Veřejný časové osy
+      public: Veřejné časové osy
       thread: Konverzace
     edit:
       title: Upravit filtr
@@ -611,36 +652,52 @@ cs:
       title: Filtry
     new:
       title: Přidat nový filtr
-  followers:
-    domain: Doména
-    explanation_html: Chcete-li zaručit soukromí vašich příspěvků, musíte mít na vědomí, kdo vás sleduje. <strong>Vaše soukromé příspěvky jsou doručeny na všechny instance, kde máte sledovatele</strong>. Nejspíš si je budete chtít zkontrolovat a odstranit sledovatele na instancích, jejichž personálu či softwaru nedůvěřujete s respektováním vašeho soukromí.
-    followers_count: Počet sledovatelů
-    lock_link: Zamkněte svůj účet
-    purge: Odstranit ze sledovatelů
-    success:
-      few: V průběhu blokování sledovatelů ze %{count} domén...
-      one: V průběhu blokování sledovatelů z jedné domény...
-      other: V průběhu blokování sledovatelů z %{count} domén...
-    true_privacy_html: Berte prosím na vědomí, že <strong>skutečného soukromí se dá dosáhnout pouze za pomoci end-to-end šifrování</strong>.
-    unlocked_warning_html: Kdokoliv vás může sledovat a okamžitě vidět vaše soukromé příspěvky. %{lock_link}, abyste mohl/a zkontrolovat a odmítnout sledovatele.
-    unlocked_warning_title: Váš účet není zamknutý
   footer:
     developers: Vývojáři
     more: Více…
     resources: Zdroje
   generic:
+    all: Všechny
     changes_saved_msg: Změny byly úspěšně uloženy!
     copy: Kopírovat
+    order_by: Seřadit od
     save_changes: Uložit změny
     validation_errors:
       few: Něco ještě není úplně v pořádku! Prosím zkontrolujte %{count} chyby níže
+      many: Něco ještě není úplně v pořádku! Prosím zkontrolujte %{count} chyb níže
       one: Něco ještě není úplně v pořádku! Prosím zkontrolujte chybu níže
       other: Něco ještě není úplně v pořádku! Prosím zkontrolujte %{count} chyb níže
+  html_validator:
+    invalid_markup: 'obsahuje neplatný HTML kód: %{error}'
+  identity_proofs:
+    active: Aktivní
+    authorize: Ano, autorizovat
+    authorize_connection_prompt: Autorizovat toto kryptografické spojení?
+    errors:
+      failed: Kryptografické spojení selhalo. Prosím zkuste to znovu z %{provider}.
+      keybase:
+        invalid_token: Tokeny Keybase jsou hashe podpisů a musí být 66 znaků dlouhé
+        verification_failed: Keybase nerozpoznává tento token jako podpis uživatele %{kb_username} na Keybase. Prosím zkuste to znovu z Keybase.
+      wrong_user: Nelze vytvořit důkaz pro uživatele %{proving}, zatímco jste přihlášen/a jako %{current}. Přihlaste se jako %{proving} a zkuste to znovu.
+    explanation_html: Zde můžete kryptograficky připojit vaše ostatní identity, například profil Keybase. To dovolí jiným lidem vám posílat šifrované zprávy a důvěřovat obsahu, který jim pošlete.
+    i_am_html: Na %{service} jsem %{username}.
+    identity: Identita
+    inactive: Neaktivní
+    publicize_checkbox: 'A tootnout tohle:'
+    publicize_toot: 'Je to dokázáno! Na %{service} jsem %{username}: %{url}'
+    status: Stav ověření
+    view_proof: Zobrazit důkaz
   imports:
-    preface: Můžete importovat data, která jste exportoval/a z jiné instance, jako například seznam lidí, které sledujete či blokujete.
+    modes:
+      merge: Sloučit
+      merge_long: Ponechat existující záznamy a přidat nové
+      overwrite: Přepsat
+      overwrite_long: Nahradit aktuální záznamy novými
+    preface: Můžete importovat data, která jste exportoval/a z jiného serveru, jako například seznam lidí, které sledujete či blokujete.
     success: Vaše data byla úspěšně nahrána a nyní budou zpracována v daný čas
     types:
       blocking: Seznam blokovaných
+      domain_blocking: Seznam blokovaných domén
       following: Seznam sledovaných
       muting: Seznam ignorovaných
     upload: Nahrát
@@ -651,7 +708,7 @@ cs:
     expires_in:
       '1800': 30 minut
       '21600': 6 hodin
-      '3600': 1 hodina
+      '3600': 1 hodinu
       '43200': 12 hodin
       '604800': 1 týden
       '86400': 1 den
@@ -660,54 +717,57 @@ cs:
     invited_by: 'Byl/a jste pozván/a uživatelem:'
     max_uses:
       few: "%{count} použití"
+      many: "%{count} použití"
       one: 1 použití
       other: "%{count} použití"
     max_uses_prompt: Bez limitu
-    prompt: Vygenerujte a sdílejte s ostatními odkazy a umožněte jim přístup na tuto instanci
+    prompt: Vygenerujte a sdílejte s ostatními odkazy a umožněte jim přístup na tento server
     table:
       expires_at: Vyprší
       uses: Použití
-    title: Pozvěte lidi
+    title: Pozvat lidi
   lists:
     errors:
       limit: Dosáhl/a jste maximálního počtu seznamů
   media_attachments:
     validations:
-      images_and_video: K příspěvku, který již obsahuje obrázky, nelze připojit video
+      images_and_video: K tootu, který již obsahuje obrázky, nelze připojit video
       too_many: Nelze připojit více než 4 soubory
   migrations:
     acct: přezdívka@doména nového účtu
     currently_redirecting: 'Váš profil má nastaveno přesměrování na:'
     proceed: Uložit
-    updated_msg: Vaše nastavení migrace účtu bylo úspěšně aktualizováno!
+    updated_msg: Vaše nastavení přesunutí účtu bylo úspěšně aktualizováno!
   moderation:
-    title: Moderace
+    title: Moderování
   notification_mailer:
     digest:
       action: Zobrazit všechna oznámení
       body: Zde najdete stručný souhrn zpráv, které jste zmeškal/a od vaší poslední návštěvy %{since}
       mention: "%{name} vás zmínil/a v:"
       new_followers_summary:
-        few: Navíc jste získal/a %{count} nové sledovatele, zatímco jste byl/a pryč! Skvělé!
-        one: Navíc jste získal/a jednoho nového sledovatele, zatímco jste byl/a pryč! Hurá!
-        other: Navíc jste získal/a %{count} nových sledovatelů, zatímco jste byl/a pryč! Úžasné!
+        few: Navíc jste získal/a %{count} nové sledující, zatímco jste byl/a pryč! Skvělé!
+        many: Navíc jste získal/a %{count} nových sledujících, zatímco jste byl/a pryč! Úžasné!
+        one: Navíc jste získal/a jednoho nového sledujícího, zatímco jste byl/a pryč! Hurá!
+        other: Navíc jste získal/a %{count} nových sledujících, zatímco jste byl/a pryč! Úžasné!
       subject:
         few: "%{count} nová oznámení od vaší poslední návštěvy \U0001F418"
+        many: "%{count} nových oznámení od vaší poslední návštěvy \U0001F418"
         one: "1 nové oznámení od vaší poslední návštěvy \U0001F418"
         other: "%{count} nových oznámení od vaší poslední návštěvy \U0001F418"
-      title: Ve vaší nepřítomnosti...
+      title: Ve vaší nepřítomnosti…
     favourite:
-      body: 'Váš příspěvek si oblíbil/a %{name}:'
-      subject: "%{name} si oblíbil/a váš příspěvek"
+      body: 'Váš toot si oblíbil/a %{name}:'
+      subject: "%{name} si oblíbil/a váš toot"
       title: Nové oblíbení
     follow:
       body: "%{name} vás nyní sleduje!"
       subject: "%{name} vás nyní sleduje"
-      title: Nový sledovatel
+      title: Nový sledující
     follow_request:
       action: Spravovat požadavky o sledování
       body: "%{name} požádal/a o povolení vás sledovat"
-      subject: 'Čekající sledovatel: %{name}'
+      subject: 'Čekající sledující: %{name}'
       title: Nový požadavek o sledování
     mention:
       action: Odpovědět
@@ -715,9 +775,9 @@ cs:
       subject: Byl/a jste zmíněn/a uživatelem %{name}
       title: Nová zmínka
     reblog:
-      body: 'Váš příspěvek byl boostnutý uživatelem %{name}:'
-      subject: "%{name} boostnul/a váš příspěvek"
-      title: Nové boostnutí
+      body: 'Váš toot byl boostnutý uživatelem %{name}:'
+      subject: "%{name} boostnul/a váš toot"
+      title: Nový boost
   number:
     human:
       decimal_units:
@@ -734,11 +794,33 @@ cs:
     older: Starší
     prev: Před
     truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: V této anketě jste již hlasoval/a
+      duplicate_options: obsahuje duplicitní položky
+      duration_too_long: je příliš daleko v budoucnosti
+      duration_too_short: je příliš brzy
+      expired: Anketa již skončila
+      over_character_limit: nesmí být každá delší než %{max} znaků
+      too_few_options: musí mít více než jednu položku
+      too_many_options: nesmí obsahovat více než %{max} položky
   preferences:
-    languages: Jazyky
     other: Ostatní
-    publishing: Publikování
-    web: Web
+    posting_defaults: Výchozí možnosti psaní
+    public_timelines: Veřejné časové osy
+  relationships:
+    activity: Aktivita účtu
+    dormant: Nečinné
+    last_active: Naposledy aktivních
+    most_recent: Naposledy přidaných
+    moved: Přesunuté
+    mutual: Vzájemné
+    primary: Primární
+    relationship: Vztah
+    remove_selected_domains: Odstranit všechny sledující ze zvolených domén
+    remove_selected_followers: Odstranit zvolené sledující
+    remove_selected_follows: Přestat sledovat zvolené uživatele
+    status: Stav účtu
   remote_follow:
     acct: Napište svou přezdívku@doménu, ze které chcete jednat
     missing_resource: Nemůžeme najít požadované přesměrovací URL pro váš účet
@@ -787,17 +869,17 @@ cs:
       weibo: Weibo
     current_session: Aktuální relace
     description: "%{browser} na %{platform}"
-    explanation: Toto jsou webové prohlížeče aktuálně přihlášené na váš účet Mastodon.
-    ip: IP
+    explanation: Tohle jsou webové prohlížeče aktuálně přihlášené na váš účet Mastodon.
+    ip: IP adresa
     platforms:
       adobe_air: Adobe Air
-      android: Android
+      android: Androidu
       blackberry: Blackberry
       chrome_os: Chrome OS
       firefox_os: Firefox OS
       ios: iOS
-      linux: Linux
-      mac: Mac
+      linux: Linuxu
+      mac: Macu
       other: neznámé platformě
       windows: Windows
       windows_mobile: Windows Mobile
@@ -806,35 +888,43 @@ cs:
     revoke_success: Relace úspěšně zamítnuta
     title: Relace
   settings:
+    account: Účet
+    account_settings: Nastavení účtu
+    appearance: Vzhled
     authorized_apps: Autorizované aplikace
     back: Zpět na Mastodon
     delete: Smazání účtu
     development: Vývoj
     edit_profile: Upravit profil
     export: Export dat
-    followers: Autorizovaní sledovatelé
+    featured_tags: Zvýrazněné hashtagy
+    identity_proofs: Důkazy identity
     import: Import
+    import_and_export: Import a export
     migrate: Přesunutí účtu
     notifications: Oznámení
     preferences: Předvolby
-    settings: Nastavení
-    two_factor_authentication: Dvoufaktorové ověřování
-    your_apps: Vaše aplikace
+    profile: Profil
+    relationships: Sledovaní a sledující
+    two_factor_authentication: Dvoufázové ověřování
   statuses:
     attached:
       description: 'Přiloženo: %{attached}'
       image:
         few: "%{count} obrázky"
+        many: "%{count} obrázků"
         one: "%{count} obrázek"
         other: "%{count} obrázků"
       video:
         few: "%{count} videa"
+        many: "%{count} videí"
         one: "%{count} video"
         other: "%{count} videí"
     boosted_from_html: Boostnuto z %{acct_link}
     content_warning: 'Varování o obsahu: %{warning}'
     disallowed_hashtags:
       few: 'obsahoval nepovolené hashtagy: %{tags}'
+      many: 'obsahoval nepovolené hashtagy: %{tags}'
       one: 'obsahoval nepovolený hashtag: %{tags}'
       other: 'obsahoval nepovolené hashtagy: %{tags}'
     language_detection: Zjistit jazyk automaticky
@@ -844,17 +934,24 @@ cs:
       limit: Už jste si připnul/a maximální počet tootů
       ownership: Nelze připnout toot někoho jiného
       private: Nelze připnout neveřejné tooty
-      reblog: Nelze připnout boostnutí
+      reblog: Nelze připnout boost
+    poll:
+      total_votes:
+        few: "%{count} hlasy"
+        many: "%{count} hlasů"
+        one: "%{count} hlas"
+        other: "%{count} hlasů"
+      vote: Hlasovat
     show_more: Zobrazit více
     sign_in_to_participate: Chcete-li se účastnit této konverzace, přihlaste se
     title: "%{name}: „%{quote}“"
     visibilities:
-      private: Pouze pro sledovatele
-      private_long: Zobrazit pouze sledovatelům
+      private: Pouze pro sledující
+      private_long: Zobrazit pouze sledujícím
       public: Veřejné
       public_long: Všichni mohou vidět
       unlisted: Neuvedené
-      unlisted_long: Všichni mohou vidět, ale není zahrnut ve veřejných časových osách
+      unlisted_long: Všichni mohou vidět, ale nebudou zahrnuty ve veřejných časových osách
   stream_entries:
     pinned: Připnutý toot
     reblogged: boostnul/a
@@ -865,10 +962,10 @@ cs:
       <h3 id="collect">Jaké informace sbíráme?</h3>
 
       <ul>
-        <li><em>Základní informace o účtu</em>: Pokud se na tomto serveru zaregistrujete, můžeme vás požádat o zadání uživatelského jména, e-mailové adresy a hesla. Můžete také zadat dodatečné profilové informace, jako například zobrazované jméno a krátký životopis, a nahrát si profilovou fotografii a hlavičkový obrázek. Uživatelské i zobrazované jméno, životopis, profilová fotografie a hlavičkový obrázek jsou vždy uvedeny veřejně.</li>
-        <li><em>Příspěvky, sledovatelé a další veřejné informace</em>: Seznam lidí, které sledujete, je uveden veřejně, totéž platí i pro vaše sledovatele. Když sem nahrajete zprávu, bude uloženo datum a čas, společně s aplikací, ze které jste zprávu odeslali. Zprávy mohou obsahovat mediální přílohy, jako jsou obrázky a videa. Veřejné a neuvedené příspěvky jsou dostupné veřejně. Pokud na vašem profilu uvedete příspěvek, je to také veřejně dostupná informace. Vaše příspěvky jsou doručeny vašim sledovatelům, což v některých případech znamená, že budou doručeny na různé servery, na kterých budou ukládány kopie. Pokud příspěvky smažete, bude tohle taktéž doručeno vašim sledovatelům. Akce znovusdílení nebo oblíbení jiného příspěvku je vždy veřejná.</li>
-        <li><em>Příspěvky přímé a pouze pro sledovatele</em>: Všechny příspěvky jsou uloženy a zpracovány na serveru. Příspěvky pouze pro sledovatele jsou doručeny vašim sledovatelům a uživatelům v nich zmíněným a přímé příspěvky jsou doručeny pouze uživatelům v nich zmíněným. V některých případech tohle znamená, že budou doručeny na různé servery, na kterých budou ukládány kopie. Snažíme se omezit přístup k těmto příspěvkům pouze na autorizované uživatele, ovšem jiné servery tak nemusejí učinit. Proto je důležité posoudit servery, ke kterým vaši sledovatelé patří. V nastavení si můžete zapnout volbu pro manuální schvalování či odmítnutí nových sledovatelů. <em>Prosím mějte na paměti, že operátoři tohoto serveru a kteréhokoliv přijímacího serveru mohou tyto zprávy vidět</em> a příjemci mohou vytvořit jejich snímek, zkopírovat je, nebo je jinak sdílet. <em>Nesdílejte přes Mastodon jakékoliv nebezpečné informace.</em></li>
-        <li><em>IP adresy a další metadata</em>: Když se přihlásíte, zaznamenáváme IP adresu, ze které se přihlašujete, jakožto i název vašeho webového prohlížeče. Všechny vaše webové relace jsou v nastavení přístupné k vašemu posouzení a odvolání. Nejpozdější IP adresa použita je uložena maximálně do 12 měsíců. Můžeme také uchovávat serverové záznamy, které obsahují IP adresy každého požadavku odeslaného na náš server.</li>
+      <li><em>Základní informace o účtu</em>: Pokud se na tomto serveru zaregistrujete, můžeme vás požádat o zadání uživatelského jména, e-mailové adresy a hesla. Můžete také zadat dodatečné profilové informace, jako například zobrazované jméno a krátký životopis, a nahrát si profilovou fotografii a obrázek záhlaví. Uživatelské i zobrazované jméno, životopis, profilová fotografie a obrázek záhlaví jsou vždy uvedeny veřejně.</li>
+      <li><em>Příspěvky, sledující a další veřejné informace</em>: Seznam lidí, které sledujete, je uveden veřejně, totéž platí i pro vaše sledující. Když sem nahrajete zprávu, bude uloženo datum a čas, společně s aplikací, ze které jste zprávu odeslali. Zprávy mohou obsahovat mediální přílohy, jako jsou obrázky a videa. Veřejné a neuvedené příspěvky jsou dostupné veřejně. Pokud na vašem profilu uvedete příspěvek, je to také veřejně dostupná informace. Vaše příspěvky jsou doručeny vašim sledujícím, což v některých případech znamená, že budou doručeny na různé servery, na kterých budou ukládány kopie. Pokud příspěvky smažete, bude tohle taktéž doručeno vašim sledujícím. Akce znovusdílení nebo oblíbení jiného příspěvku je vždy veřejná.</li>
+      <li><em>Příspěvky přímé a pouze pro sledující</em>: Všechny příspěvky jsou uloženy a zpracovány na serveru. Příspěvky pouze pro sledující jsou doručeny vašim sledujícím a uživatelům v nich zmíněným a přímé příspěvky jsou doručeny pouze uživatelům v nich zmíněným. V některých případech tohle znamená, že budou doručeny na různé servery, na kterých budou ukládány kopie. Upřímně se snažíme omezit přístup k těmto příspěvkům pouze na autorizované uživatele, ovšem jiné servery tak nemusejí učinit. Proto je důležité posoudit servery, ke kterým vaši sledující patří. V nastavení si můžete zapnout volbu pro manuální schvalování či odmítnutí nových sledujících. <em>Prosím mějte na paměti, že operátoři tohoto serveru a kteréhokoliv přijímacího serveru mohou tyto zprávy vidět</em> a příjemci mohou vytvořit jejich snímek, zkopírovat je, nebo je jinak sdílet. <em>Nesdílejte přes Mastodon jakékoliv nebezpečné informace.</em></li>
+      <li><em>IP adresy a další metadata</em>: Když se přihlásíte, zaznamenáváme IP adresu, ze které se přihlašujete, jakožto i název vašeho webového prohlížeče. Všechny vaše webové relace jsou v nastavení přístupné k vašemu posouzení a odvolání. Nejpozdější IP adresa použita je uložena maximálně do 12 měsíců. Můžeme také uchovávat serverové záznamy, které obsahují IP adresy každého požadavku odeslaného na náš server.</li>
       </ul>
 
       <hr class="spacer" />
@@ -878,29 +975,29 @@ cs:
       <p>Jakékoliv informace, které sbíráme, mohou být použity následujícími způsoby:</p>
 
       <ul>
-        <li>K poskytnutí základních funkcí Mastodonu. Interagovat s obsahem od jiných lidí a přispívat svým vlastním obsahem můžete pouze, pokud jste přihlášeni. Můžete například sledovat jiné lidi a zobrazit si jejich kombinované příspěvky ve vaší vlastní personalizované časové ose.</li>
-        <li>Pro pomoc moderaci komunity, například porovnáním vaší IP adresy s dalšími známými adresami pro určení vyhýbání se zákazům či jiných přestupků.</li>
-        <li>E-mailová adresa, kterou nám poskytnete, může být použita pro zasílání informací, oznámení o interakcích jiných uživatelů s vaším obsahem nebo přijatých zprávách a k odpovědím na dotazy a/nebo další požadavky či otázky.</li>
+      <li>K poskytnutí základních funkcí Mastodonu. Interagovat s obsahem od jiných lidí a přispívat svým vlastním obsahem můžete pouze, pokud jste přihlášeni. Můžete například sledovat jiné lidi a zobrazit si jejich kombinované příspěvky ve vaší vlastní personalizované časové ose.</li>
+      <li>Pro pomoc moderování komunity, například porovnáním vaší IP adresy s dalšími známými adresami pro určení vyhýbání se zákazům či jiných přestupků.</li>
+      <li>E-mailová adresa, kterou nám poskytnete, může být použita pro zasílání informací, oznámení o interakcích jiných uživatelů s vaším obsahem nebo přijatých zprávách a k odpovědím na dotazy a/nebo další požadavky či otázky.</li>
       </ul>
 
       <hr class="spacer" />
 
       <h3 id="protect">Jak vaše informace chráníme?</h3>
 
-      <p>Implenentujeme různá bezpečnostní opatření pro udržování bezpečnosti vašich osobních dat, když zadáváte, odesíláte, či přistupujete k vašim osobním datům. Mimo jiné je vaše relace v prohlížeči, jakož i provoz mezi vašimi aplikacemi a API, zabezpečena pomocí SSL, a vaše heslo je hashováno pomocí silného jednosměrného algoritmu. Pro větší zabezpečení vašeho účtu můžete povolit dvoufaktorovou autentikaci.</p>
+      <p>Implenentujeme různá bezpečnostní opatření pro udržování bezpečnosti vašich osobních dat, když zadáváte, odesíláte, či přistupujete k vašim osobním datům. Mimo jiné je vaše relace v prohlížeči, jakož i provoz mezi vašimi aplikacemi a API, zabezpečena pomocí SSL, a vaše heslo je hashováno pomocí silného jednosměrného algoritmu. Pro větší zabezpečení vašeho účtu můžete povolit dvoufázové ověřování.</p>
 
       <hr class="spacer" />
 
       <h3 id="data-retention">Jaké jsou naše zásady o uchovávání údajů?</h3>
 
-      <p>Budeme se snažit:</p>
+      <p>Budeme se upřímně snažit:</p>
 
       <ul>
-        <li>Uchovávat serverové záznamy obsahující IP adresy všech požadavků pro tento server, pokud se takové záznamy uchovávají, maximálně 90 dní.</li>
-        <li>Uchovávat IP adresy související s registrovanými uživateli maximálně 12 měsíců.</li>
+      <li>Uchovávat serverové záznamy obsahující IP adresy všech požadavků pro tento server, pokud se takové záznamy uchovávají, maximálně 90 dní.</li>
+      <li>Uchovávat IP adresy související s registrovanými uživateli maximálně 12 měsíců.</li>
       </ul>
 
-      <p>Kdykoliv si můžete vyžádat a stáhnout archiv vašeho obsahu, včetně vašich příspěvků, mediálních příloh, profilové fotografie a hlavičkového obrázku.</p>
+      <p>Kdykoliv si můžete vyžádat a stáhnout archiv vašeho obsahu, včetně vašich příspěvků, mediálních příloh, profilové fotografie a obrázku záhlaví.</p>
 
       <p>Kdykoliv můžete nenávratně smazat váš účet.</p>
 
@@ -908,7 +1005,7 @@ cs:
 
       <h3 id="cookies">Používáme cookies?</h3>
 
-      <p>Ano. Cookies jsou malé soubory, které stránka nebo její poskytovatel uloží na pevný disk vašeho počítače (pokud to dovolíte). Tyto cookies umožňují stránce rozpoznat váš prohlížeč a, pokud máte registrovaný účet, přidružit ho s vaším registrovaným účtem.</p>
+      <p>Ano. Cookies jsou malé soubory, které stránka nebo její poskytovatel uloží na pevný disk vašeho počítače (pokud to dovolíte). Tyto cookies umožňují stránce rozpoznat váš prohlížeč, a pokud máte registrovaný účet, přidružit ho s vaším registrovaným účtem.</p>
 
       <p>Používáme cookies pro pochopení a ukládání vašich předvoleb pro budoucí návštěvy.</p>
 
@@ -918,15 +1015,15 @@ cs:
 
       <p>Vaše osobně identifikovatelné informace neprodáváme, neobchodujeme s nimi, ani je nijak nepřenášíme vnějším stranám. Do tohoto se nepočítají důvěryhodné třetí strany, které nám pomáhají provozovat naši stránku, podnikat, nebo vás obsluhovat, pokud tyto strany souhlasí se zachováním důvěrnosti těchto informací. Můžeme také uvolnit vaše informace, pokud věříme, že je to nutné pro soulad se zákonem, prosazování našich zásad, nebo ochranu práv, majetku, či bezpečnost nás či ostatních.</p>
 
-      <p>Váš veřejný obsah může být stažen jinými servery na síti. Vaše příspěvky veřejné a pouze pro sledovatele budou doručeny na servery vašich sledovatelů a přímé zprávy budou doručeny na servery příjemců, pokud jsou tito sledovatelé nebo příjemci zaregistrováni na jiném serveru, než je tento.</p>
+      <p>Váš veřejný obsah může být stažen jinými servery na síti. Vaše příspěvky veřejné a pouze pro sledující budou doručeny na servery vašich sledujících a přímé zprávy budou doručeny na servery příjemců, pokud jsou tito sledující nebo příjemci zaregistrováni na jiném serveru, než je tento.</p>
 
-      <p>Když autorizujete aplikaci, aby používala váš účet, může, v závislosti na rozsahu oprávnění, které jí udělíte, přistupovat k vašim veřejným profilovým informacím, seznamu lidí, které sledujete, vašim sledovatelům, vašim seznamům, všem vašim příspěvkům a příspěvkům, které jste si oblíbili. Aplikace nikdy nemohou získat vaši e-mailovou adresu či heslo.</p>
+      <p>Když autorizujete aplikaci, aby používala váš účet, může, v závislosti na rozsahu oprávnění, které jí udělíte, přistupovat k vašim veřejným profilovým informacím, seznamu lidí, které sledujete, vašim sledujícím, vašim seznamům, všem vašim příspěvkům a příspěvkům, které jste si oblíbili. Aplikace nikdy nemohou získat vaši e-mailovou adresu či heslo.</p>
 
       <hr class="spacer" />
 
       <h3 id="children">Používání stránky dětmi</h3>
 
-      <p>Pokud se tento server nachází v EU nebo EHP: Naše stránka, produkty a služby jsou všechny směřovány na lidi, kterým je alespoň 16 let. Pokud je vám méně než 16, dle požadavků nařízení GDPR (<a href="https://cs.wikipedia.org/wiki/Obecn%C3%A9_na%C5%99%C3%ADzen%C3%AD_o_ochran%C4%9B_osobn%C3%ADch_%C3%BAdaj%C5%AF">Obecné nařízení o ochraně sobních údajů</a>) tuto stránku nepoužívejte.</p>
+      <p>Pokud se tento server nachází v EU nebo EHP: Naše stránka, produkty a služby jsou všechny směřovány na lidi, kterým je alespoň 16 let. Pokud je vám méně než 16, dle požadavků nařízení GDPR (<a href="https://cs.wikipedia.org/wiki/Obecn%C3%A9_na%C5%99%C3%ADzen%C3%AD_o_ochran%C4%9B_osobn%C3%ADch_%C3%BAdaj%C5%AF">Obecné nařízení o ochraně osobních údajů</a>) tuto stránku nepoužívejte.</p>
 
       <p>Pokud se tento server nachází v USA: Naše stránka, produkty a služby jsou všechny směřovány na lidi, kterým je alespoň 13 let. Pokud je vám méně než 13, dle požadavků zákona COPPA (<a href="https://cs.wikipedia.org/wiki/Children%27s_online_privacy_protection_act">Children's Online Privacy Protection Act</a>) tuto stránku nepoužívejte.</p>
 
@@ -943,29 +1040,29 @@ cs:
       <p>Původně adaptováno ze <a href="https://github.com/discourse/discourse">zásad soukromí Discourse</a>.</p>
     title: Podmínky používání a zásady soukromí %{instance}
   themes:
-    contrast: Vysoký kontrast
-    default: Mastodon
+    contrast: Mastodon (vysoký kontrast)
+    default: Mastodon (tmavý)
     mastodon-light: Mastodon (světlý)
   time:
     formats:
       default: "%d. %b %Y, %H:%M"
       month: "%b %Y"
   two_factor_authentication:
-    code_hint: Pro potvrzení zadejte kód vygenerovaný vaší autentikační aplikací
-    description_html: Povolíte-li <strong>dvoufaktorové ověřování</strong>, budete při přihlášení potřebovat telefon, který vám vygeneruje přístupové tokeny, které musíte zadat.
+    code_hint: Pro potvrzení zadejte kód vygenerovaný vaší ověřovací aplikací
+    description_html: Povolíte-li <strong>dvoufázové ověřování</strong>, budete při přihlášení potřebovat telefon, který vám vygeneruje přístupové tokeny, které musíte zadat.
     disable: Zakázat
     enable: Povolit
-    enabled: Dvoufaktorové ověřování je povoleno
-    enabled_success: Dvoufaktorové ověřování bylo úspěšně povoleno
+    enabled: Dvoufázové ověřování je povoleno
+    enabled_success: Dvoufázové ověřování bylo úspěšně povoleno
     generate_recovery_codes: Vygenerovat záložní kódy
     instructions_html: "<strong>Naskenujte tento QR kód Google Authenticatorem nebo jinou TOTP aplikací na vašem telefonu</strong>. Od teď bude tato aplikace generovat tokeny, které budete muset zadat při přihlášení."
     lost_recovery_codes: Záložní kódy vám dovolí dostat se k vašemu účtu, pokud ztratíte telefon. Ztratíte-li záložní kódy, můžete je zde znovu vygenerovat. Vaše staré záložní kódy budou zneplatněny.
     manual_instructions: 'Nemůžete-li oskenovat QR kód a je potřeba ho zadat ručně, zde je tajemství v prostém textu:'
     recovery_codes: Záložní kódy pro obnovu
-    recovery_codes_regenerated: Záložní kódy byly úspěšně znovu vygenerované
+    recovery_codes_regenerated: Záložní kódy byly úspěšně znovu vygenerovány
     recovery_instructions_html: Ztratíte-li někdy přístup k vašemu telefonu, můžete k získání přístupu k účtu použít jeden ze záložních kódů. <strong>Uchovávejte tyto kódy v bezpečí</strong>. Můžete si je například vytisknout a uložit je mezi jiné důležité dokumenty.
     setup: Nastavit
-    wrong_code: Zadaný kód byl neplatný! Je serverový čas a čas na zařízení správný?
+    wrong_code: Zadaný kód byl neplatný! Je čas na serveru a na zařízení správný?
   user_mailer:
     backup_ready:
       explanation: Vyžádal/a jste si úplnou zálohu svého účtu Mastodon. Nyní je připravena ke stažení!
@@ -975,7 +1072,7 @@ cs:
       explanation:
         disable: Zatímco je váš účet zmražen, zůstávají data vašeho účtu nedotčená, ale nemůžete vykonávat žádné akce, dokud nebude odemčen.
         silence: Zatímco je váš účet omezen, mohou vaše tooty na tomto serveru vidět pouze lidé, kteří váš již sledují, a můžete být vyloučen/a z různých veřejných výpisů. Ostatní vás však pořád mohou manuálně sledovat.
-        suspend: Váš účet byl pozastaven a všechny vaše tooty a vaše nahrané mediální soubory byly nenávratně odstraněny z tohoto serveru a serverů, na kterých jste měl/a sledovatele.
+        suspend: Váš účet byl pozastaven a všechny vaše tooty a vaše nahrané mediální soubory byly nenávratně odstraněny z tohoto serveru a serverů, na kterých jste měl/a sledující.
       review_server_policies: Posoudit politiku serveru
       subject:
         disable: Váš účet %{acct} byl zmražen
@@ -989,25 +1086,25 @@ cs:
         suspend: Účet pozastaven
     welcome:
       edit_profile_action: Nastavit profil
-      edit_profile_step: Můžete si přizpůsobit svůj profil nahráním avataru a obrázku na hlavičce, změnou zobrazovaného jména a dalších. Chcete-li posoudit nové sledovatele předtím, než vás mohou sledovat, můžete svůj účet uzamknout.
+      edit_profile_step: Můžete si přizpůsobit svůj profil nahráním avataru a obrázku záhlaví, změnou zobrazovaného jména a dalších. Chcete-li posoudit nové sledující předtím, než vás mohou sledovat, můžete svůj účet uzamknout.
       explanation: Zde je pár tipů na začátek
-      final_action: Začněte přispívat
-      final_step: 'Začněte přispívat! I když nemáte sledovatele, mohou vaše zprávy vidět jiní lidé, například na místní časové ose a mezi hashtagy. Můžete se ostatním představit pomocí hashtagu #introductions.'
+      final_action: Začít psát
+      final_step: 'Začněte psát! I když nemáte sledující, mohou vaše zprávy vidět jiní lidé, například na místní časové ose a v hashtazích. Můžete se ostatním představit pomocí hashtagu #introductions.'
       full_handle: Vaše celá adresa profilu
-      full_handle_hint: Tohle je, co byste řekl/a svým přátelům, aby vám mohli posílat zprávy nebo vás sledovat z jiné instance.
+      full_handle_hint: Tohle je, co byste řekl/a svým přátelům, aby vám mohli posílat zprávy nebo vás sledovat z jiného serveru.
       review_preferences_action: Změnit nastavení
       review_preferences_step: Nezapomeňte si nastavit své volby, například jaké e-maily chcete přijímat či jak soukromé mají být vaše příspěvky ve výchozím stavu. Nemáte-li epilepsii, můžete si nastavit automatické přehrávání obrázků GIF.
       subject: Vítejte na Mastodonu
       tip_federated_timeline: Federovaná časová osa je náhled celé sítě Mastodon. Zahrnuje ovšem pouze lidi, které sledují vaši sousedé, takže není úplná.
       tip_following: Administrátora/y serveru sledujete automaticky. Chcete-li najít další zajímavé lidi, podívejte se na místní a federované časové osy.
-      tip_local_timeline: Místní časová osa je náhled lidí na %{instance}. Toto jsou vaši nejbližší sousedé!
+      tip_local_timeline: Místní časová osa je náhled lidí na %{instance}. Tohle jsou vaši nejbližší sousedé!
       tip_mobile_webapp: Pokud vám váš mobilní prohlížeč nabídne přidat si Mastodon na vaši domovskou obrazovku, můžete dostávat oznámení. V mnoha ohledech to funguje jako nativní aplikace!
       tips: Tipy
       title: Vítejte na palubě, %{name}!
   users:
     follow_limit_reached: Nemůžete sledovat více než %{limit} lidí
     invalid_email: E-mailová adresa je neplatná
-    invalid_otp_token: Neplatný kód pro dvoufaktorovou autentikaci
+    invalid_otp_token: Neplatný kód pro dvoufázové ověřování
     otp_lost_help_html: Pokud jste ztratil/a přístup k oběma, můžete se spojit %{email}
     seamless_external_login: Jste přihlášen/a přes externí službu, nastavení hesla a e-mailu proto nejsou dostupná.
     signed_in_as: 'Přihlášen/a jako:'
diff --git a/config/locales/cy.yml b/config/locales/cy.yml
index 53b474c167f62ebbdbfbefd29fe9e6e3bca8c6f1..080e89214bd9ffd44c8c87e0967e324724cf4ac9 100644
--- a/config/locales/cy.yml
+++ b/config/locales/cy.yml
@@ -4,31 +4,30 @@ cy:
     about_hashtag_html: Dyma dŵtiau cyhoeddus wedi eu tagio gyda <strong>#%{hashtag}</strong>. Gallwch ryngweithio gyda nhw os oes gennych gyfrif yn unrhyw le yn y ffeddysawd.
     about_mastodon_html: Mae Mastodon yn rwydwaith cymdeithasol sy'n seiliedig ar brotocolau gwe a meddalwedd cod agored rhad ac am ddim. Yn debyg i e-bost mae'n ddatganoledig.
     about_this: Ynghylch
+    active_count_after: yn weithredol
+    active_footnote: Defnyddwyr Gweithredol Misol (DGM)
     administered_by: 'Gweinyddir gan:'
     api: API
     apps: Apiau symudol
-    closed_registrations: Mae cofrestru wedi cau ar yr achos hwn ar hyn o bryd. Fodd bynnag, mae modd ffeindio achos arall er mwyn creu cyfrif arno a chael mynediad at union yr un rhwydwaith o'r man hwnnw.
+    apps_platforms: Defnyddio Mastodon o iOS, Android a phlatfformau eraill
+    browse_directory: Pori cyfeiriadur proffil a hidlo wrth diddordebau
+    browse_public_posts: Pori ffrwd byw o byst cyhoeddus ar Fastodon
     contact: Cyswllt
     contact_missing: Heb ei osod
     contact_unavailable: Ddim yn berthnasol
+    discover_users: Darganfod defnyddwyr
     documentation: Dogfennaeth
     extended_description_html: |
       <h3>Lle da ar gyfer rheolau</h3>
       <p>Nid yw'r disgrifiad estynedig wedi ei osod eto.</p>
-    features:
-      humane_approach_body: Gan ddysgu o fethiannau rhwydweithiau eraill, mae Mastodon yn anelu i wneud penderfyniadau dylunio moesol i ymladd camddefnydd o gyfryngau cymdeithasol.
-      humane_approach_title: Agwedd fwy dynol
-      not_a_product_body: Nid yw Mastodon yn rwydwaith masnachol. Nid oes hysbysebion, cloddio data na gerddi caeedig. Nid oes awdurdod canolog.
-      not_a_product_title: Rwyt yn berson, nid yn beth
-      real_conversation_body: Gyda'r modd i ddefnyddio hyd at 500 o nodau a chefnogaeth ar gyfer cynnwys gronynnol a rhybuddion cyfryngau, mae modd i chi fynegi'ch hun yn y ffordd yr hoffech chi.
-      real_conversation_title: Wedi ei adeiladu ar gyfer sgyrsiau go iawn
-      within_reach_body: Nifer o apiau ar gyfer iOS, Android, a nifer blatfformau eraill diolch i amgylchedd API hygyrch i ddatblygwyr sy'n caniatau i chi gadw mewn cysylltiad a'ch ffrindiau o unrhywle.
-      within_reach_title: Bob tro o fewn gafael
+    federation_hint_html: Gyda cyfrif ar %{instance}, gallwch dilyn pobl ar unrhyw gweinydd Mastodon, a thu hwnt.
     generic_description: Mae %{domain} yn un gweinydd yn y rhwydwaith
+    get_apps: Rhowch gynnig ar ap dyfeis symudol
     hosted_on: Mastodon wedi ei weinyddu ar %{domain}
     learn_more: Dysu mwy
-    other_instances: Rhestr achosion
     privacy_policy: Polisi preifatrwydd
+    see_whats_happening: Gweld beth sy'n digwydd
+    server_stats: 'Ystadegau gweinydd:'
     source_code: Cod ffynhonnell
     status_count_after:
       few: statwsau
@@ -38,6 +37,7 @@ cy:
       two: statwsau
       zero: statwsau
     status_count_before: Ysgriffennwyd gan
+    tagline: Dilyn ffrindiau a darganfod rhai newydd
     terms: Telerau gwasanaeth
     user_count_after:
       few: defnyddwyr
@@ -60,6 +60,7 @@ cy:
       zero: Dilynwyr
     following: Yn dilyn
     joined: Ymunodd %{date}
+    last_active: diweddaraf
     link_verified_on: Gwiriwyd perchnogaeth y ddolen yma ar %{date}
     media: Cyfryngau
     moved_html: 'Mae %{name} wedi symud i %{new_profile_link}:'
@@ -83,16 +84,20 @@ cy:
       admin: Gweinyddwr
       bot: Bot
       moderator: Safonwr
+    unavailable: Proffil ddim ar gael
     unfollow: Dad-ddilyn
   admin:
     account_actions:
       action: Cyflawni gweithred
+      title: Perfformio gweithrediad goruwchwylio ar %{acct}
     account_moderation_notes:
       create: Gadael nodyn
-      created_msg: Crewyd nodyn cymedroli yn llwyddiannus!
+      created_msg: Crewyd nodyn goruwchwylio yn llwyddiannus!
       delete: Dileu
-      destroyed_msg: Dinistrwyd nodyn cymedroli yn llwyddiannus!
+      destroyed_msg: Dinistrwyd nodyn goruwchwylio yn llwyddiannus!
     accounts:
+      approve: Cymeradwyo
+      approve_all: Cymeradwyo pob un
       are_you_sure: Ydych chi'n siŵr?
       avatar: Afatar
       by_domain: Parth
@@ -138,23 +143,29 @@ cy:
       moderation:
         active: Yn weithredol
         all: Popeth
+        pending: Yn aros
         silenced: Wedi ei dawelu
         suspended: Wedi ei atal
-        title: Cymedroli
-      moderation_notes: Nodiadau cymedroli
+        title: Goruwchwyliad
+      moderation_notes: Nodiadau goruwchwylio
       most_recent_activity: Gweithgarwch diweddaraf
       most_recent_ip: IP diweddaraf
+      no_account_selected: Ni newidwyd dim cyfrif achos ni ddewiswyd dim un
       no_limits_imposed: Dim terfynau wedi'i gosod
       not_subscribed: Heb danysgrifio
       outbox_url: Allflwch URL
+      pending: Yn aros am adolygiad
       perform_full_suspension: Atal
       profile_url: URL proffil
       promote: Hyrwyddo
       protocol: Protocol
       public: Cyhoeddus
-      push_subscription_expires: Tanysgrifiad PuSH yn dod i ben
+      push_subscription_expires: Tanysgrifiad gwthiadwy yn dod i ben
       redownload: Adnewyddu proffil
+      reject: Gwrthod
+      reject_all: Gwrthod pob un
       remove_avatar: Dileu afatar
+      remove_header: Dileu pennawd
       resend_confirmation:
         already_confirmed: Mae'r defnyddiwr hwn wedi ei gadarnhau yn barod
         send: Ailanfonwch e-bost cadarnhad
@@ -165,20 +176,21 @@ cy:
       role: Caniatâd
       roles:
         admin: Gweinyddwr
-        moderator: Safonwr
+        moderator: Aroglygydd
         staff: Staff
         user: Defnyddiwr
       salmon_url: URL Eog
       search: Chwilio
       shared_inbox_url: URL Mewnflwch wedi ei rannu
       show:
-        created_reports: Adroddiadau a grewyd gan y cyfri hwn
-        targeted_reports: Adroddiadau am y cyfri hwn
+        created_reports: Adroddiadau a wnaed
+        targeted_reports: Adroddwyd gan eraill
       silence: Tawelu
       silenced: Tawelwyd
       statuses: Statysau
       subscribe: Tanysgrifio
       suspended: Ataliwyd
+      time_in_queue: Yn aros yn y rhestr am %{time}
       title: Cyfrifon
       unconfirmed_email: E-bost heb ei gadarnhau
       undo_silenced: Dadwneud tawelu
@@ -192,6 +204,7 @@ cy:
         assigned_to_self_report: Aseiniodd %{name} adroddiad %{target} i'w hunan
         change_email_user: Newidodd %{name} gyfeiriad e-bost y defnyddiwr %{target}
         confirm_user: Cadarnhaodd %{name} gyfeiriad e-bost y defnyddiwr %{target}
+        create_account_warning: Anfonwyd rhybudd i %{target} gan %{name}
         create_custom_emoji: Uwchlwythodd %{name} emoji newydd %{target}
         create_domain_block: Blociodd %{name} y parth %{target}
         create_email_domain_block: Cosbrestrwyd parth e-bost %{target} gan %{name}
@@ -250,8 +263,10 @@ cy:
       config: Cyfluniad
       feature_deletions: Dileadau cyfrif
       feature_invites: Dolenni gwahodd
+      feature_profile_directory: Cyfeiriadur proffil
       feature_registrations: Cofrestriadau
       feature_relay: Relái ffederasiwn
+      feature_timeline_preview: Rhagolwg o'r ffrwd
       features: Nodweddion
       hidden_service: Ffederasiwn a gwasanaethau cudd
       open_reports: adroddiadau agored
@@ -267,13 +282,14 @@ cy:
       week_users_active: gweithredol yr wythnos hon
       week_users_new: defnyddwyr yr wythnos hon
     domain_blocks:
-      add_new: Ychwanegu
+      add_new: Ychwanegu bloc parth newydd
       created_msg: Mae'r bloc parth nawr yn cael ei brosesu
       destroyed_msg: Mae'r bloc parth wedi ei ddadwneud
       domain: Parth
+      existing_domain_block_html: Rydych yn barod wedi gosod cyfyngau fwy llym ar %{name}, mae rhaid i chi ei <a href="%{unblock_url}">ddadblocio</a> yn gyntaf.
       new:
         create: Creu bloc
-        hint: Ni fydd y bloc parth yn atal cread cofnodion cyfrif yn y bas data, ond mi fydd yn gosod dulliau cymedroli penodol ôl-weithredol ac awtomatig ar y cyfrifau hynny.
+        hint: Ni fydd y bloc parth yn atal cread cofnodion cyfrif yn y bas data, ond mi fydd yn gosod dulliau goruwchwylio penodol ôl-weithredol ac awtomatig ar y cyfrifau hynny.
         severity:
           desc_html: Mae <strong>Tawelu</strong> yn gwneud twtiau y cyfrif yn anweledig i unrhyw un nad yw'n dilyn y cyfrif. Mae <strong>Atal</strong> yn cael gwared ar holl gynnwys, cyfryngau a data proffil y cyfrif. Defnyddiwch <strong>Dim</strong> os ydych chi ond am wrthod dogfennau cyfryngau.
           noop: Dim
@@ -284,14 +300,25 @@ cy:
       reject_media_hint: Dileu dogfennau cyfryngau wedi eu cadw yn lleol ac yn gwrthod i lawrlwytho unrhyw rai yn y dyfodol. Amherthnasol i ataliadau
       reject_reports: Gwrthod adroddiadau
       reject_reports_hint: Anwybyddu'r holl adroddiadau sy'n dod o'r parth hwn. Amherthnasol i ataliadau
+      rejecting_media: Yn gwrthod ffeiliau cyfryngau
+      rejecting_reports: Yn gwrthod adroddiadau
+      severity:
+        silence: tawelu
+        suspend: ataliedig
       show:
-        affected_accounts: "%{count} o gyfrifoedd yn y bas data wedi eu hefeithio"
+        affected_accounts:
+          few: Effeithiwyd ar %{count} gyfrifon
+          many: Effeithiwyd ar %{count} gyfrifon
+          one: Effeithiwyd ar un cyfrif
+          other: Effeithiwyd ar %{count} gyfrifon
+          two: Effeithiwyd ar %{count} gyfrifon
+          zero: Effeithiwyd ar %{count} gyfrifon
         retroactive:
           silence: Dad-dawelu pob cyfri presennol o'r parth hwn
           suspend: Dad-atal pob cyfrif o'r parth hwn sy'n bodoli
         title: Dadwneud blocio parth ar gyfer %{domain}
         undo: Dadwneud
-      undo: Dadwneud
+      undo: Dadwneud bloc parth
     email_domain_blocks:
       add_new: Ychwanegu
       created_msg: Llwyddwyd i ychwanegu parth e-bost i'r gosbrestr
@@ -302,11 +329,29 @@ cy:
         create: Ychwanegu parth
         title: Cofnod newydd yng nghosbrestr e-byst
       title: Cosbrestr e-bost
+    followers:
+      back_to_account: Nôl i'r gyfrif
+      title: Dilynwyr %{acct}
     instances:
+      by_domain: Parth
+      delivery_available: Mae'r cyflenwad ar gael
+      known_accounts:
+        few: "%{count} cyfrifon hysbys"
+        many: "%{count} cyfrifon hysbys"
+        one: "%{count} cyfrif hysbys"
+        other: "%{count} cyfrifon hysbys"
+        two: "%{count} cyfrifon hysbys"
+        zero: "%{count} cyfrifon hysbys"
       moderation:
         all: Pob
         limited: Gyfyngedig
+        title: Goruwchwyliad
       title: Ffederasiwn
+      total_blocked_by_us: Wedi'i bloc gan ni
+      total_followed_by_them: Yn dilyn ganynt
+      total_followed_by_us: Yn dilyn ganom ni
+      total_reported: Adroddiadau amdanynt
+      total_storage: Atodiadau cyfryngau
     invites:
       deactivate_all: Diffodd pob un
       filter:
@@ -315,6 +360,8 @@ cy:
         expired: Wedi dod i ben
         title: Hidlo
       title: Gwahoddiadau
+    pending_accounts:
+      title: Cyfrifau yn aros (%{count})
     relays:
       add_new: Ychwanegau relái newydd
       delete: Dileu
@@ -340,7 +387,7 @@ cy:
       action_taken_by: Gwnaethpwyd hyn gan
       are_you_sure: Ydych chi'n sicr?
       assign_to_self: Aseinio i mi
-      assigned: Cymedrolwr wedi'i aseinio
+      assigned: Arolygwr wedi'i aseinio
       comment:
         none: Dim
       created_at: Adroddwyd
@@ -388,6 +435,9 @@ cy:
       preview_sensitive_media:
         desc_html: Bydd rhagolygon ar wefannau eraill yn dangos ciplun hyd yn oed os oes na gyfryngau wedi eu marcio'n sensitif
         title: Dangos cyfryngau sensitif mewn rhagolygon OpenGraph
+      profile_directory:
+        desc_html: Caniatáu i ddefnyddwyr gael eu gweld
+        title: Galluogi cyfeiriadur proffil
       registrations:
         closed_message:
           desc_html: I'w arddangos ar y dudalen flaen wedi i gofrestru cau. Mae modd defnyddio tagiau HTML
@@ -398,9 +448,12 @@ cy:
         min_invite_role:
           disabled: Neb
           title: Caniatau gwahoddiadau gan
-        open:
-          desc_html: Caniatau i unrhywun greu cyfrif
-          title: Agor cofrestru
+      registrations_mode:
+        modes:
+          approved: Mae angen cymeradwyaeth ar gyfer cofrestru
+          none: Ni all unrhyw un cofrestru
+          open: Gall unrhyw un cofrestru
+        title: Modd cofrestriadau
       show_known_fediverse_at_about_page:
         desc_html: Wedi'i ddewis, bydd yn dangos rhagolwg o dŵtiau o'r holl ffedysawd. Fel arall bydd ond yn dangos tŵtiau lleol.
         title: Dangos ffedysawd hysbys ar ragolwg y ffrwd
@@ -450,16 +503,32 @@ cy:
     tags:
       accounts: Cyfrifon
       hidden: Cudd
+      hide: Cuddio o gyfeiriadur
       name: Hashnod
+      title: Hashnodau
+      unhide: Dangoswch yn y cyfeiriadur
+      visible: Gweladwy
     title: Gweinyddiaeth
     warning_presets:
+      add_new: Ychwanegu newydd
       delete: Dileu
       edit: Golygu
+      edit_preset: Golygu rhagosodiad rhybudd
+      title: Rheoli rhagosodiadau rhybudd
   admin_mailer:
+    new_pending_account:
+      body: Mae manylion y cyfrif newydd yn isod. Gallwch cymeradwyo neu wrthod y ceisiad hon.
+      subject: Cyfrif newydd i fynu ar gyfer adolygiad ar %{instance} (%{username})
     new_report:
       body: Mae %{reporter} wedi cwyno am %{target}
       body_remote: Mae rhywun o %{domain} wedi cwyno am %{target}
-      subject: Cwyn newydd am %{instance} {#%{id}}
+      subject: Cwyn newydd am %{instance} (#%{id})
+  appearance:
+    advanced_web_interface: Rhyngwyneb gwe uwch
+    advanced_web_interface_hint: 'Os hoffech gwneud defnydd o gyd o''ch lled sgrin, mae''r rhyngwyneb gwe uwch yn gadael i chi ffurfweddu sawl colofn wahanol i weld cymaint o wybodaeth â hoffech: Catref, hysbysiadau, ffrwd y ffedysawd, unrhyw nifer o rhestrau ac hashnodau.'
+    animations_and_accessibility: Animeiddiau ac hygyrchedd
+    confirmation_dialogs: Deialog cadarnhau
+    sensitive_content: Cynnwys sensitif
   application_mailer:
     notification_preferences: Newid gosodiadau e-bost
     salutation: "%{name},"
@@ -476,8 +545,9 @@ cy:
     warning: Byddwch yn ofalus a'r data hyn. Peidiwch a'i rannu byth!
     your_token: Eich tocyn mynediad
   auth:
-    agreement_html: Wrth glicio "Cofrestru" isod yr ydych yn cytuno i ddilyn <a href="%{rules_path}">y rheolau ar gyfer yr achos hwn</a> a <a href="%{terms_path}">ein termau gwasanaeth</a>.
+    apply_for_account: Gofyn am wahoddiad
     change_password: Cyfrinair
+    checkbox_agreement_html: Rydw i'n cytuno i'r <a href="%{rules_path}" target="_blank">rheolau'r gweinydd</a> a'r <a href="%{terms_path}" target="_blank">telerau gwasanaeth</a>
     confirm_email: Cadarnhau e-bost
     delete_account: Dileu cyfrif
     delete_account_html: Os hoffech chi ddileu eich cyfrif, mae modd <a href="%{path}">parhau yma</a>. Bydd gofyn i chi gadarnhau.
@@ -488,17 +558,17 @@ cy:
     logout: Allgofnodi
     migrate_account: Symud i gyfrif gwahanol
     migrate_account_html: Os hoffech chi ailgyfeirio'r cyfrif hwn at un gwahanol, mae modd <a href="%{path}">ei ffurfweddu yma</a>.
-    or: neu
     or_log_in_with: Neu logiwch mewn a
     providers:
       cas: CAS
       saml: SAML
     register: Cofrestru
-    register_elsewhere: Cofrestru ar weinydd gwahanol
+    registration_closed: Nid yw %{instance} yn derbyn aelodau newydd
     resend_confirmation: Ailanfon cyfarwyddiadau cadarnhau
     reset_password: Ailosod cyfrinair
     security: Diogelwch
     set_new_password: Gosod cyfrinair newydd
+    trouble_logging_in: Trafferdd mewngofnodi?
   authorize_follow:
     already_following: Yr ydych yn dilyn y cyfrif hwn yn barod
     error: Yn anffodus, roedd gwall tra'n edrych am y cyfrif anghysbell
@@ -517,11 +587,11 @@ cy:
       about_x_years: "%{count}blwyddyn"
       almost_x_years: "%{count}blwyddyn"
       half_a_minute: Newydd fod
-      less_than_x_minutes: "%{count}m"
+      less_than_x_minutes: "%{count}munud"
       less_than_x_seconds: Newydd fod
       over_x_years: "%{count}blwyddyn"
       x_days: "%{count}dydd"
-      x_minutes: "%{count}m"
+      x_minutes: "%{count}munud"
       x_months: "%{count}mis"
       x_seconds: "%{count}eiliad"
   deletes:
@@ -532,6 +602,20 @@ cy:
     success_msg: Llwyddwyd i ddileu eich cyfrif
     warning_html: Dim ond dileu cynnwys o'r achos hwn ellid bod yn sicr ei fod wedi ei ddileu. Mae cynnwys sydd wedi ei rannu'n eang yn debygol o adael olion. Ni fydd gweinyddwyr all-lein a gweinyddwyr sydd wedi dad-danysgrifio o'ch diwedderiadau ddim yn diweddaru eu cronfeydd data.
     warning_title: Argaeledd cynnwys wedi'i rannu
+  directories:
+    directory: Cyfeiriadur proffil
+    enabled: Rydych chi wedi'ch rhestru yn y cyfeiriadur ar hyn o bryd.
+    enabled_but_waiting: Rydych wedi dewis i chi gael eich rhestru yn y cyfeiriadur, ond nid oes gennych y nifer lleiaf o ddilynwyr (%{min_followers}) i'w rhestru eto.
+    explanation: Darganfod defnyddwyr yn seiliedig ar eu diddordebau
+    explore_mastodon: Archwilio %{title}
+    how_to_enable: Ar hyn o bryd nid ydych chi wedi dewis y cyfeiriadur. Gallwch ddewis i mewn isod. Defnyddiwch hashnodau yn eich bio-destun i'w restru dan hashnodau penodol!
+    people:
+      few: "%{count} o bobl"
+      many: "%{count} o bobl"
+      one: "%{count} berson"
+      other: "%{count} o bobl"
+      two: "%{count} o bobl"
+      zero: "%{count} person"
   errors:
     '403': Nid oes gennych ganiatad i weld y dudalen hon.
     '404': Nid yw'r dudalen yr oeddech yn chwilio amdani'n bodoli.
@@ -544,6 +628,9 @@ cy:
       content: Mae'n ddrwg gennym ni, ond fe aeth rhywbeth o'i le ar ein rhan ni.
       title: Nid yw'r dudalen hon yn gywir
     noscript_html: I ddefnyddio ap gwe Mastodon, galluogwch JavaScript os gwlwch yn dda. Fel arall, gallwch drio un o'r <a href="%{apps_path}">apiau cynhenid</a> ar gyfer Mastodon ar eich platfform.
+  existing_username_validator:
+    not_found: ni ddarganfwyd defnyddiwr lleol gyda'r enw cyfrif hynny
+    not_found_multiple: ni ddarganfwyd %{usernames}
   exports:
     archive_takeout:
       date: Dyddiad
@@ -554,9 +641,15 @@ cy:
       size: Maint
     blocks: Yr ydych yn blocio
     csv: CSV
+    domain_blocks: Blociau parth
     follows: Yr ydych yn dilyn
+    lists: Rhestrau
     mutes: Yr ydych yn tawelu
     storage: Storio cyfryngau
+  featured_tags:
+    add_new: Ychwanegu
+    errors:
+      limit: Yr ydych yn barod wedi cynnwys yr uchafswm o hashnodau
   filters:
     contexts:
       home: Ffrwd gartref
@@ -573,34 +666,58 @@ cy:
       title: Hidlyddion
     new:
       title: Ychwanegu hidlydd newydd
-  followers:
-    domain: Parth
-    explanation_html: Os ydych am sicrhau preifatrwydd eich tŵtiau, rhaid i chi fod yn ymwybodol o bwy sy'n eich dilyn. <strong>Mae eich tŵtiau preifat yn cael eu hanfon at bob achos lle mae gennych ddilynwyr</strong>. Efallai hoffech chi i'w hadolygu o bryd i'w gilydd, a chael gwared ar ddilynwyr os nad ydych yn credu i'r staff neu'r meddalwedd ar yr achosion hynny barchu eich preifatrwydd.
-    followers_count: Nifer y dilynwyr
-    lock_link: Cloi eich cyfrif
-    purge: Dileu o dilynwyr
-    success: Yn y broses o ysgafn-flocio dilynwyr o %{count} parth...
-    true_privacy_html: Cofiwch <strong>mai ond amgryptio pen-i-ben all sicrhau gwir breifatrwydd</strong>.
-    unlocked_warning_html: Gall unrhywun eich dilyn yn syth i weld eich tŵtiau preifat. %{lock_link} i gael adolygu a gwrthod dilynwyr.
-    unlocked_warning_title: Nid yw eich cyfrif wedi ei gloi
   footer:
     developers: Datblygwyr
     more: Mwy…
     resources: Adnoddau
   generic:
+    all: Popeth
     changes_saved_msg: Llwyddwyd i gadw y newidiadau!
     copy: Copïo
+    order_by: Trefnu wrth
     save_changes: Cadw newidiadau
-    validation_errors: Mae rhywbeth o'i le o hyd! Edrychwch ar y %{count} gwall isod os gwelwch yn dda
+    validation_errors:
+      few: Mae rhywbeth o'i le o hyd! Edrychwch ar y %{count} gwall isod os gwelwch yn dda
+      many: Mae rhywbeth o'i le o hyd! Edrychwch ar y %{count} gwall isod os gwelwch yn dda
+      one: Mae rhywbeth o'i le o hyd! Edrychwch ar y gwall isod os gwelwch yn dda
+      other: Mae rhywbeth o'i le o hyd! Edrychwch ar y %{count} gwall isod os gwelwch yn dda
+      two: Mae rhywbeth o'i le o hyd! Edrychwch ar y %{count} gwall isod os gwelwch yn dda
+      zero: Mae rhywbeth o'i le o hyd! Edrychwch ar y %{count} gwall isod os gwelwch yn dda
+  html_validator:
+    invalid_markup: 'yn cynnwys marciad HTML annilys: %{error}'
+  identity_proofs:
+    active: Yn weithredol
+    authorize: Ie, awdurdodi
+    authorize_connection_prompt: Awdurdodi y cysylltiad cryptograffig hon?
+    errors:
+      failed: Methwyd y cysylltiad cryptograffig. Ceisiwch eto o %{provider}, os gwelwch yn dda.
+      keybase:
+        invalid_token: Mae tocynnau keybase yn hashiau o llofnodau ac mae rhaid iddynt bod yn 66 cymeriadau hecs
+        verification_failed: Nid yw Keybase yn adnabod y tocyn hyn fel llofnod defnyddiwr Keybase %{kb_username}. Cesiwch eto o Keybase, os gwelwch yn dda.
+      wrong_user: Ni all greu prawf ar gyfer %{proving} tra wedi mewngofnodi fel %{current}. Mewngofnodi fel %{proving} a cheisiwch eto.
+    explanation_html: Fama gallwch cysylltu i'ch hunanieithau arall yn cryptograffig, er enghraifft proffil Keybase. Mae hyn yn gadael pobl arall i anfon chi negeseuon amgryptiedig a ymddiried mewn cynnwys rydych yn eich anfon iddynt.
+    i_am_html: Rydw i'n %{username} ar %{service}.
+    identity: Hunaniaeth
+    inactive: Anweithgar
+    publicize_checkbox: 'A thŵtiwch hon:'
+    publicize_toot: 'Wedi profi! Rydw i''n %{username} ar %{service}: %{url}'
+    status: Statws gwirio
+    view_proof: Gweld prawf
   imports:
+    modes:
+      merge: Cyfuno
+      merge_long: Cadw'r cofnodau presennol ac ychwanegu rhai newydd
+      overwrite: Trosysgrifio
+      overwrite_long: Disodli cofnodau bresennol gyda'r cofnodau newydd
     preface: Mae modd mewnforio data yr ydych wedi allforio o achos arall, megis rhestr o bobl yr ydych yn ei ddilyn neu yn blocio.
     success: Uwchlwythwyd eich data yn llwyddiannus ac fe fydd yn cael ei brosesu mewn da bryd
     types:
       blocking: Rhestr blocio
+      domain_blocking: Rhestr rhwystro parth
       following: Rhestr dilyn
       muting: Rhestr tawelu
     upload: Uwchlwytho
-  in_memoriam_html: In Memoriam.
+  in_memoriam_html: Mewn Cofiad.
   invites:
     delete: Dadactifadu
     expired: Wedi darfod
@@ -614,7 +731,13 @@ cy:
     expires_in_prompt: Byth
     generate: Cynhyrchu
     invited_by: 'Cawsoch eich gwahodd gan:'
-    max_uses: "%{count} defnydd"
+    max_uses:
+      few: "%{count} defnydd"
+      many: "%{count} defnydd"
+      one: 1 iws
+      other: "%{count} defnydd"
+      two: "%{count} defnydd"
+      zero: "%{count} defnydd"
     max_uses_prompt: Dim terfyn
     prompt: Cynhyrchwch a rhannwch ddolenni gyda eraill i ganiatau mynediad i'r achos hwn
     table:
@@ -634,14 +757,26 @@ cy:
     proceed: Cadw
     updated_msg: Diweddarwyd gosodiad mudo eich cyfrif yn llwyddiannus!
   moderation:
-    title: Cymedroli
+    title: Goruwchwyliad
   notification_mailer:
     digest:
       action: Gweld holl hysbysiadau
       body: Dyma grynodeb byr o'r holl negeseuon golloch chi ers eich ymweliad diwethaf ar %{since}
       mention: 'Soniodd %{name} amdanoch chi:'
-      new_followers_summary: Hefyd, rydych wedi ennill %{count} dilynwr newydd tra eich bod i ffwrdd! Hwrê!
-      subject: "%{count} hysbysiad newydd ers eich ymweliad diwethaf \U0001F418"
+      new_followers_summary:
+        few: Hefyd, rydych wedi ennill %{count} dilynwr newydd tra eich bod i ffwrdd! Hwrê!
+        many: Hefyd, rydych wedi ennill %{count} dilynwr newydd tra eich bod i ffwrdd! Hwrê!
+        one: Yr ydych wedi ennill dilynwr newydd tra eich bod i ffwrdd! Hwrê!
+        other: Hefyd, rydych wedi ennill %{count} dilynwr newydd tra eich bod i ffwrdd! Hwrê!
+        two: Hefyd, rydych wedi ennill %{count} dilynwr newydd tra eich bod i ffwrdd! Hwrê!
+        zero: Hefyd, rydych wedi ennill %{count} dilynwr newydd tra eich bod i ffwrdd! Hwrê!
+      subject:
+        few: "%{count} hysbysiad newydd ers eich ymweliad diwethaf"
+        many: "%{count} hysbysiad newydd ers eich ymweliad diwethaf"
+        one: 1 hysbysiad newydd ers eich ymweliad diwethaf
+        other: "%{count} hysbysiad newydd ers eich ymweliad diwethaf"
+        two: "%{count} hysbysiad newydd ers eich ymweliad diwethaf"
+        zero: "%{count} hysbysiad newydd ers eich ymweliad diwethaf"
       title: Yn eich absenoldeb...
     favourite:
       body: 'Cafodd eich statws ei hoffi gan %{name}:'
@@ -670,32 +805,71 @@ cy:
       decimal_units:
         format: "%n%u"
         units:
-          billion: B
-          million: M
-          quadrillion: Q
-          thousand: K
-          trillion: T
+          billion: Biliwn
+          million: Miliwn
+          quadrillion: Cwadriliwn
+          thousand: Mil
+          trillion: Triliwn
   pagination:
     newer: Diweddarach
     next: Nesaf
     older: HÅ·n
     prev: Blaenorol
     truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: Rydych chi barod wedi pleidleisio ar y pleidlais hon
+      duplicate_options: yn cynnwys eitemau dyblyg
+      duration_too_long: yn rhy bell yn y dyfodol
+      duration_too_short: yn rhy fuan
+      expired: Mae'r pleidlais wedi gorffen yn barod
+      over_character_limit: ni all fod yn hirach na %{max} cymeriad yr un
+      too_few_options: rhaid cael fwy nag un eitem
+      too_many_options: ni all cynnwys fwy na %{max} o eitemau
   preferences:
-    languages: Ieithoedd
     other: Arall
-    publishing: Cyhoeddi
-    web: Gwe
+    posting_defaults: Rhagosodiadau postio
+    public_timelines: Ffrydau gyhoeddus
+  relationships:
+    activity: Gweithgareddau cyfrif
+    dormant: Segur
+    last_active: Gweithred ddiwethaf
+    most_recent: Yn diweddaraf
+    moved: Wedi symud
+    mutual: Cydfuddiannol
+    primary: Cynradd
+    relationship: Perthynas
+    remove_selected_domains: Tynnu pob dilynydd o'r parthau dewisiedig
+    remove_selected_followers: Tynnu'r dilynydd dewisiedig
+    remove_selected_follows: Dad-ddilyn y defnyddwyr dewisiedig
+    status: Statws cyfrif
   remote_follow:
     acct: Mewnbynnwch eich enwdefnyddiwr@parth yr ydych eisiau gweithredu ohonno
     missing_resource: Ni ellir canfod yr URL ailgyferio angenrheidiol i'ch cyfrif
     no_account_html: Heb gyfrif? Mae modd i chi <a href='%{sign_up_path}' target='_blank'>gofrestru yma</a>
     proceed: Ymlaen i ddilyn
     prompt: 'Yr ydych am ddilyn:'
+    reason_html: |-
+      <strong>Pam yw'r cam hyn yn angenrheidiol? </strong>
+      Efallai nid yw <code>%{instance}</code> yn gweinydd ble wnaethoch gofrestru, felly mae'n rhaid i ni ailarweinio chi at eich gweinydd catref yn gyntaf.
+  remote_interaction:
+    favourite:
+      proceed: Ymlaen i hoffi
+      prompt: 'Hoffech hoffi''r tŵt hon:'
+    reblog:
+      proceed: Ymlaen i fŵstio
+      prompt: 'Hoffech fŵstio''r tŵt hon:'
+    reply:
+      proceed: Ymlaen i ateb
+      prompt: 'Hoffech ateb y tŵt hon:'
   remote_unfollow:
     error: Gwall
     title: Teitl
     unfollowed: Dad-ddilynwyd
+  scheduled_statuses:
+    over_daily_limit: Rydych wedi rhagori'r cyfwng o %{limit} o dŵtiau rhestredig ar y dydd hynny
+    over_total_limit: Rydych wedi rhagori'r cyfwng o %{limit} o dŵtiau rhestredig
+    too_soon: Mae rhaid i'r dydd rhestredig fod yn y dyfodol
   sessions:
     activity: Gweithgaredd ddiwethaf
     browser: Porwr
@@ -725,37 +899,48 @@ cy:
       adobe_air: Adobe Air
       android: Android
       blackberry: Blackberry
-      chrome_os: ChromeOS
-      firefox_os: Firefox OS
+      chrome_os: OS Chrome
+      firefox_os: OS Firefox
       ios: iOS
       linux: Linux
       mac: Mac
       other: platfform anhysbys
       windows: Windows
       windows_mobile: Windows Mobile
-      windows_phone: Windows Phone
+      windows_phone: Ffôn Windows
     revoke: Diddymu
     revoke_success: Sesiwn wedi ei ddiddymu yn llwyddiannus
     title: Sesiynau
   settings:
+    account: Cyfrif
+    account_settings: Gosodiadau'r cyfrif
+    appearance: Arddangosiad
     authorized_apps: Apiau awdurdodedig
     back: Yn ôl i Mastodon
     delete: Dileu cyfrif
     development: Datblygu
     edit_profile: Golygu proffil
     export: Allforio data
-    followers: Dilynwyr awdurdodedig
+    featured_tags: Hashnodau Nodedig
+    identity_proofs: Profiadau Hunaniaeth
     import: Mewnforio
+    import_and_export: Mewnfori ac allfori
     migrate: Mudo cyfrif
     notifications: Hysbysiadau
     preferences: Dewisiadau
-    settings: Gosodiadau
+    profile: Proffil
+    relationships: Dilynion a dilynwyr
     two_factor_authentication: Awdurdodi dau-gam
-    your_apps: Eich rhaglenni
   statuses:
     attached:
       description: 'Ynghlwm: %{attached}'
-      image: "%{count} o luniau"
+      image:
+        few: "%{count} o luniau"
+        many: "%{count} o luniau"
+        one: "%{count} llun"
+        other: "%{count} o luniau"
+        two: "%{count} o luniau"
+        zero: "%{count} o luniau"
       video:
         few: "%{count} fideo"
         many: "%{count} fideo"
@@ -765,7 +950,13 @@ cy:
         zero: "%{count} fideo"
     boosted_from_html: Wedi ei fŵstio %{acct_link}
     content_warning: 'Rhybudd cynnwys: %{warning}'
-    disallowed_hashtags: 'yn cynnwys yr hashnod gwaharddedig: %{tags}'
+    disallowed_hashtags:
+      few: 'yn cynnwys yr hashnod gwaharddedig: %{tags}'
+      many: 'yn cynnwys yr hashnod gwaharddedig: %{tags}'
+      one: 'yn cynnwys hashnod gwaharddedig: %{tags}'
+      other: 'yn cynnwys yr hashnod gwaharddedig: %{tags}'
+      two: 'yn cynnwys yr hashnod gwaharddedig: %{tags}'
+      zero: 'yn cynnwys yr hashnod gwaharddedig: %{tags}'
     language_detection: Canfod iaith yn awtomataidd
     open_in_web: Agor yn y wê
     over_character_limit: wedi mynd heibio'r uchafswm nodyn o %{max}
@@ -774,6 +965,15 @@ cy:
       ownership: Ni ellir pinio tŵt rhywun arall
       private: Ni ellir pinio tŵt nad yw'n gyhoeddus
       reblog: Ni ellir pinio bŵstiau
+    poll:
+      total_votes:
+        few: "%{count} o bleidleisiau"
+        many: "%{count} o bleidleisiau"
+        one: "%{count} bleidlais"
+        other: "%{count} o bleidleisiau"
+        two: "%{count} o bleidleisiau"
+        zero: "%{count} pleidlais"
+      vote: Pleidleisio
     show_more: Dangos mwy
     sign_in_to_participate: Mengofnodwch i gymryd rhan yn y sgwrs
     title: '%{name}: "%{quote}"'
@@ -794,10 +994,10 @@ cy:
       <h3 id="collect">Pa wybodaeth ydyn ni'n ei gasglu?</h3>
 
       <ul>
-        <li><em>Gwybodaeth cyfrif sylfaenol</em>: Os ydych yn cofrestru ar y gweinydd hwn, mae'n bosib y byddwch yn cael eich gofyn i fewnbynnu enw defnyddiwr, cyfeiriad e-bost a chyfrinair. Mae modd i chi hefyd fewnbynnu gwybodaeth ychwanegol megis enw arddangos a bywgraffiad ac uwchlwytho llun proffil a llun pennawd. Mae'r enw defnyddiwr, enw arddangos, bywgraffiad, llun proffil a'r llun pennawd wedi eu rhestru'n gyhoeddus bob tro.</li>
-        <li><em>Postio, dilyn a gwybodaeth gyhoeddus arall</em>: Mae'r rhestr o bobl yr ydych yn dilyn wedi ei restru'n gyhoeddus, mae'r un peth yn wir am eich dilynwyr. Pan yr ydych yn mewnosod neges, mae'r dyddiad a'r amser yn cael ei gofnodi ynghyd a'r rhaglen y wnaethoch anfon y neges ohonni. Gall negeseuon gynnwys atodiadau cyfryngau, megis lluniau neu fideo. Mae negeseuon cyhoeddus a negeseuon heb eu rhestru ar gael yn gyhoeddus. Pan yr ydych yn nodweddu neges ar eich proffil, mae hynny hefyd yn wybodaeth sydd ar gael yn gyhoeddus. Mae eich negeseuon yn cael eu hanfon i'ch dilynwyr, mewn rhai achosion mae hyn yn golygu eu bod yn cael eu hanfon i amryw o weinyddwyr ac fe fydd copiau yn cael eu cadw yno. Pan yr ydych yn dileu negeseuon, mae hyn hefyd yn cael ei hanfon i'ch dilynwyr. Mae'r weithred o rannu neu hoffi neges arall yn gyhoeddus bob tro.</li>
-        <li><em>Negeseuon uniongyrchol a dilynwyr yn unig</em>: Mae pob neges yn cael eu cadw a'u prosesu ar y gweinydd. Mae negeseuon dilynwyr yn unig yn cael eu hanfon i'ch dilynwyr a'r defnyddwyr sy'n cael eu crybwyll ynddynt tra bod negeseuon uniongyrchol yn cael eu hanfon at rheini sy'n cael crybwyll ynddynt yn unig. Mewn rhai achostion golyga hyn eu bod yn cael eu hanfon i weinyddwyr gwahanol a'u cadw yno. yr ydym yn gnweud ymgais ewyllys da i gyfyngu'r mynediad at y negeseuon yna i bobl ac awdurdod yn unig, ond mae'n bosib y bydd gweinyddwyr eraill yn methu a gwneud hyn. Mae'n bwysig felly i chi fod yn wyliadwrus o ba weinyddwyr y mae eich dilynwyr yn perthyn iddynt. Mae modd i chi osod y dewis i ganiatau a gwrthod dilynwyr newydd a llaw yn y gosodiadau. <em>Cofiwch gall gweithredwyr y gweinydd ac unrhyw weinydd derbyn weld unrhyw negeseuon o'r fath</em>, ac fe all y derbynwyr gymryd sgrinlin, copïo neu drwy ddulliau eraill rannu rhain. <em>Peidiwch a rhannu unrhyw wybodaeth beryglus dros Mastodon.</em></li>
-        <li><em>IPs a mathau eraill o metadata</em>: Pan yr ydych yn mewngofnodi, yr ydym yn cofnodi y cyfeiriad IP yr ydych yn mewngofnodi ohonno, ynghyd a enw eich rhaglen pori. Mae pob un sesiwn mewngofnodi ar gael i chi adolygu a gwrthod yn y gosodiadau. Mae'r cyfeiriad IP diweddaraf yn cael ei storio hyd at 12 mis. Mae'n bosib y byddwn hefyd yn cadw cofnodion gweinydd sy'n cynnwys y cyfeiriad IP am bob cais sy'n cael ei wneud i'n gweinydd.</li>
+      <li><em>Gwybodaeth cyfrif sylfaenol</em>: Os ydych yn cofrestru ar y gweinydd hwn, mae'n bosib y byddwch yn cael eich gofyn i fewnbynnu enw defnyddiwr, cyfeiriad e-bost a chyfrinair. Mae modd i chi hefyd fewnbynnu gwybodaeth ychwanegol megis enw arddangos a bywgraffiad ac uwchlwytho llun proffil a llun pennawd. Mae'r enw defnyddiwr, enw arddangos, bywgraffiad, llun proffil a'r llun pennawd wedi eu rhestru'n gyhoeddus bob tro.</li>
+      <li><em>Postio, dilyn a gwybodaeth gyhoeddus arall</em>: Mae'r rhestr o bobl yr ydych yn dilyn wedi ei restru'n gyhoeddus, mae'r un peth yn wir am eich dilynwyr. Pan yr ydych yn mewnosod neges, mae'r dyddiad a'r amser yn cael ei gofnodi ynghyd a'r rhaglen y wnaethoch anfon y neges ohonni. Gall negeseuon gynnwys atodiadau cyfryngau, megis lluniau neu fideo. Mae negeseuon cyhoeddus a negeseuon heb eu rhestru ar gael yn gyhoeddus. Pan yr ydych yn nodweddu neges ar eich proffil, mae hynny hefyd yn wybodaeth sydd ar gael yn gyhoeddus. Mae eich negeseuon yn cael eu hanfon i'ch dilynwyr, mewn rhai achosion mae hyn yn golygu eu bod yn cael eu hanfon i amryw o weinyddwyr ac fe fydd copiau yn cael eu cadw yno. Pan yr ydych yn dileu negeseuon, mae hyn hefyd yn cael ei hanfon i'ch dilynwyr. Mae'r weithred o rannu neu hoffi neges arall yn gyhoeddus bob tro.</li>
+      <li><em>Negeseuon uniongyrchol a dilynwyr yn unig</em>: Mae pob neges yn cael eu cadw a'u prosesu ar y gweinydd. Mae negeseuon dilynwyr yn unig yn cael eu hanfon i'ch dilynwyr a'r defnyddwyr sy'n cael eu crybwyll ynddynt tra bod negeseuon uniongyrchol yn cael eu hanfon at rheini sy'n cael crybwyll ynddynt yn unig. Mewn rhai achostion golyga hyn eu bod yn cael eu hanfon i weinyddwyr gwahanol a'u cadw yno. yr ydym yn gnweud ymgais ewyllys da i gyfyngu'r mynediad at y negeseuon yna i bobl ac awdurdod yn unig, ond mae'n bosib y bydd gweinyddwyr eraill yn methu a gwneud hyn. Mae'n bwysig felly i chi fod yn wyliadwrus o ba weinyddwyr y mae eich dilynwyr yn perthyn iddynt. Mae modd i chi osod y dewis i ganiatau a gwrthod dilynwyr newydd a llaw yn y gosodiadau. <em>Cofiwch gall gweithredwyr y gweinydd ac unrhyw weinydd derbyn weld unrhyw negeseuon o'r fath</em>, ac fe all y derbynwyr gymryd sgrinlin, copïo neu drwy ddulliau eraill rannu rhain. <em>Peidiwch a rhannu unrhyw wybodaeth beryglus dros Mastodon.</em></li>
+      <li><em>IPs a mathau eraill o metadata</em>: Pan yr ydych yn mewngofnodi, yr ydym yn cofnodi y cyfeiriad IP yr ydych yn mewngofnodi ohonno, ynghyd a enw eich rhaglen pori. Mae pob un sesiwn mewngofnodi ar gael i chi adolygu a gwrthod yn y gosodiadau. Mae'r cyfeiriad IP diweddaraf yn cael ei storio hyd at 12 mis. Mae'n bosib y byddwn hefyd yn cadw cofnodion gweinydd sy'n cynnwys y cyfeiriad IP am bob cais sy'n cael ei wneud i'n gweinydd.</li>
       </ul>
 
       <hr class="spacer" />
@@ -807,9 +1007,9 @@ cy:
       <p>Gall unrhyw wybodaeth yr ydym yn ei gasglu oddi wrthych gael ei ddefnyddio yn y ffyrdd canlynol:</p>
 
       <ul>
-        <li>I ddarparu prif weithgaredd Mastodon. Gallwch ond rhyngweithio a chynnwys pobl eraill pan yr ydych wedi'ch mewngofnodi. Er enghraifft, gallwch ddilyn pobl eraill i weld eu negeseuon wedi cyfuno ar ffrwd gartref bersonol.</li>
-        <li>I helpu gyda goruwchwylio'r gymuned, er enghraifft drwy gymharu eich cyfeiriad IP gyda rhai eraill hysbys er mwyn sefydlu ymgais i geisio hepgor gwaharddiad neu droseddau eraill.</li>
-        <li>Gall y cyfeiriad e-bost yr ydych yn ei ddarparu gael ei ddefnyddio i anfon gwybodaeth atoch, hsybysiadau am bobl eraill yn rhyngweithio a'ch cynnwys neu'n anfon negeseuon atoch a/neu geisiadau neu gwestiynnau eraill.</li>
+      <li>I ddarparu prif weithgaredd Mastodon. Gallwch ond rhyngweithio a chynnwys pobl eraill pan yr ydych wedi'ch mewngofnodi. Er enghraifft, gallwch ddilyn pobl eraill i weld eu negeseuon wedi cyfuno ar ffrwd gartref bersonol.</li>
+      <li>I helpu gyda goruwchwylio'r gymuned, er enghraifft drwy gymharu eich cyfeiriad IP gyda rhai eraill hysbys er mwyn sefydlu ymgais i geisio hepgor gwaharddiad neu droseddau eraill.</li>
+      <li>Gall y cyfeiriad e-bost yr ydych yn ei ddarparu gael ei ddefnyddio i anfon gwybodaeth atoch, hsybysiadau am bobl eraill yn rhyngweithio a'ch cynnwys neu'n anfon negeseuon atoch a/neu geisiadau neu gwestiynnau eraill.</li>
       </ul>
 
       <hr class="spacer" />
@@ -825,8 +1025,8 @@ cy:
       <p>Gwnawn ymdrech ewyllys da i:</p>
 
       <ul>
-        <li>Gadw cofnod gweinydd yn cynnwys y cyfeiriad IP o bob cais i'r gweinydd hwn, i'r graddau y mae cofnodion o'r fath yn cael eu cadw, am ddim mwy na 90 diwrnod.</li>
-        <li>Gadw cyfeiriadau IP a chysylltiad i ddefnyddwyr cofrestredig am ddim mwy na 12 mis.</li>
+      <li>Gadw cofnod gweinydd yn cynnwys y cyfeiriad IP o bob cais i'r gweinydd hwn, i'r graddau y mae cofnodion o'r fath yn cael eu cadw, am ddim mwy na 90 diwrnod.</li>
+      <li>Gadw cyfeiriadau IP a chysylltiad i ddefnyddwyr cofrestredig am ddim mwy na 12 mis.</li>
       </ul>
 
       <p>Mae modd i chi wneud cais am, a lawrlwytho archif o'ch cynnwys, gan gynnwys eich tŵtiau, atodiadau cyfryngau, llun proffil a llun pennawd.</p>
@@ -872,8 +1072,8 @@ cy:
       <p>Cafodd ei addasu yn wreiddiol o'r<a href="https://github.com/discourse/discourse">Polisi preifatrwydd disgwrs</a>.</p>
     title: "%{instance} Termau Gwasanaeth a Polisi Preifatrwydd"
   themes:
-    contrast: Cyferbyniad uchel
-    default: Mastodon
+    contrast: Mastodon (Cyferbyniad uchel)
+    default: Mastodon (Tywyll)
     mastodon-light: Mastodon (golau)
   time:
     formats:
@@ -901,6 +1101,16 @@ cy:
       subject: Mae eich archif yn barod i'w lawrlwytho
       title: Allfudo archif
     warning:
+      explanation:
+        disable: Er bod eich cyfrif wedi'i rewi, mae eich data cyfrif yn parhau i fod yn gyfan, ond ni allwch chi berfformio unrhyw gamau nes ei ddatgloi.
+        silence: Pan mae eich cyfrif yn gyfyngiedig, dim ond pobl sydd yn barod yn eich dilyn yn gweld eich tŵtiau ar y gweinydd hon, a efallai byddwch yn cael eich tynnu o restrau cyhoeddus. Er hyn, gall eraill eich dilyn chi wrth law.
+        suspend: Mae eich cyfrif wedi cael ei wahardd, a mae gyd o'ch tŵtiau a'ch ffeiliau cyfrwng uwchlwythadwy wedi cael eu tynnu or gweinydd yn barhaol, ac o weinyddau ble yr oedd eich dilynwyr.
+      review_server_policies: Adolygu polisïau'r gweinydd
+      subject:
+        disable: Mae'ch cyfrif %{acct} wedi'i rewi
+        none: Rhybudd am %{acct}
+        silence: Mae'ch cyfrif %{acct} wedi bod yn gyfyngedig
+        suspend: Mae'ch cyfrif %{acct} wedi'i atal
       title:
         disable: Cyfrif wedi'i rewi
         none: Rhybudd
@@ -912,7 +1122,7 @@ cy:
       explanation: Dyma ambell nodyn i'ch helpu i ddechrau
       final_action: Dechrau postio
       final_step: 'Dechrau postio! Hyd yn oed heb ddilynwyr mae''n bosib i eraill weld eich negeseuon cyhoeddus, er enghraifft at y ffrwd leol ac mewn hashnodau. Mae''n bosib yr hoffech hi gyflwyno''ch hun ar yr hashnod #introductions.'
-      full_handle: Eich enw Mastodon llawn
+      full_handle: Eich enw llawn
       full_handle_hint: Dyma'r hyn y bysech yn dweud wrth eich ffrindiau er mwyn iddyn nhw gael anfon neges atoch o achos arall.
       review_preferences_action: Newid dewisiadau
       review_preferences_step: Gwnewch yn siŵr i chi osod eich dewisiadau, megis pa e-byst hoffech eu derbyn, neu ba lefel preifatrwydd hoffech eich tŵtiau ragosod i. Os nad oes gennych salwch symud, gallwch ddewis i ganiatau chwarae GIFs yn awtomatig.
@@ -920,7 +1130,7 @@ cy:
       tip_federated_timeline: Mae'r ffrwd ffederasiwn yn olwg firehose o'r rhwydwaith Mastodon. Ond mae ond yn cynnwys y bobl mae eich cymdogion wedi ymrestru iddynt, felly nid yw'n gyflawn.
       tip_following: Rydych yn dilyn goruwchwyliwr eich gweinydd yn ddiofyn. I ganfod pobl mwy diddorol, edrychwch ar y ffrydiau lleol a'r rhai wedi ei ffedereiddio.
       tip_local_timeline: Mae'r ffrwd leol yn olwg firehose o bobl ar %{instance}. Dyma eich cymdogion agosaf!
-      tip_mobile_webapp: Os yw eich porwr gwe yn cynnig i ch ychwanegu Mastodon i'ch sgrîn gartref, mae modd i chi dderbyn hysbysiadau push. Mewn sawl modd mae'n gweithio fel ap cynhenid!
+      tip_mobile_webapp: Os yw eich porwr gwe yn cynnig i chi ychwanegu Mastodon i'ch sgrîn gartref, mae modd i chi dderbyn hysbysiadau gwthiadwy. Mewn sawl modd mae'n gweithio fel ap cynhenid!
       tips: Awgrymiadau
       title: Croeso, %{name}!
   users:
diff --git a/config/locales/da.yml b/config/locales/da.yml
index ca4ff32dac53e28fdc9a478a72fa149a0be2b766..da6ab1054514d89477b15549d8ae658ad00c291e 100644
--- a/config/locales/da.yml
+++ b/config/locales/da.yml
@@ -5,9 +5,8 @@ da:
     about_mastodon_html: Mastodon er et socialt netværk der er baseret på åbne web protokoller og frit, open-source source software. Der er decentraliseret ligesom e-mail tjenester.
     about_this: Om
     administered_by: 'Administreret af:'
-    api: API
     apps: Apps til mobilen
-    closed_registrations: Registreringer er på nuværrende tidspunkt lukkede for denne instans. Du kan dog finde andre instanser du kan oprette dig på og få adgang til det samme netværk derfra.
+    apps_platforms: Brug Mastodon på iOS, Android og andre platformer
     contact: Kontakt
     contact_missing: Ikke sat
     contact_unavailable: Ikke tilgængeligt
@@ -15,24 +14,11 @@ da:
     extended_description_html: |
       <h3>Et godt sted for regler</h3>
       <p>Den udvidede beskrivelse er endnu ikke blevet opsat.</p>
-    features:
-      humane_approach_body: Ved at lære fra fejl fra andre netværk, sigter Mastodon for at tage etisk designmæssig valg for at bekæmpe misbrug af sociale medier.
-      humane_approach_title: En mere human tilgang
-      not_a_product_body: Mastodon er ikke et kommercielt netværk. Ingen reklamer, ingen datamining, ingen indhegnet haver. Der er ingen central regering.
-      not_a_product_title: Du er en person, ikke et produkt
-      real_conversation_body: Med 500 tegn til din rådighed og understøttelse af granulært indhold og medie advarsler, kan du udtrykke dig på en hvilken som helst måde du ønsker.
-      real_conversation_title: Bygget til rigtige samtaler
-      within_reach_body: Adskillige apps for iOS, Android og andre platforme takket være et udviklervenligt API økosystem tillader dig at holde kontakten med dine venner hvor som helst.
-      within_reach_title: Altid indenfor rækkevidde
     generic_description: "%{domain} er en server i netværket"
     hosted_on: Mostodon hostet på %{domain}
     learn_more: Lær mere
-    other_instances: Liste over instanser
     privacy_policy: Privatlivspolitik
     source_code: Kildekode
-    status_count_after:
-      one: status
-      other: statusser
     status_count_before: Som har skrevet
     terms: Vilkår for service
     user_count_after:
@@ -97,8 +83,6 @@ da:
       display_name: Visningsnavn
       domain: Domæne
       edit: Rediger
-      email: Email
-      email_status: Email status
       enable: Aktiver
       enabled: Aktiveret
       feed_url: Link til feed
@@ -131,7 +115,7 @@ da:
       protocol: Protokol
       public: Offentligt
       push_subscription_expires: PuSH abonnement udløber
-      redownload: Opdater profilbillede
+      redownload: Opdater profil
       remove_avatar: Fjern profilbillede
       resend_confirmation:
         already_confirmed: Denne bruger er allerede blevet bekræftet
@@ -150,8 +134,8 @@ da:
       search: Søg
       shared_inbox_url: Link til delt indbakke
       show:
-        created_reports: Anmeldelser oprettet af denne konto
-        targeted_reports: Anmeldelser fra denne konto
+        created_reports: Anmeldelser oprettet
+        targeted_reports: Anmeldelser fra andre
       silence: Dæmp
       silenced: Dæmpet
       statuses: Statusser
@@ -163,7 +147,6 @@ da:
       undo_suspension: Fortryd udelukkelse
       unsubscribe: Abonner ikke længere
       username: Brugernavn
-      web: Web
     action_logs:
       actions:
         assigned_to_self_report: "%{name} tildelte anmeldelsen %{target} til sig selv"
@@ -234,7 +217,6 @@ da:
       recent_users: Seneste brugere
       search: Søg på fuld tekst
       single_user_mode: Enkelt bruger mode
-      software: Software
       space: Brugt lagerplads
       title: Betjeningspanel
       total_users: samlede antal brugere
@@ -243,7 +225,7 @@ da:
       week_users_active: aktive denne uge
       week_users_new: brugere denne uge
     domain_blocks:
-      add_new: Tilføj ny
+      add_new: Tilføj ny domain block
       created_msg: Domæne blokade bliver nu behandlet
       destroyed_msg: Domæne blokade er blevet annulleret
       domain: Domæne
@@ -268,7 +250,7 @@ da:
           suspend: Fjern udelukkelsen af alle eksisterende konti fra dette domæne
         title: Annuller domæne blokeringen for domænet %{domain}
         undo: Fortryd
-      undo: Fortryd
+      undo: Fortryd domain block
     email_domain_blocks:
       add_new: Tilføj ny
       created_msg: Tilføjede succesfuldt email domænet til sortliste
@@ -282,7 +264,7 @@ da:
     followers:
       back_to_account: Tilbage til konto
     instances:
-      title: Kendte instanser
+      title: Førderation
     invites:
       deactivate_all: Deaktiver alle
       filter:
@@ -304,7 +286,6 @@ da:
       pending: Venter på godkendelse fra relæet
       save_and_enable: Gem og aktiver
       setup: Opsæt en videresendelses forbindelse
-      status: Status
       title: Videresendelser
     report_notes:
       created_msg: Anmeldelse note blev oprettet!
@@ -334,7 +315,6 @@ da:
       reported_by: Anmeldt af
       resolved: Løst
       resolved_msg: Anmeldelse er sat til at være løst!
-      status: Status
       title: Anmeldelser
       unassign: Utildel
       unresolved: Uløst
@@ -353,11 +333,11 @@ da:
         desc_html: Ændre udseendet med CSS indlæst på hver side
         title: Brugerdefineret CSS
       hero:
-        desc_html: Vist på forsiden. Mindst 600x100px anbefales. Hvis ikke sat, vil dette falde tilbage til billedet for instansen
+        desc_html: Vist på forsiden. Mindst 600x100px anbefales. Hvis ikke sat, vil dette falde tilbage til billedet fra serveren
         title: Billede af helt
       peers_api_enabled:
-        desc_html: Domæne navne denne instans er stødt på i fediverset
-        title: Udgiv liste over opdagede instanser
+        desc_html: Domæne navne denne server er stødt på i fediverset
+        title: Udgiv liste over opdagede server
       preview_sensitive_media:
         desc_html: Forhåndsvisninger af links på andre websider vil vise et miniaturebillede selv hvis mediet er markeret som følsomt
         title: Vis følsomt medie i OpenGraph forhåndsvisninger
@@ -371,9 +351,6 @@ da:
         min_invite_role:
           disabled: Ingen
           title: Tillad invitationer af
-        open:
-          desc_html: Tillad alle at oprette en konto
-          title: Ã…ben registrering
       show_known_fediverse_at_about_page:
         desc_html: Når slået til, vil det vise trut fra hele det kendte fedivers på forhåndsvisning. Ellers vil det kun vise lokale trut.
         title: Vis kendte fedivers på tidslinje forhåndsvisning
@@ -382,20 +359,20 @@ da:
         title: Vis personale emblem
       site_description:
         desc_html: Introduktions afsnit på forsiden. Beskriv hvad der gør denne Mastodon server speciel og alt andet vigtigt. Du kan bruge HTML tags, især <code>&lt;a&gt;</code> og <code>&lt;em&gt;</code>.
-        title: Beskrivelse af instans
+        title: Beskrivelse af serveren
       site_description_extended:
-        desc_html: Et godt sted for placering af adfærdskodes, regler, retningslinjer og andre ting der gør din instans unik. Du kan bruge HTML tags
+        desc_html: Et godt sted for placering af adfærdskodes, regler, retningslinjer og andre ting der gør din server unik. Du kan bruge HTML tags
         title: Brugerdefineret udvidet information
       site_short_description:
-        desc_html: Vist på sidelinjen og meta tags. Beskriv hvad Mastodon er og hvad der gør denne server speciel i et enkelt afsnit. Hvis tomt, vil standard være beskrivelsen af instansen.
-        title: Kort beskrivelse af instans
+        desc_html: Vist på sidelinjen og meta tags. Beskriv hvad Mastodon er og hvad der gør denne server speciel i et enkelt afsnit. Hvis tomt, vil standard være beskrivelsen af serveren.
+        title: Kort beskrivelse af serveren
       site_terms:
         desc_html: Du kan skrive din egen privatlivpolitik, servicevilkår, eller lignende. Du kan bruge HTML tags
         title: Brugerdefineret servicevilkår
-      site_title: Navn på instans
+      site_title: Navn af serveren
       thumbnail:
         desc_html: Brugt til forhåndsvisninger via OpenGraph og API. 1200x630px anbefales
-        title: Miniaturebillede for instans
+        title: Miniaturebillede for serveren
       timeline_preview:
         desc_html: Vis offentlig tidslinje på landingssiden
         title: Tidslinje forhåndsvisning
@@ -423,7 +400,6 @@ da:
     tags:
       accounts: Kontoer
       hidden: Skjult
-    title: Administration
   admin_mailer:
     new_report:
       body: "%{reporter} har anmeldt %{target}"
@@ -431,7 +407,6 @@ da:
       subject: Ny anmeldelse for %{instance} (#%{id})
   application_mailer:
     notification_preferences: Ændre email præferencer
-    salutation: "%{name},"
     settings: 'Ændre email præferencer: %{link}'
     view: 'Se:'
     view_profile: Se profil
@@ -445,7 +420,6 @@ da:
     warning: Vær meget forsigtig med disse data. Del dem aldrig med nogen!
     your_token: Din adgangs token
   auth:
-    agreement_html: Ved at oprette dig erklærer du dig enig i at følge <a href="%{rules_path}">instanses regler</a> og <a href="%{terms_path}">vores servicevilkår</a>.
     change_password: Kodeord
     confirm_email: Bekræft email
     delete_account: Slet konto
@@ -457,13 +431,8 @@ da:
     logout: Log ud
     migrate_account: Flyt til en anden konto
     migrate_account_html: Hvis du ønsker at omdirigere denne konto til en anden, kan du <a href="%{path}">gøre det her</a>.
-    or: eller
     or_log_in_with: Eller log in med
-    providers:
-      cas: CAS
-      saml: SAML
     register: Opret dig
-    register_elsewhere: Opret dig på en anden server
     resend_confirmation: Gensend bekræftelses instrukser
     reset_password: Nulstil kodeord
     security: Sikkerhed
@@ -486,20 +455,16 @@ da:
       about_x_years: "%{count}Ã¥r"
       almost_x_years: "%{count}Ã¥r"
       half_a_minute: Lige nu
-      less_than_x_minutes: "%{count}m"
       less_than_x_seconds: Lige nu
       over_x_years: "%{count}Ã¥r"
-      x_days: "%{count}d"
-      x_minutes: "%{count}m"
       x_months: "%{count}md"
-      x_seconds: "%{count}s"
   deletes:
     bad_password_msg: Godt forsøg, hackere! Forkert kodeord
     confirm_password: Indtast dit nuværende kodeord for at bekræfte din identitet
     description_html: Dette vil <strong>permanent, uigenkaldeligt</strong> fjerne indhold fra din konto samt deaktivere den. Dit brugernavn vil forblive reserveret for at forhindre fremtidige efterligninger.
     proceed: Slet konto
     success_msg: Din konto er nu blevet slettet
-    warning_html: Kun sletning af indhold fra denne specifikke instans er garanteret. Indhold der er blevet delt rundt omkring vil sandsynligvis efterlade spor. Offline servere og servere der ikke længere abonnerer på dine opdateringer vil ikke opdatere deres databaser.
+    warning_html: Kun sletning af indhold fra denne specifikke server er garanteret. Indhold der er blevet delt rundt omkring vil sandsynligvis efterlade spor. Offline servere og servere der ikke længere abonnerer på dine opdateringer vil ikke opdatere deres databaser.
     warning_title: Tilgængelighed af delt indhold
   errors:
     '403': Du har ikke tilladelse til at se denne side.
@@ -522,7 +487,6 @@ da:
       request: Anmod om dit arkiv
       size: Størrelse
     blocks: Du blokerer
-    csv: CSV
     follows: Du følger
     mutes: Du dæmper
     storage: Medie lager
@@ -542,18 +506,6 @@ da:
       title: Filtrer
     new:
       title: Tilføj nyt filter
-  followers:
-    domain: Domæne
-    explanation_html: Hvis du vil sikre dig privatliv over dine statusser, skal du være klar over hvem der følger dig. <strong>Dine private statusser leveres til alle instanser som du har følger fra</strong>. Det kan være en ide at gennemgå dem, og fjerne følgere hvis du ikke føler dit privatliv respekteres af personalet eller software fra disse instanser.
-    followers_count: Antal følgere
-    lock_link: LÃ¥s din konto
-    purge: Fjern fra følgere
-    success:
-      one: I gang med at soft-blokere følgere fra et domæne...
-      other: I gang med at soft-blokere følgere fra %{count} domæner...
-    true_privacy_html: Husk på, at <strong>sand privatliv kan kun opnås via end-to-end kryptering</strong>.
-    unlocked_warning_html: Alle kan følge dig med det samme for at se dine private statusser. %{lock_link} for at være i stand til at gennemse og afvise følgere.
-    unlocked_warning_title: Din konto er ikke låst
   footer:
     developers: Udviklere
     more: Mere…
@@ -566,7 +518,7 @@ da:
       one: Der er noget der ikke er helt som det bør være! Tag lige et kig på følgende fejl forneden
       other: Der er noget der ikke er helt som det bør være! Tag lige et kig på følgende %{count} fejl forneden
   imports:
-    preface: Du kan importere data du har eksporteret fra en anden instans, så som en liste over folk du følger eller blokerer.
+    preface: Du kan importere data du har eksporteret fra en anden server, så som en liste over folk du følger eller blokerer.
     success: Dine data blev succesfuldt uploaded og vil nu blive behandlet hurtigst muligt
     types:
       blocking: Blokeringsliste
@@ -591,7 +543,7 @@ da:
       one: 1 benyttelse
       other: "%{count} benyttelser"
     max_uses_prompt: Ubegrænset
-    prompt: Generer og del links med andre for at give dem adgang til denne instans
+    prompt: Generer og del links med andre for at give dem adgang til denne server
     table:
       expires_at: Udløber
       uses: Benyttelser
@@ -647,14 +599,9 @@ da:
   number:
     human:
       decimal_units:
-        format: "%n%u"
         units:
           billion: mia.
           million: mio.
-          quadrillion: Q
-          thousand: K
-          trillion: T
-          unit: "\n"
   pagination:
     newer: Nyere
     next: Næste
@@ -662,10 +609,7 @@ da:
     prev: Forrige
     truncate: "...&hellip;"
   preferences:
-    languages: Sprog
     other: Andet
-    publishing: Offentligører
-    web: Web
   remote_follow:
     acct: Indtast dit brugernavn@domæne du vil handle fra
     missing_resource: Kunne ikke finde det påkrævede omdirigerings link for din konto
@@ -678,7 +622,6 @@ da:
     unfollowed: Følger ikke længere
   sessions:
     activity: Sidste aktivitet
-    browser: Browser
     browsers:
       alipay: Ali-pay
       blackberry: Blackberry OS
@@ -700,15 +643,11 @@ da:
     current_session: Nuværrende session
     description: "%{browser} på %{platform}"
     explanation: Disse er de web browsere der på nuværende tidspunkt er logget ind på din Mastodon konto.
-    ip: IP
     platforms:
       adobe_air: Adobe air
-      android: Android
       blackberry: Blackberry OS
       chrome_os: Chromeos
       firefox_os: Firefox Os
-      ios: iOS
-      linux: Linux
       mac: Mac.
       other: ukendt platform
       windows: Microsoft windows
@@ -724,23 +663,17 @@ da:
     development: Udvikling
     edit_profile: Rediger profil
     export: Data eksportering
-    followers: Godkendte følgere
     import: Importer
     migrate: Konto migrering
     notifications: Notifikationer
     preferences: Præferencer
-    settings: Indstillinger
     two_factor_authentication: To-faktor godkendelse
-    your_apps: Dine applikationer
   statuses:
     attached:
       description: 'Vedhæftede: %{attached}'
       image:
         one: "%{count} billede"
         other: "%{count} billeder"
-      video:
-        one: "%{count} video"
-        other: "%{count} videoer"
     boosted_from_html: Fremhævet fra %{acct_link}
     content_warning: 'Advarsel om indhold: %{warning}'
     disallowed_hashtags:
@@ -756,7 +689,6 @@ da:
       reblog: Fremhævede trut kan ikke fastgøres
     show_more: Vis mere
     sign_in_to_participate: Log ind for at deltage i samtalen
-    title: '%{name}: "%{quote}"'
     visibilities:
       private: Kun-følgere
       private_long: Vis kun til følgere
@@ -772,13 +704,9 @@ da:
     body_html: "<p><h2> Privatlivspolitik </h2> \n<h3 id=\"collect\">Hvilke information indsamler vi?</h3> \n\n<ul>\n  <li><em>Grundlæggende kontoinformation </em>: Hvis du registrerer dig på denne server, bliver du måske bedt om at indtaste et brugernavn, en e-mail-adresse og et kodeord. Du kan også indtaste yderligere profiloplysninger, såsom et visningsnavn og biografi, og uploade et profilbillede og headerbillede. Brugernavnet, visningsnavnet, biografien, profilbilledet og hovedbilledet vises altid offentligt. </li> \n  <li> <em>Stillinger, følgende og andre offentlige oplysninger </em>: Listen over personer du følger er offentliggjort, det samme gælder for dine tilhængere. Når du sender en besked, gemmes datoen og klokkeslættet såvel som det program, du sendte beskeden fra. Meddelelser kan indeholde medievedhæftninger, som f.eks. Billeder og videoer. Offentlige og unoterede indlæg er offentligt tilgængelige. Når du har et indlæg på din profil, er det også offentligt tilgængelig information. Dine indlæg leveres til dine tilhængere, i nogle tilfælde betyder det, at de leveres til forskellige servere, og der gemmes kopier der. Når du sletter indlæg, leveres det også til dine tilhængere. Handlingen med reblogging eller favorisering af et andet indlæg er altid offentligt. </li>\n  <li><em> Direkte og efterfølger-kun indlæg </ em>: Alle indlæg gemmes og behandles på serveren. Følgere-kun indlæg leveres til dine tilhængere og brugere, der er nævnt i dem, og direkte indlæg leveres kun til brugere nævnt i dem. I nogle tilfælde betyder det, at de leveres til forskellige servere, og der gemmes kopier der. Vi gør en god tro for at begrænse adgangen til disse stillinger kun til autoriserede personer, men andre servere kan undlade at gøre det. Derfor er det vigtigt at gennemgå de servere, dine tilhængere tilhører. Du kan skifte en mulighed for at godkende og afvise nye følgere manuelt i indstillingerne. <em> Vær opmærksom på, at operatørerne af serveren og enhver modtagende server muligvis kan se sådanne meddelelser </em>, og at modtagere muligvis skærmbilleder, kopierer eller på anden vis deler dem igen. <em> Del ikke nogen farlig information over Mastodon. </em> </li>\n  <li> <em> IP'er og andre metadata </em>: Når du logger ind, registrerer vi den IP-adresse, du logger ind fra, samt navnet på din browser-applikation. Alle indloggede sessioner er tilgængelige til din anmeldelse og tilbagekaldelse i indstillingerne. Den seneste anvendte IP-adresse gemmes i op til 12 måneder. Vi kan også beholde serverlogfiler, som indeholder IP-adressen til hver anmodning til vores server. </li>\n</ul>\n\n<hr class=\"spacer\" />\n\n<h3 id=\"use\">Hvad bruger vi dine oplysninger til? </h3>\n\n<p> Enhver af de oplysninger, vi indsamler fra dig, kan bruges på følgende måder: </p>\n\n<ul>\n  <li> At levere kernen funktionalitet Mastodon. Du kan kun interagere med andres indhold og indsende dit eget indhold, når du er logget ind. Du kan f.eks. Følge andre personer for at se deres kombinerede indlæg på din egen personlige tidslinje. </li>\n  <li> For at hjælpe moderering af samfundet, f.eks. sammenligning af din IP-adresse med andre kendte, for at bestemme forbud mod unddragelse eller andre overtrædelser. </li>\n  <li> Den e-mail-adresse, du angiver, kan bruges til at sende dig oplysninger, meddelelser om andre personer, der interagerer med dit indhold eller sender dig beskeder, og for at svare på henvendelser og / eller andre forespørgsler eller spørgsmål. </li>\n</ul>\n\n<hr class=\"spacer\" />\n\n<h3 id=\"protect\">Hvordan beskytter vi dine oplysninger? </h3>\n\n<p> Vi implementerer en række sikkerhedsforanstaltninger for at opretholde sikkerheden for dine personlige oplysninger, når du indtaster, indsender eller har adgang til dine personlige oplysninger. Bl.a. er din browsersession samt trafikken mellem dine applikationer og API'en sikret med SSL, og din adgangskode er hashed ved hjælp af en stærk envejsalgoritme. Du kan muligvis aktivere tofaktors godkendelse for yderligere at sikre adgang til din konto. </p>\n\n<hr class=\"spacer\" />\n\n<h3 id=\"data-retention\"> Hvad er vores data retention politik? </h3>\n\n<p> Vi vil gøre en god tro indsats for at: </p>\n\n<ul>\n  <li> Behold serverlogfiler, der indeholder IP-adressen på alle anmodninger til denne server, for så vidt som sådanne logfiler holdes, ikke mere end 90 dage. </li>\n  <li> Behold de IP-adresser, der er forbundet med registrerede brugere, ikke mere end 12 måneder. </li>\n</ul>\n\n<p> Du kan anmode om og downloade et arkiv af dit indhold, herunder dine indlæg, medievedhæftninger, profilbillede og headerbillede. </p>\n\n<p> Du kan til enhver tid slette din konto. </p>\n\n<hr class=\"spacer\" />\n\n<h3 id=\"cookies\"> Bruger vi cookies? </h3>\n\n<p> Ja. Cookies er små filer, som et websted eller dets tjenesteudbyder overfører til din computers harddisk via din webbrowser (hvis du tillader det). Disse cookies gør det muligt for webstedet at genkende din browser og, hvis du har en registreret konto, associerer den med din registrerede konto. </p>\n\n<p> Vi bruger cookies til at forstå og gemme dine præferencer til fremtidige besøg. </p>\n\n<hr class=\"spacer\" />\n\n<h3 id=\"disclose\"> Viser vi nogen information til eksterne parter? </h3>\n\n<p> Vi sælger ikke, handler eller på anden måde overfører dine personlige identificerbare oplysninger til eksterne parter. Dette omfatter ikke tillid til tredjeparter, der hjælper os med at drive vores hjemmeside, udføre vores forretning eller servicere dig, så længe parterne er enige om at holde disse oplysninger fortrolige. Vi kan også frigive dine oplysninger, når vi mener, at udgivelsen er hensigtsmæssig for at overholde loven, håndhæve vores webstedspolitikker eller beskytte vores eller andre rettigheder, ejendom eller sikkerhed. </p>\n\n<p> Dit offentlige indhold kan downloades af andre servere i netværket. Dine offentlige og efterfølger-kun indlæg leveres til de servere, hvor dine tilhængere er bosat, og direkte meddelelser leveres til modtagerens servere, for så vidt som disse tilhængere eller modtagere opholder sig på en anden server end dette. </p>\n\n<p> Når du autoriserer et program til at bruge din konto, afhænger det af omfanget af tilladelser, du godkender, det kan få adgang til dine offentlige profiloplysninger, din følgende liste, dine tilhængere, dine lister, alle dine indlæg og dine favoritter. Applikationer kan aldrig få adgang til din e-mail-adresse eller adgangskode. </p>\n\n<hr class=\"spacer\" />\n\n<h3 id=\"children\"> Bebyggelse af børn </h3>\n\n<p> Hvis denne server er i EU eller EØS: Vores websted, produkter og tjenester er alle rettet mod personer, der er mindst 16 år gamle. Hvis du er under 16 år, skal du ikke bruge dette websted efter kravene i GDPR (<a href=\"https://en.wikipedia.org/wiki/General_Data_Protection_Regulation\"> Generel databeskyttelsesforordning </a>). . </p>\n\n<p> Hvis denne server er i USA: Vores websted, produkter og tjenester er alle rettet mod personer, der er mindst 13 år. Hvis du er under 13 år, skal du ikke bruge kravene i COPPA (<a href=\"https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act\"> Børns online beskyttelse af personlige oplysninger </a>) dette websted. </p>\n\n<p> Lovkrav kan være anderledes, hvis denne server er i en anden jurisdiktion. </p>\n\n<hr class = \"spacer\" />\n\n<h3 id=\"changes\"> Ændringer i vores privatlivspolitik </h3>\n\n<p> Hvis vi beslutter os for at ændre vores privatlivspolitik, vil vi sende disse ændringer på denne side. </p>\n\n<p> Dette dokument er CC-BY-SA. Det blev senest opdateret 7. marts 2018. </p>\n\n<p> Oprindelig tilpasset fra <a href=\"https://github.com/discourse/discourse\"> Discourse privacy policy </a>.</p>\n"
     title: Vilkår og privatlivpolitik for %{instance}
   themes:
-    contrast: Høj kontrast
-    default: Mastodont
-    mastodon-light: Mastodon (lys)
-  time:
-    formats:
-      default: "%b %d, %Y, %H:%M"
-      month: "%b %Y"
+    contrast: Mastodon (Høj kontrast)
+    default: Mastodont (Mørk)
+    mastodon-light: Mastodon (Lys)
   two_factor_authentication:
     code_hint: Indtast koden der er genereret af din app for at bekræfte
     description_html: Hvis du aktiverer <strong>to-faktor godkendelse</strong>, vil du være nødt til at være i besiddelse af din telefon, der genererer tokens som du skal indtaste, når du logger ind.
@@ -807,7 +735,7 @@ da:
       final_action: Kom igang med at poste
       final_step: 'Start med at skrive opslag! Selv uden følgere vil dine offentlige beskeder kunne ses af andre, foreksempel på den lokale tidslinje og i hashtags. Måske kunne du tænke dig at introducere dig selv på #introductions hashtagget.'
       full_handle: Dit fulde brugernavn
-      full_handle_hint: Dette er hvad du vil fortælle dine venner så de kan sende dig beskeder eller følge dig fra andre instanser.
+      full_handle_hint: Dette er hvad du vil fortælle dine venner så de kan sende dig beskeder eller følge dig fra andre server.
       review_preferences_action: Ændre præferencer
       review_preferences_step: Vær sikker på at sætte dine præferencer, så som hvilke emails du kunne tænke dig at modtage, eller hvilket niveau af privatliv der skal være standard for dine opslag. Hvis du kunne tænke dig ikke at blive køresyg, kan du vælge at aktivere automatisk afspilning af GIFfer.
       subject: Velkommen til Mastodon
diff --git a/config/locales/de.yml b/config/locales/de.yml
index b9074662e228a747d8bbb960a34fbabdccee732a..cfdaacab0657d17a66674eb585cc8fedae6e954a 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -1,51 +1,51 @@
 ---
 de:
   about:
-    about_hashtag_html: Dies sind öffentliche Beiträge, die mit <strong>#%{hashtag}</strong> getaggt wurden. Wenn du irgendwo im Fediversum ein Konto besitzt, kannst du mit ihnen interagieren.
+    about_hashtag_html: Das sind öffentliche Beiträge, die mit <strong>#%{hashtag}</strong> getaggt wurden. Wenn du irgendwo im Fediversum ein Konto besitzt, kannst du mit ihnen interagieren.
     about_mastodon_html: Mastodon ist ein soziales Netzwerk. Es basiert auf offenen Web-Protokollen und freier, quelloffener Software. Es ist dezentral (so wie E-Mail!).
-    about_this: Über diese Instanz
-    administered_by: 'Administriert von:'
+    about_this: Über diesen Server
+    active_count_after: aktiv
+    active_footnote: Monatlich Aktive Nutzer_innen (MAU)
+    administered_by: 'Betrieben von:'
     api: API
     apps: Mobile Apps
-    closed_registrations: Die Registrierung auf dieser Instanz ist momentan geschlossen. Aber du kannst dein Konto auch auf einer anderen Instanz erstellen! Von dort hast du genauso Zugriff auf das Mastodon-Netzwerk.
+    apps_platforms: Benutze Mastodon auf iOS, Android und anderen Plattformen
+    browse_directory: Durchsuche das Profilverzeichnis und filtere nach Interessen
+    browse_public_posts: Stöbere durch öffentliche Beiträge auf Mastodon
     contact: Kontakt
     contact_missing: Nicht angegeben
-    contact_unavailable: N/A
+    contact_unavailable: Nicht verfügbar
+    discover_users: Benutzer_innen entdecken
     documentation: Dokumentation
     extended_description_html: |
-      <h3>Ein guter Platz für Regeln</h3>
-      <p>Die erweiterte Beschreibung wurde noch nicht aufgesetzt.</p>
-    features:
-      humane_approach_body: Aus den Fehlern anderer Netzwerke lernend, zielt Mastodon darauf ab, mit ethischen Design-Entscheidungen den Missbrauch sozialer Medien zu verhindern.
-      humane_approach_title: Ein menschlicherer Ansatz
-      not_a_product_body: Mastodon ist kein kommerzielles Netzwerk. Keine Werbung, kein Abgraben deiner Daten, keine geschlossene Plattform. Es gibt keine Zentrale.
-      not_a_product_title: Du bist ein Mensch und keine Ware
-      real_conversation_body: Mit 65535 Zeichen pro Beitrag und Features wie Inhalts- und Bilderwarnungen kannst du dich so ausdrücken, wie du es möchtest.
-      real_conversation_title: Geschaffen für echte Gespräche
-      within_reach_body: Verschiedene Apps für iOS, Android und andere Plattformen erlauben es dir, dank unseres blühenden API-Ökosystems, dich von überall auf dem Laufenden zu halten.
-      within_reach_title: Immer für dich da
-    generic_description: "%{domain} ist ein Server im Netzwerk"
-    hosted_on: Mastodon, beherbergt auf %{domain}
+      <h3>Ein hervorragender Ort für Regeln</h3>
+      <p>Die erweiterte Beschreibung wurde von dem Administrator noch nicht eingestellt.</p>
+    federation_hint_html: Mit einem Konto auf %{instance} wirst du in der Lage sein Nutzer_innen auf beliebigen Mastodon-Servern und darüber hinaus zu folgen.
+    generic_description: "%{domain} ist ein Server im Fediversum"
+    get_apps: Versuche eine mobile App
+    hosted_on: Mastodon, gehostet auf %{domain}
     learn_more: Mehr erfahren
-    other_instances: Andere Instanzen
     privacy_policy: Datenschutzerklärung
+    see_whats_happening: Finde heraus, was gerade in der Welt los ist
+    server_stats: 'Serverstatistiken:'
     source_code: Quellcode
     status_count_after:
-      one: Statusmeldung
-      other: Statusmeldungen
+      one: Beitrag
+      other: Beiträge
     status_count_before: mit
+    tagline: Finde deine Freunde und entdecke neue
     terms: Nutzungsbedingungen
     user_count_after:
-      one: Benutzer:in
-      other: Benutzer:innen
-    user_count_before: Zuhause für
+      one: Profil
+      other: Profile
+    user_count_before: Hostet
     what_is_mastodon: Was ist Mastodon?
   accounts:
     choices_html: "%{name} empfiehlt:"
     follow: Folgen
     followers:
-      one: Folgender
-      other: Folgende
+      one: Folger_innen
+      other: Folger_innen
     following: Folgt
     joined: Beigetreten am %{date}
     last_active: zuletzt aktiv
@@ -65,9 +65,10 @@ de:
     posts_with_replies: Beiträge mit Antworten
     reserved_username: Dieser Profilname ist belegt
     roles:
-      admin: Admin
+      admin: Administrator
       bot: Bot
       moderator: Moderator
+    unavailable: Profil nicht verfügbar
     unfollow: Entfolgen
   admin:
     account_actions:
@@ -79,6 +80,8 @@ de:
       delete: Löschen
       destroyed_msg: Moderationsnotiz erfolgreich gelöscht!
     accounts:
+      approve: Akzeptieren
+      approve_all: Alle akzeptieren
       are_you_sure: Bist du sicher?
       avatar: Profilbild
       by_domain: Domain
@@ -105,10 +108,10 @@ de:
       enable: Freischalten
       enabled: Freigegeben
       feed_url: Feed-URL
-      followers: Folgende
-      followers_url: URL des Folgenden
+      followers: Folger_innen
+      followers_url: URL der Folger_innen
       follows: Folgt
-      header: Header
+      header: Titelbild
       inbox_url: Posteingangs-URL
       invited_by: Eingeladen von
       ip: IP-Adresse
@@ -116,35 +119,40 @@ de:
       location:
         all: Alle
         local: Lokal
-        remote: Entfernt
-        title: Ort
+        remote: Fern
+        title: Ursprung
       login_status: Loginstatus
-      media_attachments: Medienanhänge
+      media_attachments: Dateien
       memorialize: In Gedenkmal verwandeln
       moderation:
         active: Aktiv
         all: Alle
+        pending: In Warteschlange
         silenced: Stummgeschaltet
         suspended: Gesperrt
         title: Moderation
       moderation_notes: Moderationsnotizen
       most_recent_activity: Letzte Aktivität
       most_recent_ip: Letzte IP-Adresse
-      no_limits_imposed: Keine Limits eingesetzt
+      no_account_selected: Keine Konten wurden geändert, da keine ausgewählt wurden
+      no_limits_imposed: Keine Beschränkungen
       not_subscribed: Nicht abonniert
       outbox_url: Postausgangs-URL
-      perform_full_suspension: Sperren
+      pending: In Warteschlange
+      perform_full_suspension: Verbannen
       profile_url: Profil-URL
       promote: Befördern
       protocol: Protokoll
       public: Öffentlich
       push_subscription_expires: PuSH-Abonnement läuft aus
       redownload: Profil neu laden
+      reject: Ablehnen
+      reject_all: Alle ablehnen
       remove_avatar: Profilbild entfernen
-      remove_header: Header entfernen
+      remove_header: Titelbild entfernen
       resend_confirmation:
-        already_confirmed: Diese:r Benutzer:in wurde bereits bestätigt
-        send: Bestätigungsmail erneut senden
+        already_confirmed: Diese_r Benutzer_in wurde bereits bestätigt
+        send: Bestätigungs-E-Mail erneut senden
         success: Bestätigungs-E-Mail erfolgreich gesendet!
       reset: Zurücksetzen
       reset_password: Passwort zurücksetzen
@@ -152,24 +160,25 @@ de:
       role: Berechtigungen
       roles:
         admin: Administrator
-        moderator: Moderator:in
+        moderator: Moderator_in
         staff: Mitarbeiter
         user: Nutzer
       salmon_url: Salmon-URL
       search: Suche
       shared_inbox_url: Geteilte Posteingang-URL
       show:
-        created_reports: Erstellte Beschwerdemeldungen
-        targeted_reports: Beschwerdemeldungen von anderen
+        created_reports: Erstellte Meldungen
+        targeted_reports: Von anderen gemeldet
       silence: Stummschalten
       silenced: Stummgeschaltet
       statuses: Beiträge
       subscribe: Abonnieren
-      suspended: Gesperrt
+      suspended: Verbannt
+      time_in_queue: "%{time} in der Warteschlange"
       title: Konten
       unconfirmed_email: Unbestätigte E-Mail-Adresse
-      undo_silenced: Stummschaltung zurücknehmen
-      undo_suspension: Sperre zurücknehmen
+      undo_silenced: Stummschaltung aufheben
+      undo_suspension: Verbannung aufheben
       unsubscribe: Abbestellen
       username: Profilname
       warn: Warnen
@@ -183,29 +192,29 @@ de:
         create_custom_emoji: "%{name} hat neues Emoji %{target} hochgeladen"
         create_domain_block: "%{name} hat die Domain %{target} blockiert"
         create_email_domain_block: "%{name} hat die E-Mail-Domain %{target} geblacklistet"
-        demote_user: "%{name} stufte Benutzer:in %{target} herunter"
+        demote_user: "%{name} stufte Benutzer_in %{target} herunter"
         destroy_custom_emoji: "%{name} zerstörte Emoji %{target}"
         destroy_domain_block: "%{name} hat die Domain %{target} entblockt"
         destroy_email_domain_block: "%{name} hat die E-Mail-Domain %{target} gewhitelistet"
-        destroy_status: "%{name} hat Status von %{target} entfernt"
-        disable_2fa_user: "%{name} hat Zwei-Faktor-Anforderung für Benutzer:in %{target} deaktiviert"
+        destroy_status: "%{name} hat einen Beitrag von %{target} entfernt"
+        disable_2fa_user: "%{name} hat Zwei-Faktor-Anforderung für Benutzer_in %{target} deaktiviert"
         disable_custom_emoji: "%{name} hat das %{target} Emoji deaktiviert"
-        disable_user: "%{name} hat den Login für Benutzer:in  %{target} deaktiviert"
+        disable_user: "%{name} hat Zugang von Benutzer_in %{target} deaktiviert"
         enable_custom_emoji: "%{name} hat das %{target} Emoji aktiviert"
-        enable_user: "%{name} hat die Anmeldung für di:en Benutzer:in %{target} aktiviert"
-        memorialize_account: "%{name} hat %{target}s Konto in eine Gedenkseite umgewandelt"
+        enable_user: "%{name} hat Zugang von Benutzer_in %{target} aktiviert"
+        memorialize_account: "%{name} hat das Konto von %{target} in eine Gedenkseite umgewandelt"
         promote_user: "%{name} hat %{target} befördert"
         remove_avatar_user: "%{name} hat das Profilbild von %{target} entfernt"
         reopen_report: "%{name} hat die Meldung %{target} wieder geöffnet"
-        reset_password_user: "%{name} hat das Passwort für di:en Benutzer:in %{target} zurückgesetzt"
+        reset_password_user: "%{name} hat das Passwort von %{target} zurückgesetzt"
         resolve_report: "%{name} hat die Meldung %{target} bearbeitet"
-        silence_account: "%{name} hat %{target}s Konto stummgeschaltet"
-        suspend_account: "%{name} hat %{target}s Konto gesperrt"
+        silence_account: "%{name} hat das Konto von %{target} stummgeschaltet"
+        suspend_account: "%{name} hat das Konto von %{target} verbannt"
         unassigned_report: "%{name} hat die Zuweisung der Meldung %{target} entfernt"
-        unsilence_account: "%{name} hat die Stummschaltung von %{target}s Konto aufgehoben"
-        unsuspend_account: "%{name} hat die Sperrung von %{target}s Konto aufgehoben"
-        update_custom_emoji: "%{name} hat das %{target} Emoji aktualisiert"
-        update_status: "%{name} hat den Status von %{target} aktualisiert"
+        unsilence_account: "%{name} hat die Stummschaltung von %{target} aufgehoben"
+        unsuspend_account: "%{name} hat die Verbannung von %{target} aufgehoben"
+        update_custom_emoji: "%{name} hat das %{target} Emoji geändert"
+        update_status: "%{name} hat einen Beitrag von %{target} aktualisiert"
       deleted_status: "(gelöschter Beitrag)"
       title: Überprüfungsprotokoll
     custom_emojis:
@@ -221,7 +230,7 @@ de:
       emoji: Emoji
       enable: Aktivieren
       enabled_msg: Das Emoji wurde aktiviert
-      image_hint: PNG bis 50 kB
+      image_hint: PNG bis zu 50 kB
       listed: Gelistet
       new:
         title: Eigenes Emoji hinzufügen
@@ -234,32 +243,34 @@ de:
       updated_msg: Emoji erfolgreich aktualisiert!
       upload: Hochladen
     dashboard:
-      backlog: Unerledigte Jobs
+      backlog: Rückständige Jobs
       config: Konfiguration
       feature_deletions: Kontolöschung
-      feature_invites: Einladungslinks
+      feature_invites: Einladungen
       feature_profile_directory: Profilverzeichnis
-      feature_registrations: Registrierung
-      feature_relay: Föderations-Relay
-      features: Eigenschaften
+      feature_registrations: Offene Anmeldung
+      feature_relay: Föderationsrelais
+      feature_timeline_preview: Zeitleistenvorschau
+      features: Funktionen
       hidden_service: Föderation mit versteckten Diensten
-      open_reports: Offene Meldungen
+      open_reports: Ausstehende Meldungen
       recent_users: Neueste Nutzer
       search: Volltextsuche
       single_user_mode: Einzelnutzermodus
       software: Software
       space: Speicherverbrauch
       title: Übersicht
-      total_users: Benutzer:innen insgesamt
+      total_users: Benutzer_innen insgesamt
       trends: Trends
       week_interactions: Interaktionen diese Woche
       week_users_active: Aktiv diese Woche
-      week_users_new: Benutzer:innen diese Woche
+      week_users_new: Benutzer_innen diese Woche
     domain_blocks:
       add_new: Neue Domainblockade hinzufügen
       created_msg: Die Domain-Blockade wird nun durchgeführt
       destroyed_msg: Die Domain-Blockade wurde rückgängig gemacht
       domain: Domain
+      existing_domain_block_html: Es gibt schon eine Blockade für %{name}, diese muss erst <a href="%{unblock_url}">aufgehoben</a> werden.
       new:
         create: Blockade einrichten
         hint: Die Domain-Blockade wird nicht verhindern, dass Konteneinträge in der Datenbank erstellt werden. Aber es werden rückwirkend und automatisch alle Moderationsmethoden auf diese Konten angewendet.
@@ -273,8 +284,8 @@ de:
       reject_media_hint: Entfernt lokal gespeicherte Mediendateien und verhindert deren künftiges Herunterladen. Für Sperren irrelevant
       reject_reports: Meldungen ablehnen
       reject_reports_hint: Ignoriere alle Meldungen von dieser Domain. Irrelevant für Sperrungen
-      rejecting_media: Mediendateien ablehnen
-      rejecting_reports: Beschwerdemeldungen ablehnen
+      rejecting_media: Mediendateien werden nicht gespeichert
+      rejecting_reports: Meldungen werden ignoriert
       severity:
         silence: stummgeschaltet
         suspend: gesperrt
@@ -300,21 +311,22 @@ de:
       title: E-Mail-Domain-Blockade
     followers:
       back_to_account: Zurück zum Konto
-      title: "%{acct}'s Follower"
+      title: "%{acct}'s Folger_innen"
     instances:
-      delivery_available: Zustellung ist verfügbar
+      by_domain: Domain
+      delivery_available: Zustellung funktioniert
       known_accounts:
         one: "%{count} bekanntes Konto"
-        other: "%{count} bekannte Accounts"
+        other: "%{count} bekannte Konten"
       moderation:
         all: Alle
-        limited: Limitiert
+        limited: Beschränkt
         title: Moderation
       title: Föderation
-      total_blocked_by_us: Von uns gesperrt
+      total_blocked_by_us: Von uns blockiert
       total_followed_by_them: Gefolgt von denen
       total_followed_by_us: Gefolgt von uns
-      total_reported: Beschwerdemeldungen über sie
+      total_reported: Beschwerden über sie
       total_storage: Medienanhänge
     invites:
       deactivate_all: Alle deaktivieren
@@ -324,6 +336,8 @@ de:
         expired: Ausgelaufen
         title: Filter
       title: Einladungen
+    pending_accounts:
+      title: Ausstehende Konten (%{count})
     relays:
       add_new: Neues Relay hinzufügen
       delete: Löschen
@@ -336,9 +350,9 @@ de:
       inbox_url: Relay-URL
       pending: Warte auf Zustimmung des Relays
       save_and_enable: Speichern und aktivieren
-      setup: Relayverbindung einrichten
-      status: Status
-      title: Relays
+      setup: Relaisverbindung einrichten
+      status: Zustand
+      title: Relais
     report_notes:
       created_msg: Meldungs-Kommentar erfolgreich erstellt!
       destroyed_msg: Meldungs-Kommentar erfolgreich gelöscht!
@@ -361,13 +375,13 @@ de:
         create_and_unresolve: Mit Kommentar wieder öffnen
         delete: Löschen
         placeholder: Beschreibe, welche Maßnahmen ergriffen wurden oder irgendwelche andere Neuigkeiten…
-      reopen: Meldung wieder öffnen
+      reopen: Meldung wieder eröffnen
       report: 'Meldung #%{id}'
       reported_account: Gemeldetes Konto
       reported_by: Gemeldet von
       resolved: Gelöst
       resolved_msg: Meldung erfolgreich gelöst!
-      status: Status
+      status: Zustand
       title: Meldungen
       unassign: Zuweisung entfernen
       unresolved: Ungelöst
@@ -386,23 +400,23 @@ de:
         desc_html: Verändere das Aussehen mit CSS, dass auf jeder Seite geladen wird
         title: Benutzerdefiniertes CSS
       hero:
-        desc_html: Wird auf der Startseite angezeigt. Mindestens 600x100px sind empfohlen. Wenn es nicht gesetzt wurde, wird das Instanz-Thumbnail dafür verwendet
-        title: Bild für Startseite
+        desc_html: Wird auf der Startseite angezeigt. Mindestens 600x100px sind empfohlen. Wenn es nicht gesetzt wurde, wird das Server-Thumbnail dafür verwendet
+        title: Bild für Einstiegsseite
       mascot:
         desc_html: Angezeigt auf mehreren Seiten. Mehr als 293x205px empfohlen. Wenn es nicht gesetzt wurde wird es auf das Standard-Maskottchen zurückfallen
         title: Maskottchen-Bild
       peers_api_enabled:
-        desc_html: Domain-Namen dieser Instanz, die im Fediverse gefunden wurden
-        title: Veröffentliche Liste von gefundenen Instanzen
+        desc_html: Domain-Namen, die der Server im Fediversum gefunden hat
+        title: Veröffentliche entdeckte Server durch die API
       preview_sensitive_media:
         desc_html: Linkvorschauen auf anderen Webseiten werden ein Vorschaubild anzeigen, obwohl die Medien als heikel gekennzeichnet sind
-        title: Heikle Medien in OpenGraph-Vorschauen anzeigen
+        title: Heikle Medien im OpenGraph-Vorschau anzeigen
       profile_directory:
         desc_html: Erlaube Benutzer auffindbar zu sein
         title: Aktiviere Profilverzeichnis
       registrations:
         closed_message:
-          desc_html: Wird auf der Frontseite angezeigt, wenn die Registrierung geschlossen ist. Du kannst HTML-Tags benutzen
+          desc_html: Wird auf der Einstiegsseite gezeigt, wenn die Anmeldung geschlossen ist. Du kannst HTML-Tags nutzen
           title: Nachricht über geschlossene Registrierung
         deletion:
           desc_html: Allen erlauben, ihr Konto eigenmächtig zu löschen
@@ -410,35 +424,38 @@ de:
         min_invite_role:
           disabled: Niemand
           title: Einladungen erlauben von
-        open:
-          desc_html: Allen erlauben, ein Konto zu erstellen
-          title: Registrierung öffnen
+      registrations_mode:
+        modes:
+          approved: Zustimmung benötigt zur Registrierung
+          none: Niemand kann sich registrieren
+          open: Jeder kann sich registrieren
+        title: Registrierungsmodus
       show_known_fediverse_at_about_page:
-        desc_html: Wenn aktiviert, wird es alle Beiträge aus dem bereits bekannten Teil des Fediversums auf der Startseite anzeigen. Andernfalls werden lokale Beitrage der Instanz angezeigt.
-        title: Verwende öffentliche Zeitleiste für die Vorschau
+        desc_html: Wenn aktiviert, wird es alle Beiträge aus dem bereits bekannten Teil des Fediversums auf der Startseite anzeigen. Andernfalls werden lokale Beitrage des Servers angezeigt.
+        title: Zeige eine öffentliche Zeitleiste auf der Einstiegsseite
       show_staff_badge:
         desc_html: Zeige Mitarbeiter-Badge auf Benutzerseite
         title: Zeige Mitarbeiter-Badge
       site_description:
-        desc_html: Einleitungsabschnitt auf der Frontseite. Beschreibe, was diese Mastodon-Instanz ausmacht. Du kannst HTML-Tags benutzen, insbesondere <code>&lt;a&gt;</code> und <code>&lt;em&gt;</code>.
-        title: Beschreibung der Instanz
+        desc_html: Einleitungsabschnitt auf der Frontseite. Beschreibe, was diesen Mastodon-Server ausmacht. Du kannst HTML-Tags benutzen, insbesondere <code>&lt;a&gt;</code> und <code>&lt;em&gt;</code>.
+        title: Beschreibung des Servers
       site_description_extended:
-        desc_html: Bietet sich für Verhaltenskodizes, Regeln, Richtlinien und weiteres an, was deine Instanz auszeichnet. Du kannst HTML-Tags benutzen
-        title: Erweiterte Beschreibung der Instanz
+        desc_html: Bietet sich für Verhaltenskodizes, Regeln, Richtlinien und weiteres an, was deinen Server auszeichnet. Du kannst HTML-Tags benutzen
+        title: Erweiterte Beschreibung des Servers
       site_short_description:
-        desc_html: Wird angezeigt in der Seitenleiste und in Meta-Tags. Beschreibe in einem einzigen Abschnitt, was Mastodon ist und was diesen Server ausmacht. Falls leer, wird die Instanz-Beschreibung verwendet.
-        title: Kurze Instanz-Beschreibung
+        desc_html: Wird angezeigt in der Seitenleiste und in Meta-Tags. Beschreibe in einem einzigen Abschnitt, was Mastodon ist und was diesen Server von anderen unterscheidet. Falls leer, wird die Server-Beschreibung verwendet.
+        title: Kurze Beschreibung des Servers
       site_terms:
-        desc_html: Hier kannst du deine eigenen Geschäftsbedingungen, Datenschutzerklärung und anderes rechtlich Relevante eintragen. Du kannst HTML-Tags benutzen
-        title: Eigene Geschäftsbedingungen
-      site_title: Name der Instanz
+        desc_html: Hier kannst du deine eigenen Geschäftsbedingungen, Datenschutzerklärung und anderes rechtlich Relevante eintragen. Du kannst HTML-Tags nutzen
+        title: Benutzerdefinierte Geschäftsbedingungen
+      site_title: Name des Servers
       thumbnail:
         desc_html: Wird für die Vorschau via OpenGraph und API verwendet. 1200×630 px wird empfohlen
-        title: Instanz-Thumbnail
+        title: Vorschaubild des Servers
       timeline_preview:
-        desc_html: Auf der Frontseite die öffentliche Zeitleiste anzeigen
+        desc_html: Auf der Einstiegsseite die öffentliche Zeitleiste anzeigen
         title: Zeitleisten-Vorschau
-      title: Instanz-Einstellungen
+      title: Server-Einstellungen
     statuses:
       back_to_account: Zurück zum Konto
       batch:
@@ -449,7 +466,7 @@ de:
       media:
         title: Medien
       no_media: Keine Medien
-      no_status_selected: Keine Beiträge wurden verändert, weil keine ausgewählt wurden
+      no_status_selected: Keine Beiträge wurden geändert, weil keine ausgewählt wurden
       title: Beiträge des Kontos
       with_media: Mit Medien
     subscriptions:
@@ -462,7 +479,7 @@ de:
     tags:
       accounts: Konten
       hidden: Versteckt
-      hide: Vor Verzeichnis verstecken
+      hide: Vom Profilverzeichnis verstecken
       name: Hashtag
       title: Hashtags
       unhide: Zeige in Verzeichnis
@@ -475,17 +492,26 @@ de:
       edit_preset: Warnungsvorlage bearbeiten
       title: Warnungsvorlagen verwalten
   admin_mailer:
+    new_pending_account:
+      body: Die Details von diesem neuem Konto sind unten. Du kannst die Anfrage akzeptieren oder ablehnen.
+      subject: Neues Konto zur Überprüfung auf %{instance} verfügbar (%{username})
     new_report:
       body: "%{reporter} hat %{target} gemeldet"
       body_remote: Jemand von %{domain} hat %{target} gemeldet
       subject: Neue Meldung auf %{instance} (#%{id})
+  appearance:
+    advanced_web_interface: Fortgeschrittene Benutzeroberfläche
+    advanced_web_interface_hint: Wenn du mehr aus deiner Bildschirmbreite herausholen möchtest, erlaubt dir die fortgeschrittene Benutzeroberfläche viele unterschiedliche Spalten auf einmal zu sehen, wie z.B. deine Startseite, Benachrichtigungen, das gesamte bekannte Netz, deine Listen und beliebige Hashtags.
+    animations_and_accessibility: Animationen und Barrierefreiheit
+    confirmation_dialogs: Bestätigungsfenster
+    sensitive_content: Heikle Inhalte
   application_mailer:
     notification_preferences: Ändere E-Mail-Einstellungen
     salutation: "%{name},"
     settings: 'E-Mail-Einstellungen ändern: %{link}'
     view: 'Ansehen:'
     view_profile: Zeige Profil
-    view_status: Zeige Status
+    view_status: Beitrag öffnen
   applications:
     created: Anwendung erfolgreich erstellt
     destroyed: Anwendung erfolgreich gelöscht
@@ -495,8 +521,9 @@ de:
     warning: Sei mit diesen Daten sehr vorsichtig. Teile sie mit niemandem!
     your_token: Dein Zugangs-Token
   auth:
-    agreement_html: Indem du dich registrierst, erklärst du dich mit den untenstehenden <a href="%{rules_path}">Regeln dieser Instanz</a> und der <a href="%{terms_path}">Datenschutzerklärung</a> einverstanden.
+    apply_for_account: Eine Einladung anfragen
     change_password: Passwort
+    checkbox_agreement_html: Ich akzeptiere die <a href="%{rules_path}" target="_blank">Server-Regeln</a> und die <a href="%{terms_path}" target="_blank">Nutzungsbedingungen</a>
     confirm_email: E-Mail bestätigen
     delete_account: Konto löschen
     delete_account_html: Falls du dein Konto löschen willst, kannst du <a href="%{path}">hier damit fortfahren</a>. Du wirst um Bestätigung gebeten werden.
@@ -507,17 +534,17 @@ de:
     logout: Abmelden
     migrate_account: Ziehe zu einem anderen Konto um
     migrate_account_html: Wenn du wünschst, dieses Konto zu einem anderen umzuziehen, kannst du <a href="%{path}">dies hier einstellen</a>.
-    or: oder
     or_log_in_with: Oder anmelden mit
     providers:
       cas: CAS
       saml: SAML
     register: Registrieren
-    register_elsewhere: Registrieren auf einem anderen Server
+    registration_closed: "%{instance} akzeptiert keine neuen Mitglieder"
     resend_confirmation: Bestätigungs-Mail erneut versenden
     reset_password: Passwort zurücksetzen
     security: Sicherheit
     set_new_password: Neues Passwort setzen
+    trouble_logging_in: Schwierigkeiten beim Anmelden?
   authorize_follow:
     already_following: Du folgst diesem Konto bereits
     error: Das Remote-Konto konnte nicht geladen werden
@@ -526,8 +553,8 @@ de:
     following: 'Erfolg! Du folgst nun:'
     post_follow:
       close: Oder du schließt einfach dieses Fenster.
-      return: Zeige Profil des Benutzers
-      web: Das Web öffnen
+      return: Zeige das Profil
+      web: In der Benutzeroberfläche öffnen
     title: "%{acct} folgen"
   datetime:
     distance_in_words:
@@ -538,8 +565,8 @@ de:
       half_a_minute: Gerade eben
       less_than_x_minutes: "%{count}m"
       less_than_x_seconds: Gerade eben
-      over_x_years: "%{count}y"
-      x_days: "%{count}d"
+      over_x_years: "%{count}J"
+      x_days: "%{count}T"
       x_minutes: "%{count}m"
       x_months: "%{count}mo"
       x_seconds: "%{count}s"
@@ -549,13 +576,13 @@ de:
     description_html: Hiermit wird <strong>dauerhaft und unwiederbringlich</strong> der Inhalt deines Kontos gelöscht und dein Konto deaktiviert. Dein Profilname wird reserviert, um künftige Imitationen zu verhindern.
     proceed: Konto löschen
     success_msg: Dein Konto wurde erfolgreich gelöscht
-    warning_html: Wir können nur dafür garantieren, dass die Inhalte auf dieser einen Instanz gelöscht werden. Bei Inhalten, die weit verbreitet wurden, ist es wahrscheinlich, dass Spuren bleiben werden. Server, die offline sind oder keine Benachrichtigungen von deinem Konto mehr empfangen, werden ihre Datenbanken nicht bereinigen.
+    warning_html: Wir können nur dafür garantieren, dass die Inhalte auf diesem einen Server gelöscht werden. Bei Inhalten, die weit verbreitet wurden, ist es wahrscheinlich, dass Spuren bleiben werden. Server, die offline sind oder keine Benachrichtigungen von deinem Konto mehr empfangen, werden ihre Datenbanken nicht bereinigen.
     warning_title: Verfügbarkeit verstreuter Inhalte
   directories:
     directory: Profilverzeichnis
     enabled: Du bist gerade in dem Verzeichnis gelistet.
-    enabled_but_waiting: Du bist damit einverstanden im Verzeichnis gelistet zu werden, aber du hast nicht die minimale Anzahl an Folgenden (%{min_followers}), damit es passiert.
-    explanation: Entdecke Benutzer basierend auf deren Interessen
+    enabled_but_waiting: Du bist damit einverstanden im Verzeichnis aufgelistet zu werden, aber du hast noch nicht genug Folger_innen (%{min_followers}).
+    explanation: Entdecke Benutzer_innen basierend auf deren Interessen
     explore_mastodon: Entdecke %{title}
     how_to_enable: Du hast dich gerade nicht dazu entschieden im Verzeichnis gelistet zu werden. Du kannst dich unten dafür eintragen. Benutze Hashtags in deiner Profilbeschreibung, um unter spezifischen Hashtags gelistet zu werden!
     people:
@@ -563,8 +590,8 @@ de:
       other: "%{count} Leute"
   errors:
     '403': Dir fehlt die Befugnis, diese Seite sehen zu können.
-    '404': Diese Seite existiert nicht.
-    '410': Diese Seite existiert nicht mehr.
+    '404': Die Seite nach der du gesucht hast wurde nicht gefunden.
+    '410': Die Seite nach der du gesucht hast existiert hier nicht mehr.
     '422':
       content: Sicherheitsüberprüfung fehlgeschlagen. Blockierst du Cookies?
       title: Sicherheitsüberprüfung fehlgeschlagen
@@ -573,11 +600,14 @@ de:
       content: Bitte verzeih, etwas ist bei uns schief gegangen.
       title: Diese Seite ist kaputt
     noscript_html: Bitte aktiviere JavaScript, um die Mastodon-Web-Anwendung zu verwenden. Alternativ kannst du auch eine der <a href="%{apps_path}">nativen Mastodon-Anwendungen</a> für deine Plattform probieren.
+  existing_username_validator:
+    not_found: kann lokalen Benutzer nicht mit diesem Nuternamen finden
+    not_found_multiple: kann %{usernames} nicht finden
   exports:
     archive_takeout:
       date: Datum
       download: Dein Archiv herunterladen
-      hint_html: Du kannst ein Archiv deiner <strong>Beiträge und hochgeladenen Medien</strong> anfragen. Die exportierten Daten werden im ActivityPub-Format gespeichert, welches mit jeder Software lesbar ist die das Format unterstützt. Du kannst alle 7 Tage ein Archiv anfordern.
+      hint_html: Du kannst ein Archiv deiner <strong>Beiträge und hochgeladenen Medien</strong> anfragen. Die exportierten Daten werden in dem ActivityPub-Format gespeichert, welches mit jeder Software lesbar ist die das Format unterstützt. Du kannst alle 7 Tage ein Archiv anfordern.
       in_progress: Stelle dein Archiv zusammen...
       request: Dein Archiv anfragen
       size: Größe
@@ -588,6 +618,10 @@ de:
     lists: Listen
     mutes: Du hast stummgeschaltet
     storage: Medienspeicher
+  featured_tags:
+    add_new: Neu hinzufügen
+    errors:
+      limit: Du hast bereits die maximale Anzahl an empfohlenen Hashtags erreicht
   filters:
     contexts:
       home: Startseite
@@ -604,34 +638,50 @@ de:
       title: Filter
     new:
       title: Neuen Filter hinzufügen
-  followers:
-    domain: Instanz
-    explanation_html: Wenn du sicherstellen willst, dass deine Beiträge privat sind, musst du wissen, wer dir folgt. <strong>Deine privaten Beiträge werden an alle Instanzen weitergegeben, auf denen Menschen registriert sind, die dir folgen.</strong> Wenn du den Betreibenden einer Instanz misstraust und du befürchtest, dass sie deine Privatsphäre missachten könnten, kannst du sie hier entfernen.
-    followers_count: Zahl der Folgenden
-    lock_link: dein Konto sperrst
-    purge: Von der Liste deiner Folgenden löschen
-    success:
-      one: Folgende von einer Domain werden soft-geblockt …
-      other: Folgende von %{count} Domains werden soft-geblockt …
-    true_privacy_html: Bitte beachte, dass <strong>wirklicher Schutz deiner Privatsphäre nur durch Ende-zu-Ende-Verschlüsselung erreicht werden kann.</strong>.
-    unlocked_warning_html: Wer dir folgen will, kann dies jederzeit ohne deine vorige Einverständnis tun und erhält damit automatisch Zugriff auf deine privaten Beiträge. Wenn du %{lock_link}, kannst du vorab entscheiden, wer dir folgen darf und wer nicht.
-    unlocked_warning_title: Dein Konto ist nicht gesperrt
   footer:
     developers: Entwickler
     more: Mehr…
     resources: Ressourcen
   generic:
+    all: Alle
     changes_saved_msg: Änderungen gespeichert!
     copy: Kopieren
+    order_by: Sortieren nach
     save_changes: Änderungen speichern
     validation_errors:
       one: Etwas ist noch nicht ganz richtig! Bitte korrigiere den Fehler
       other: Etwas ist noch nicht ganz richtig! Bitte korrigiere %{count} Fehler
+  html_validator:
+    invalid_markup: 'enthält ungültiges HTML-Markup: %{error}'
+  identity_proofs:
+    active: Aktiv
+    authorize: Ja, autorisieren
+    authorize_connection_prompt: Diese kryptographische Verbindung autorisieren?
+    errors:
+      failed: Die kryptographische Verbindung ist fehlgeschlagen. Bitte versuche es nochmal von %{provider}.
+      keybase:
+        invalid_token: Keybase-Tokens sind Hashsignaturen und müssen 66 Hexadezimalzeichen lang sein
+        verification_failed: Keybase nimmt dieses Token nicht als Signatur für Keybase-Benutzer %{kb_username} an. Bitte versuche es nochmal über Keybase.
+      wrong_user: Kann keinen Beweis für %{proving} erstellen während du als %{current} angemeldet bist. Melde dich als %{proving} an und versuche es noch einmal.
+    explanation_html: Hier kannst du kryptographisch deine anderen Identitäten wie dein Keybase-Profil verbinden. Dadurch können andere Leute dir verschlüsselte Nachrichten senden und dem Inhalt, den sie dir senden, vertrauen.
+    i_am_html: Ich bin %{username} auf %{service}.
+    identity: Identität
+    inactive: Inaktiv
+    publicize_checkbox: 'Und poste das:'
+    publicize_toot: 'Es ist offiziell! Ich bin %{username} auf %{service}: %{url}'
+    status: Verifizierungsstatus
+    view_proof: Zeige Nachweis
   imports:
-    preface: Daten, die du aus einer anderen Instanz exportiert hast, kannst du hier importieren. Beispielsweise die Liste derjenigen, denen du folgst oder die du blockiert hast.
+    modes:
+      merge: Zusammenführen
+      merge_long: Behalte existierende Datensätze und füge neue hinzu
+      overwrite: Überschreiben
+      overwrite_long: Ersetze aktuelle Datensätze mit neuen
+    preface: Daten, die du aus einem anderen Server exportiert hast, kannst du hier importieren. Beispielsweise die Liste derjenigen, denen du folgst oder die du blockiert hast.
     success: Deine Daten wurden erfolgreich hochgeladen und werden in Kürze verarbeitet
     types:
       blocking: Blockierliste
+      domain_blocking: Domain-Blockliste
       following: Folgeliste
       muting: Stummschaltungsliste
     upload: Hochladen
@@ -653,7 +703,7 @@ de:
       one: 1 mal verwendet
       other: "%{count} mal verwendet"
     max_uses_prompt: Kein Limit
-    prompt: Generiere und teile Links um Zugang zu dieser Instanz zu geben
+    prompt: Generiere und teile Links um Zugang zu diesem Server zu geben
     table:
       expires_at: Läuft ab
       uses: Verwendungen
@@ -664,7 +714,7 @@ de:
   media_attachments:
     validations:
       images_and_video: Es kann kein Video an einen Beitrag, der bereits Bilder enthält, angehängt werden
-      too_many: Es können nicht mehr als 4 Bilder angehängt werden
+      too_many: Es können nicht mehr als 4 Dateien angehängt werden
   migrations:
     acct: benutzername@domain des neuen Kontos
     currently_redirecting: 'Deine Profilweiterleitung wurde gesetzt auf:'
@@ -716,18 +766,39 @@ de:
           quadrillion: Q
           thousand: K
           trillion: T
-          unit: ''
   pagination:
     newer: Neuer
     next: Vorwärts
     older: Älter
     prev: Zurück
     truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: Du hast bereits für diese Umfrage abgestimmt
+      duplicate_options: enthält doppelte Einträge
+      duration_too_long: ist zu weit in der Zukunft
+      duration_too_short: ist zu früh
+      expired: Die Umfrage ist bereits vorbei
+      over_character_limit: kann nicht länger als jeweils %{max} Zeichen sein
+      too_few_options: muss mindestens einen Eintrag haben
+      too_many_options: kann nicht mehr als %{max} Einträge beinhalten
   preferences:
-    languages: Sprachen
     other: Weiteres
-    publishing: Beiträge
-    web: Web
+    posting_defaults: Standardeinstellungen für Beiträge
+    public_timelines: Öffentliche Zeitleisten
+  relationships:
+    activity: Kontoaktivität
+    dormant: Inaktiv
+    last_active: Zuletzt aktiv
+    most_recent: Neuste
+    moved: Umgezogen
+    mutual: Bekannt
+    primary: Primär
+    relationship: Beziehung
+    remove_selected_domains: Entferne alle Follower von den ausgewählten Domains
+    remove_selected_followers: Entferne ausgewählte Follower
+    remove_selected_follows: Entfolge ausgewählte Benutzer
+    status: Kontostatus
   remote_follow:
     acct: Profilname@Domain, von wo aus du dieser Person folgen möchtest
     missing_resource: Die erforderliche Weiterleitungs-URL für dein Konto konnte nicht gefunden werden
@@ -795,20 +866,25 @@ de:
     revoke_success: Sitzung erfolgreich geschlossen
     title: Sitzungen
   settings:
+    account: Konto
+    account_settings: Konto & Sicherheit
+    appearance: Aussehen
     authorized_apps: Autorisierte Anwendungen
     back: Zurück zu Mastodon
     delete: Konto löschen
     development: Entwicklung
     edit_profile: Profil bearbeiten
     export: Datenexport
-    followers: Autorisierte Folgende
+    featured_tags: Empfohlene Hashtags
+    identity_proofs: Identitätsnachweise
     import: Datenimport
+    import_and_export: Importieren und Exportieren
     migrate: Konto-Umzug
     notifications: Benachrichtigungen
     preferences: Einstellungen
-    settings: Einstellungen
+    profile: Profil
+    relationships: Folger_innen und Gefolgte
     two_factor_authentication: Zwei-Faktor-Auth
-    your_apps: Deine Anwendungen
   statuses:
     attached:
       description: 'Angehängt: %{attached}'
@@ -821,8 +897,8 @@ de:
     boosted_from_html: Geteilt von %{acct_link}
     content_warning: 'Inhaltswarnung: %{warning}'
     disallowed_hashtags:
-      one: 'Enthält den unerlaubten Hashtag: %{tags}'
-      other: 'Enthält die unerlaubten Hashtags: %{tags}'
+      one: 'enthält einen verbotenen Hashtag: %{tags}'
+      other: 'enthält verbotene Hashtags: %{tags}'
     language_detection: Sprache automatisch erkennen
     open_in_web: Im Web öffnen
     over_character_limit: Zeichenlimit von %{max} überschritten
@@ -831,6 +907,11 @@ de:
       ownership: Du kannst nur eigene Beiträge anheften
       private: Du kannst nur öffentliche Beiträge anheften
       reblog: Du kannst keine geteilten Beiträge anheften
+    poll:
+      total_votes:
+        one: "%{count} Stimme"
+        other: "%{count} Stimmen"
+      vote: Abstimmen
     show_more: Mehr anzeigen
     sign_in_to_participate: Melde dich an, um an der Konversation teilzuhaben
     title: '%{name}: "%{quote}"'
@@ -844,17 +925,17 @@ de:
   stream_entries:
     pinned: Angehefteter Beitrag
     reblogged: teilte
-    sensitive_content: Sensible Inhalte
+    sensitive_content: Heikle Inhalte
   terms:
     body_html: |
       <h2>Datenschutzerklärung</h2>
       <h3 id="collect">Welche Informationen sammeln wir?</h3>
 
       <ul>
-        <li><em>Grundlegende Kontoinformationen</em>: Wenn du dich auf diesem Server registrierst, wirst du darum gebeten, einen Benutzer:innen-Namen, eine E-Mail-Adresse und ein Passwort einzugeben. Du kannst auch zusätzliche Profilinformationen wie etwa einen Anzeigenamen oder eine Biografie eingeben und ein Profilbild oder ein Headerbild hochladen. Der Benutzer:innen-Name, der Anzeigename, die Biografie, das Profilbild und das Headerbild werden immer öffentlich angezeigt.</li>
-        <li><em>Beiträge, Folge- und andere öffentliche Informationen</em>: Die Liste der Leute, denen du folgst, wird öffentlich gezeigt, das gleiche gilt für deine Folgenden (Follower). Sobald du eine Nachricht übermittelst, wird das Datum und die Uhrzeit gemeinsam mit der Information, welche Anwendung du dafür verwendet hast, gespeichert. Nachricht können Medienanhänge enthalten, etwa Bilder und Videos. Öffentliche und ungelistete Beiträge sind öffentlich verfügbar. Sobald du einen Beitrag auf deinem Profil featurest, sind dies auch öffentlich verfügbare Informationen. Deine Beiträge werden an deine Folgenden ausgeliefert, was in manchen Fällen bedeutet, dass sie an andere Server ausgeliefert werden und dort Kopien gespeichert werden. Sobald du Beiträge löschst, wird dies ebenso an deine Follower ausgeliefert. Die Handlungen des Teilens und Favorisieren eines anderen Beitrages ist immer öffentlich.</li>
-        <li><em>Direkte und "Nur Folgende"-Beiträge</em>: Alle Beiträge werden auf dem Server gespeichert und verarbeitet. "Nur Folgende"-Beiträge werden an deine Folgenden und an Benutzer:innen, die du in ihnen erwähnst, ausgeliefert, direkte Beiträge nur an in ihnen erwähnte Benutzer:innen. In manchen Fällen bedeutet dass, dass sie an andere Server ausgeliefert werden und dort Kopien gespeichert werden. Wir bemühen uns nach bestem Wissen und Gewissen, den Zugriff auf diese Beiträge auf nur autorisierte Personen einzuschränken, jedoch könnten andere Server dabei scheitern. Deswegen ist es wichtig, die Server, zu denen deine Folgenden gehören, zu überprüfen. Du kannst eine Option in den Einstellungen umschalten, um neue Folgenden manuell anzunehmen oder abzuweisen. <em>Bitte beachte, dass die Betreiber des Server und jedes empfangenden Servers solche Nachrichten anschauen könnten</em> und dass Empfänger von diesen eine Bildschirmkopie erstellen könnten, sie kopieren oder anderweitig weiterverteilen könnten. <em>Teile nicht irgendwelche gefährlichen Informationen über Mastodon.</em></li>
-        <li><em>Internet Protocol-Adressen (IP-Adressen) und andere Metadaten</em>: Sobald du dich anmeldest, erfassen wir sowohl die IP-Adresse, von der aus du dich anmeldest, als auch den Namen deine Browseranwendung. Alle angemeldeten Sitzungen (Sessions) sind für deine Überprüfung und Widerruf in den Einstellungen verfügbar. Die letzte verwendete IP-Adresse wird bis zu 12 Monate lang gespeichert. Wir könnten auch Serverprotokoll behalten, welche die IP-Adresse von jeder Anfrage an unseren Server enthalten.</li>
+      <li><em>Grundlegende Kontoinformationen</em>: Wenn du dich auf diesem Server registrierst, wirst du darum gebeten, einen Benutzer:innen-Namen, eine E-Mail-Adresse und ein Passwort einzugeben. Du kannst auch zusätzliche Profilinformationen wie etwa einen Anzeigenamen oder eine Biografie eingeben und ein Profilbild oder ein Headerbild hochladen. Der Benutzer:innen-Name, der Anzeigename, die Biografie, das Profilbild und das Headerbild werden immer öffentlich angezeigt.</li>
+      <li><em>Beiträge, Folge- und andere öffentliche Informationen</em>: Die Liste der Leute, denen du folgst, wird öffentlich gezeigt, das gleiche gilt für deine Folgenden (Follower). Sobald du eine Nachricht übermittelst, wird das Datum und die Uhrzeit gemeinsam mit der Information, welche Anwendung du dafür verwendet hast, gespeichert. Nachricht können Medienanhänge enthalten, etwa Bilder und Videos. Öffentliche und ungelistete Beiträge sind öffentlich verfügbar. Sobald du einen Beitrag auf deinem Profil anpinnst, sind dies auch öffentlich verfügbare Informationen. Deine Beiträge werden an deine Folgenden ausgeliefert, was in manchen Fällen bedeutet, dass sie an andere Server ausgeliefert werden und dort Kopien gespeichert werden. Sobald du Beiträge löschst, wird dies ebenso an deine Follower ausgeliefert. Die Handlungen des Teilens und Favorisieren eines anderen Beitrages ist immer öffentlich.</li>
+      <li><em>Direkte und "Nur Folgende"-Beiträge</em>: Alle Beiträge werden auf dem Server gespeichert und verarbeitet. "Nur Folgende"-Beiträge werden an deine Folgenden und an Benutzer:innen, die du in ihnen erwähnst, ausgeliefert, direkte Beiträge nur an in ihnen erwähnte Benutzer:innen. In manchen Fällen bedeutet dass, dass sie an andere Server ausgeliefert werden und dort Kopien gespeichert werden. Wir bemühen uns nach bestem Wissen und Gewissen, den Zugriff auf diese Beiträge auf nur autorisierte Personen einzuschränken, jedoch könnten andere Server dabei scheitern. Deswegen ist es wichtig, die Server, zu denen deine Folgenden gehören, zu überprüfen. Du kannst eine Option in den Einstellungen umschalten, um neue Folgenden manuell anzunehmen oder abzuweisen. <em>Bitte beachte, dass die Betreiber des Server und jedes empfangenden Servers solche Nachrichten anschauen könnten</em> und dass Empfänger von diesen eine Bildschirmkopie erstellen könnten, sie kopieren oder anderweitig weiterverteilen könnten. <em>Teile nicht irgendwelche gefährlichen Informationen über Mastodon.</em></li>
+      <li><em>Internet Protocol-Adressen (IP-Adressen) und andere Metadaten</em>: Sobald du dich anmeldest, erfassen wir sowohl die IP-Adresse, von der aus du dich anmeldest, als auch den Namen deine Browseranwendung. Alle angemeldeten Sitzungen (Sessions) sind für deine Überprüfung und Widerruf in den Einstellungen verfügbar. Die letzte verwendete IP-Adresse wird bis zu 12 Monate lang gespeichert. Wir könnten auch Serverprotokoll behalten, welche die IP-Adresse von jeder Anfrage an unseren Server enthalten.</li>
       </ul>
 
       <hr class="spacer" />
@@ -864,9 +945,9 @@ de:
       <p>Jede der von dir gesammelten Information kann in den folgenden Weisen verwendet werden:</p>
 
       <ul>
-        <li>Um die Kernfunktionalität von Mastodon bereitzustellen. Du kannst du mit dem Inhalt anderer Leute interagieren und deine eigenen Inhalte beitragen, wenn du angemeldet bist. Zum Beispiel kannst du anderen folgen, um deren kombinierten Beiträge in deine personalisierten Start-Timeline zu sehen.</li>
-        <li>Um Moderation der Community zu ermöglichen, zum Beispiel beim Vergleichen deiner IP-Adresse mit anderen bekannten, um Verbotsumgehung oder andere Vergehen festzustellen.</li>
-        <li>Die E-Mail-Adresse, die du bereitstellst, kann dazu verwendet werden, dir Informationen, Benachrichtigungen über andere Leute, die mit deinen Inhalten interagieren oder dir Nachrichten senden, und auf Anfragen, Wünsche und/oder Fragen zu antworten.</li>
+      <li>Um die Kernfunktionalität von Mastodon bereitzustellen. Du kannst du mit dem Inhalt anderer Leute interagieren und deine eigenen Inhalte beitragen, wenn du angemeldet bist. Zum Beispiel kannst du anderen folgen, um deren kombinierten Beiträge in deine personalisierten Start-Timeline zu sehen.</li>
+      <li>Um Moderation der Community zu ermöglichen, zum Beispiel beim Vergleichen deiner IP-Adresse mit anderen bekannten, um Verbotsumgehung oder andere Vergehen festzustellen.</li>
+      <li>Die E-Mail-Adresse, die du bereitstellst, kann dazu verwendet werden, dir Informationen, Benachrichtigungen über andere Leute, die mit deinen Inhalten interagieren oder dir Nachrichten senden, und auf Anfragen, Wünsche und/oder Fragen zu antworten.</li>
       </ul>
 
       <hr class="spacer" />
@@ -882,13 +963,13 @@ de:
       <p>Wir werden mit bestem Wissen und Gewissen:</p>
 
       <ul>
-        <li>Serverprotokolle, die IP-Adressen von allen deinen Anfragen an diesen Server, falls solche Protokolle behalten werden, für nicht mehr als 90 Tage behalten.</li>
-        <li>registrierten Benutzer:innen zugeordnete IP-Adressen nicht länger als 12 Monate behalten.</li>
+      <li>Serverprotokolle, die IP-Adressen von allen deinen Anfragen an diesen Server, falls solche Protokolle behalten werden, für nicht mehr als 90 Tage behalten.</li>
+      <li>registrierten Benutzer:innen zugeordnete IP-Adressen nicht länger als 12 Monate behalten.</li>
       </ul>
 
       <p>Du kannst ein Archiv deines Inhalts anfordern und herunterladen, inkludierend deiner Beiträge, Medienanhänge, Profilbilder und Headerbilder.</p>
 
-      <p>Du kannst dein Konto jederzeit unwiderruflich  löschen.</p>
+      <p>Es ist in den meisten Fällen möglich dein Konto jederzeit eigenmächtig unwiderruflich zu löschen.</p>
 
       <hr class="spacer"/>
 
@@ -912,7 +993,7 @@ de:
 
       <h3 id="children">Webseitenbenutzung durch Kinder</h3>
 
-      <p>Wenn sich dieser Server in der EU oder im Europäischen Wirtschaftsraum befinden: Unsere Website, Produkte und Dienstleistungen sind alle an Leute gerichtet, die mindestens 16 Jahre als sind. Wenn du unter 16 bist, darfst du nach den Bestimmungen der DSGVO (<a href="https://de.wikipedia.org/wiki/Datenschutz-Grundverordnung">Datenschutz-Grundverordnung</a>) diese Webseite nicht benutzen.</p>
+      <p>Wenn sich dieser Server in der EU oder im Europäischen Wirtschaftsraum befindet: Unsere Website, Produkte und Dienstleistungen sind alle an Leute gerichtet, die mindestens 16 Jahre als sind. Wenn du unter 16 bist, darfst du nach den Bestimmungen der DSGVO (<a href="https://de.wikipedia.org/wiki/Datenschutz-Grundverordnung">Datenschutz-Grundverordnung</a>) diese Webseite nicht benutzen.</p>
 
       <p>Wenn sich dieser Server in den USA befindet: Unsere Webseite, Produkte und Dienstleistungen sind alle an Leute gerichtet, die mindestens 13 Jahre alt sind. Wenn du unter 13 bist, darfst du nach den Bestimmungen des COPPA (<a href="https://de.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act, dt. "Gesetz zum Schutz der Privatsphäre von Kindern im Internet"</a>) diese Webseite nicht benutzen.</p>
 
@@ -922,7 +1003,7 @@ de:
 
       <h3 id="changes">Änderung an unserer Datenschutzerklärung</h3>
 
-      <p>Wenn wir uns entscheiden, Änderungen an unserer Datenschutzerklärung vorzunehmen, werden wird diese Änderungen auf dieser Seite bekannt gegeben.</p>
+      <p>Wenn wir uns entscheiden, Änderungen an unserer Datenschutzerklärung vorzunehmen, werden wir diese Änderungen auf dieser Seite bekannt gegeben.</p>
 
       <p>Dies ist eine Übersetzung, Irrtümer und Übersetzungsfehler vorbehalten. Im Zweifelsfall gilt die englische Originalversion.</p>
 
@@ -931,16 +1012,16 @@ de:
       <p>Ursprünglich übernommen von der <a href="https://github.com/discourse/discourse">Discourse-Datenschutzerklärung</a>.</p>
     title: "%{instance} Nutzungsbedingungen und Datenschutzerklärung"
   themes:
-    contrast: Hoher Kontrast
-    default: Mastodon
-    mastodon-light: Mastodon (hell)
+    contrast: Mastodon (Hoher Kontrast)
+    default: Mastodon (Dunkel)
+    mastodon-light: Mastodon (Hell)
   time:
     formats:
       default: "%d.%m.%Y %H:%M"
       month: "%b %Y"
   two_factor_authentication:
     code_hint: Gib zur Bestätigung den Code ein, den deine Authenticator-App generiert hat
-    description_html: Wenn du <strong>Zwei-Faktor-Authentisierung (2FA)</strong> aktivierst, wirst du dein Telefon zum Anmelden benötigen. Darauf werden Tokens erzeugt, die du bei der Anmeldung eingeben musst.
+    description_html: Wenn du <strong>Zwei-Faktor-Authentifizierung (2FA)</strong> aktivierst, wirst du dein Telefon zum Anmelden benötigen. Darauf werden Sicherheitscodes erzeugt, die du bei der Anmeldung eingeben musst.
     disable: Deaktivieren
     enable: Aktivieren
     enabled: Zwei-Faktor-Authentisierung ist aktiviert
@@ -982,7 +1063,7 @@ de:
       final_action: Fang an zu posten
       final_step: 'Fang an zu posten! Selbst ohne Follower werden deine öffentlichen Beitrage von anderen gesehen, zum Beispiel auf der lokalen Zeitleiste oder in Hashtags. Vielleicht möchtest du dich vorstellen mit dem #introductions-Hashtag.'
       full_handle: Dein vollständiger Benutzername
-      full_handle_hint: Dies ist was du deinen Freunden sagen kannst, damit sie dich anschreiben oder von einer anderen Instanz folgen können.
+      full_handle_hint: Dies ist was du deinen Freunden sagen kannst, damit sie dich anschreiben oder von einem anderen Server folgen können.
       review_preferences_action: Einstellungen ändern
       review_preferences_step: Stelle sicher, dass du deine Einstellungen einstellst, wie zum Beispiel welche E-Mails du gerne erhalten möchtest oder was für Privatsphäreneinstellungen voreingestellt werden sollten. Wenn dir beim Ansehen von GIFs nicht schwindelig wird, dann kannst du auch das automatische Abspielen dieser aktivieren.
       subject: Willkommen bei Mastodon
diff --git a/config/locales/devise.ar.yml b/config/locales/devise.ar.yml
index 927eeee5a10c886cc501bda5f612b289ea784956..366bd81b94b38a5190bdaa32a7202138c02bf65a 100644
--- a/config/locales/devise.ar.yml
+++ b/config/locales/devise.ar.yml
@@ -12,52 +12,53 @@ ar:
       last_attempt: بإمكانك إعادة المحاولة مرة واحدة قبل أن يتم قفل حسابك.
       locked: إن حسابك مقفل.
       not_found_in_database: "%{authentication_keys} أو كلمة سر خاطئة."
-      timeout: لقد إنتهت مدة صلاحية جلستك. قم بتسجيل الدخول من جديد للمواصلة.
+      pending: إنّ حسابك في انتظار مراجعة.
+      timeout: لقد انتهت مدة صلاحية جلستك. قم بتسجيل الدخول من جديد للمواصلة.
       unauthenticated: يجب عليك تسجيل الدخول أو إنشاء حساب قبل المواصلة.
       unconfirmed: يجب عليك تأكيد عنوان بريدك الإلكتروني قبل المواصلة.
     mailer:
       confirmation_instructions:
         action: للتحقق من عنوان البريد الإلكتروني
         action_with_app: تأكيد ثم العودة إلى %{app}
-        explanation: لقد قمت بإنشاء حساب على %{host} بواسطة عنوان البريد الإلكتروني الحالي. إنك على بعد خطوات قليلة من تفعليه. إن لم تكن من طلب ذلك، يرجى ألّا تولي إهتماما بهذه الرسالة.
+        explanation: لقد قمت بإنشاء حساب على %{host} بواسطة عنوان البريد الإلكتروني الحالي. إنك على بعد خطوات قليلة من تفعليه. إن لم تكن من طلب ذلك، يرجى ألّا تولي اهتماما بهذه الرسالة.
         extra_html: ندعوك إلى الإطلاع على <a href="%{terms_path}">القواعد الخاصة بمثيل الخادوم هذا</a> and <a href="%{policy_path}">و شروط الخدمة الخاصة بنا</a>.
-        subject: 'ماستدون : تعليمات التأكيد لمثيل الخادوم  %{instance}'
+        subject: 'ماستدون: تعليمات التأكيد لمثيل الخادوم %{instance}'
         title: للتحقق من عنوان البريد الإلكتروني
       email_changed:
-        explanation: 'لقد تم تغيير عنوان البريد الإلكتروني الخاص بحسابك إلى :'
+        explanation: 'لقد تم تغيير عنوان البريد الإلكتروني الخاص بحسابك إلى:'
         extra: إن لم تقم شخصيًا بتعديل عنوان بريدك الإلكتروني ، ذلك يعني أنّ شخصا آخر قد نَفِذَ إلى حسابك. فالرجاء قم بتعديل كلمتك السرية في الحال أو قم بالإتصال بمدير مثيل الخادوم إن كنت غير قادر على استعمال حسابك.
-        subject: 'ماستدون : تم استبدال عنوان بريدك الإلكتروني'
+        subject: 'ماستدون: تم استبدال عنوان بريدك الإلكتروني'
         title: عنوان البريد الإلكتروني الجديد
       password_change:
         explanation: تم تغيير كلمة السر الخاصة بحسابك.
-        extra: إن لم تقم شخصيًا بتعديل كلمتك السرية، ذلك يعني أنّ شخصا آخر قد سيطر على حسابك. فالرجاء قم بتعديل كلمتك السرية في الحال أو قم بالإتصال بمدير مثيل الخادوم إن كنت غير قادر على استعمال حسابك.
-        subject: 'ماستدون : تم تغيير كلمة المرور'
+        extra: إن لم تقم شخصيًا بتعديل كلمتك السرية، ذلك يعني أنّ شخصا آخر قد سيطر على حسابك. فالرجاء قم بتعديل كلمتك السرية في الحال أو قم بالاتصال بمدير مثيل الخادوم إن كنت غير قادر على استعمال حسابك.
+        subject: 'ماستدون: تم تغيير كلمة المرور'
         title: تم تغيير كلمة السر
       reconfirmation_instructions:
         explanation: ندعوك لتأكيد العنوان الجديد قصد تعديله في بريدك.
-        extra: إن لم تكن صاحب هذا الطلب ، يُرجى عدم إعارة الإهتمام لهذه الرسالة. فعنوان البريد الإلكتروني المتعلق بحساب ماستدون سوف يبقى هو مِن غير أي تعديل إلّا و فقط إن قمت بالنقر على الرابط أعلاه قصد تعديله.
-        subject: 'ماستدون : تأكيد كلمة السر الخاصة بـ %{instance}'
+        extra: إن لم تكن صاحب هذا الطلب ، يُرجى عدم إعارة الاهتمام لهذه الرسالة. فعنوان البريد الإلكتروني المتعلق بحساب ماستدون سوف يبقى هو مِن غير أي تعديل إلّا و فقط إن قمت بالنقر على الرابط أعلاه قصد تعديله.
+        subject: 'ماستدون: تأكيد كلمة السر الخاصة بـ %{instance}'
         title: التحقق من عنوان البريد الإلكتروني
       reset_password_instructions:
         action: تغيير كلمة السر
         explanation: لقد قمت بطلب تغيير كلمة السر الخاصة بحسابك.
-        extra: إن لم تكن صاحب هذا الطلب ، يُرجى عدم إعارة الإهتمام لهذه الرسالة. فكلِمَتُك السرية تبقى هي مِن غير أي تعديل إلّا و فقط إن قمت بالنقر على الرابط أعلاه قصد إنشاء كلمة سرية جديدة.
-        subject: 'ماستدون : تعليمات إستعادة كلمة المرور'
+        extra: إن لم تكن صاحب هذا الطلب ، يُرجى عدم إعارة الاهتمام لهذه الرسالة. فكلِمَتُك السرية تبقى هي مِن غير أي تعديل إلّا و فقط إن قمت بالنقر على الرابط أعلاه قصد إنشاء كلمة سرية جديدة.
+        subject: 'ماستدون: تعليمات استعادة كلمة المرور'
         title: إعادة تعيين كلمة السر
       unlock_instructions:
-        subject: 'ماستدون : تعليمات فك القفل'
+        subject: 'ماستدون: تعليمات فك القفل'
     omniauth_callbacks:
       failure: تعذرت المصادقة من %{kind} بسبب "%{reason}".
       success: تمت المصادقة بنجاح عبر حساب %{kind}.
     passwords:
-      no_token: ليس بإمكانك النفاذ إلى هذه الصفحة  إن لم تقم بالنقر على الرابط المتواجد في الرسالة الإلكترونية. الرجاء التحقق مِن أنك قمت بإدخال عنوان الرابط كاملا كما هو مذكور في رسالة إعادة تعيين الكلمة السرية.
-      send_instructions: إن كان عنوان بريدك الإلكتروني ضمن قاعدة بياناتنا، فسوف تتلقّى في غضون دقائق رابطا يُمكّنُك مِن استعادة كلمتك السرية على عنوان علبة البريد الإلكتروني الخاصة بك.إن لم تجد هذه الرسالة، يرجى تفقد مجلّد البريد المزعج.
-      send_paranoid_instructions: إن كان عنوان بريدك الإلكتروني ضمن قاعدة بياناتنا، فسوف تتلقّى في غضون دقائق رابطا يُمكّنُك مِن استعادة كلمتك السرية على عنوان علبة البريد الإلكتروني الخاصة بك.إن لم تجد هذه الرسالة، يرجى تفقد مجلّد البريد المزعج.
+      no_token: ليس بإمكانك النفاذ إلى هذه الصفحة إن لم تقم بالنقر على الرابط المتواجد في الرسالة الإلكترونية. الرجاء التحقق مِن أنك قمت بإدخال عنوان الرابط كاملا كما هو مذكور في رسالة إعادة تعيين الكلمة السرية.
+      send_instructions: إن كان عنوان بريدك الإلكتروني ضمن قاعدة بياناتنا، فسوف تتلقّى في غضون دقائق رابطا يُمكّنُك مِن استعادة كلمتك السرية على عنوان علبة البريد الإلكتروني الخاصة بك. إن لم تجد هذه الرسالة، يرجى تفقد مجلّد البريد المزعج.
+      send_paranoid_instructions: إن كان عنوان بريدك الإلكتروني ضمن قاعدة بياناتنا، فسوف تتلقّى في غضون دقائق رابطا يُمكّنُك مِن استعادة كلمتك السرية على عنوان علبة البريد الإلكتروني الخاصة بك. إن لم تجد هذه الرسالة، يرجى تفقد مجلّد البريد المزعج.
       updated: تم تغيير كلمة المرور بنجاح. أنت مسجل الآن.
       updated_not_active: تم تغيير كلمة المرور بنجاح.
     registrations:
-      destroyed: إلى اللقاء ! لقد تم إلغاء حسابك. نتمنى أن نراك مجددا.
-      signed_up: أهلا وسهلا ! تم تسجيل دخولك بنجاح.
+      destroyed: إلى اللقاء! لقد تم إلغاء حسابك. نتمنى أن نراك مجددا.
+      signed_up: أهلا وسهلا! تم تسجيل دخولك بنجاح.
       signed_up_but_inactive: لقد تمت عملية إنشاء حسابك بنجاح إلاّ أنه لا يمكننا تسجيل دخولك إلاّ بعد قيامك بتفعيله.
       signed_up_but_locked: لقد تم تسجيل حسابك بنجاح إلّا أنه لا يمكنك تسجيل الدخول لأن حسابك مجمد.
       signed_up_but_unconfirmed: لقد تم إرسال رسالة تحتوي على رابط للتفعيل إلى عنوان بريدك الإلكتروني. بالضغط على الرابط سوف يتم تفعيل حسابك. لذا يُرجى إلقاء نظرة على ملف الرسائل غير المرغوب فيها إنْ لم تَعثُر على الرسالة السالفة الذِكر.
@@ -70,12 +71,12 @@ ar:
     unlocks:
       send_instructions: سوف تتلقى خلال بضع دقائق رسالة إلكترونية تحتوي على التعليمات اللازمة لفك القفل عن حسابك. إن لم تتلقى تلك الرسالة ، ندعوك إلى تفقُّد مجلد البريد المزعج.
       send_paranoid_instructions: إن كان حسابك موجود فعليًا فسوف تتلقى في غضون دقائق رسالة إلكترونية تحتوي على تعليمات تدُلُّك على كيفية فك القفل عن حسابك. إن لم تتلقى تلك الرسالة ، ندعوك إلى تفقُّد مجلد البريد المزعج.
-      unlocked: لقد تمت عملية إلغاء تجميد حسابك بنجاح. للمواصلة،  يُرجى تسجيل الدخول.
+      unlocked: لقد تمت عملية إلغاء تجميد حسابك بنجاح. للمواصلة ، يُرجى تسجيل الدخول.
   errors:
     messages:
-      already_confirmed: قمت بتأكيده من قبل، يرجى إعادة محاولة تسجيل الدخول
+      already_confirmed: قمت بتأكيده من قبل ، يرجى إعادة محاولة تسجيل الدخول
       confirmation_period_expired: يجب التأكد منه قبل انقضاء مدة %{period}، يرجى إعادة طلب جديد
-      expired: إنتهت مدة صلاحيته، الرجاء طلب واحد جديد
+      expired: انتهت مدة صلاحيته، الرجاء طلب واحد جديد
       not_found: لا يوجد
       not_locked: ليس مقفلاً
       not_saved:
@@ -83,5 +84,5 @@ ar:
         many: "%{count} أخطاء منعت هذا %{resource} من الحفظ:"
         one: 'خطأ واحد منع هذا %{resource} من الحفظ:'
         other: "%{count} أخطاء منعت هذا %{resource} من الحفظ:"
-        two: 'أخطاء منعت هذا %{resource} من الحفظ:'
-        zero: 'أخطاء منعت هذا %{resource} من الحفظ:'
+        two: "%{count} أخطاء منعت هذا %{resource} من الحفظ:"
+        zero: "%{count} أخطاء منعت هذا %{resource} من الحفظ:"
diff --git a/config/locales/devise.bn.yml b/config/locales/devise.bn.yml
new file mode 100644
index 0000000000000000000000000000000000000000..152c698290639f4688cdb5184962daafc705fc52
--- /dev/null
+++ b/config/locales/devise.bn.yml
@@ -0,0 +1 @@
+bn:
diff --git a/config/locales/devise.ca.yml b/config/locales/devise.ca.yml
index c41a218e14fa860852db4d90005b8c8195bf4f8d..7f2df1f995f83c20faa2eb4060a15c294794c81a 100644
--- a/config/locales/devise.ca.yml
+++ b/config/locales/devise.ca.yml
@@ -3,15 +3,18 @@ ca:
   devise:
     confirmations:
       confirmed: L'adreça de correu s'ha confirmat correctament.
-      send_instructions: En pocs minuts rebràs un correu electrònic amb instruccions sobre com confirmar l'adreça de correu.
-      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.
+      send_instructions: "En pocs minuts rebràs un correu electrònic amb instruccions sobre com confirmar l'adreça de correu. \nSi us plau verifica la carpeta de corrreu brossa si no has rebut aquest correu."
+      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.
+        Si us plau verifica la carpeta de corrreu brossa si no has rebut aquest correu.
     failure:
       already_authenticated: Ja estàs registrat.
       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.
-      not_found_in_database: "%{authentication_keys} o contrasenya no vàlids."
+      last_attempt: Tens un intent més, abans que es bloqueji el compte.
+      locked: El compte s'ha bloquejat.
+      not_found_in_database: "%{authentication_keys} o contrasenya no són vàlids."
+      pending: El teu compte encara està en revisió.
       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.
@@ -20,17 +23,18 @@ ca:
         action: Verifica l'adreça de correu
         action_with_app: Confirma i torna a %{app}
         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>.
+        explanation_when_pending: Has sol·licitat una invitació a %{host} amb aquesta adreça de correu electrònic. Un cop confirmis la teva adreça de correu electrònic revisarem la teva sol·licitud. No es pot iniciar la sessió fins llavors. Si la teva sol·licitud és rebutjada les teves dades s’eliminaran, de manera que no s’exigirà cap altra acció. Si no has estat tu qui ha fet aquest sol·licitud si us plau ignora aquest correu electrònic.
+        extra_html: Si us plau consulta també <a href="%{terms_path}"> les regles del servidor</a> i <a href="%{policy_path}"> les nostres condicions de servei</a>.
         subject: 'Mastodon: Instruccions de confirmació %{instance}'
         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 la 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 del servidor si no pots accedir al teu compte.
         subject: 'Mastodon: s''ha canviat l''adreça electrònica'
         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 la 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 del servidor si no pots accedir al teu compte.
         subject: 'Mastodon: Contrasenya canviada'
         title: Contrasenya canviada
       reconfirmation_instructions:
@@ -48,7 +52,7 @@ ca:
         subject: 'Mastodon: Instruccions per a desblocar'
     omniauth_callbacks:
       failure: No podem autentificar-te desde %{kind} degut a "%{reason}".
-      success: Autentificat amb èxit des del compte %{kind} .
+      success: Autentificat amb èxit des del compte %{kind}.
     passwords:
       no_token: No pots accedir a aquesta pàgina sense provenir des del correu de restabliment de la contrasenya. Si vens des del correu de restabliment de contrasenya, assegura't que estàs emprant l'adreça completa proporcionada.
       send_instructions: Rebràs un correu electrònic amb instruccions sobre com reiniciar la contrasenya en pocs minuts.
@@ -60,9 +64,10 @@ ca:
       signed_up: Benvingut! T'has registrat amb èxit.
       signed_up_but_inactive: T´has registrat amb èxit. No obstant, no podem identificar-te perquè el compte encara no s'ha activat.
       signed_up_but_locked: T´has registrat amb èxit. No obstant, no podem identificar-te perquè el compte està blocat.
+      signed_up_but_pending: S'ha enviat un missatge amb un enllaç de confirmació a la teva adreça de correu electrònic. Després de que hagis fet clic a l'enllaç, revisarem la teva sol·licitud. Se't notificarà si s'aprova.
       signed_up_but_unconfirmed: Un missatge amb un enllaç de confirmació ha estat enviat per correu electrònic. Si us plau segueixi l'enllaç per activar el seu compte.
       update_needs_confirmation: Ha actualitzat el seu compte amb èxit, però necessitem verificar la nova adreça de correu. Si us plau comprovi el correu i segueixi l'enllaç per confirmar la nova adreça de correu.
-      updated: el seu compte ha estat actualitzat amb èxit.
+      updated: El seu compte ha estat actualitzat amb èxit.
     sessions:
       already_signed_out: Has tancat la sessió amb èxit.
       signed_in: T'has registrat amb èxit.
diff --git a/config/locales/devise.co.yml b/config/locales/devise.co.yml
index 108a4ef11e2145eba8f578aa270ab6e944d7df4f..16481737f1e8e478a615d131a46ab4ae9b8ab4ee 100644
--- a/config/locales/devise.co.yml
+++ b/config/locales/devise.co.yml
@@ -12,6 +12,7 @@ co:
       last_attempt: Avete un’ultimu tintativu nanzu chì u vostru contu sia chjosu.
       locked: U vostru contu hè chjosu.
       not_found_in_database: L’ %{authentication_keys} o a chjave d’accessu ùn sò curretti.
+      pending: U vostru contu hè sempre in corsu di rivista.
       timeout: A vostra sezzione hè spirata. Ricunnettatevi pè cuntinuà.
       unauthenticated: Cunnettatevi o arregistratevi pè cuntinuà.
       unconfirmed: Duvete cunfirmà u vostru contu pè cuntinuà.
@@ -20,17 +21,18 @@ co:
         action: Verificà l’indirizzu email
         action_with_app: Cunfirmà è rivene à %{app}
         explanation: Avete creatu un contu nant’à %{host} cù st’indirizzu email. Pudete attivallu cù un clic, o ignurà quessu missaghji s’ellu un era micca voi.
-        extra_html: Pensate à leghje <a href="%{terms_path}">e regule di l’istanza</a> è <a href="%{policy_path}">i termini d’usu</a>.
+        explanation_when_pending: Avete dumandatu un'invitazione à %{host}, cù st'indirizzu e-mail. Una volta ch'ellu hè cunfirmatu, avemu da dà un'ochjata à a vostra dumanda. Ùn pudete micca cunnettavi nanz'à quessa. S'ella hè righjittata a vostra dumanda, i vostri dati saranu sguassati è ùn duverete fà nund'altru. S'ellu ùn era micca voi, pudete ignurà quess'e-mail.
+        extra_html: Pensate à leghje <a href="%{terms_path}">e regule di u servore</a> è <a href="%{policy_path}">i termini d’usu</a>.
         subject: 'Mastodon: Istruzzione di cunfirmazione per %{instance}'
         title: Verificà l’indirizzu email
       email_changed:
         explanation: 'L’indirizzu email di u vostru contu hè stata cambiata per:'
-        extra: S’ellu un era micca voi ch’avete cambiatu u vostru email, qualch’un’altru hà accessu à u vostru contu. Duvete cambià a vostra chjave d’accessu o cuntattà l’amministratore di l’istanza s’ellu ùn hè più pussibule di cunnettavi.
+        extra: S’ellu un era micca voi ch’avete cambiatu u vostru email, qualch’un’altru hà accessu à u vostru contu. Duvete cambià a vostra chjave d’accessu o cuntattà l’amministratore di u servore s’ellu ùn hè più pussibule di cunnettavi.
         subject: 'Mastodon: Email cambiatu'
         title: Novu indirizzu email
       password_change:
         explanation: A chjave d’accessu per u vostru contu hè stata cambiata.
-        extra: S’ellu un era micca voi ch’avete cambiatu a vostra chjave d’accessu, qualch’un’altru hà accessu à u vostru contu. Duvete cambià a vostra chjave d’accessu o cuntattà l’amministratore di l’istanza s’ellu ùn hè più pussibule di cunnettavi.
+        extra: S’ellu un era micca voi ch’avete cambiatu a vostra chjave d’accessu, qualch’un’altru hà accessu à u vostru contu. Duvete cambià a vostra chjave d’accessu o cuntattà l’amministratore di u servore s’ellu ùn hè più pussibule di cunnettavi.
         subject: 'Mastodon: Chjave d’accessu cambiata'
         title: Chjave cambiata
       reconfirmation_instructions:
@@ -60,6 +62,7 @@ co:
       signed_up: Benvinutu! Site cunnettatu·a.
       signed_up_but_inactive: Site arregistratu·a, mà ùn pudete micca cunnettavi perchè u vostru contu deve esse attivatu.
       signed_up_but_locked: Site arregistratu·a, mà ùn pudete micca cunnettavi perchè u vostru contu hè chjosu.
+      signed_up_but_pending: Un missaghju cù un ligame di cunfirmazione hè statu mandatu à u vostr'indirizzu e-mail. Dop'à avè cliccatu u ligame, avemu da rivede a vostra dumanda - sarete nutificatu·a s'ella hè appruvata.
       signed_up_but_unconfirmed: Un missaghju cù un ligame di cunfirmazione hè statu mandatu à u vostru indirizzu e-mail. Aprite stu ligame pè attivà u vostru contu. Pensate à verificà u cartulare di spam s’ellu ùn c’hè nunda.
       update_needs_confirmation: U vostru contu hè statu messu à ghjornu mà duvemu verificà u vostru novu e-mail. Un missaghju cù un ligame di cunfirmazione hè statu mandatu. Pensate à verificà u cartulare di spam s’ellu ùn c’hè nunda.
       updated: U vostru contu hè statu messu à ghjornu.
diff --git a/config/locales/devise.cs.yml b/config/locales/devise.cs.yml
index 850ff1fe822f5236b775bdab4b697107df3e7b88..94c41ed986e8f6db36a43eddf23599397408f6df 100644
--- a/config/locales/devise.cs.yml
+++ b/config/locales/devise.cs.yml
@@ -3,15 +3,16 @@ cs:
   devise:
     confirmations:
       confirmed: Vaše e-mailová adresa byla úspěšně ověřena.
-      send_instructions: Za několik minut obdržíte e-mail s instrukcemi pro potvrzení vašeho účtu. Pokud tento e-mail neobdržíte, zkontrolujte si složku „spam“.
-      send_paranoid_instructions: Pokud tato e-mailová adresa existuje v naší databázi, obdržíte za několik minut e-mail s instrukcemi pro potvrzení vašeho účtu. Pokud tento e-mail neobdržíte, zkontrolujte si složku „spam“.
+      send_instructions: Za několik minut obdržíte e-mail s instrukcemi pro potvrzení vašeho účtu. Pokud tento e-mail neobdržíte, prosím zkontrolujte si složku „spam“.
+      send_paranoid_instructions: Pokud vaše e-mailová adresa existuje v naší databázi, obdržíte za několik minut e-mail s instrukcemi pro potvrzení vaší e-mailové adresy. Pokud tento e-mail neobdržíte, prosím zkontrolujte si složku „spam“.
     failure:
       already_authenticated: Již jste přihlášen/a.
       inactive: Váš účet ještě není aktivován.
-      invalid: Neplatné %{authentication_keys} nebo heslo.
+      invalid: Neplatný %{authentication_keys} nebo heslo.
       last_attempt: Máte ještě jeden pokus, než bude váš účet uzamčen.
       locked: Váš účet je uzamčen.
       not_found_in_database: Neplatné %{authentication_keys} nebo heslo.
+      pending: Váš účet je stále posuzován.
       timeout: Vaše relace vypršela. Pro pokračování se prosím přihlaste znovu.
       unauthenticated: Před pokračováním se musíte přihlásit nebo registrovat.
       unconfirmed: Před pokračováním musíte potvrdit svůj e-mail.
@@ -19,18 +20,19 @@ cs:
       confirmation_instructions:
         action: Potvrdit e-mailovou adresu
         action_with_app: Potvrdit a navrátit se do %{app}
-        explanation: S touto e-mailovou adresou jste si vytvořil/a účet na %{host}. K jeho aktivaci vám zbývá jedno kliknutí. Pokud jste to nebyl/a vy, ignorujte této e-mail.
-        extra_html: Prosím podívejte se také na <a href="%{terms_path}">pravidla této instance</a> a <a href="%{policy_path}">naše podmínky používání</a>.
+        explanation: S touto e-mailovou adresou jste si vytvořil/a účet na %{host}. K jeho aktivaci vám zbývá jedno kliknutí. Pokud jste to nebyl/a vy, prosím ignorujte tento e-mail.
+        explanation_when_pending: S touto e-mailovou adresou jste si vyžádal/a pozvánku na %{host}. Jakmile svou e-mailovou adresu potvrdíte, posoudíme váš poadavek. Do té doby se nemůžete přihlásit. Pokud bude váš požadavek zamítnut, budou vaše data odstraněna, takže od vás nebude vyžadována žádná další akce. Pokud jste to nebyl/a vy, prosím ignorujte tento e-mail.
+        extra_html: Prosím podívejte se také na <a href="%{terms_path}">pravidla tohoto serveru</a> a <a href="%{policy_path}">naše podmínky používání</a>.
         subject: 'Mastodon: Potvrzovací instrukce pro %{instance}'
         title: Potvrďte e-mailovou adresu
       email_changed:
         explanation: 'E-mailová adresa vašeho účtu byla změněna na:'
-        extra: Pokud jste si e-mail nezměnil/a, je pravděpodobné, že někdo jiný získal přístup k vašemu účtu. Prosím změňte si okamžitě heslo, nebo, pokud se nemůžete na účet přihlásit, kontaktujte administrátora instance.
+        extra: Pokud jste si e-mail nezměnil/a, je pravděpodobné, že někdo jiný získal přístup k vašemu účtu. Prosím změňte si okamžitě heslo, nebo, pokud se nemůžete na účet přihlásit, kontaktujte administrátora serveru.
         subject: 'Mastodon: E-mail byl změněn'
         title: Nová e-mailová adresa
       password_change:
         explanation: Heslo k vašemu účtu bylo změněno.
-        extra: Pokud jste si heslo nezměnil/a, je pravděpodobné, že někdo jiný získal přístup k vašemu účtu. Prosím změňte si okamžitě heslo, nebo, pokud se nemůžete na účet přihlásit, kontaktujte administrátora instance.
+        extra: Pokud jste si heslo nezměnil/a, je pravděpodobné, že někdo jiný získal přístup k vašemu účtu. Prosím změňte si okamžitě heslo, nebo, pokud se nemůžete na účet přihlásit, kontaktujte administrátora serveru.
         subject: 'Mastodon: Heslo bylo změněno'
         title: Heslo bylo změněno
       reconfirmation_instructions:
@@ -42,7 +44,7 @@ cs:
         action: Změnit heslo
         explanation: Vyžádal/a jste si pro svůj účet nové heslo.
         extra: Pokud jste tohle nevyžádal/a, prosím ignorujte tento e-mail. Vaše heslo nebude změněno, dokud nepřejdete na výše uvedenou adresu a nevytvoříte si nové.
-        subject: 'Mastodon: Instrukce pro obnovu hesla'
+        subject: 'Mastodon: Instrukce pro obnovení hesla'
         title: Obnovení hesla
       unlock_instructions:
         subject: 'Mastodon: Instrukce pro odemčení účtu'
@@ -50,9 +52,9 @@ cs:
       failure: Nelze vás ověřit z %{kind}, protože „%{reason}“.
       success: Úspěšně ověřeno z účtu %{kind}.
     passwords:
-      no_token: Tuto stránku nemůžete navštívit, pokud nepřicházíte z e-mailu pro obnovu hesla. Pokud jste z něj přišel/la, ujistěte se, že jste použil/a celé URL z e-mailu.
-      send_instructions: Pokud vaše e-mailová adresa existuje v naší databázi, obdržíte za pár minut ve vašem e-mailu odkaz pro obnovení hesla. Prosím zkontrolujte si složku spam, jestli jste tento e-mail neobdržel/a.
-      send_paranoid_instructions: Pokud vaše e-mailová adresa existuje v naší databázi, obdržíte za pár minut ve vašem e-mailu odkaz pro obnovení hesla. Prosím zkontrolujte si složku spam, jestli jste tento e-mail neobdržel/a.
+      no_token: Tuto stránku nemůžete navštívit, pokud nepřicházíte z e-mailu pro obnovení hesla. Pokud z něj přicházíte, ujistěte se, že jste použil/a celé URL z e-mailu.
+      send_instructions: Pokud vaše e-mailová adresa existuje v naší databázi, obdržíte za několik minut ve vašem e-mailu odkaz pro obnovení hesla. Pokud tento e-mail neobdržíte, prosím zkontrolujte si složku „spam“.
+      send_paranoid_instructions: Pokud vaše e-mailová adresa existuje v naší databázi, obdržíte za několik minut ve vašem e-mailu odkaz pro obnovení hesla. Pokud tento e-mail neobdržíte, prosím zkontrolujte si složku „spam“.
       updated: Vaše heslo bylo úspěšně změněno. Nyní jste přihlášen/a.
       updated_not_active: Vaše heslo bylo úspěšně změněno.
     registrations:
@@ -60,16 +62,17 @@ cs:
       signed_up: Vítejte! Registroval/a jste se úspěšně.
       signed_up_but_inactive: Registroval/a jste se úspěšně. Nemohli jsme vás však přihlásit, protože váš účet ještě není aktivován.
       signed_up_but_locked: Registroval/a jste se úspěšně. Nemohli jsme vás však přihlásit, protože váš účet je uzamčen.
-      signed_up_but_unconfirmed: Na vaši e-mailovou adresu byla poslána zpráva s potvrzovacím odkazem. Pro aktivaci účtu přejděte na danou adresu. Prosím zkontrolujte si složku spam, jestli jste tento e-mail neobdržel/a.
-      update_needs_confirmation: Váš účet byl úspěšně aktualizován, ale je potřeba ověřit vaši novou e-mailovou adresu. Prosím zkontrolujte si e-mail a klikněte na odkaz pro potvrzení vaši nové e-mailové adresy. Prosím zkontrolujte si složku spam, jestli jste tento e-mail neobdržel/a.
+      signed_up_but_pending: Na vaši e-mailovou adresu byla poslána zpráva s potvrzovacím odkazem. Poté, co kliknete na odkaz, posoudíme váš požadavek. Pokud bude schválen, budete informován/a.
+      signed_up_but_unconfirmed: Na vaši e-mailovou adresu byla poslána zpráva s potvrzovacím odkazem. Pro aktivaci účtu přejděte na danou adresu. Pokud jste tento e-mail neobdržel/a, prosím zkontrolujte si složku spam.
+      update_needs_confirmation: Váš účet byl úspěšně aktualizován, ale je potřeba ověřit vaši novou e-mailovou adresu. Pokud tento e-mail neobdržíte, prosím zkontrolujte si složku „spam“.
       updated: Váš účet byl úspěšně aktualizován.
     sessions:
       already_signed_out: Odhlášení proběhlo úspěšně.
       signed_in: Přihlášení proběhlo úspěšně.
       signed_out: Odhlášení proběhlo úspěšně.
     unlocks:
-      send_instructions: Za pár minut obdržíte e-mail s instrukcemi pro odemčení vašeho účtu. Prosím zkontrolujte si složku spam, jestli jste tento e-mail neobdržel/a.
-      send_paranoid_instructions: Pokud váš účet existuje, obdržíte za pár minut e-mail s instrukcemi pro odemčení vašeho účtu. Prosím zkontrolujte si složku spam, jestli jste tento e-mail neobdržel/a.
+      send_instructions: Za několik minut obdržíte e-mail s instrukcemi pro odemčení vašeho účtu. Pokud tento e-mail neobdržíte, prosím zkontrolujte si složku „spam“.
+      send_paranoid_instructions: Pokud váš účet existuje, obdržíte za několik minut e-mail s instrukcemi pro odemčení vašeho účtu. Pokud tento e-mail neobdržíte, prosím zkontrolujte si složku „spam“.
       unlocked: Váš účet byl úspěšně odemčen. Pro pokračování se prosím přihlaste.
   errors:
     messages:
@@ -80,5 +83,6 @@ cs:
       not_locked: nebyl uzamčen
       not_saved:
         few: "%{count} chyby zabránily uložení tohoto %{resource}:"
+        many: "%{count} chyb zabránilo uložení tohoto %{resource}:"
         one: '1 chyba zabránila uložení tohoto %{resource}:'
         other: "%{count} chyb zabránilo uložení tohoto %{resource}:"
diff --git a/config/locales/devise.cy.yml b/config/locales/devise.cy.yml
index 7d96e57f9b70035d6ba5d78ec85e0d18470f81c9..727c71464494442060156c825d2eae40719d77b0 100644
--- a/config/locales/devise.cy.yml
+++ b/config/locales/devise.cy.yml
@@ -12,13 +12,16 @@ cy:
       last_attempt: Mae gennych un cyfle arall cyn i'ch cyfrif gael ei gloi.
       locked: Mae eich cyfrif wedi ei gloi.
       not_found_in_database: "%{authentication_keys} neu gyfrinair annilys."
+      pending: Mae eich cyfrif dal o dan adolygiad.
       timeout: Mae eich sesiwn wedi dod i ben. Mewngofnodwch eto i barhau.
       unauthenticated: Mae angen i chi fewngofnodi neu gofrestru cyn parhau.
       unconfirmed: Mae rhaid i chi gadarnhau eich cyfeiriad e-bost cyn parhau.
     mailer:
       confirmation_instructions:
         action: Gwiriwch eich cyfeiriad e-bost
+        action_with_app: Cadarnhau a dychwelyd i %{app}
         explanation: Yr ydych wedi creu cyfrif ar %{host} gyda'r cyfrif e-bost hwn. Dim ond un clic sydd angen i'w wneud yn weithredol. Os nad chi oedd hyn, anwybyddwch yr e-bost hwn os gwelwch yn dda.
+        explanation_when_pending: Rydych wedi gwneud cais am wahoddiad i %{host} gyda'r ebost hyn. Unwaith rydych wedi cadarnhau eich ebost, byddem yn adolygu eich cais. Ni fyddwch yn gallu mewngofnodi tan yr amser hono. Os caiff eich cais ei wrthod, felly nid oes angen unrhyw gweithred pellach o chi. Os nad oeddech wedi gwneud y cais hyn, anwybyddu'r ebost hon, os gwelwch yn dda.
         extra_html: Gwnewch yn siŵr i edrych ar <a href="%{terms_path}">reolau'r achos</a> a <a href="%{policy_path}">ein telerau gwasanaeth</a>.
         subject: 'Mastodon: Canllawiau cadarnhau i %{instance}'
         title: Gwirio cyfeiriad e-bost
@@ -59,6 +62,7 @@ cy:
       signed_up: Croeso! Rydych wedi cofrestru'n llwyddiannus.
       signed_up_but_inactive: Yr ydych wedi cofrestru'n llwyddiannus. Fodd bynnag, ni allwn eich mewngofnodi achos nid yw eich cyfrif wedi ei actifadu eto.
       signed_up_but_locked: Yr ydych wedi cofrestru'n llwyddiannus. Fodd bynnag, ni allwn eich mewngofnodi achos fod eich cyfrif wedi ei gloi.
+      signed_up_but_pending: Mae neges a'ch cysylltiad cadarnhau wedi cael ei hanfon i'ch ebost. Ar ôl i chi ei glicio, byddem yn adolygu eich cais. Byddwch yn derbyn hysbysiad os caiff ei gymeradwyo.
       signed_up_but_unconfirmed: Mae neges gyda dolen cadarnhau wedi ei anfon i'ch cyfeiriad e-bost. Dilynwch y ddolen er mwyn actifadu eich cyfrif. Edrychwch yn eich ffolder sbam os na dderbynioch chi'r e-bost hwn os gwelwch yn dda.
       update_needs_confirmation: Rydych wedi diweddaru eich cyfrif yn llwyddiannus, ond mae angen i ni wirio'ch cyfeiriad e-bost newydd. Edrychwch ar eich e-byst a dilynwch y ddolen gadarnhau er mwyn cadarnhau eich cyfeiriad e-bost newydd. Edrychwch ar eich ffolder sbam os na dderbynioch chi yr e-bost hwn.
       updated: Mae eich cyfrif wedi ei ddiweddaru yn llwyddiannus.
@@ -77,4 +81,10 @@ cy:
       expired: wedi dod i ben, gwnewch gais am un newydd os gwelwch yn dda
       not_found: heb ei ganfod
       not_locked: heb ei gloi
-      not_saved: 'Gwaharddwyd yr %{resource} rhag cael ei arbed oherwydd %{count} gwall:'
+      not_saved:
+        few: 'Gwaharddwyd yr %{resource} rhag cael ei arbed oherwydd %{count} gwall:'
+        many: 'Gwaharddwyd yr %{resource} rhag cael ei arbed oherwydd %{count} gwall:'
+        one: 'Gwaharddwyd yr %{resource} rhag cael ei arbed oherwydd 1 gwall:'
+        other: 'Gwaharddwyd yr %{resource} rhag cael ei arbed oherwydd %{count} gwall:'
+        two: 'Gwaharddwyd yr %{resource} rhag cael ei arbed oherwydd %{count} gwall:'
+        zero: 'Gwaharddwyd yr %{resource} rhag cael ei arbed oherwydd %{count} gwall:'
diff --git a/config/locales/devise.da.yml b/config/locales/devise.da.yml
index 56ae5183bf396c29357df8125c5dc6d2e899f043..4816d6456b7f63c112e24237a4067487fce4e324 100644
--- a/config/locales/devise.da.yml
+++ b/config/locales/devise.da.yml
@@ -20,17 +20,17 @@ da:
         action: Bekræft email adresse
         action_with_app: Bekræft og vend tilbage til %{app}
         explanation: Du har oprettet en konto på %{host} med denne email adresse. Du er et klik fra at aktivere din konto. Hvis du ikke har oprettet dig, ignorer venligst denne email.
-        extra_html: Tjek også <a href="%{terms_path}">reglerne for instansen</a> og <a href="%{policy_path}">vores betingelser</a>.
+        extra_html: Tjek også <a href="%{terms_path}">reglerne for serveren</a> og <a href="%{policy_path}">vores betingelser</a>.
         subject: 'Mastodon: Bekræftelses instrukser for %{instance}'
         title: Bekræft email adresse
       email_changed:
         explanation: 'Email adressen for din konto bliver ændret til:'
-        extra: Hvis du ikke har ændret din email adresse er det muligt, at nogen har fået adgang til din konto. Venligst ændre dit kodeord med det samme eller kontakt administratoren på instansen hvis du er låst ude af din konto.
+        extra: Hvis du ikke har ændret din email adresse er det muligt, at nogen har fået adgang til din konto. Venligst ændre dit kodeord med det samme eller kontakt administratoren på serveren hvis du er låst ude af din konto.
         subject: 'Mastodon: Email ændret'
         title: Ny email adresse
       password_change:
         explanation: Kodeordet for din konto er blevet ændret.
-        extra: Hvis du ikke har ændret dit kodeord er det muligt, at nogen har fået adgang til din konto. Venligst ændre dit kodeord med det samme eller kontakt administratoren på instansen hvis du er låst ude af din konto.
+        extra: Hvis du ikke har ændret dit kodeord er det muligt, at nogen har fået adgang til din konto. Venligst ændre dit kodeord med det samme eller kontakt administratoren på serveren hvis du er låst ude af din konto.
         subject: 'Mastodon: Kodeord ændret'
         title: Kodeordet er blevet ændret
       reconfirmation_instructions:
diff --git a/config/locales/devise.de.yml b/config/locales/devise.de.yml
index fc41c9db51a67a178c4b0a2819c6ed90adf76185..bd573dc3e9a50ea756d89036f2bb793451283cef 100644
--- a/config/locales/devise.de.yml
+++ b/config/locales/devise.de.yml
@@ -12,6 +12,7 @@ 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."
+      pending: Dein Konto wird immer noch überprüft.
       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.
@@ -20,17 +21,18 @@ de:
         action: E-Mail-Adresse verifizieren
         action_with_app: Bestätigen und zu %{app} zurückkehren
         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>.
+        explanation_when_pending: Du hast dich für eine Einladung bei %{host} mit dieser E-Mailadresse beworben. Sobald du deine E-Mailadresse bestätigst werden wir deine Anfrage überprüfen. Du kannst dich in dieser Zeit nicht anmelden. Wenn deine Anfrage abgelehnt wird, werden deine Daten entfernt, also wird keine weitere Handlung benötigt. Wenn du das nicht warst kannst du diese E-Mail ignorieren.
+        extra_html: Bitte lies auch die <a href="%{terms_path}">Regeln des Servers</a> und <a href="%{policy_path}">unsere Nutzungsbedingungen</a>.
         subject: 'Mastodon: Bestätigung deines Kontos bei %{instance}'
         title: Verifiziere E-Mail-Adresse
       email_changed:
         explanation: 'Die E-Mail-Adresse deines Accounts wird geändert zu:'
-        extra: Wenn du deine E-Mail-Adresse nicht geändert hast, dann kann es vermutlich sein, dass jemand Zugriff zu deinem Account erhalten hat. Bitte ändere sofort dein Passwort oder kontaktiere den Administrator deiner Instanz, wenn du dich ausgesperrt hast.
+        extra: Wenn du deine E-Mail-Adresse nicht geändert hast, dann kann es vermutlich sein, dass jemand Zugriff zu deinem Account erhalten hat. Bitte ändere sofort dein Passwort oder kontaktiere den Administrator des Servers, wenn du dich ausgesperrt hast.
         subject: 'Mastodon: E-Mail-Adresse geändert'
         title: Neue E-Mail-Adresse
       password_change:
         explanation: Das Passwort für deinen Account wurde geändert.
-        extra: Wenn du dein Passwort nicht geändert hast, dann kann es vermutlich sein, dass jemand Zugriff zu deinem Account erhalten hat. Bitte ändere sofort dein Passwort oder kontaktiere den Administrator deiner Instanz, wenn du dich ausgesperrt hast.
+        extra: Wenn du dein Passwort nicht geändert hast, dann kann es vermutlich sein, dass jemand Zugriff zu deinem Account erhalten hat. Bitte ändere sofort dein Passwort oder kontaktiere den Administrator des Servers, wenn du dich ausgesperrt hast.
         subject: 'Mastodon: Passwort geändert'
         title: Passwort geändert
       reconfirmation_instructions:
@@ -60,6 +62,7 @@ de:
       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_pending: Eine Nachricht mit einem Bestätigungslink wurde an dich per E-Mail geschickt. Nachdem du diesen Link angeklickt hast werden wir deine Anfrage überprüfen. Du wirst benachrichtigt falls die Anfrage angenommen wurde.
       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.
       update_needs_confirmation: Deine Daten wurden aktualisiert, aber du musst deine neue E-Mail-Adresse bestätigen. Du erhältst in wenigen Minuten eine E-Mail. Darin ist erklärt, wie du die Änderung deiner E-Mail-Adresse abschließen kannst.
       updated: Deine Daten wurden aktualisiert.
diff --git a/config/locales/devise.el.yml b/config/locales/devise.el.yml
index e9725d96b968f6c2f9e06f3e33470566c69b863e..0b5c686368f7a17b7050a95a0e0cbd70ae3fefff 100644
--- a/config/locales/devise.el.yml
+++ b/config/locales/devise.el.yml
@@ -12,6 +12,7 @@ el:
       last_attempt: Έχεις μια ακόμα προσπάθεια πριν κλειδωθεί ο λογαριασμός σου.
       locked: Ο λογαριασμός σου κλειδώθηκε.
       not_found_in_database: Λάθος %{authentication_keys} ή συνθηματικό.
+      pending: Εκκρεμεί η έγκριση του λογαριασμού σου.
       timeout: Η τρέχουσα σύνδεσή σου έληξε. Παρακαλούμε συνδέσου ξανά για να συνεχίσεις.
       unauthenticated: Πρέπει να συνδεθείς ή να εγγραφείς για να συνεχίσεις.
       unconfirmed: Πρέπει να επιβεβαιώσεις τη διεύθυνση email σου για να συνεχίσεις.
@@ -20,6 +21,7 @@ el:
         action: Επιβεβαίωσε διεύθυνση email
         action_with_app: Επιβεβαίωση και επιστροφή στο %{app}
         explanation: Δημιούργησες έναν λογαριασμό στο %{host} με αυτή τη διεύθυνση email. Με ένα κλικ θα τον ενεργοποιήσεις. Αν δεν το έκανες εσύ, παρακαλούμε αγνόησε αυτό το email.
+        explanation_when_pending: Έχεις υποβάλλει αίτηση πρόσκλησης στο %{host} με αυτή την ηλεκτρονική διεύθυνση email. Μόλις επιβεβαιώσεις το email σου, θα ελέγξουμε την αίτηση σου. Μέχρι τότε δε θα μπορεις να συνδεθείς. Αν απορριφθεί η αίτησή σου, τα στοιχεία σου θα αφαιρεθούν, άρα δε θα χρειαστεί να κάνεις κάτι επιπλέον. Αν δεν υπέβαλες εσύ την αίτηση, αγνόησε αυτό το email.
         extra_html: Παρακαλούμε να διαβάσεις <a href="%{terms_path}">του κανόνες αυτού του κόμβου</a> και <a href="%{policy_path}">τους όρους χρήσης της υπηρεσίας μας</a>.
         subject: 'Mastodon: Οδηγίες επιβεβαίωσης για %{instance}'
         title: Επιβεβαίωσε διεύθυνση email
@@ -60,6 +62,7 @@ el:
       signed_up: Καλώς ήρθες! Εγγράφηκες με επιτυχία.
       signed_up_but_inactive: Εγγράφηκες με επιτυχία. Όμως δε μπορέσαμε να σε συνδέσουμε γιατί ο λογαριασμός σου δεν έχει ενεργοποιηθεί ακόμα.
       signed_up_but_locked: Εγγράφηκες με επιτυχία. Όμως δε μπορέσαμε να σε συνδέσουμε γιατί ο λογαριασμός σου είναι κλειδωμένος.
+      signed_up_but_pending: Στάλθηκε στο email σου μήνυμα με ένα σύνδεσμο επιβεβαίωσης. Μόλις τον ακολουθήσεις θα ελέγξουμε την αίτηση σου. Θα ειδοποιήσεις εάν γίνει δεκτή.
       signed_up_but_unconfirmed: Σου στείλαμε ένα μήνυμα με σύνδεσμο επιβεβαίωσης στη διεύθυνση email σου. Παρακαλούμε ακολούθησε το σύνδεσμο για να ενεργοποιήσεις το λογαριασμό σου. Παρακαλούμε έλεγξε το φάκελο με τα ανεπιθύμητα μηνύματα σου αν δεν το λάβεις.
       update_needs_confirmation: Ενημέρωσες το λογαριασμό σου με επιτυχία αλλά χρειαζόμαστε να επιβεβαιώσουμε τη νέα διεύθυνση email σου. Παρακαλούμε έλεγξε τα email σου και ακολούθησε το σύνδεσμο για να την επιβεβαιώσεις. Παρακαλούμε έλεγξε το φάκελο με τα ανεπιθύμητα μηνύματα σου αν δεν το λάβεις.
       updated: Ο λογαριασμός σου επιβεβαιώθηκε με επιτυχία.
diff --git a/config/locales/devise.en.yml b/config/locales/devise.en.yml
index bd0642b25169809a8ea161321bdae3869795ddeb..2930733c00cd1d076608e6cadef5c9c976d1b5bf 100644
--- a/config/locales/devise.en.yml
+++ b/config/locales/devise.en.yml
@@ -12,6 +12,7 @@ en:
       last_attempt: You have one more attempt before your account is locked.
       locked: Your account is locked.
       not_found_in_database: Invalid %{authentication_keys} or password.
+      pending: Your account is still under review.
       timeout: Your session expired. Please sign in again to continue.
       unauthenticated: You need to sign in or sign up before continuing.
       unconfirmed: You have to confirm your email address before continuing.
@@ -20,17 +21,18 @@ en:
         action: Verify email address
         action_with_app: Confirm and return to %{app}
         explanation: You have created an account on %{host} with this email address. You are one click away from activating it. If this wasn't you, please ignore this email.
-        extra_html: Please also check out <a href="%{terms_path}">the rules of the instance</a> and <a href="%{policy_path}">our terms of service</a>.
+        explanation_when_pending: You applied for an invite to %{host} with this email address. Once you confirm your e-mail address, we will review your application. You can't login until then. If your application is rejected, your data will be removed, so no further action will be required from you. If this wasn't you, please ignore this email.
+        extra_html: Please also check out <a href="%{terms_path}">the rules of the server</a> and <a href="%{policy_path}">our terms of service</a>.
         subject: 'Mastodon: Confirmation instructions for %{instance}'
         title: Verify email address
       email_changed:
         explanation: 'The email address for your account is being changed to:'
-        extra: If you did not change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the instance admin if you're locked out of your account.
+        extra: If you did not change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account.
         subject: 'Mastodon: Email changed'
         title: New email address
       password_change:
         explanation: The password for your account has been changed.
-        extra: If you did not change your password, it is likely that someone has gained access to your account. Please change your password immediately or contact the instance admin if you're locked out of your account.
+        extra: If you did not change your password, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account.
         subject: 'Mastodon: Password changed'
         title: Password changed
       reconfirmation_instructions:
@@ -60,6 +62,7 @@ en:
       signed_up: Welcome! You have signed up successfully.
       signed_up_but_inactive: You have signed up successfully. However, we could not sign you in because your account is not yet activated.
       signed_up_but_locked: You have signed up successfully. However, we could not sign you in because your account is locked.
+      signed_up_but_pending: A message with a confirmation link has been sent to your email address. After you click the link, we will review your application. You will be notified if it is approved.
       signed_up_but_unconfirmed: A message with a confirmation link has been sent to your email address. Please follow the link to activate your account. Please check your spam folder if you didn't receive this email.
       update_needs_confirmation: You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirm link to confirm your new email address. Please check your spam folder if you didn't receive this email.
       updated: Your account has been updated successfully.
diff --git a/config/locales/devise.eo.yml b/config/locales/devise.eo.yml
index 71dd6c1ef40fa029a18e8ed5af987141b65849a2..d7b7b2d6c67cbd1e2c29efb13ec8d3e01cbe3ad8 100644
--- a/config/locales/devise.eo.yml
+++ b/config/locales/devise.eo.yml
@@ -12,24 +12,27 @@ eo:
       last_attempt: Vi ankoraŭ povas provi unufoje antaŭ ol via konto estos ŝlosita.
       locked: Via konto estas ŝlosita.
       not_found_in_database: Nevalida %{authentication_keys} aÅ­ pasvorto.
+      pending: Via konto ankoraÅ­ estas kontrolanta.
       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: Konfirmi retadreson
+        action_with_app: Konfirmi kaj reveni al %{app}
         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>.
+        explanation_when_pending: Vi petis inviton al %{host} per ĉi tiu retpoŝta adreso. Kiam vi konfirmas vian retpoŝtan adreson, ni revizios vian kandidatiĝon. Vi ne povas ensaluti ĝis tiam. Se via kandidatiĝo estas rifuzita, viaj datumoj estos forigitaj, do neniu alia ago estos postulita de vi. Se tio ne estis vi, bonvolu ignori ĉi tiun retpoŝton.
+        extra_html: Bonvolu rigardi <a href="%{terms_path}">la regulojn de la servilo</a> kaj <a href="%{policy_path}">niajn uzkondiĉojn</a>.
         subject: 'Mastodon: Konfirmaj instrukcioj por %{instance}'
         title: Konfirmi retadreson
       email_changed:
         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.
+        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 servilo, se vi estas blokita ekster via konto.
         subject: 'Mastodon: Retadreso ŝanĝita'
         title: Nova retadreso
       password_change:
         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.
+        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 servilo, se vi estas blokita ekster via konto.
         subject: 'Mastodon: Pasvorto ŝanĝita'
         title: Pasvorto ŝanĝita
       reconfirmation_instructions:
@@ -59,6 +62,7 @@ eo:
       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_pending: Mesaĝo kun konfirma ligilo estis sendita al via retpoŝta adreso. Post kiam vi alklakis la ligilon, ni revizios vian kandidatiĝon. Vi estos sciigita se ĝi estas aprobita.
       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.
diff --git a/config/locales/devise.es.yml b/config/locales/devise.es.yml
index ecb97fd13207dfe6ff566a1fc01235185e8f9924..8210415f21ba4e9f9e9c94c4e857848b511d287b 100644
--- a/config/locales/devise.es.yml
+++ b/config/locales/devise.es.yml
@@ -2,7 +2,7 @@
 es:
   devise:
     confirmations:
-      confirmed: Su dirección de correo ha sido confirmada con éxito.
+      confirmed: Su direccion de email ha sido confirmada con exito.
       send_instructions: Recibirá un correo electrónico con instrucciones sobre cómo confirmar su dirección de correo en pocos minutos.
       send_paranoid_instructions: Si su dirección de correo electrónico existe en nuestra base de datos, recibirá un correo electrónico con instrucciones sobre cómo confirmar su dirección de correo en pocos minutos.
     failure:
@@ -12,19 +12,22 @@ es:
       last_attempt: Tiene un intento más antes de que su cuenta sea bloqueada.
       locked: Su cuenta está bloqueada.
       not_found_in_database: Inválido %{authentication_keys} o contraseña.
+      pending: Su cuenta aun se encuentra bajo revisión.
       timeout: Su sesión ha expirado. Por favor inicie sesión de nuevo para continuar.
       unauthenticated: Necesita iniciar sesión o registrarse antes de continuar.
       unconfirmed: Tiene que confirmar su dirección de correo electrónico antes de continuar.
     mailer:
       confirmation_instructions:
         action: Verificar dirección de correo electrónico
+        action_with_app: Confirmar y regresar a %{app}
         explanation: Has creado una cuenta en %{host} con esta dirección de correo electrónico. Estas a un clic de activarla. Si no fue usted, por favor ignore este correo electrónico.
+        explanation_when_pending: Usted ha solicitado una invitación a %{host} con esta dirección de correo electrónico. Una vez que confirme su dirección de correo electrónico, revisaremos su aplicación. No puede iniciar sesión hasta que su aplicación sea revisada. Si su solicitud está rechazada, sus datos serán eliminados, así que no será necesaria ninguna acción adicional por ti. Si no fuera usted, por favor ignore este correo electrónico.
         extra_html: Por favor revise <a href="%{terms_path}">las reglas de la instancia</a> y <a href="%{policy_path}">nuestros términos de servicio</a>.
         subject: 'Mastodon: Instrucciones de confirmación para %{instance}'
         title: Verificar dirección de correo electrónico
       email_changed:
         explanation: 'El correo electrónico para su cuenta esta siendo cambiada a:'
-        extra: Si usted no a cambiado su correo electrónico. es probable que alguien a conseguido acceso a su cuenta. Por favor cambie su contraseña inmediatamente o contacte a el administrador de la instancia si usted esta bloqueado de su cuenta.
+        extra: Si usted no ha cambiado su correo electrónico, es probable que alguien haya conseguido acceso a su cuenta. Por favor cambie su contraseña inmediatamente o contacte al administrador de la instancia si usted no puede iniciar sesión.
         subject: 'Mastodon: Correo electrónico cambiado'
         title: Nueva dirección de correo electrónico
       password_change:
@@ -59,6 +62,7 @@ es:
       signed_up: "¡Bienvenido! Se ha registrado con éxito."
       signed_up_but_inactive: Se ha registrado con éxito. Sin embargo, no podemos identificarle porque su cuenta no ha sido activada todavía.
       signed_up_but_locked: Se ha registrado con éxito. Sin embargo, no podemos identificarle porque su cuenta está bloqueada.
+      signed_up_but_pending: Un mensaje con un enlace de confirmacion ha sido enviado a su direccion de email. Luego de clickear el link revisaremos su aplicacion. Seras notificado si es aprovada.
       signed_up_but_unconfirmed: Un mensaje con un enlace de confirmación ha sido enviado a su correo electrónico. Por favor siga el enlace para activar su cuenta.
       update_needs_confirmation: Ha actualizado su cuenta con éxito, pero necesitamos verificar su nueva dirección de correo. Por favor compruebe su correo y siga el enlace para confirmar su nueva dirección de correo.
       updated: su cuenta ha sido actualizada con éxito.
diff --git a/config/locales/devise.eu.yml b/config/locales/devise.eu.yml
index 9893f5ba32564701457fd9729f9e63dae7729ed2..3526f2ab5373a22dd59c1cbe2d827513587ef4a0 100644
--- a/config/locales/devise.eu.yml
+++ b/config/locales/devise.eu.yml
@@ -12,6 +12,7 @@ eu:
       last_attempt: Saiakera bat geratzen zaizu zure kontua giltzapetu aurretik.
       locked: Zure kontua giltzapetuta dago.
       not_found_in_database: Baliogabeko %{authentication_keys} edo pasahitza.
+      pending: Zure kontua oraindik berrikusteke dago.
       timeout: Zure saioa iraungitu da. Hasi saioa berriro jarraitzeko.
       unauthenticated: Saioa hasi edo izena eman behar duzu jarraitu aurretik.
       unconfirmed: Zure e-mail helbidea baieztatu behar duzu jarraitu aurretik.
@@ -20,17 +21,18 @@ eu:
         action: Baieztatu e-mail helbidea
         action_with_app: Berretsi eta itzuli %{app} aplikaziora
         explanation: Kontu bat sortu duzu %{host} ostalarian e-mail helbide honekin. Aktibatzeko klik bat falta zaizu. Ez baduzu zuk sortu, ez egin ezer e-mail honekin.
-        extra_html: Egiaztatu <a href="%{terms_path}">instantziaren arauak</a> eta <a href="%{policy_path}">zerbitzuaren erabilera baldintzak</a>.
+        explanation_when_pending: "%{host} instantziara gonbidatua izatea eskatu duzu e-mail helbide honekin. Behin zure e-mail helbidea berresten duzula, zure eskaera berrikusiko da. Ezin duzu aurretik saioa hasi. Zure eskaera ukatuko balitz, zure datuak ezabatuko lirateke, eta ez zenuke beste ezer egiteko beharrik. Hau ez bazara zu izan, ezikusi e-mail hau."
+        extra_html: Egiaztatu <a href="%{terms_path}">zerbitzariaren arauak</a> eta <a href="%{policy_path}">zerbitzuaren erabilera baldintzak</a>.
         subject: 'Mastodon: %{instance} instantziaren argibideak baieztapenerako'
         title: Baieztatu e-mail helbidea
       email_changed:
         explanation: 'Zure kontuaren e-mail helbidea honetara aldatuko da:'
-        extra: Ez baduzu e-mail helbidea aldatu, agian baten bat zure kontura sartzea lortu du. Aldatu zure pasahitza berehala edo jarri instantziako administratzailearekin kontaktuan zure kontura sartzerik ez baduzu.
+        extra: Ez baduzu e-mail helbidea aldatu, agian baten bat zure kontura sartzea lortu du. Aldatu zure pasahitza berehala edo jarri zerbitzariko administratzailearekin kontaktuan zure kontura sartzerik ez baduzu.
         subject: 'Mastodon: E-mail helbidea aldatuta'
         title: E-mail helbide berria
       password_change:
         explanation: Zure kontuaren pasahitza aldatu da.
-        extra: Ez baduzu pasahitza aldatu, agian baten bat zure kontura sartzea lortu du. Aldatu zure pasahitza berehala edo jarri instantziako administratzailearekin kontaktuan zure kontura sartzerik ez baduzu.
+        extra: Ez baduzu pasahitza aldatu, agian baten bat zure kontura sartzea lortu du. Aldatu zure pasahitza berehala edo jarri zerbitzariko administratzailearekin kontaktuan zure kontura sartzerik ez baduzu.
         subject: 'Mastodon: Pasahitza aldatuta'
         title: Pasahitza aldatuta
       reconfirmation_instructions:
@@ -60,6 +62,7 @@ eu:
       signed_up: Ongi etorri! Ongi hasi duzu saioa.
       signed_up_but_inactive: Ongi eman duzu izena. Hala ere, ezin duzu saioa hasi zure kontua oraindik ez dagoelako aktibatuta.
       signed_up_but_locked: Ongi eman duzu izena. Hala ere, ezin duzu saioa hasi zure kontua giltzapetuta dagoelako.
+      signed_up_but_pending: Berrespen esteka bat duen mezu bat bidali da zure e-mail helbidera. Behin esteka sakatzen duzula, zure eskaera berrikusiko da. Onartzen bada jakinaraziko zaizu.
       signed_up_but_unconfirmed: Baieztapen esteka bat duen e-mail bidali zaizu. Jarraitu esteka zure kontua aktibatzeko. Egiaztatu spam karpeta ez baduzu e-mail hau jaso.
       update_needs_confirmation: Zure kontua ongi eguneratu duzu, baina zure email helbide berria egiaztatu behar dugu. Baieztapen esteka bat duen e-mail bidali zaizu, jarraitu esteka zure e-mal helbide berria baieztatzeko. Egiaztatu spam karpeta ez baduzu e-mail hau jaso.
       updated: Zure kontua ongi eguneratu da.
diff --git a/config/locales/devise.fa.yml b/config/locales/devise.fa.yml
index e6e16b4b49b74e9ec25a2a3ea90627ce5843a631..963572e6b47e12233c8dd0cb17bfb2ec1ac8824c 100644
--- a/config/locales/devise.fa.yml
+++ b/config/locales/devise.fa.yml
@@ -12,13 +12,16 @@ fa:
       last_attempt: پیش از آن که حساب شما قفل شود، یک فرصت دیگر دارید.
       locked: حساب شما قفل شده است.
       not_found_in_database: خطای %{authentication_keys} یا رمز نامعتبر.
+      pending: حساب شما همچنان در دست بررسی است.
       timeout: مهلت این ورود شما به سر رسید. برای ادامه، دوباره وارد شوید.
       unauthenticated: برای ادامه باید وارد شوید یا ثبت نام کنید.
       unconfirmed: برای ادامه باید نشانی ایمیل خود را تأیید کنید.
     mailer:
       confirmation_instructions:
         action: تأیید نشانی ایمیل
+        action_with_app: تأیید و بازگشت به %{app}
         explanation: شما با این نشانی ایمیل حسابی در %{host} باز کرده‌اید. با یک کلیک می‌توانید این حساب را فعال کنید. اگر شما چنین کاری نکردید، لطفاً این ایمیل را نادیده بگیرید.
+        explanation_when_pending: شما با این نشانی ایمیل برای %{host} درخواست دعوت‌نامه داده‌اید. اگر ایمیل خود را تأیید کنید، ما درخواست شما را بررسی خواهیم کرد. تا وقتی بررسی تمام نشده، شما نمی‌توانید به حساب خود وارد شوید. اگر درخواست شما رد شود، ما اطلاعاتی را که از شما داریم پاک خواهیم کرد پس نیازی به کاری از سمت شما نخواهد بود. اگر شما چنین درخواستی نداده‌اید، لطفاً این ایمیل را نادیده بگیرید.
         extra_html: لطفاً همچنین <a href="%{terms_path}">قانون‌های این سرور</a> و <a href="%{policy_path}">شرایط کاربری</a> آن را ببینید.
         subject: 'ماستدون: راهنمایی برای تأیید %{instance}'
         title: تأیید نشانی ایمیل
@@ -59,6 +62,7 @@ fa:
       signed_up: خوش آمدید! شما با موفقیت ثبت نام کردید.
       signed_up_but_inactive: خوش آمدید! شما با موفقیت ثبت نام کردید. ولی هنوز وارد سیستم نیستید زیرا حساب شما هنوز فعال نیست.
       signed_up_but_locked: خوش آمدید! شما با موفقیت ثبت نام کردید. ولی هنوز وارد سیستم نیستید زیرا حساب شما قفل شده است.
+      signed_up_but_pending: پیغامی که دارای یک پیوند برای تأیید است به نشانی ایمیل شما فرستاده شده. پس از این‌که پیوند را باز کردید، ما درخواست شما را بررسی خواهیم کرد. اگر درخواست شما پذیرفته شود، به شما خواهیم گفت.
       signed_up_but_unconfirmed: یک پیغام برای تأیید به نشانی ایمیل شما فرستاده شده. لطفاً پیوند موجود در ایمیل را دنبال کنید تا حسابتان فعال شود.
       update_needs_confirmation: شما با موفقیت حسابتان را به‌روز کردید، ولی لازم است که ما نشانی ایمیل تازهٔ شما را تأیید کنیم. لطفاً ایمیل خود را ببینید و پیوند موجود در ایمیل را دنبال کنید تا تا نشانی ایمیل تازهٔ شما تأیید شود.
       updated: حساب شما با موفقبت به‌روز شد.
diff --git a/config/locales/devise.fi.yml b/config/locales/devise.fi.yml
index e356abf9f46a0d6ca7e2d3841b4dbf2c95cfcd44..12ab0f3ab9d2270a81cfd7386ffbd0ab8ea3ed83 100644
--- a/config/locales/devise.fi.yml
+++ b/config/locales/devise.fi.yml
@@ -18,6 +18,7 @@ fi:
     mailer:
       confirmation_instructions:
         action: Vahvista sähköpostiosoite
+        action_with_app: Vahvista ja palaa %{app}
         explanation: Olet luonut tilin palvelimelle %{host} käyttäen tätä sähköpostiosoitetta. Aktivoi tili yhdellä klikkauksella. Jos et luonut tiliä itse, voit jättää tämän viestin huomiotta.
         extra_html: Katso myös <a href="%{terms_path}">instanssin säännöt</a> ja <a href="%{policy_path}">käyttöehdot</a>.
         subject: 'Mastodon: Vahvistusohjeet - %{instance}'
diff --git a/config/locales/devise.fr.yml b/config/locales/devise.fr.yml
index 718b4056e70b95eefaf459c7f8b8caa9942255b7..2d3c86c1fb9c5c6062c0ec0e5fa9b2522427f4ca 100644
--- a/config/locales/devise.fr.yml
+++ b/config/locales/devise.fr.yml
@@ -8,10 +8,11 @@ fr:
     failure:
       already_authenticated: Vous êtes déjà connecté⋅e.
       inactive: Votre compte n’est pas encore activé.
-      invalid: "%{authentication_keys} invalide."
+      invalid: "%{authentication_keys} ou mot de passe invalide."
       last_attempt: Vous avez droit à une tentative avant que votre compte ne soit verrouillé.
       locked: Votre compte est verrouillé.
-      not_found_in_database: "%{authentication_keys} invalide."
+      not_found_in_database: "%{authentication_keys} ou mot de passe invalide."
+      pending: Votre compte est toujours en cours d'approbation.
       timeout: Votre session a expiré. Veuillez vous reconnecter pour continuer.
       unauthenticated: Vous devez vous connecter ou vous inscrire pour continuer.
       unconfirmed: Vous devez valider votre compte pour continuer.
@@ -20,18 +21,19 @@ fr:
         action: Vérifier l’adresse courriel
         action_with_app: Confirmer et retourner à %{app}
         explanation: Vous avez créé un compte sur %{host} avec cette adresse courriel. Vous êtes à un clic de l’activer. Si ce n’était pas vous, veuillez ignorer ce courriel.
-        extra_html: Merci de consultez également <a href="%{terms_path}">les règles de l’instance</a> et <a href="%{policy_path}">nos conditions d’utilisation</a>.
-        subject: Merci de confirmer votre inscription sur %{instance}
+        explanation_when_pending: Vous avez demandé à vous inscrire à %{host} avec cette adresse courriel. Une fois que vous aurez confirmé cette adresse, nous étudierons votre demande. Vous ne pourrez pas vous connecté d'ici-là. Si votre demande est refusée, vos données seront supprimées du serveur, aucune action supplémentaire de votre part n'est donc requise. Si vous n'êtes pas à l'origine de cette demande, veuillez ignorer ce courriel.
+        extra_html: Merci de consultez également <a href="%{terms_path}">les règles du serveur</a> et <a href="%{policy_path}">nos conditions d’utilisation</a>.
+        subject: 'Mastodon : Merci de confirmer votre inscription sur %{instance}'
         title: Vérifier l’adresse courriel
       email_changed:
         explanation: 'L’adresse courriel de votre compte est en cours de modification pour devenir :'
-        extra: Si vous n’avez pas changé votre adresse courriel, il est probable que quelqu’un ait eu accès à votre compte. Veuillez changer votre mot de passe immédiatement ou contacter l’administrateur·rice de l’instance si vous êtes bloqué·e hors de votre compte.
+        extra: Si vous n’avez pas changé votre adresse courriel, il est probable que quelqu’un ait eu accès à votre compte. Veuillez changer votre mot de passe immédiatement ou contacter l’administrateur·rice du serveur si vous êtes bloqué·e hors de votre compte.
         subject: 'Mastodon : Courriel modifié'
         title: Nouvelle adresse courriel
       password_change:
         explanation: Le mot de passe de votre compte a été changé.
-        extra: Si vous n’avez pas changé votre mot de passe, il est probable que quelqu’un ait eu accès à votre compte. Veuillez changer votre mot de passe immédiatement ou contacter l’administrateur·rice de l’instance si vous êtes bloqué·e hors de votre compte.
-        subject: Votre mot de passe a été modifié avec succès
+        extra: Si vous n’avez pas changé votre mot de passe, il est probable que quelqu’un ait eu accès à votre compte. Veuillez changer votre mot de passe immédiatement ou contacter l’administrateur·rice du serveur si vous êtes bloqué·e hors de votre compte.
+        subject: 'Mastodon : Votre mot de passe a été modifié avec succès'
         title: Mot de passe modifié
       reconfirmation_instructions:
         explanation: Confirmez la nouvelle adresse pour changer votre courriel.
@@ -42,10 +44,10 @@ fr:
         action: Modifier le mot de passe
         explanation: Vous avez demandé un nouveau mot de passe pour votre compte.
         extra: Si vous ne l’avez pas demandé, veuillez ignorer ce courriel. Votre mot de passe ne changera pas tant que vous n’aurez pas cliqué sur le lien ci-dessus et que vous n’en aurez pas créé un nouveau.
-        subject: Instructions pour changer votre mot de passe
+        subject: 'Mastodon : Instructions pour changer votre mot de passe'
         title: Réinitialisation du mot de passe
       unlock_instructions:
-        subject: Instructions pour déverrouiller votre compte
+        subject: 'Mastodon : Instructions pour déverrouiller votre compte'
     omniauth_callbacks:
       failure: 'Nous n’avons pas pu vous authentifier via %{kind} : ''%{reason}''.'
       success: Authentifié avec succès via %{kind}.
@@ -56,12 +58,13 @@ fr:
       updated: Votre mot de passe a été modifié avec succès, vous êtes maintenant connecté⋅e.
       updated_not_active: Votre mot de passe a été modifié avec succès.
     registrations:
-      destroyed: Votre compte a été supprimé avec succès. Nous espérons vous revoir bientôt.
-      signed_up: Bienvenue, vous êtes connecté⋅e.
+      destroyed: Au revoir ! Votre compte a été supprimé avec succès. Nous espérons vous revoir bientôt.
+      signed_up: Bienvenue ! Vous êtes connecté⋅e.
       signed_up_but_inactive: Vous êtes bien enregistré⋅e. Vous ne pouvez cependant pas vous connecter car votre compte n’est pas encore activé.
       signed_up_but_locked: Vous êtes bien enregistré⋅e. Vous ne pouvez cependant pas vous connecter car votre compte est verrouillé.
-      signed_up_but_unconfirmed: Un message contenant un lien de confirmation a été envoyé à votre adresse courriel. Ouvrez ce lien pour activer votre compte.
-      update_needs_confirmation: Votre compte a bien été mis à jour mais nous devons vérifier votre nouvelle adresse courriel. Merci de vérifier vos courriels et de cliquer sur le lien de confirmation pour finaliser la validation de votre nouvelle adresse.
+      signed_up_but_pending: Un message avec un lien de confirmation a été envoyé à votre adresse courriel. Après avoir cliqué sur le lien, nous étudierons votre demande. Vous serez informé·e si elle a été approuvée.
+      signed_up_but_unconfirmed: Un message contenant un lien de confirmation a été envoyé à votre adresse courriel. Ouvrez ce lien pour activer votre compte. Veuillez vérifier votre dossier d'indésirables si vous ne recevez pas le courriel.
+      update_needs_confirmation: Votre compte a bien été mis à jour, mais nous devons vérifier votre nouvelle adresse courriel. Merci de vérifier vos courriels et de cliquer sur le lien de confirmation pour finaliser la validation de votre nouvelle adresse. Si vous n'avez pas reçu le courriel, vérifiez votre dossier d'indésirables.
       updated: Votre compte a été modifié avec succès.
     sessions:
       already_signed_out: Déconnecté·e.
diff --git a/config/locales/devise.gl.yml b/config/locales/devise.gl.yml
index 9f60747a6a1f43eed850adf5217c75d12deae063..60a935a8a2f36788d57817fb1b042b83477df298 100644
--- a/config/locales/devise.gl.yml
+++ b/config/locales/devise.gl.yml
@@ -12,6 +12,7 @@ gl:
       last_attempt: Quédalle un intento antes de que a conta sexa bloqueada.
       locked: A súa conta foi bloqueada.
       not_found_in_database: Contrasinal ou %{authentication_keys} non válidos.
+      pending: A súa conta está en proceso de revisión.
       timeout: Caducou a sesión. Por favor conéctese de novo para seguir.
       unauthenticated: Precisa rexistrarse ou conectarse para continuar.
       unconfirmed: Debe confirmar o seu enderezo de correo antes de continuar.
@@ -20,17 +21,18 @@ gl:
         action: Validar enderezo de correo-e
         action_with_app: Confirmar e voltar a %{app}
         explanation: Creou unha conta en %{host} con este enderezo de correo. Está a punto de activalo, si non foi vostede quen fixo a petición, por favor ignore este correo.
-        extra_html: Por favor, lea tamén <a href="%{terms_path}">as normas da instancia</a> e <a href="%{policy_path}">os termos do servizo</a>.
+        explanation_when_pending: Vostede solicitou un convite para %{host} con este enderezo de correo. Unha vez confirme o enderezo de correo revisaremos a solicitude. Non pode conectarse ata entón. Si a solicitude fose rexeitada, os seus datos eliminaranse, así que non precisaría facer nada máis. Se non fixo vostede unha solicitude por favor ignore este correo.
+        extra_html: Por favor, lea tamén <a href="%{terms_path}">as normas do sevidor</a> e <a href="%{policy_path}">os termos do servizo</a>.
         subject: 'Mastodon: Instruccións de confirmación para %{instance}'
         title: Verificar enderezo de correo-e
       email_changed:
         explanation: 'O seu enderezo de correo para esta conta foi cambiado a:'
-        extra: Si non fixo a petición de cambio de correo-e é probable que alguén obtivese acceso a súa conta. Por favor, cambie o contrasinal inmediatamente ou contacte coa administración da instancia si non ten acceso a súa conta.
+        extra: Se non fixo a petición de cambio de correo-e é probable que alguén obtivese acceso a súa conta. Por favor, cambie o contrasinal inmediatamente ou contacte coa administración do servidor se non ten acceso a súa conta.
         subject: 'Mastodon: email cambiado'
         title: Novo enderezo de correo
       password_change:
         explanation: Cambiouse o contrasinal da súa conta.
-        extra: Si non cambio o contrasinal, é probable que alguén obtivese acceso a súa conta. Por favor cambie o contrasinal inmediatamente ou contacte coa administración da instancia si non ten acceso a súa conta.
+        extra: Se non cambiou o contrasinal, é probable que alguén obtivese acceso a súa conta. Por favor cambie o contrasinal inmediatamente ou contacte coa administración do servidor se non ten acceso a súa conta.
         subject: 'Mastodon: contrasinal cambiado'
         title: Contrainal cambiado
       reconfirmation_instructions:
@@ -60,6 +62,7 @@ gl:
       signed_up: Ben vida! Rexistrouse con éxito.
       signed_up_but_inactive: Rexistrouse correctamente. Porén, aínda non podemos conectala porque a súa conta aínda non foi activada.
       signed_up_but_locked: Rexistrouse correctamente. Porén, non podemos conectala porque a conta está bloqueada.
+      signed_up_but_pending: Enviouselle unha mensaxe de correo que contén unha ligazón de confirmación. Tras pulsar na ligazón, revisaremos a súa solicitude. Notificarémoslle se está aprobada.
       signed_up_but_unconfirmed: Foi enviada unha mensaxe con unha ligazón de confirmación ao seu enderezo electrónico. Por favor siga a ligazón para activar a súa conta. Por favor comprobe o cartafol de spam si non recibe este correo.
       update_needs_confirmation: Actualizou a súa conta correctamente, pero precisamos verificar o seu enderezo. Por favor comprobe o seu email e siga a ligazón de confirmación para confirmar o seu novo enderezo. Por favor comprobe o cartafol de spam si non recibe este correo.
       updated: A súa conta foi actualizada correctamente.
diff --git a/config/locales/devise.he.yml b/config/locales/devise.he.yml
index 3d8f7fa59b64931bb5a781e97274831f36b5c28b..be8af6f9e70e4a333cfaed6469f74555545cd7a2 100644
--- a/config/locales/devise.he.yml
+++ b/config/locales/devise.he.yml
@@ -56,6 +56,3 @@ he:
       expired: פג תוקפו. נא לבקש חדש
       not_found: לא נמצא
       not_locked: לא היה נעול
-      not_saved:
-        one: 'שגיאה אחת מנעה את שמירת %{resource} זה:'
-        other: "%{count} שגיאות מנעו את שמירת %{resource} זה:"
diff --git a/config/locales/devise.hr.yml b/config/locales/devise.hr.yml
index 2a859054a66ae19a260efc55c156c7acc523e9a4..e0c569ceed8304271cb57771d5cb939be9ed06bf 100644
--- a/config/locales/devise.hr.yml
+++ b/config/locales/devise.hr.yml
@@ -2,18 +2,9 @@
 hr:
   devise:
     confirmations:
-      already_authenticated: Već si prijavljen.
       confirmed: Tvoja email adresa je uspješno potvrđena.
-      inactive: Tvoj račun još nije aktiviran.
-      invalid: Nevaljan %{authentication_keys} ili lozinka.
-      last_attempt: Imaš još jedan pokušaj prije no što ti se račun zaključa.
-      locked: Tvoj račun je zaključan.
-      not_found_in_database: Nevaljan %{authentication_keys} ili lozinka.
       send_instructions: Primit ćeš email sa uputama kako potvrditi  svoju email adresu za nekoliko minuta.
       send_paranoid_instructions: Ako tvoja email adresa postoji u našoj bazi podataka, primit ćeš email sa uputama kako ju potvrditi za nekoliko minuta.
-      timeout: Tvoja sesija je istekla. Molimo te, prijavi se ponovo kako bi nastavio.
-      unauthenticated: Moraš se registrirati ili prijaviti prije no što nastaviš.
-      unconfirmed: Moraš potvrditi svoju email adresu prije no što nastaviš.
     mailer:
       confirmation_instructions:
         subject: 'Mastodon: Upute za potvrđivanje %{instance}'
@@ -58,4 +49,3 @@ hr:
       expired: je istekao, zatraži novu
       not_found: nije nađen
       not_locked: nije zaključan
-      not_saved: "%{count} greške su zabranile da ovaj %{resource} bude sačuvan:"
diff --git a/config/locales/devise.hu.yml b/config/locales/devise.hu.yml
index 67baca0167ddb826428fe4de84ed9d093be681cb..e495cb5f0e7b84e6447387e1c0bfa17d78b8daa8 100644
--- a/config/locales/devise.hu.yml
+++ b/config/locales/devise.hu.yml
@@ -2,40 +2,43 @@
 hu:
   devise:
     confirmations:
-      confirmed: Az e-mail címed sikeresen meg lett erősítve.
+      confirmed: Az e-mail címed sikeresen megerősítésre került.
       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.
-      inactive: Fiókod még nem lett aktiválva.
+      inactive: Fiókodat még nem aktiválták.
       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.
+      last_attempt: Már csak egy próbálkozásod maradt mielőtt a fiókodat lezárjuk.
       locked: Fiókod le van zárva.
       not_found_in_database: Helytelen %{authentication_keys} vagy jelszó.
+      pending: Fiókod még engedélyezés alatt áll.
       timeout: A munkamenet lejárt. Jelentkezz be újra a folytatáshoz.
       unauthenticated: A folytatás előtt be kell jelentkezned.
       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>.
+        action_with_app: Megerősítés majd vissza ide %{app}
+        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ókodat aktiváljuk. Ha a regisztrációt nem te kezdeményezted, kérjük tekintsd ezt az e-mailt tárgytalannak.
+        explanation_when_pending: Ezzel az e-mail címmel meghívást kértél a(z) %{host} oldalon. Ahogy megerősíted az e-mail címed, átnézzük a jelentkezésedet. Ennek ideje alatt nem tudsz belépni. Ha a jelentkezésed elutasítjuk, az adataidat töröljük, más teendőd nincs. Ha a kérelmet 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}">a szerver 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 %{instance}'
         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.
+        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 a szervered 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
+        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 a szervered adminisztrátorával.
+        subject: 'Mastodon: Jelszavad megváltoztattuk'
+        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'
+        subject: 'Mastodon: erősítsd meg a(z) %{instance} szerverhez tartozó e-mail címed'
         title: E-mail cím megerősítése
       reset_password_instructions:
         action: Jelszó módosítása
@@ -46,30 +49,31 @@ hu:
       unlock_instructions:
         subject: 'Mastodon: Feloldási lépések'
     omniauth_callbacks:
-      failure: "%{kind} nem hitelesíthető, mert %{reason}."
+      failure: Sikertelen hitelesítés %{kind} fiókról, mert "%{reason}".
       success: Sikeres hitelesítés %{kind} fiókról.
     passwords:
-      no_token: Nem férhetsz hozzá az oldalhoz jelszó visszaállító e-mail nélkül. Ha egy jelszó visszaállító e-mail hozott ide, ellenőrizd, hogy a megadott teljes URL-t használd.
-      send_instructions: Pár percen belül kapni fogsz egy e-mailt arról, hogy hogyan tudod visszaállítani a jelszavadat.
-      send_paranoid_instructions: Ha létezik az e-mail cím, pár percen belül kapni fogsz egy e-mailt arról, hogy hogyan tudod visszaállítani a jelszavadat.
+      no_token: Nem férhetsz hozzá ehhez az oldalhoz jelszó visszaállító e-mail nélkül. Ha egy jelszó visszaállító e-mail hozott ide, ellenőrizd, hogy a megadott teljes URL-t használd.
+      send_instructions: Pár percen belül kapni fogsz egy e-mailt arról, hogy hogyan tudod visszaállítani a jelszavadat. Kérlek ellenőrizd a levélszemét mappádat, ha nem kaptál ilyen e-mailt.
+      send_paranoid_instructions: Ha létezik az e-mail cím, pár percen belül kapni fogsz egy e-mailt arról, hogy hogyan tudod visszaállítani a jelszavadat. Kérlek ellenőrizd a levélszemét mappádat, ha nem kaptál ilyen e-mailt.
       updated: Jelszavad sikeresen frissült. Bejelentkeztél.
-      updated_not_active: Jelszavad sikeresen meg lett változtatva.
+      updated_not_active: Jelszavad sikeresen megváltoztattuk.
     registrations:
-      destroyed: Viszlát! A fiókod sikeresen törölve. Reméljük hamarosan viszontláthatunk.
+      destroyed: Viszlát! A fiókodat sikeresen töröltük. Reméljük hamarosan viszontláthatunk.
       signed_up: Üdvözlünk! Sikeresen regisztráltál.
-      signed_up_but_inactive: Sikeresen regisztráltál. Ennek ellenére nem tudunk beléptetni, ugyanis a fiókod még nem lett aktiválva.
-      signed_up_but_locked: Sikeresen regisztráltál. Ennek ellenére nem tudunk beléptetni, ugyanis a fiókod le lett zárva.
-      signed_up_but_unconfirmed: Egy üzenet a megerősítési linkkel kiküldésre került az e-mail címedre. Kérjük használd a linket a fiókod aktiválásához.
-      update_needs_confirmation: Sikeresen frissítetted a fiókodat, de szükségünk van az e-mail címed megerősítésére. Kérlek ellenőrizd az e-mailedet és kövesd a levélben szereplő megerősítési linket az e-mail címed megerősítéséhez.
+      signed_up_but_inactive: Sikeresen regisztráltál. Ennek ellenére nem tudunk beléptetni, ugyanis a fiókodat még nem aktiválták.
+      signed_up_but_locked: Sikeresen regisztráltál. Ennek ellenére nem tudunk beléptetni, ugyanis a fiókod le van zárva.
+      signed_up_but_pending: Egy üzenetet a megerősítési linkkel kiküldtünk az e-mail címedre. Ha kattintasz a linkre, átnézzük a kérelmedet. Értesítünk, ha jóváhagytuk.
+      signed_up_but_unconfirmed: Egy üzenetet a megerősítési linkkel kiküldtünk az e-mail címedre. Kérjük használd a linket a fiókod aktiválásához.
+      update_needs_confirmation: Sikeresen frissítetted a fiókodat, de szükségünk van az e-mail címed megerősítésére. Kérlek ellenőrizd az e-mailedet és kövesd a levélben szereplő megerősítési linket az e-mail címed megerősítéséhez. Ellenőrizd a levélszemét mappád, ha nem kaptál volna ilyen levelet.
       updated: Fiókod frissítése sikeres.
     sessions:
-      already_signed_out: Sikeres kijelenkezés.
+      already_signed_out: Sikeres kijelentkezés.
       signed_in: Sikeres bejelentkezés.
       signed_out: Sikeres kijelentkezés.
     unlocks:
-      send_instructions: Pár percen belül egy e-mailt fogsz kapni a feloldáshoz szükséges lépésekkel.
-      send_paranoid_instructions: Ha a fiókod létezik, pár percen belül egy e-mailt fogsz kapni a feloldáshoz szükséges lépésekkel.
-      unlocked: A fiókod sikeresen fel lett oldva. Jelentkezz be a folytatáshoz.
+      send_instructions: Pár percen belül egy e-mailt fogsz kapni a feloldáshoz szükséges lépésekkel. Ellenőrizd a levélszemét mappád, ha nem kaptál volna ilyen levelet.
+      send_paranoid_instructions: Ha a fiókod létezik, pár percen belül egy e-mailt fogsz kapni a feloldáshoz szükséges lépésekkel. Ellenőrizd a levélszemét mappád, ha nem kaptál volna ilyen levelet.
+      unlocked: A fiókodat sikeresen feloldottuk. Jelentkezz be a folytatáshoz.
   errors:
     messages:
       already_confirmed: már meg lett erősítve, kérjük jelentkezz be
diff --git a/config/locales/devise.hy.yml b/config/locales/devise.hy.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c406540162aa8f9ae59ae2d79f75097ce1af0c26
--- /dev/null
+++ b/config/locales/devise.hy.yml
@@ -0,0 +1 @@
+hy:
diff --git a/config/locales/devise.id.yml b/config/locales/devise.id.yml
index 47fac413fc080252590db3020708ca7cdbf3ff47..5fa9020911358b2b165aac04723eba5ccf73413e 100644
--- a/config/locales/devise.id.yml
+++ b/config/locales/devise.id.yml
@@ -57,5 +57,4 @@ id:
       not_found: tidak ditemukan
       not_locked: tidak dikunci
       not_saved:
-        one: '1 error yang membuat %{resource} ini tidak dapat disimpan:'
         other: "%{count} error yang membuat %{resource} ini tidak dapat disimpan:"
diff --git a/config/locales/devise.it.yml b/config/locales/devise.it.yml
index 30266e46bdd4abbe4db811fb9adf1ffcd2dcbcd2..b603e12c682e89cf55689b98b3990e8345c3b0dd 100644
--- a/config/locales/devise.it.yml
+++ b/config/locales/devise.it.yml
@@ -12,6 +12,7 @@ it:
       last_attempt: Hai un altro tentativo prima che il tuo account venga bloccato.
       locked: Il tuo account è stato bloccato.
       not_found_in_database: "%{authentication_keys} o password invalida."
+      pending: Il tuo account è ancora in fase di approvazione.
       timeout: La tua sessione è terminata. Per favore, effettua l'accesso o registrati per continuare.
       unauthenticated: Devi effettuare l'accesso o registrarti per continuare.
       unconfirmed: Devi confermare il tuo indirizzo email per continuare.
@@ -20,17 +21,18 @@ it:
         action: Verifica indirizzo email
         action_with_app: Conferma e torna a %{app}
         explanation: Hai creato un account su %{host} con questo indirizzo email. Sei lonatno solo un clic dall'attivarlo. Se non sei stato tu, per favore ignora questa email.
-        extra_html: Per favore controlla<a href="%{terms_path}">le regole dell'istanza</a> e <a href="%{policy_path}">i nostri termini di servizio</a>.
+        explanation_when_pending: Hai richiesto un invito a %{host} con questo indirizzo email. Una volta confermato il tuo indirizzo e-mail, analizzeremo la tua richiesta. Non potrai eseguire l'accesso fino a quel momento. Se la tua richiesta sarà rifiutata, i tuoi dati saranno rimossi, quindi nessun'altra azione ti sarà richiesta. Se non fossi stato tu, per favore ignora questa email.
+        extra_html: Per favore controlla<a href="%{terms_path}">le regole del server</a> e <a href="%{policy_path}">i nostri termini di servizio</a>.
         subject: 'Mastodon: Istruzioni di conferma per %{instance}'
         title: Verifica indirizzo email
       email_changed:
         explanation: 'L''indirizzo email del tuo account sta per essere cambiato in:'
-        extra: Se non hai cambiato la tua email, è probabile che qualcuno abbia accesso al tuo account. Cambia immediatamente la tua password e contatta l'amministratore dell'istanza se sei bloccato fuori dal tuo account.
+        extra: Se non hai cambiato la tua email, è probabile che qualcuno abbia ottenuto l'accesso al tuo account. Cambia immediatamente la tua password e contatta l'amministratore del server se non puoi più accedere al tuo account.
         subject: 'Mastodon: Email cambiata'
         title: Nuovo indirizzo email
       password_change:
         explanation: La password del tuo account è stata cambiata.
-        extra: Se non hai cambiato la password, è probabile che qualcuno abbia accesso al tuo account. Cambia immediatamente la tua password e contatta l'amministratore dell'istanza se sei bloccato fuori dal tuo account.
+        extra: Se non hai cambiato la password, è probabile che qualcuno abbia ottenuto l'accesso al tuo account. Cambia immediatamente la tua password e contatta l'amministratore del server non puoi più accedere al tuo account.
         subject: 'Mastodon: Password modificata'
         title: Password cambiata
       reconfirmation_instructions:
@@ -60,6 +62,7 @@ it:
       signed_up: Benvenuto! Ti sei registrato con successo.
       signed_up_but_inactive: Ti sei registrato con successo. Purtroppo però non possiamo farti accedere perché non hai ancora attivato il tuo account.
       signed_up_but_locked: Ti sei registrato con successo. Purtroppo però non possiamo farti accedere perché il tuo account è bloccato.
+      signed_up_but_pending: Un messaggio con un collegamento per la conferma è stato inviato al tuo indirizzo email. Dopo aver cliccato il collegamento, esamineremo la tua richiesta. Ti sarà notificato se verrà approvata.
       signed_up_but_unconfirmed: Un messaggio con un link di conferma è stato inviato al tuo indirizzo email. Per favore, visita il link per attivare il tuo account.
       update_needs_confirmation: Hai aggiornato correttamente il tuo account, ma abbiamo bisogno di verificare il tuo nuovo indirizzo email. Per favore, controlla la posta in arrivo e visita il link di conferma per verificare il tuo indirizzo email.
       updated: Il tuo account è stato aggiornato con successo.
diff --git a/config/locales/devise.ja.yml b/config/locales/devise.ja.yml
index cae76d49385f5ebca38151d84522b841acf5a4c5..dc147be624ece8b887165f6d2d076d6d81bae1f1 100644
--- a/config/locales/devise.ja.yml
+++ b/config/locales/devise.ja.yml
@@ -12,6 +12,7 @@ ja:
       last_attempt: あと1回失敗するとアカウントがロックされます。
       locked: アカウントはロックされました。
       not_found_in_database: "%{authentication_keys}かパスワードが誤っています。"
+      pending: あなたのアカウントはまだ承認待ちです。
       timeout: セッションの有効期限が切れました。続行するには再度ログインしてください。
       unauthenticated: 続行するにはログインするか、アカウントを作成してください。
       unconfirmed: 続行するにはメールアドレスを確認する必要があります。
@@ -20,17 +21,18 @@ ja:
         action: メールアドレスの確認
         action_with_app: 確認し %{app} に戻る
         explanation: このメールアドレスで%{host}にアカウントを作成しました。有効にするまであと一歩です。もし心当たりがない場合、申し訳ありませんがこのメールを無視してください。
-        extra_html: また <a href="%{terms_path}">インスタンスのルール</a> と <a href="%{policy_path}">利用規約</a> もお読みください。
+        explanation_when_pending: このメールアドレスで%{host}への登録を申請しました。あなたがメールアドレスを確認したら、サーバー管理者が申請を審査します。それまでログインできません。申請が却下された場合、あなたのデータは削除されますので以降の操作は必要ありません。もし心当たりがない場合、申し訳ありませんがこのメールを無視してください。
+        extra_html: また <a href="%{terms_path}">サーバーのルール</a> と <a href="%{policy_path}">利用規約</a> もお読みください。
         subject: 'Mastodon: メールアドレスの確認 %{instance}'
         title: メールアドレスの確認
       email_changed:
         explanation: 'アカウントのメールアドレスは以下のように変更されます:'
-        extra: メールアドレスの変更を行っていない場合、他の誰かがあなたのアカウントにアクセスした可能性があります。すぐにパスワードを変更するか、アカウントがロックされている場合はインスタンス管理者に連絡してください。
+        extra: メールアドレスの変更を行っていない場合、他の誰かがあなたのアカウントにアクセスした可能性があります。すぐにパスワードを変更するか、アカウントがロックされている場合はサーバー管理者に連絡してください。
         subject: 'Mastodon: メールアドレスの変更'
         title: 新しいメールアドレス
       password_change:
         explanation: パスワードが変更されました。
-        extra: パスワードの変更を行っていない場合、他の誰かがあなたのアカウントにアクセスした可能性があります。すぐにパスワードを変更するか、アカウントがロックされている場合はインスタンス管理者に連絡してください。
+        extra: パスワードの変更を行っていない場合、他の誰かがあなたのアカウントにアクセスした可能性があります。すぐにパスワードを変更するか、アカウントがロックされている場合はサーバー管理者に連絡してください。
         subject: 'Mastodon: パスワードが変更されました'
         title: パスワードの変更
       reconfirmation_instructions:
@@ -60,6 +62,7 @@ ja:
       signed_up: アカウントの作成が完了しました。Mastodonへようこそ。
       signed_up_but_inactive: アカウントの作成が完了しました。しかし、アカウントが有効化されていないためログインできませんでした。
       signed_up_but_locked: アカウントの作成が完了しました。しかし、アカウントがロックされているためログインできませんでした。
+      signed_up_but_pending: メールアドレスの確認用のリンクが入力したメールアドレスに送信されました。リンクをクリックした後、あなたの申請を審査します。承認されると通知されます。
       signed_up_but_unconfirmed: メールアドレスの確認用のリンクが入力したメールアドレスに送信されました。メール内のリンクをクリックしてアカウントを有効化してください。
       update_needs_confirmation: アカウント情報の更新に成功しました。しかし、メールアドレスの確認が必要です。送信されたメール内のリンクをクリックしてメールアドレスを確認してください。
       updated: アカウント情報の更新に成功しました。
@@ -79,5 +82,4 @@ ja:
       not_found: 見つかりません
       not_locked: ロックされていません
       not_saved:
-        one: エラーが発生したため、%{resource}の保存に失敗しました。
         other: "%{count}個のエラーが発生したため、%{resource}の保存に失敗しました:"
diff --git a/config/locales/devise.kk.yml b/config/locales/devise.kk.yml
new file mode 100644
index 0000000000000000000000000000000000000000..d99116c7f0b49a8ea7cec365393d0b73575e1504
--- /dev/null
+++ b/config/locales/devise.kk.yml
@@ -0,0 +1,83 @@
+---
+kk:
+  devise:
+    confirmations:
+      confirmed: Сіздің email адресіңіз сәтті құпталды.
+      send_instructions: Email адресіңізге бірнеше минут ішінде қалай растау керегі туралы нұсқау бар хат келеді. Бұл хат егер келмесе, спам құтысын тексеріңіз.
+      send_paranoid_instructions: Email адресіңіз біздің дерекқорымызда болса, бірнеше минут ішінде растау туралы нұсқау бар хат аласыз. Бұл хатты алмасаңыз, спам құтысын тексеріңіз.
+    failure:
+      already_authenticated: Сіз кіріп тұрсыз.
+      inactive: Аккаунтыңыз әлі құпталмаған.
+      invalid: Қате %{authentication_keys} немесе құпиясөз.
+      last_attempt: Аккаунтыңыз құлыпталғанға дейін тағы бір әрекет жасаңыз.
+      locked: Аккаунтыңыз құлыпталған.
+      not_found_in_database: Қате %{authentication_keys} немесе құпиясөз.
+      timeout: Сессияңыз аяқталды. Қайтадан кіріңіз жалғастыру үшін.
+      unauthenticated: Жалғастыру үшін тіркеліңіз немесе логиніңізбен кіріңіз.
+      unconfirmed: Жалғастыру үшін email адресіңізді құптауыңыз керек.
+    mailer:
+      confirmation_instructions:
+        action: Email адресіңізді растаңыз
+        action_with_app: Растау және оралу - %{app}
+        explanation: Сіз %{host} сайтына тіркелгенсіз осы email адресімен. Активация жасауға бір адам қалды. Егер тіркелмеген болсаңыз, бұл хатты елемеңіз.
+        extra_html: Сондай-ақ <a href="%{terms_path}">шарттар мен ережелерді</a> және <a href="%{policy_path}">құпиялылық саясатын</a> оқыңыз.
+        subject: 'Mastodon: Растау туралы нұсқаулық %{instance}'
+        title: Email адресін растау
+      email_changed:
+        explanation: 'Сіздің email адресіңіз өзгертілейін деп жатыр:'
+        extra: Егер сіз электрондық поштаңызды өзгертпеген болсаңыз, онда біреу сіздің аккаунтыңызға қол жеткізді. Аккаунтыңыздан шыққан жағдайда дереу құпия сөзіңізді өзгертіңіз немесе сервер әкімшісіне хабарласыңыз.
+        subject: 'Mastodon: Email өзгертілді'
+        title: Жаңа email адрес
+      password_change:
+        explanation: Аккаунтыңыздағы құпиясөз өзгертілді.
+        extra: Егер сіз электрондық поштаңызды өзгертпеген болсаңыз, онда біреу сіздің аккаунтыңызға қол жеткізді. Аккаунтыңыздан шыққан жағдайда дереу құпия сөзіңізді өзгертіңіз немесе сервер әкімшісіне хабарласыңыз.
+        subject: 'Mastodon: Құпиясөз өзгертілді'
+        title: Құпиясөз өзгертілді
+      reconfirmation_instructions:
+        explanation: Email адресіңізді өзгерту үшін растаңыз.
+        extra: Егер сіз бұл өзгерісті жасамаған болсаңыз, бұл хатты елемеңіз. Mastodon тіркелгісінің электрондық пошта мекенжайы жоғарыдағы сілтемеге кірмейінше өзгермейді.
+        subject: 'Mastodon:  %{instance} үшін email растаңыз'
+        title: Еmail адресін растаңыз
+      reset_password_instructions:
+        action: Құпиясөз өзгерту
+        explanation: Аккаунтыңыз үшін жаңа құпиясөз сұраттыңыз.
+        extra: Егер сіз мұны сұрамаған болсаңыз, бұл хатты елемеңіз. Жоғарыдағы сілтемені ашып, жаңасын жасағанша құпия сөзіңіз өзгермейді.
+        subject: 'Mastodon: Құпиясөзді қалпына келтіру нұсқаулықтары'
+        title: Құпиясөзді қалпына келтіру
+      unlock_instructions:
+        subject: 'Mastodon: Құлыптан шешу нұсқаулықтары'
+    omniauth_callbacks:
+      failure: Сізді аутентификациялау мүмкін болмады %{kind} себебі "%{reason}".
+      success: "%{kind} аккаунтынан сәтті аутентификация."
+    passwords:
+      no_token: Бұл бетке құпиясөзді қалпына келтіру электрондық поштасынан шықпай кіре алмайсыз. Құпия сөзді қалпына келтіру электрондық поштасынан шықсаңыз, берілген толық URL мекенжайын пайдаланғаныңызды тексеріңіз.
+      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: әлдеқашан расталған, логинмен кіре беріңіз
+      confirmation_period_expired: "%{period} ішінде расталуы қажет, жаңасын сұратыңыз"
+      expired: уақыты өтіп кетті, жаңасын сұратыңыз
+      not_found: табылмады
+      not_locked: құлыпталмады
+      not_saved:
+        one: '1 тыйым салынған қате %{resource} сақталды:'
+        other: "%{count} тыйым салынған қате %{resource} сақталды:"
diff --git a/config/locales/devise.ko.yml b/config/locales/devise.ko.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f48531246e1127dd763cffa99a5101e1fd6d2976
--- /dev/null
+++ b/config/locales/devise.ko.yml
@@ -0,0 +1,85 @@
+---
+ko:
+  devise:
+    confirmations:
+      confirmed: 이메일이 성공적으로 확인 되었습니다.
+      send_instructions: 몇 분 이내로 확인 이메일이 발송 됩니다. 이메일을 받지 못 한 경우, 스팸 폴더를 확인하세요.
+      send_paranoid_instructions: 당신의 이메일이 우리의 DB에 있을 경우 몇 분 이내로 확인 메일이 발송 됩니다. 이메일을 받지 못 한 경우, 스팸 폴더를 확인하세요.
+    failure:
+      already_authenticated: 이미 로그인 된 상태입니다.
+      inactive: 계정이 활성화 되지 않았습니다.
+      invalid: 올바르지 않은 %{authentication_keys} 혹은 패스워드입니다.
+      last_attempt: 계정이 잠기기까지 한 번의 시도가 남았습니다.
+      locked: 계정이 잠겼습니다.
+      not_found_in_database: 올바르지 않은 %{authentication_keys} 혹은 패스워드입니다.
+      pending: 계정이 아직 심사 중입니다.
+      timeout: 세션이 만료 되었습니다. 다시 로그인 해 주세요.
+      unauthenticated: 계속 하려면 로그인을 해야 합니다.
+      unconfirmed: 계속 하려면 이메일을 확인 받아야 합니다.
+    mailer:
+      confirmation_instructions:
+        action: 이메일 확인
+        action_with_app: 확인하고 %{app}으로 돌아가기
+        explanation: 당신은 %{host}에서 이 이메일로 가입하셨습니다. 클릭만 하시면 계정이 활성화 됩니다. 만약 당신이 가입한 게 아니라면 이 메일을 무시해 주세요.
+        explanation_when_pending: 당신은 %{host}에 가입 요청을 하셨습니다. 이 이메일이 확인 되면 우리가 가입 요청을 리뷰하고 승인할 수 있습니다. 그 전까지는 로그인을 할 수 없습니다. 당신의 가입 요청이 거부 될 경우 당신에 대한 정보는 모두 삭제 되며 따로 요청 할 필요는 없습니다. 만약 당신이 가입 요청을 한 게 아니라면 이 메일을 무시해 주세요.
+        extra_html: <a href="%{terms_path}">서버의 룰</a>과 <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:
+        subject: '마스토돈: 잠금 해제 방법'
+    omniauth_callbacks:
+      failure: '"%{reason}" 때문에 당신을 %{kind}에서 인증할 수 없습니다.'
+      success: 성공적으로 %{kind} 계정을 인증 했습니다.
+    passwords:
+      no_token: 패스워드 재설정 이메일을 거치지 않고는 여기에 올 수 없습니다. 만약 패스워드 재설정 메일에서 온 것이라면 URL이 맞는지 확인해 주세요.
+      send_instructions: 당신의 이메일 주소가 우리의 DB에 있아면 패스워드 복구 링크가 몇 분 이내에 메일로 발송 됩니다. 만약 메일을 받지 못 하신 경우 스팸 폴더를 확인해 주세요.
+      send_paranoid_instructions: 당신의 이메일 주소가 우리의 DB에 있아면 패스워드 복구 링크가 몇 분 이내에 메일로 발송 됩니다. 만약 메일을 받지 못 하신 경우 스팸 폴더를 확인해 주세요.
+      updated: 패스워드가 재설정 되었습니다. 로그인 되었습니다.
+      updated_not_active: 패스워드가 성공적으로 변경 되었습니다.
+    registrations:
+      destroyed: 안녕히 가세요! 계정이 성공적으로 제거되었습니다. 다시 만나기를 희망합니다.
+      signed_up: 안녕하세요! 성공적으로 가입했습니다.
+      signed_up_but_inactive: 성공적으로 가입 했습니다. 그러나, 계정이 활성화 되지 않았기 때문에 아직 로그인 할 수 없습니다.
+      signed_up_but_locked: 성공적으로 가입 했습니다. 그러나, 계정이 잠겨있기 때문에 아직 로그인 할 수 없습니다.
+      signed_up_but_pending: 확인 링크를 포함한 메일이 발송 되었습니다. 링크를 클릭한 이후, 우리가 당신의 신청양식을 검토합니다. 승인이 되면 알림을 발송합니다.
+      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: 이미 확인 되었습니다, 로그인 하세요
+      confirmation_period_expired: "%{period} 안에 확인을 해야 합니다, 새로 요청하세요"
+      expired: 만료되었습니다, 새로 요청하세요
+      not_found: 찾을 수 없습니다
+      not_locked: 잠기지 않았습니다
+      not_saved:
+        other: "%{count}개의 에러로 인해 %{resource}가 저장 될 수 없습니다:"
diff --git a/config/locales/devise.lt.yml b/config/locales/devise.lt.yml
new file mode 100644
index 0000000000000000000000000000000000000000..6c5cb837ac8c136ddd4d85ef0a39145c386d62af
--- /dev/null
+++ b/config/locales/devise.lt.yml
@@ -0,0 +1 @@
+lt:
diff --git a/config/locales/devise.lv.yml b/config/locales/devise.lv.yml
new file mode 100644
index 0000000000000000000000000000000000000000..1be0eabc091569fadd234dc415e9a399b26e32c1
--- /dev/null
+++ b/config/locales/devise.lv.yml
@@ -0,0 +1 @@
+lv:
diff --git a/config/locales/devise.ms.yml b/config/locales/devise.ms.yml
new file mode 100644
index 0000000000000000000000000000000000000000..2925688a0330ed791a036a41ffcb8fc31c75352f
--- /dev/null
+++ b/config/locales/devise.ms.yml
@@ -0,0 +1 @@
+ms:
diff --git a/config/locales/devise.nl.yml b/config/locales/devise.nl.yml
index a768d3c1d2a4429eb87309575608c230c63f80a8..51a95403fdee475c688d5e866aaabef6314f4809 100644
--- a/config/locales/devise.nl.yml
+++ b/config/locales/devise.nl.yml
@@ -9,10 +9,10 @@ nl:
       already_authenticated: Je bent al ingelogd.
       inactive: Jouw account is nog niet geactiveerd.
       invalid: "%{authentication_keys} of wachtwoord ongeldig."
-      invalid_token: Ongeldige bevestigingscode.
       last_attempt: Je hebt nog één poging over voordat jouw account wordt opgeschort.
       locked: Jouw account is opgeschort.
       not_found_in_database: "%{authentication_keys} of wachtwoord ongeldig."
+      pending: Jouw account moet nog steeds worden beoordeeld.
       timeout: Jouw sessie is verlopen, log opnieuw in.
       unauthenticated: Je dient in te loggen of te registreren.
       unconfirmed: Je dient eerst jouw account te bevestigen.
@@ -21,6 +21,7 @@ nl:
         action: E-mailadres verifiëren
         action_with_app: Bevestigen en naar %{app} teruggaan
         explanation: Je hebt een account op %{host} aangemaakt en met één klik kun je deze activeren. Wanneer jij dit account niet hebt aangemaakt, mag je deze e-mail negeren.
+        explanation_when_pending: Je vroeg met dit e-mailadres een uitnodiging aan voor %{host}. Nadat je jouw e-mailadres hebt bevestigd, beoordelen we jouw aanvraag. Je kunt tot dan nog niet inloggen. Wanneer jouw aanvraag wordt afgekeurd, worden jouw gegevens verwijderd en hoef je daarna verder niets meer te doen. Wanneer jij dit niet was, kun je deze e-mail negeren.
         extra_html: Bekijk ook de <a href="%{terms_path}">regels van de Mastodonserver</a> en <a href="%{policy_path}">onze gebruiksvoorwaarden</a>.
         subject: 'Mastodon: E-mail bevestigen voor %{instance}'
         title: E-mailadres verifiëren
@@ -61,6 +62,7 @@ nl:
       signed_up: Je bent geregistreerd.
       signed_up_but_inactive: Je bent geregistreerd. Je kon alleen niet automatisch ingelogd worden omdat jouw account nog niet geactiveerd is.
       signed_up_but_locked: Je bent ingeschreven. Je kon alleen niet automatisch ingelogd worden omdat jouw account is opgeschort.
+      signed_up_but_pending: Er is een bericht met een bevestigingslink naar jouw e-mailadres verzonden. Nadat je op deze link hebt geklikt nemen we jouw aanvraag in behandeling. Je wordt op de hoogte gesteld wanneer deze wordt goedgekeurd.
       signed_up_but_unconfirmed: Je ontvangt via e-mail instructies hoe je jouw account kunt activeren. Kijk tussen je spam wanneer niks werd ontvangen.
       update_needs_confirmation: Je hebt je e-mailadres succesvol gewijzigd, maar we moeten je nieuwe mailadres nog bevestigen. Controleer jouw e-mail en klik op de link in de mail om jouw e-mailadres te bevestigen. Kijk tussen je spam wanneer niks werd ontvangen.
       updated: Jouw accountgegevens zijn opgeslagen.
diff --git a/config/locales/devise.oc.yml b/config/locales/devise.oc.yml
index 99809b8585c6ce6f6b0ffd357041ce11838be492..42be33f6b5b4c2de4dd03e503163fe6053bf355a 100644
--- a/config/locales/devise.oc.yml
+++ b/config/locales/devise.oc.yml
@@ -12,6 +12,7 @@ oc:
       last_attempt: Vos demòra un ensag abans que vòstre compte siasque blocat.
       locked: Vòstre compte es blocat.
       not_found_in_database: "%{authentication_keys} invalida."
+      pending: Vòstre compte es encara en aprobacion.
       timeout: Vòstra session a expirat. Mercés de vos tornar connectar per contunhar.
       unauthenticated: Vos cal vos connectar o marcar abans de contunhar.
       unconfirmed: Vos cal confirmar vòstra adreça de corrièl abans de contunhar.
@@ -20,17 +21,18 @@ oc:
         action: Verificar l’adreça de corrièl
         action_with_app: Confirmar e tornar a %{app}
         explanation: Venètz de crear un compte sus %{host} amb aquesta adreça de corrièl. Vos manca pas qu’un clic per l’activar. S’èra pas vosautre mercés de far pas cas a aqueste messatge.
-        extra_html: Pensatz tanben de gaitar <a href="%{terms_path}">las règlas de l’instància</a> e <a href="%{policy_path}">nòstres tèrmes e condicions d’utilizacion</a>.
+        explanation_when_pending: Avètz demandat una invitacion a %{host} amb aquesta adreça electronica. Un còp que confirmetz vòstra adreça electronica revisarem vòstra demanda. Se pòt iniciar la session fins alara. Se vòstra demanda es pas acceptada vòstras donadas seràn suprimidas, de manièra que caldrà pas cap d’autra accion. S’èra pas vos qu’avètz fach la demanda, se vos plai ignoratz aqueste corrièl.
+        extra_html: Pensatz tanben de gaitar <a href="%{terms_path}">las règlas del servidor</a> e <a href="%{policy_path}">nòstres tèrmes e condicions d’utilizacion</a>.
         subject: 'Mastodon : consignas de confirmacion per %{instance}'
         title: Verificatz l’adreça de corrièl
       email_changed:
         explanation: 'L’adreça per aqueste compte es ara :'
-        extra: S’avètz pas demandat aqueste cambiament d’adreça, poiriá arribar que qualqu’un mai aguèsse agut accès a vòstre compte. Mercés de cambiar sulpic vòstre senhal o de contactar vòstre administrator d’instància se l’accès a vòstre compte vos es barrat.
+        extra: S’avètz pas demandat aqueste cambiament d’adreça, poiriá arribar que qualqu’un mai aguèsse agut accès a vòstre compte. Mercés de cambiar sulpic vòstre senhal o de contactar vòstre administrator de servidor se l’accès a vòstre compte vos es barrat.
         subject: 'Mastodon : corrièl cambiat'
         title: Nòva adreça de corrièl
       password_change:
         explanation: Lo senhal per vòstre compte a cambiat.
-        extra: S’avètz pas demandat aqueste cambiament de senhal, poiriá arribar que qualqu’un mai aguèsse agut accès a vòstre compte. Mercés de cambiar sulpic vòstre senhal o de contactar vòstre administrator d’instància se l’accès a vòstre compte vos es barrat.
+        extra: S’avètz pas demandat aqueste cambiament de senhal, poiriá arribar que qualqu’un mai aguèsse agut accès a vòstre compte. Mercés de cambiar sulpic vòstre senhal o de contactar vòstre administrator de servidor se l’accès a vòstre compte vos es barrat.
         subject: Mastodon : senhal cambiat
         title: Senhal cambiat
       reconfirmation_instructions:
@@ -60,6 +62,7 @@ oc:
       signed_up: La benvenguda ! Sètz ben marcat al malhum.
       signed_up_but_inactive: Sètz ben marcat. Pasmens, avèm pas pogut vos connectar perque vòstre compte es pas encara validat.
       signed_up_but_locked: Sètz ben marcat. Pasmens, avèm pas pogut vos connectar perque vòstre compte es pas encara blocat.
+      signed_up_but_pending: Un messatge amb un ligam de confirmacion es estat enviat a vòstra adreça electronica. Aprèp aver clicat lo ligam, revisarem vòstra demanda. Seretz avisat se’s aprovada.
       signed_up_but_unconfirmed: Un messatge amb un ligam de confirmacion es estat enviat a vòstra adreça de corrièl. Clicatz sul ligam per activar vòstre compte. Mercés de verificar tanben vòstre dorsièr de corrièls indesirables.
       update_needs_confirmation: Avètz ben mes a jorn vòstre compte, mai nos cal verificar vòstra nòva adreça de corrièl. Mercés de verificar vòstres messatges e clicar sul ligam de confirmacion per confirmar vòstra nòva adreça de corrièl. Mercés de verificar tanben vòstre dorsièr de corrièls indesirables.
       updated: Vòstre compte es estat mes a jorn amb succès.
diff --git a/config/locales/devise.pl.yml b/config/locales/devise.pl.yml
index 57c21437b815afa7de4ac0361c4e2668682ec591..a0af51c328aa7ee4d0fbbdc833ce384703067dbf 100644
--- a/config/locales/devise.pl.yml
+++ b/config/locales/devise.pl.yml
@@ -12,6 +12,7 @@ pl:
       last_attempt: Masz jeszcze jedną próbę; Twoje konto zostanie zablokowane jeśli się nie powiedzie.
       locked: Twoje konto zostało zablokowane.
       not_found_in_database: Nieprawidłowy %{authentication_keys} lub hasło.
+      pending: Twoje konto oczekuje na przeglÄ…d.
       timeout: Twoja sesja wygasła. Zaloguj się ponownie, aby kontynuować..
       unauthenticated: Zapisz się lub zaloguj, aby kontynuować.
       unconfirmed: Zweryfikuj adres e-mail, aby kontynuować.
@@ -20,17 +21,18 @@ pl:
         action: Zweryfikuj adres e-mail
         action_with_app: Potwierdź i wróć do %{app}
         explanation: Utworzyłeś(-aś) konto na %{host} podając ten adres e-mail. Jedno kliknięcie dzieli Cię od aktywacji tego konta. Jeżeli to nie Ty, zignoruj ten e-mail.
-        extra_html: Przeczytaj też <a href="%{terms_path}">regulamin instancji</a> i <a href="%{policy_path}">nasze zasady użytkowania</a>.
+        explanation_when_pending: Poprosiłeś(-aś) o zaproszenie na %{host} używajac tego adresu e-mail. Kiedy potwierdzisz swój adres e-mail, przejrzymy Twoje podanie. Do tego czasu nie możesz się zalogować. Jeżeli Twoje podanie zostanie odrzucone, Twoje dane zostaną usunięte i nie będziesz musiał(-a) podejmować żadnych dodatkowych działań. Jeżeli to nie Ty, zignoruj ten e-mail.
+        extra_html: Przeczytaj też <a href="%{terms_path}">regulamin serwera</a> i <a href="%{policy_path}">nasze zasady użytkowania</a>.
         subject: 'Mastodon: Instrukcje weryfikacji adresu e-mail na %{instance}'
         title: Zweryfikuj adres e-mail
       email_changed:
         explanation: 'Adres e-mail dla Twojego konta zostanie zmieniony na:'
-        extra: Jeżeli nie próbowałeś(-aś) zmienić adresu e-mail, prawdopodobnie ktoś uzyskał dostęp do Twojego konta. Zmień natychmiastowo hasło lub skontaktuj się z administratorem isntancji, jeżeli nie masz dostępu do konta.
+        extra: Jeżeli nie próbowałeś(-aś) zmienić adresu e-mail, prawdopodobnie ktoś uzyskał dostęp do Twojego konta. Zmień natychmiastowo hasło lub skontaktuj się z administratorem serwera, jeżeli nie masz dostępu do konta.
         subject: 'Mastodon: Zmieniono adres e-mail'
         title: Nowy adres e-mail
       password_change:
         explanation: Hasło do Twojego konta zostało zmienione.
-        extra: Jeżeli nie zmieniałeś(-aś) hasła, prawdopodobnie ktoś uzyskał dostęp do Twojego konta. Zmień hasło natychmiastowo lub skontaktuj się z administratorem instancji, jeżeli nie masz dostępu do konta.
+        extra: Jeżeli nie zmieniałeś(-aś) hasła, prawdopodobnie ktoś uzyskał dostęp do Twojego konta. Zmień hasło natychmiastowo lub skontaktuj się z administratorem serwera, jeżeli nie masz dostępu do konta.
         subject: 'Mastodon: Zmieniono hasło'
         title: Zmieniono hasło
       reconfirmation_instructions:
@@ -56,10 +58,11 @@ pl:
       updated: Twoje hasło zostało zmienione. Jesteś zalogowany(-a).
       updated_not_active: Twoje hasło zostało zmienione.
     registrations:
-      destroyed: Twoje konto zostało zawieszone. Mamy jednak nadzieję, że do nas wrócisz. Do zobaczenia!
-      signed_up: Twoje konto zostało utworzone. Witamy!
+      destroyed: Do zobaczenia! Twoje konto zostało zawieszone. Mamy jednak nadzieję, że do nas wrócisz.
+      signed_up: Witamy! Twoje konto zostało utworzone.
       signed_up_but_inactive: Twoje konto zostało utworzone. Nie mogliśmy Cię jednak zalogować, ponieważ konto nie zostało jeszcze aktywowane.
       signed_up_but_locked: Twoje konto zostało utworzone. Nie mogliśmy Cię jednak zalogować, ponieważ konto jest zablokowane.
+      signed_up_but_pending: Na Twój adres e-mail została wysłana wiadomosć z odnośnikiem potwierdzającym. Po kliknięciu w odnośnik, przejrzymy Twoje podanie. Zostaniesz poinformowany(-a), gdy zostanie ono przyjęte.
       signed_up_but_unconfirmed: Na Twój adres e-mail została wysłana wiadomosć z odnośnikiem potwierdzającym. Kliknij w odnośnik, aby aktywować konto. Jeżeli nie otrzymano wiadomości, sprawdź folder ze spamem.
       update_needs_confirmation: Konto zostało zaktualizowane, musimy jednak zweryfikować Twój nowy adres e-mail. Została na niego wysłana wiadomość z odnośnikiem potwierdzającym. Jeżeli nie otrzymano wiadomości, sprawdź folder ze spamem.
       updated: Konto zostało zaktualizowane.
diff --git a/config/locales/devise.pt-BR.yml b/config/locales/devise.pt-BR.yml
index ede0048925015711ccfaadb231ee158b85eadc1c..0b6d361876ac8d1e9135f9bdc0c1478593a5c7cf 100644
--- a/config/locales/devise.pt-BR.yml
+++ b/config/locales/devise.pt-BR.yml
@@ -12,6 +12,7 @@ pt-BR:
       last_attempt: Você tem apenas mais uma tentativa sobrando antes que a sua conta seja bloqueada.
       locked: A sua conta está bloqueada.
       not_found_in_database: "%{authentication_keys} ou senha inválida."
+      pending: Sua conta ainda está sendo revisada.
       timeout: A sua sessão expirou. Por favor, entre novamente para continuar.
       unauthenticated: Você precisa entrar ou cadastrar-se antes de continuar.
       unconfirmed: Você precisa confirmar o seu endereço de e-mail antes de continuar.
@@ -20,6 +21,7 @@ pt-BR:
         action: Verificar endereço de e-mail
         action_with_app: Confirmar e voltar para %{app}
         explanation: Você criou uma conta em %{host} com esse endereço de e-mail. Você está a um clique de ativá-la. Se não foi você, por favor ignore esse e-mail.
+        explanation_when_pending: Você pediu um convite para %{host} com esse endereço de email. Assim que você confirmar o seu endereço de e-mail, iremos revisar o seu pedido. Você não poderá fazer login até então. Se sua aplicação for rejeitada, seus dados serão removidos e nenhuma ação será necessária da sua parte. Se você não pediu por isso, por favor ignore esse e-mail.
         extra_html: Por favor confira também <a href="%{terms_path}">as regras da instância</a> e <a href="%{policy_path}">nossos termos de serviço</a>.
         subject: 'Mastodon: Instruções de confirmação para %{instance}'
         title: Verifique o endereço de e-mail
@@ -60,6 +62,7 @@ pt-BR:
       signed_up: Bem vindo! A sua conta foi registrada com sucesso.
       signed_up_but_inactive: A sua conta foi registrada. No entanto, não abrimos a sua sessão porque a sua conta ainda não foi ativada.
       signed_up_but_locked: A sua conta foi registrada. No entanto, não abrimos a sua sessão porque a sua conta está bloqueada.
+      signed_up_but_pending: Uma mensagem com um link de confirmação foi enviada ao seu endereço de e-mail. Depois que você clicar no link, revisaremos seu pedido. Você será notificado se seu pedido for aprovado.
       signed_up_but_unconfirmed: Uma mensagem com um link de confirmação foi enviada para o seu endereço de e-mail. Por favor, siga o link para ativar a sua conta e, caso não tenha recebido esta mensagem, cheque a sua pasta de spam.
       update_needs_confirmation: Você mudou o seu endereço de e-mail ou a sua senha, mas é necessário confirmar a mudança. Por favor siga o link que foi enviado para o seu novo endereço de e-mail e, caso não tenha recebido esta mensagem, cheque a sua pasta de spam.
       updated: A sua conta foi alterada com sucesso.
diff --git a/config/locales/devise.pt.yml b/config/locales/devise.pt.yml
index 5fd54ff501d4ee19627a6deb9026dca9ee0ece43..9b44bbf00c6e6dadb06cf72c565e3270e9e78d15 100644
--- a/config/locales/devise.pt.yml
+++ b/config/locales/devise.pt.yml
@@ -2,34 +2,35 @@
 pt:
   devise:
     confirmations:
-      confirmed: O teu endereço de email foi confirmado.
-      send_instructions: Vais receber um email com as instruções para confirmar o teu endereço de email dentro de alguns minutos.
-      send_paranoid_instructions: Se o teu endereço de email já existir na nossa base de dados, vais receber um email com as instruções de confirmação dentro de alguns minutos.
+      confirmed: O teu endereço de e-mail foi confirmado com sucesso.
+      send_instructions: Vais receber um email com as instruções para confirmar o teu endereço de email dentro de alguns minutos. Por favor, verifica a caixa de spam se não recebeste o e-mail.
+      send_paranoid_instructions: Se o teu endereço de email já existir na nossa base de dados, vais receber um email com as instruções de confirmação dentro de alguns minutos. Por favor, verifica a caixa de spam se não recebeste o e-mail.
     failure:
       already_authenticated: A tua sessão já está aberta.
       inactive: A tua conta ainda não está ativada.
-      invalid: "%{authentication_keys} ou palavra-passe não válida."
+      invalid: "%{authentication_keys} ou palavra-passe inválida."
       last_attempt: Tens mais uma tentativa antes de a tua conta ficar bloqueada.
       locked: A tua conta está bloqueada.
-      not_found_in_database: "%{authentication_keys} ou palavra-passe não válida."
+      not_found_in_database: "%{authentication_keys} ou palavra-passe inválida."
       timeout: A tua sessão expirou. Por favor, entra de novo para continuares.
-      unauthenticated: Precisas de entrar na tua conta ou registares-te antes de continuar.
+      unauthenticated: Precisas de entrar na tua conta ou de te registares antes de continuar.
       unconfirmed: Tens de confirmar o teu endereço de email antes de continuar.
     mailer:
       confirmation_instructions:
         action: Verificar o endereço de e-mail
+        action_with_app: Confirmar e regressar a %{app}
         explanation: Criaste uma conta em %{host} com este endereço de e-mail. Estás a um clique de activá-la. Se não foste tu que fizeste este registo, por favor ignora esta mensagem.
-        extra_html: Por favor vê as <a href="%{terms_path}">as regras da instância</a> e os <a href="%{policy_path}">termos de serviço</a>.
+        extra_html: Por favor lê <a href="%{terms_path}">as regras da instância</a> e os <a href="%{policy_path}"> nossos termos de serviço</a>.
         subject: 'Mastodon: Instruções de confirmação %{instance}'
         title: Verificar o endereço de e-mail
       email_changed:
         explanation: 'O e-mail associado à tua conta será alterado para:'
-        extra: Se não alteraste o teu e-mail é possível que alguém tenha conseguido aceder à tua conta. Por favor muda a tua palavra-passe imediatamente ou entra em contato com um administrador da tua instância se ficaste sem acesso à tua conta.
+        extra: Se não alteraste o teu e-mail é possível que alguém tenha conseguido aceder à tua conta. Por favor muda a tua palavra-passe imediatamente ou entra em contato com um administrador do servidor se ficaste sem acesso à tua conta.
         subject: 'Mastodon: Email alterado'
         title: Novo endereço de e-mail
       password_change:
         explanation: A palavra-passe da tua conta foi alterada.
-        extra: Se não alteraste a tua palavra-passe, é possível que alguém tenha conseguido aceder à tua conta. Por favor muda a tua palavra-passe imediatamente ou entra em contato com um administrador da tua instância se ficaste sem acesso à tua conta.
+        extra: Se não alteraste a tua palavra-passe, é possível que alguém tenha conseguido aceder à tua conta. Por favor muda a tua palavra-passe imediatamente ou entra em contato com um administrador do servidor se ficaste sem acesso à tua conta.
         subject: 'Mastodon: Nova palavra-passe'
         title: Palavra-passe alterada
       reconfirmation_instructions:
diff --git a/config/locales/devise.ro.yml b/config/locales/devise.ro.yml
new file mode 100644
index 0000000000000000000000000000000000000000..79dbaa871cae8753fe261033b12cd507f3536ad9
--- /dev/null
+++ b/config/locales/devise.ro.yml
@@ -0,0 +1 @@
+ro:
diff --git a/config/locales/devise.ru.yml b/config/locales/devise.ru.yml
index 2186066c9dde3fb98f55669a188a698aae660e42..65441f24b717b6b1f1e2196384414b08b518cf65 100644
--- a/config/locales/devise.ru.yml
+++ b/config/locales/devise.ru.yml
@@ -3,8 +3,8 @@ ru:
   devise:
     confirmations:
       confirmed: Ваш адрес e-mail был успешно подтвержден.
-      send_instructions: Вы получите e-mail с инструкцией по подтверждению Вашего адреса e-mail в течение нескольких минут.
-      send_paranoid_instructions: Если Ваш адрес e-mail есть в нашей базе данных, вы получите e-mail с инструкцией по подтверждению Вашего адреса в течение нескольких минут.
+      send_instructions: Вы получите e-mail с инструкцией по подтверждению вашего адреса e-mail в течение нескольких минут.
+      send_paranoid_instructions: Если Ваш адрес e-mail есть в нашей базе данных, вы получите e-mail с инструкцией по подтверждению вашего адреса в течение нескольких минут.
     failure:
       already_authenticated: Вы уже авторизованы.
       inactive: Ваш аккаунт еще не активирован.
@@ -12,63 +12,67 @@ ru:
       last_attempt: У Вас есть последняя попытка, после чего вход будет заблокирован.
       locked: Ваш аккаунт заблокирован.
       not_found_in_database: Неверно введены %{authentication_keys} или пароль.
+      pending: Ваша заявка на вступление всё ещё рассматривается.
       timeout: Ваша сессия истекла. Пожалуйста, войдите снова, чтобы продолжить.
       unauthenticated: Вам необходимо войти или зарегистрироваться.
       unconfirmed: Вам необходимо подтвердить ваш адрес e-mail для продолжения.
     mailer:
       confirmation_instructions:
         action: Подтвердите e-mail адрес
+        action_with_app: Подтвердить и вернуться в %{app}
         explanation: Вы создали учётную запись на сайте %{host}, используя этот e-mail адрес. Остался лишь один шаг для активации. Если это были не вы, просто игнорируйте письмо.
+        explanation_when_pending: Вы подали заявку на %{host}, используя этот адрес e-mail. Как только вы его подтвердите, мы начнём изучать вашу заявку. До тех пор вы не сможете войти на сайт. Если ваша заявка будет отклонена, все данные будут автоматически удалены, от вас не потребуется никаких дополнительных действий. Если это были не вы, пожалуйста, проигнорируйте данное письмо.
         extra_html: Пожалуйста, ознакомьтесь <a href="%{terms_path}">правилами узла</a> and <a href="%{policy_path}">условиями пользования Сервисом</a>.
         subject: 'Mastodon: Инструкция по подтверждению на узле %{instance}'
         title: Подтвердите e-mail адрес
       email_changed:
-        explanation: 'E-mail адрес Вашей учётной записи будет изменён на:'
-        extra: Если Вы не меняли адрес e-mail, возможно кто-то получил доступ к Вашей учётной записи. Пожалуйста, срочно смените пароль или свяжитесь с администратором узла, если у Вас нет доступа к учётной записи.
+        explanation: 'E-mail адрес вашей учётной записи будет изменён на:'
+        extra: Если Вы не меняли адрес e-mail, возможно кто-то получил доступ к вашей учётной записи. Пожалуйста, срочно смените пароль или свяжитесь с администратором узла, если у вас нет доступа к учётной записи.
         subject: 'Mastodon: Адрес e-mail изменён'
         title: Новый адрес e-mail
       password_change:
         explanation: Пароль Вашей учётной записи был изменён.
-        extra: Если Вы не меняли пароль, возможно кто-то получил доступ к Вашей учётной записи. Пожалуйста, срочно смените пароль или свяжитесь с администратором узла, если у Вас нет доступа к учётной записи.
+        extra: Если Вы не меняли пароль, возможно кто-то получил доступ к вашей учётной записи. Пожалуйста, срочно смените пароль или свяжитесь с администратором узла, если у вас нет доступа к учётной записи.
         subject: 'Mastodon: Пароль изменен'
         title: Пароль изменён
       reconfirmation_instructions:
         explanation: Подтвердите новый адрес для смены e-mail.
-        extra: Если смену e-mail инициировали не Вы, пожалуйста, игнорируйте это письмо. Адрес e-mail для учётной записи Mastodon не будет изменён, пока Вы не перейдёте по ссылке выше.
+        extra: Если смену e-mail инициировали не вы, пожалуйста, игнорируйте это письмо. Адрес e-mail для учётной записи Mastodon не будет изменён, пока вы не перейдёте по ссылке выше.
         subject: 'Mastodon: Подтверждение e-mail для узла %{instance}'
         title: Подтвердите e-mail адрес
       reset_password_instructions:
         action: Смена пароля
-        explanation: Вы запросили новый пароль для Вашей учётной записи.
-        extra: Если это сделали не Вы, пожалуйста, игнорируйте письмо. Ваш пароль не будет изменён, пока Вы не перейдёте по ссылке выше и не создадите новый пароль.
+        explanation: Вы запросили новый пароль для вашей учётной записи.
+        extra: Если это сделали не вы, пожалуйста, игнорируйте письмо. Ваш пароль не будет изменён, пока вы не перейдёте по ссылке выше и не создадите новый пароль.
         subject: 'Mastodon: инструкция по смене пароля'
         title: Сброс пароля
       unlock_instructions:
         subject: 'Mastodon: Инструкция по разблокировке'
     omniauth_callbacks:
-      failure: Не получилось аутентифицировать Вас с помощью %{kind} по следующей причине - "%{reason}".
+      failure: Не получилось аутентифицировать вас с помощью %{kind} по следующей причине - "%{reason}".
       success: Аутентификация с помощью аккаунта %{kind} прошла успешно.
     passwords:
-      no_token: Вы можете получить доступ к этой странице, только перейдя по ссылке в e-mail для сброса пароля. Если Вы действительно перешли по такой ссылке, пожалуйста, удостоверьтесь, что ссылка была введена полностью и без изменений.
+      no_token: Вы можете получить доступ к этой странице, только перейдя по ссылке в e-mail для сброса пароля. Если вы действительно перешли по такой ссылке, пожалуйста, удостоверьтесь, что ссылка была введена полностью и без изменений.
       send_instructions: Вы получите e-mail с инструкцией по сбросу пароля в течение нескольких минут.
-      send_paranoid_instructions: Если Ваш адрес e-mail есть в нашей базе данных, Вы получите e-mail со ссылкой для сброса пароля в течение нескольких минут.
+      send_paranoid_instructions: Если Ваш адрес e-mail есть в нашей базе данных, вы получите e-mail со ссылкой для сброса пароля в течение нескольких минут.
       updated: Ваш пароль был успешно изменен. Вход выполнен.
       updated_not_active: Ваш пароль был успешно изменен.
     registrations:
-      destroyed: До свидания! Ваш аккаунт был успешно удален. Мы надеемся скоро увидеть Вас снова.
+      destroyed: До свидания! Ваш аккаунт был успешно удален. Мы надеемся скоро увидеть вас снова.
       signed_up: Добро пожаловать! Вы успешно зарегистрировались.
-      signed_up_but_inactive: Вы успешно зарегистрировались. Тем не менее, мы не можем авторизовать Вас, поскольку Ваш аккаунт еще не активирован.
-      signed_up_but_locked: Вы успешно зарегистрировались. Тем не менее, мы не можем авторизовать Вас, поскольку Ваш аккаунт заблокирован.
-      signed_up_but_unconfirmed: Сообщение со ссылкой для подтверждения было выслано на Ваш адрес e-mail. Пожалуйста, пройдите по ссылке для активации Вашего аккаунта.
-      update_needs_confirmation: Вы успешно обновили Ваш аккаунт, но нам нужно подтвердить ваш новый адрес e-mail. Пожалуйста, проверьте почту и пройдите по ссылке для подтверждения Вашего нового адреса.
+      signed_up_but_inactive: Вы успешно зарегистрировались. Тем не менее, мы не можем авторизовать вас, поскольку ваш аккаунт еще не активирован.
+      signed_up_but_locked: Вы успешно зарегистрировались. Тем не менее, мы не можем авторизовать вас, поскольку ваш аккаунт заблокирован.
+      signed_up_but_pending: На ваш e-mail адрес было отправлено письмо с ссылкой для подтверждения. После перехода по ней, мы начнём рассматривать вашу заявку. В случае подтверждения, мы вас оповестим.
+      signed_up_but_unconfirmed: Сообщение со ссылкой для подтверждения было выслано на ваш адрес e-mail. Пожалуйста, пройдите по ссылке для активации вашего аккаунта.
+      update_needs_confirmation: Вы успешно обновили данные учётной записи, но нам нужно подтвердить ваш новый адрес e-mail. Пожалуйста, проверьте почту и перейдите по ссылке из письма для подтверждения вашего нового адреса.
       updated: Ваш аккаунт был успешно обновлен.
     sessions:
       already_signed_out: Выход прошел успешно.
       signed_in: Вход прошел успешно.
       signed_out: Выход прошел успешно.
     unlocks:
-      send_instructions: Вы получите e-mail с инструкцией по разблокировке Вашего аккаунта в течение нескольких минут.
-      send_paranoid_instructions: Если Ваш аккаунт существует, Вы получите e-mail с инструкцией по его разблокировке в течение нескольких минут.
+      send_instructions: Вы получите e-mail с инструкцией по разблокировке вашего аккаунта в течение нескольких минут.
+      send_paranoid_instructions: Если Ваш аккаунт существует, вы получите e-mail с инструкцией по его разблокировке в течение нескольких минут.
       unlocked: Ваш аккаунт был успешно разблокирован. пожалуйста, войдите для продолжения.
   errors:
     messages:
diff --git a/config/locales/devise.sk.yml b/config/locales/devise.sk.yml
index 16cd9262e2d0c7f5c43444b15ec670f74b8f1d2a..85de603d3e2068a4d159a0c31a96c05c3e7fd2b8 100644
--- a/config/locales/devise.sk.yml
+++ b/config/locales/devise.sk.yml
@@ -2,35 +2,36 @@
 sk:
   devise:
     confirmations:
-      confirmed: Váš účet bol úspešne overený.
-      send_instructions: O niekoľko minút obdržíte email s inštrukciami ako potvrdiť váš účet.
-      send_paranoid_instructions: Ak sa váš email nachádza v našej databáze, obdržíte email s inštrukciami ako potvrdiť váš účet.
+      confirmed: Tvoja emailová adresa bola úspešne overená.
+      send_instructions: O niekoľko minút obdržíš email s pokynmi ako potvrdiť svoj účet. Prosím, skontroluj si aj zložku spam, ak sa k tebe toto potvrdenie nedostalo.
+      send_paranoid_instructions: Ak sa tvoja emailová adresa nachádza v našej databázi, o niekoľko minút obdržíš email s pokynmi ako potvrdiť svoj účet. Prosím, skontroluj aj zložku spam, ak sa k tebe toto potvrdenie nedostalo.
     failure:
       already_authenticated: Už si prihlásený/á.
       inactive: Tvoj účet ešte nebol potvrdený.
       invalid: Nesprávny %{authentication_keys}, alebo heslo.
       last_attempt: Máš posledný pokus pred zamknutím tvojho účtu.
       locked: Tvoj účet je zamknutý.
-      not_found_in_database: Nesprávny %{authentication_keys} alebo heslo.
-      timeout: Vaša aktívna sezóna vypršala. Pre pokračovanie sa prosím znovu prihláste.
+      not_found_in_database: Nesprávny %{authentication_keys}, alebo heslo.
+      pending: Tvoj účet je stále prehodnocovaný.
+      timeout: Tvoja aktívna sezóna vypršala. Pre pokračovanie sa prosím prihlás znovu.
       unauthenticated: K pokračovaniu sa musíš zaregistrovať alebo prihlásiť.
       unconfirmed: Pred pokračovaním musíš potvrdiť svoj email.
     mailer:
       confirmation_instructions:
-        action: Potvŕď emailovú adresu
+        action: Potvrď emailovú adresu
         action_with_app: Potvrď a vráť sa na %{app}
         explanation: S touto emailovou adresou si si vytvoril/a účet na %{host}. Si iba jeden klik od jeho aktivácie. Pokiaľ si to ale nebol/a ty, prosím ignoruj tento email.
-        extra_html: Prosím pozri sa aj na <a href="%{terms_path}"> pravidlá tohto servera,</a> a <a href="%{policy_path}"> naše užívaťeľské podiemky</a>.
-        subject: 'Mastodon: Potvrdzovacie inštrukcie pre %{instance}'
+        extra_html: Prosím, pozri sa aj na <a href="%{terms_path}"> pravidlá tohto servera,</a> a <a href="%{policy_path}"> naše užívaťeľské podiemky</a>.
+        subject: 'Mastodon: Potvrdzovacie pokyny 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.
+        extra: Ak 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 tvojmu účtu bolo zmenené.
-        extra: Ak si heslo nezmenil/a, 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.
+        extra: Ak si heslo nezmenil/a, 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:
@@ -41,32 +42,33 @@ sk:
       reset_password_instructions:
         action: Zmeň svoje heslo
         explanation: Vyžiadal/a si 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'
+        extra: Ak 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: Pokyny pre obnovu hesla'
         title: Nastav nové heslo
       unlock_instructions:
-        subject: 'Mastodon: Inštrukcie pre odomknutie účtu'
+        subject: 'Mastodon: Pokyny na odomknutie účtu'
     omniauth_callbacks:
-      failure: Nebolo možné ťa overiť z dôvodu,%{kind} že "%{reason}".
+      failure: Nebolo možné ťa overiť z %{kind}, lebo "%{reason}".
       success: Úspešné overenie z účtu %{kind}.
     passwords:
-      no_token: Túto stránku nemôžete navštíviť pokiaľ neprichádzate z emailu s inštrukciami na obnovu hesla. Pokiaľ prichádzate z tohto emailu, prosím uistite sa že ste použili celú URL z emailu.
-      send_instructions: Ak zadaný email existuje v našej databázi, tak o niekoľko minút obdržíte email s inštrukciami ako nastaviť nové heslo.
-      send_paranoid_instructions: Ak zadaný email existuje v našej databázi, zachvíľu obdržíte odkaz na obnovu hesla na svoj email. Skontrolujte aj spam ak tento email nevidíte.
+      no_token: Túto stránku nemôžeš navštíviť, ak neprichádzaš z emailu s pokynmi na obnovu hesla. Pokiaľ prichádzaš z tohto emailu, prosím uisti sa že si použil/a celú URL adresu z emailu.
+      send_instructions: Ak sa tvoja emailová adresa nachádza v databázi, tak o niekoľko minút obdržíš email s pokynmi ako nastaviť nové heslo. Ak máš pocit, že si email neobdržal/a, prosím skontroluj aj svoju spam zložku.
+      send_paranoid_instructions: Ak sa tvoja emailová adresa nachádza v databázi, za chvíľu obdržíš odkaz pre obnovu hesla na svoj email. Skontroluj ale prosím aj svoj spam, ak tento email nevidíš.
       updated: Tvoje heslo bolo úspešne zmenené. Teraz si prihlásený/á.
       updated_not_active: Tvoje heslo bolo úspešne zmenené.
     registrations:
       destroyed: Dovidenia! Tvoj účet bol úspešne zrušený. Dúfame ale, že ťa tu opäť niekedy uvidíme.
       signed_up: Vitaj! Tvoja registrácia bola úspešná.
-      signed_up_but_inactive: Registrácia bola úspešná. Avšak, účet ešte nebol aktivovaný, takže ťa nemôžeme prihlásiť.
-      signed_up_but_locked: Prihlasovanie úspešné. Avšak tvoj účet je zamknutý, takže ťa nieje možné prihlásiť.
-      signed_up_but_unconfirmed: Správa s odkazom na potvrdenie registrácie bola odoslaná na tvoj email. Pre aktváciu účtu, klikni prosím na daný odkaz. Takisto ale skontroluj aj svoju spam zložku, pokiaľ sa ti zdá, že si tento email nedostal/a.
-      update_needs_confirmation: Účet bol úspešne zmenený ale ešte potrebujeme overiť tvoju novú emailovú adresu. Pre overenie prosím klikni na link v správe ktorú si dostal/a na email. Takisto ale skontroluj aj svoju spam zložku, ak sa ti zdá, že si tento email nedostal/a.
+      signed_up_but_inactive: Registrácia bola úspešná. Avšak, účet ešte nebol aktivovaný, takže ťa nemožno prihlásiť.
+      signed_up_but_locked: Registroval/a si sa úspešné. Avšak, tvoj účet je zamknutý, takže ťa nemožno prihlásiť.
+      signed_up_but_pending: Na tvoj email bola odoslaná správa s odkazom na potvrdenie. Po tom, čo naňho klikneš, bude tvoje uchádzanie posúdené. Budeš informovaný, ak sa tvoja požiadavka schváli.
+      signed_up_but_unconfirmed: Správa s odkazom na potvrdenie registrácie bola odoslaná na tvoj email. Pre aktváciu účtu, následuj prosím daný odkaz. Takisto ale skontroluj aj svoju spam zložku, pokiaľ sa ti zdá, že si tento email nedostal/a.
+      update_needs_confirmation: Účet bol úspešne pozmenený, ale ešte potrebujeme overiť tvoju novú emailovú adresu. Pre overenie prosím klikni na link v správe ktorú si dostal/a na email. Takisto ale skontroluj aj svoju spam zložku, ak sa ti zdá, že si tento email nedostal/a.
       updated: Tvoj účet bol úspešne aktualizovaný.
     sessions:
-      already_signed_out: Odhlásil/a si sa úspešné.
-      signed_in: Prihlásil/a si sa úspešné.
-      signed_out: Odhlásil/a si sa úspešné.
+      already_signed_out: Už si sa úspešne odhlásil/a.
+      signed_in: Prihlásil/a si sa úspešne.
+      signed_out: Odhlásil/a si sa úspešne.
     unlocks:
       send_instructions: O niekoľko minút obdržíš email s pokynmi, ako nastaviť nové heslo. Prosím, skontroluj ale aj svoju spam zložku, pokiaľ sa ti zdá, že si tento email nedostal/a.
       send_paranoid_instructions: Ak tvoj účet existuje, o niekoľko minút obdržíš email s pokynmi ako si ho odomknúť. Prosím, skontroluj ale aj svoju spam zložku, pokiaľ sa ti zdá, že si tento email nedostal/a.
@@ -77,8 +79,9 @@ sk:
       confirmation_period_expired: musí byť potvrdený do %{period}, prosím požiadaj o nový
       expired: vypŕšal, prosím, vyžiadaj si nový
       not_found: nenájdený
-      not_locked: nebol uzamknutý
+      not_locked: nebol zamknutý
       not_saved:
-        few: "%{resource} nebol uložený kôli %{count} chybám:"
-        one: "%{resource} nebol uložený kôli chybe:"
-        other: "%{resource} nebol uložený kôli %{count} chybám:"
+        few: "%{count} chýb zabránilo uloženiu tohto %{resource}:"
+        many: "%{count} chýb zabránilo uloženiu tohto %{resource}:"
+        one: '1 chyba zabránila uloženiu tohto %{resource}:'
+        other: "%{count} chyby zabránili uloženiu tohto %{resource}:"
diff --git a/config/locales/devise.sl.yml b/config/locales/devise.sl.yml
index 13c48e1991bb87bad12445c69c118f982785a193..7d1e05fdf0f9dd9b48a0dfbb913ba6e5427e7a32 100644
--- a/config/locales/devise.sl.yml
+++ b/config/locales/devise.sl.yml
@@ -12,13 +12,16 @@ sl:
       last_attempt: Pred zaklepom računa imate še en poskus.
       locked: Vaš račun je zaklenjen.
       not_found_in_database: Neveljavno %{authentication_keys} ali geslo.
+      pending: Vaš račun je še vedno pod drobnogledom.
       timeout: Vaša seja je potekla. Če želite nadaljevati, se znova prijavite.
       unauthenticated: Pred nadaljevanjem se morate prijaviti ali vpisati.
       unconfirmed: Pred nadaljevanjem morate potrditi svoj e-poštni naslov.
     mailer:
       confirmation_instructions:
         action: Potrdi e-poštni naslov
+        action_with_app: Potrdi in se vrni v %{app}
         explanation: S tem e-poštnim naslovom ste ustvarili račun na %{host}. Z enim samim klikom ga aktivirate. Če to niste bili vi, prosimo, prezrite to e-poštno sporočilo.
+        explanation_when_pending: S tem e-poštnim naslovom ste zaprosili za povabilo na %{host}. Ko potrdite svoj e-poštni naslov, bomo pregledali vašo prijavo. Do takrat se ne morete prijaviti. Če bo vaša prijava zavrnjena, bodo vaši podatki odstranjeni, zato ne bo potrebno nadaljnje ukrepanje. Če to niste bili vi, prezrite to e-poštno sporočilo.
         extra_html: Preverite tudi <a href="%{terms_path}">pravila vozlišča</a> in <a href="%{policy_path}">naše pogoje storitve</a>.
         subject: 'Mastodon: Navodila za potrditev za %{instance}'
         title: Potrdi e-poštni naslov
@@ -34,3 +37,17 @@ sl:
         title: Geslo je spremenjeno
       reconfirmation_instructions:
         explanation: Potrdite novi naslov, da spremenite svoj e-poštni naslov.
+        extra: Če te spremembe niste sprožili, prezrite to e-poštno sporočilo. E-poštni naslov za račun Mastodon se ne bo spremenil, dokler ne kliknete na zgornjo povezavo.
+        subject: 'Mastodon: Potrdite e-pošto za %{instance}'
+        title: Potrdi e-poštni naslov
+      reset_password_instructions:
+        action: Spremeni geslo
+        explanation: Zahtevali ste novo geslo za svoj račun.
+        extra: Če tega niste zahtevali, prezrite to e-poštno sporočilo. Vaše geslo se ne bo spremenilo, dokler ne kliknete na zgornjo povezavo in ustvarite novega.
+        subject: 'Mastodon: Navodila za ponastavitev gesla'
+        title: Ponastavitev gesla
+      unlock_instructions:
+        subject: 'Mastodon: Odkleni navodila'
+    omniauth_callbacks:
+      failure: Overitev iz %{kind} ni možna zaradi "%{reason}".
+      success: Overitev iz računa %{kind} je bila uspešna.
diff --git a/config/locales/devise.sq.yml b/config/locales/devise.sq.yml
new file mode 100644
index 0000000000000000000000000000000000000000..0380d962e65e9ea85685b95e4a8c229428e34444
--- /dev/null
+++ b/config/locales/devise.sq.yml
@@ -0,0 +1,83 @@
+---
+sq:
+  devise:
+    confirmations:
+      confirmed: Adresa juaj email u ripohua me sukses.
+      send_instructions: Brenda pak minutash, do të merrni një email me udhëzime se si të ripohoni adresën tuaj email. Ju lutemi, kontrolloni dosjen e mesazheve të padëshiruar, nëse nuk e morët këtë email.
+      send_paranoid_instructions: Nëse adresa juaj email gjendet në bazën tonë të të dhënave, brenda pak minutash, do të merrni një email me udhëzime se si të ripohoni adresën tuaj email. Ju lutemi, kontrolloni dosjen e mesazheve të padëshiruar, nëse nuk e morët këtë email.
+    failure:
+      already_authenticated: Jeni tashmë i futur.
+      inactive: Llogaria juaj s’është aktivizuar ende.
+      invalid: "%{authentication_keys} ose fjalëkalim i pavlefshëm."
+      last_attempt: Mund të provoni edhe një herë, përpara se llogaria juaj të kyçet.
+      locked: Llogaria juaj është e kyçur.
+      not_found_in_database: "%{authentication_keys} ose fjalëkalim i pavlefshëm."
+      timeout: Sesioni juaj ka skaduar. Ju lutemi, që të vazhdohet, ribëni hyrjen.
+      unauthenticated: Përpara se të vazhdohet më tej, lypset të bëni hyrjen ose të regjistroheni.
+      unconfirmed: Përpara se të vazhdohet, lypset të ripohoni adresën tuaj email.
+    mailer:
+      confirmation_instructions:
+        action: Verifikoni adresë email
+        action_with_app: Ripohojeni dhe kthehuni te %{app}
+        explanation: Keni krijuar një llogari te %{host}, me këtë adresë email. Jeni një klikim larg aktivizimit të saj. Nëse s’jeni ju, shpërfilleni këtë email.
+        extra_html: Ju lutemi, shihni edhe <a href="%{terms_path}">rregullat e shërbyesit</a> dhe <a href="%{policy_path}">kushtet tona të shërbimit</a>.
+        subject: 'Mastodon: Udhëzime ripohimi për %{instance}'
+        title: Verifikoni adresë email
+      email_changed:
+        explanation: 'Adresa email për llogarinë tuaj po ndryshohet në:'
+        extra: Nëse email-in tuaj nuk e ndryshuat ju, gjasat janë që dikush tjetër ka arritur të hyjë në llogarinë tuaj. Ju lutemi, ndryshoni menjëherë fjalëkalimin tuaj ose lidhuni me përgjegjësin e shërbyesit, nëse jeni kyçur jashtë llogarisë tuaj.
+        subject: 'Mastodon: Email-i u ndryshua'
+        title: Adresë email e re
+      password_change:
+        explanation: Fjalëkalimi për llogarinë tuaj u ndryshua.
+        extra: Nëse fjalëkalimin tuaj nuk e ndryshuat ju, gjasat janë që dikush tjetër ka arritur të hyjë në llogarinë tuaj. Ju lutemi, ndryshoni menjëherë fjalëkalimin tuaj ose lidhuni me përgjegjësin e shërbyesit, nëse jeni kyçur jashtë llogarisë tuaj.
+        subject: 'Mastodon: Fjalëkalimi u ndryshua'
+        title: Fjalëkalimi u ndryshua
+      reconfirmation_instructions:
+        explanation: Që të ndryshohet email-i juaj, ripohoni adresën e re.
+        extra: Nëse ky ndryshim s’qe filluar prej jush, ju lutemi, shpërfilleni këtë email. Adresa email për llogarinë Mastodon s’do të ndryshojë, para se të hyni në lidhjen më sipër.
+        subject: 'Mastodon: Ripohoni email-in për %{instance}'
+        title: Verifikoni adresë email
+      reset_password_instructions:
+        action: Ndryshoni fjalëkalimin
+        explanation: Kërkuat një fjalëkalim të ri për këtë llogari.
+        extra: Nëse këtë s’e kërkuat ju, ju lutemi, shpërfilleni këtë email. Fjalëkalimi juaj s’do të ndryshohet pa hyrë në lidhjen më sipër dhe krijimin e një të riu.
+        subject: 'Mastodon: Udhëzime ricaktimi fjalëkalimi'
+        title: Ricaktim fjalëkalimi
+      unlock_instructions:
+        subject: 'Mastodon: Udhëzime shkyçjeje'
+    omniauth_callbacks:
+      failure: S’u bë dot mirëfilltësimi juaj nga %{kind}, sepse "%{reason}".
+      success: Mirëfilltësimi nga llogaria %{kind} u bë me sukses.
+    passwords:
+      no_token: S’mund të hyni në këtë faqe paardhur nga një email ricaktimi fjalëkalimi. Nëse vini nga një email ricaktimi fjalëkalimi, ju lutemi, sigurohuni se përdorët URL-në e plotë dhënë për ju.
+      send_instructions: Nëse adresa juaj email gjendet në bazën tonë të të dhënave, brenda pak minutash, te adresa juaj email do të merrni një lidhje rimarrjeje fjalëkalimi. Ju lutemi, kontrolloni dosjen e mesazheve të padëshiruar, nëse nuk e morët këtë email.
+      send_paranoid_instructions: Nëse adresa juaj email gjendet në bazën tonë të të dhënave, brenda pak minutash, te adresa juaj email do të merrni një lidhje rimarrjeje fjalëkalimi. Ju lutemi, kontrolloni dosjen e mesazheve të padëshiruar, nëse nuk e morët këtë email.
+      updated: Fjalëkalimi juaj u ndryshua me sukses. Tani jeni i futur.
+      updated_not_active: Fjalëkalimi juaj u ndryshua me sukses.
+    registrations:
+      destroyed: Shëndet! Llogaria juaj u fshi me sukses. Shpresojmë t’ju rishohim së shpejti.
+      signed_up: Mirë se vini! U regjistruat me sukses.
+      signed_up_but_inactive: U regjistruat me sukses. Megjithatë, s’u bë dot hyrja juaj, ngaqë llogaria juaj s’është aktivizuar ende.
+      signed_up_but_locked: U regjistruat me sukses. Megjithatë, s’u bë dot hyrja juaj, ngaqë llogaria juaj është kyçur.
+      signed_up_but_unconfirmed: Te adresa juaj email u dërgua një mesazh me një lidhje ripohimi. Ju lutemi, që të aktivizoni llogarinë tuaj, ndiqni lidhjen. Ju lutemi, kontrolloni dosjen e mesazheve të padëshiruar, nëse nuk e morët këtë email.
+      update_needs_confirmation: E përditësuat me sukses llogarinë tuaj, por na duhet të verifikojmë adresën tuaj të re email. Ju lutemi, që të ripohoni adresën tuaj të re email, kontrolloni email-in tuaj dhe ndiqni lidhjen. Ju lutemi, kontrolloni dosjen e mesazheve të padëshiruar, nëse nuk e morët këtë email.
+      updated: Llogaria juaj u përditësua me sukses.
+    sessions:
+      already_signed_out: Dolët me sukses.
+      signed_in: Hytë me sukses.
+      signed_out: Dolët me sukses.
+    unlocks:
+      send_instructions: Brenda pak minutash, do të merrni një email me udhëzime se si të shkyçni llogarinë tuaj. Ju lutemi, kontrolloni dosjen e mesazheve të padëshiruar, nëse nuk e morët këtë email.
+      send_paranoid_instructions: Nëse llogaria juaj ekziston, brenda pak minutash, do të merrni një email me udhëzime se si të shkyçni llogarinë tuaj. Ju lutemi, kontrolloni dosjen e mesazheve të padëshiruar, nëse nuk e morët këtë email.
+      unlocked: Llogaria juaj u shkyç me sukses. Ju lutemi, që të vazhdohet, bëni hyrjen.
+  errors:
+    messages:
+      already_confirmed: qe e ripohuar tashmë, ju lutemi, provoni të bëni hyrjen
+      confirmation_period_expired: lyp të ripohohet brenda %{period}, ju lutemi, kërkoni një të ri
+      expired: ka skaduar, ju lutemi, kërkoni një të ri
+      not_found: s’u gjet
+      not_locked: s’qe kyçur
+      not_saved:
+        one: 'Ruajtjen e këtij %{resource} e pengoi 1 gabim:'
+        other: 'Ruajtjen e këtij %{resource} e penguan %{count} gabime:'
diff --git a/config/locales/devise.sr-Latn.yml b/config/locales/devise.sr-Latn.yml
index 21ddbd7267391d2f3d95861def7660b62691676e..c2c5f7c76fc9635cdc20f3e77a9c11219d305db5 100644
--- a/config/locales/devise.sr-Latn.yml
+++ b/config/locales/devise.sr-Latn.yml
@@ -58,6 +58,5 @@ sr-Latn:
       not_locked: nije zaključan
       not_saved:
         few: "%{count} greške sprečavaju %{resource}a:"
-        many: "%{count} grešaka sprečavaju %{resource}a:"
         one: '1 greška sprečava %{resource}a:'
         other: "%{count} grešaka sprečavaju %{resource}a:"
diff --git a/config/locales/devise.sr.yml b/config/locales/devise.sr.yml
index 475d1e2a54c842168cc768cada8dc53be1388de0..baffc270184fb2e6661a8f9b7e9c3cf97c900608 100644
--- a/config/locales/devise.sr.yml
+++ b/config/locales/devise.sr.yml
@@ -80,6 +80,5 @@ sr:
       not_locked: није закључан
       not_saved:
         few: "%{count} грешке спречавају %{resource}a:"
-        many: "%{count} грешака спречавају %{resource}a:"
         one: '1 грешка спречава %{resource}а:'
         other: "%{count} грешака спречавају %{resource}a:"
diff --git a/config/locales/devise.ta.yml b/config/locales/devise.ta.yml
new file mode 100644
index 0000000000000000000000000000000000000000..4320953ce2ab23ded9cc319b3002dfc1bc13903a
--- /dev/null
+++ b/config/locales/devise.ta.yml
@@ -0,0 +1 @@
+ta:
diff --git a/config/locales/devise.te.yml b/config/locales/devise.te.yml
new file mode 100644
index 0000000000000000000000000000000000000000..34c54f18f624c6d89026a04bd92ebc0df9c63e48
--- /dev/null
+++ b/config/locales/devise.te.yml
@@ -0,0 +1 @@
+te:
diff --git a/config/locales/devise.th.yml b/config/locales/devise.th.yml
index fec944310c0eee6e35c61733c3044be60e8ccf89..8a9a65465ed5d6e9853b561ba376fb0c11626ba1 100644
--- a/config/locales/devise.th.yml
+++ b/config/locales/devise.th.yml
@@ -2,60 +2,37 @@
 th:
   devise:
     confirmations:
-      confirmed: Your email address has been successfully confirmed.
+      confirmed: ยืนยันที่อยู่อีเมลของคุณสำเร็จ
       send_instructions: You will receive an email with instructions for how to confirm your email address in a few minutes.
       send_paranoid_instructions: If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes.
     failure:
-      already_authenticated: You are already signed in.
-      inactive: Your account is not activated yet.
-      invalid: Invalid %{authentication_keys} or password.
-      last_attempt: You have one more attempt before your account is locked.
-      locked: Your account is locked.
-      not_found_in_database: Invalid %{authentication_keys} or password.
-      timeout: Your session expired. Please sign in again to continue.
-      unauthenticated: You need to sign in or sign up before continuing.
-      unconfirmed: You have to confirm your email address before continuing.
+      already_authenticated: คุณได้ลงชื่อเข้าอยู่แล้ว
+      inactive: ยังไม่ได้เปิดใช้งานบัญชีของคุณ
+      invalid: "%{authentication_keys} หรือรหัสผ่านไม่ถูกต้อง"
+      not_found_in_database: "%{authentication_keys} หรือรหัสผ่านไม่ถูกต้อง"
+      timeout: เซสชันของคุณหมดอายุแล้ว โปรดลงชื่อเข้าอีกครั้งเพื่อดำเนินการต่อ
     mailer:
-      confirmation_instructions:
-        subject: 'Mastodon: Confirmation instructions for %{instance}'
+      email_changed:
+        title: ที่อยู่อีเมลใหม่
       password_change:
-        subject: 'Mastodon: Password changed'
+        subject: 'Mastodon: เปลี่ยนรหัสผ่านแล้ว'
+        title: เปลี่ยนรหัสผ่านแล้ว
       reset_password_instructions:
-        subject: 'Mastodon: Reset password instructions'
-      unlock_instructions:
-        subject: 'Mastodon: Unlock instructions'
-    omniauth_callbacks:
-      failure: Could not authenticate you from %{kind} because "%{reason}".
-      success: Successfully authenticated from %{kind} account.
+        action: เปลี่ยนรหัสผ่าน
     passwords:
-      no_token: You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided.
       send_instructions: If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes.
       send_paranoid_instructions: If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes.
-      updated: Your password has been changed successfully. You are now signed in.
-      updated_not_active: Your password has been changed successfully.
     registrations:
-      destroyed: Bye! Your account has been successfully cancelled. We hope to see you again soon.
-      signed_up: Welcome! You have signed up successfully.
-      signed_up_but_inactive: You have signed up successfully. However, we could not sign you in because your account is not yet activated.
-      signed_up_but_locked: You have signed up successfully. However, we could not sign you in because your account is locked.
       signed_up_but_unconfirmed: A message with a confirmation link has been sent to your email address. Please follow the link to activate your account.
       update_needs_confirmation: You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirm link to confirm your new email address.
-      updated: Your account has been updated successfully.
     sessions:
-      already_signed_out: Signed out successfully.
-      signed_in: Signed in successfully.
-      signed_out: Signed out successfully.
+      already_signed_out: ลงชื่อออกสำเร็จ
+      signed_in: ลงชื่อเข้าสำเร็จ
+      signed_out: ลงชื่อออกสำเร็จ
     unlocks:
       send_instructions: You will receive an email with instructions for how to unlock your account in a few minutes.
       send_paranoid_instructions: If your account exists, you will receive an email with instructions for how to unlock it in a few minutes.
-      unlocked: Your account has been unlocked successfully. Please sign in to continue.
   errors:
     messages:
-      already_confirmed: was already confirmed, please try signing in
-      confirmation_period_expired: needs to be confirmed within %{period}, please request a new one
-      expired: has expired, please request a new one
-      not_found: not found
-      not_locked: was not locked
-      not_saved:
-        one: '1 error prohibited this %{resource} from being saved:'
-        other: "%{count} errors prohibited this %{resource} from being saved:"
+      not_found: ไม่พบ
+      not_locked: ไม่ได้ล็อคอยู่
diff --git a/config/locales/devise.tr.yml b/config/locales/devise.tr.yml
new file mode 100644
index 0000000000000000000000000000000000000000..0a504dd67635900ff497a05acbeaef792c885d93
--- /dev/null
+++ b/config/locales/devise.tr.yml
@@ -0,0 +1,15 @@
+---
+tr:
+  devise:
+    confirmations:
+      confirmed: E-posta adresiniz başarıyla onaylandı.
+      send_instructions: Birkaç dakika içinde e-posta adresinizi nasıl onaylayacağınıza ilişkin talimatları içeren bir e-posta alacaksınız. Bu e-postayı almadıysanız, lütfen spam klasörünüzü kontrol edin.
+      send_paranoid_instructions: E-posta adresiniz veritabanımızda varsa, e-posta adresinizi birkaç dakika içinde nasıl doğrulayacağınıza ilişkin talimatları içeren bir e-posta alacaksınız. Bu e-postayı almadıysanız, lütfen spam klasörünüzü kontrol edin.
+    failure:
+      already_authenticated: Zaten oturum açtınız.
+      inactive: Hesabınız henüz etkinleştirilmedi.
+      last_attempt: Hesabınız kilitlenmeden önce bir kez daha denemeniz gerekir.
+      locked: Hesabınız kilitli.
+    mailer:
+      confirmation_instructions:
+        action: E-posta adresinizi doğrulayın
diff --git a/config/locales/devise.zh-CN.yml b/config/locales/devise.zh-CN.yml
index 4ee021fcc3c2df93be0e0df2aff0545598b13e5a..22fa130f60d49d54179b4b04abe36c399344eb3f 100644
--- a/config/locales/devise.zh-CN.yml
+++ b/config/locales/devise.zh-CN.yml
@@ -12,24 +12,27 @@ zh-CN:
       last_attempt: 你还有最后一次尝试机会,再次失败你的帐户将被锁定。
       locked: 你的帐户已被锁定。
       not_found_in_database: "%{authentication_keys}或密码错误。"
+      pending: 你的账户仍在审核中。
       timeout: 你已登录超时,请重新登录。
       unauthenticated: 继续操作前请注册或者登录。
       unconfirmed: 继续操作前请先确认你的帐户。
     mailer:
       confirmation_instructions:
         action: 验证电子邮件地址
+        action_with_app: 确认并返回%{app}
         explanation: 你在 %{host} 上使用这个电子邮件地址创建了一个帐户。只需点击下面的链接,即可完成激活。如果你并没有创建过帐户,请忽略此邮件。
-        extra_html: 请记得阅读<a href="%{terms_path}">本实例的相关规定</a>和<a href="%{policy_path}">我们的使用条款</a>。
+        explanation_when_pending: 你用这个电子邮件申请了在 %{host} 注册。在确认电子邮件地址之后,我们会审核你的申请。在此之前,你不能登录。如果你的申请被驳回,你的数据会被移除,因此你无需再采取任何行动。如果申请人不是你,请忽略这封邮件。
+        extra_html: 请记得阅读<a href="%{terms_path}">本服务器的相关规定</a>和<a href="%{policy_path}">我们的使用条款</a>。
         subject: Mastodon:确认 %{instance} 帐户信息
         title: 验证电子邮件地址
       email_changed:
         explanation: 你的帐户的电子邮件地址即将变更为:
-        extra: 如果你并没有请求更改你的电子邮件地址,则他人很有可能已经入侵你的帐户。请立即更改你的密码;如果你已经无法访问你的帐户,请联系实例的管理员请求协助。
+        extra: 如果你并没有请求更改你的电子邮件地址,则他人很有可能已经入侵你的帐户。请立即更改你的密码;如果你已经无法访问你的帐户,请联系服务器管理员请求协助。
         subject: Mastodon:电子邮件地址已被更改
         title: 新电子邮件地址
       password_change:
         explanation: 你的帐户的密码已被更改。
-        extra: 如果你并没有请求更改你的密码,则他人很有可能已经入侵你的帐户。请立即更改你的密码;如果你已经无法访问你的帐户,请联系实例的管理员请求协助。
+        extra: 如果你并没有请求更改你的密码,则他人很有可能已经入侵你的帐户。请立即更改你的密码;如果你已经无法访问你的帐户,请联系服务器的管理员请求协助。
         subject: Mastodon:密码已被更改
         title: 密码已被重置
       reconfirmation_instructions:
@@ -59,7 +62,8 @@ zh-CN:
       signed_up: 欢迎!你已注册成功。
       signed_up_but_inactive: 你已注册,但尚未激活帐户。
       signed_up_but_locked: 你已注册,但帐户被锁定了。
-      signed_up_but_unconfirmed: 一封带有确认链接的邮件已经发送至你的邮箱,请点击邮件中的链接以激活你的帐户。如果没有,请检查你的垃圾邮箱。
+      signed_up_but_pending: 一封带有确认链接的邮件已经发送到了您的邮箱。 在您点击确认链接后,我们将会审核您的申请。审核通过后,我们将会通知您。
+      signed_up_but_unconfirmed: 一封带有确认链接的邮件已经发送至你的邮箱,请点击邮件中的链接以激活你的帐户。如果没有,请检查你的垃圾邮件。
       update_needs_confirmation: 信息更新成功,但我们需要验证你的新电子邮件地址,请点击邮件中的链接以确认。如果没有,请检查你的垃圾邮箱。
       updated: 帐户资料更新成功。
     sessions:
diff --git a/config/locales/devise.zh-HK.yml b/config/locales/devise.zh-HK.yml
index b7d88ef941abe06b2ce66068683cb020359d1eda..ceae8b238a50890cc0c32392fb101d89befdf232 100644
--- a/config/locales/devise.zh-HK.yml
+++ b/config/locales/devise.zh-HK.yml
@@ -78,5 +78,4 @@ zh-HK:
       not_found: 找不到
       not_locked: 並未被鎖定
       not_saved:
-        one: 1 個錯誤令 %{resource} 無法被儲存︰
         other: "%{count} 個錯誤令 %{resource} 無法被儲存︰"
diff --git a/config/locales/devise.zh-TW.yml b/config/locales/devise.zh-TW.yml
index abbe45942301c78635457a6d3d7bb0456547309a..cb989630eeb30aa1ad368ddb575f3e06503af050 100644
--- a/config/locales/devise.zh-TW.yml
+++ b/config/locales/devise.zh-TW.yml
@@ -2,81 +2,84 @@
 zh-TW:
   devise:
     confirmations:
-      confirmed: 您的 E-mail 驗證成功。
-      send_instructions: 您將會在幾分鐘內收到驗證信。
-      send_paranoid_instructions: 如果您的 E-mail 存在於我們的資料庫,將會在幾分鐘內收到驗證信。
+      confirmed: 您的電子信箱位址已確認成功。
+      send_instructions: 幾分鐘後您將收到確認信件。若未收到此信件,請檢查垃圾郵件資料夾。
+      send_paranoid_instructions: 如果您的電子信箱存在於我們的資料庫,將會在幾分鐘內收到確認信。若未收到請檢查垃圾郵件資料夾。
     failure:
-      already_authenticated: 您已經登入了。
+      already_authenticated: 您已登入。
       inactive: 您的帳戶尚未啟用。
-      invalid: 不正確的 %{authentication_keys} 或密碼。
-      last_attempt: 您剩下最後一次嘗試機會,如失敗將會進行帳戶鎖定。如有問題請洽詢站點管理員。
+      invalid: 無效的 %{authentication_keys} 或密碼。
+      last_attempt: 在帳號遭封鎖前您還有最後一次嘗試機會。
       locked: 您的帳戶已被鎖定。
-      not_found_in_database: 不正確的 %{authentication_keys} 或密碼。
-      timeout: 您的登入階段已經逾期,請重新登入以繼續使用。
-      unauthenticated: 您必須先登入或註冊,以繼續使用。
-      unconfirmed: 您必須先完成 E-mail 驗證,以繼續使用。
+      not_found_in_database: 無效的 %{authentication_keys} 或密碼。
+      pending: 您的帳戶仍在審核中。
+      timeout: 登入階段逾時。請重新登入以繼續。
+      unauthenticated: 您必須先登入或註冊以繼續使用。
+      unconfirmed: 您必須先確認電子信箱才能繼續使用。
     mailer:
       confirmation_instructions:
-        action: 驗證 E-mail 地址
-        explanation: 您已經在 %{host} 上以此 E-mail 地址建立了一個帳號。您距離啟用它只剩一次點擊之遙了。如果這不是你,請忽略此 E-mail 。
-        extra_html: 同時也請看看<a href="%{terms_path}">該站點的規則</a>與<a href="%{policy_path}">我們的服務條款</a>。
-        subject: 'Mastodon: 信箱驗證 %{instance}'
-        title: 驗證 E-mail 地址
+        action: 驗證電子信箱位址
+        action_with_app: 確認並返回 %{app}
+        explanation: 您已經在 %{host} 上以此電子信箱位址建立了一支帳戶。您距離啟用它只剩一點之遙了。若這不是您,請忽略此信件。
+        explanation_when_pending: 您使用此電子信箱位址申請了 %{host} 的邀請。當您確認電子信箱後我們將審核您的申請,而直到核准前您都無法登入。當您的申請遭拒絕,您的資料將被移除而不必做後續動作。如果這不是您,請忽略此信件。
+        extra_html: 同時也請看看<a href="%{terms_path}">該伺服器的規則</a>與<a href="%{policy_path}">服務條款</a>。
+        subject: Mastodon:%{instance} 確認說明
+        title: 驗證電子信箱位址
       email_changed:
-        explanation: 您帳號的 E-mail 地址被變更為:
-        extra: 如果您並未變更您的 E-mail ,那麼很有可能是某人取得了你帳號的存取權限。請立刻變更您的密碼,或是若您的帳號已被鎖定,請聯絡站點的管理員。
-        subject: Mastodon  E-mail 變更
-        title: 新 E-mail 地址
+        explanation: 您帳戶的電子信箱位址將變更為:
+        extra: 若您未變更電子信箱,那麼很有可能是某人取得了你帳戶的存取權限。請立刻變更密碼,或當帳戶被鎖定時,請聯絡伺服器的管理員。
+        subject: Mastodon:已變更電子信箱
+        title: 新電子信箱位址
       password_change:
-        explanation: 您帳號的密碼已變更。
-        extra: 如果您並未變更您的密碼,那麼很有可能是某人取得了您帳號的存取權限。請立刻變更您的密碼,或是若您的帳號已被鎖定,請聯絡站點的管理員。
-        subject: 'Mastodon: 更改密碼'
+        explanation: 您帳戶的密碼已變更。
+        extra: 如果您未變更密碼,那麼很有可能是某人取得了帳戶的存取權限。請立刻變更密碼,或若帳戶被鎖定時,請聯絡伺服器的管理員。
+        subject: Mastodon:已變更密碼
         title: 密碼已變更
       reconfirmation_instructions:
-        explanation: 確認新的 E-mail 地址以變更您的 E-mail 。
-        extra: 若此次變更不是由您開啟的,請忽略這個 E-mail 。Mastodon 帳號的 E-mail 地址在您存取上面的連結前不會變更。
-        subject: Mastodon:%{instance} 的確認 E-mail
-        title: 驗證 E-mail 地址
+        explanation: 請確認新的電子信箱位址以變更。
+        extra: 若此次變更不是由您開啟的,請忽略此信件。Mastodon 帳戶的電子信箱位址在您存取上面的連結前不會變更。
+        subject: Mastodon:確認 %{instance} 的電子信箱位址
+        title: 驗證電子信箱位址
       reset_password_instructions:
         action: 變更密碼
-        explanation: 您為您的帳號請求了一個新密碼。
-        extra: 若您並未請求這個,請忽略此 E-mail 。您的密碼在您存取上面的連結並建立一個新的之前不會變更。
-        subject: 'Mastodon: 重設密碼'
+        explanation: 您已請求設定帳號的新密碼。
+        extra: 若您並未請求,請忽略此信件。您的密碼在存取上方連結並建立新連結前不會變更。
+        subject: Mastodon:重設密碼指引
         title: 重設密碼
       unlock_instructions:
-        subject: 'Mastodon: 帳號解鎖'
+        subject: Mastodon:帳戶解鎖指引
     omniauth_callbacks:
-      failure: 無法以 %{kind} 登入您的帳號,原因是︰「%{reason}」。
-      success: 成功以 %{kind} 登入您的帳號。
+      failure: 無法透過 %{kind} 認證是否為您,因為「%{reason}」。
+      success: 成功透過 %{kind} 登入帳戶。
     passwords:
-      no_token: 您請使用重設密碼信中的網址,並確認您用了完整的網址。
-      send_instructions: 您將在幾分鐘內收到重設密碼信。
-      send_paranoid_instructions: 如果您的電子信箱已經存在於我們的資料庫,您將會在幾分鐘內收到重設密碼信。
-      updated: 您的密碼已經更新,您現在正登入本站。
-      updated_not_active: 您的密碼已經更新。
+      no_token: 您必須透過密碼重設信件才能存取此頁面。若確實如此,請確定輸入的網址是完整的。
+      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: 您的帳號已成功更新。
+      destroyed: 再見!您的帳戶已成功取消,期待再相逢。
+      signed_up: 歡迎!您已成功註冊。
+      signed_up_but_inactive: 您已註冊成功,但由於您的帳戶尚未啟用,我們暫時無法讓您登入。
+      signed_up_but_locked: 您已註冊成功,但由於您的帳戶已被鎖定,我們無法讓您登入。
+      signed_up_but_pending: 包含確認連結的訊息已寄到您的電子信箱。按下此連結後我們將審核您的申請。核准後將通知您。
+      signed_up_but_unconfirmed: 包含確認連結的訊息已寄到您的電子信箱。請前往連結以啟用帳號。若未收到請檢查垃圾郵件資料夾。
+      update_needs_confirmation: 已更新您的帳號,但仍需驗證您的新信箱。請檢查電子信箱並前往確認連結來確認新信箱位址。若未收到請檢查垃圾郵件資料夾。
+      updated: 您的帳戶已成功更新。
     sessions:
-      already_signed_out: 成功登出。
-      signed_in: 成功登入。
-      signed_out: 成功登出。
+      already_signed_out: 已成功登出。
+      signed_in: 已成功登入。
+      signed_out: 已成功登出。
     unlocks:
-      send_instructions: 您將在幾分鐘內收到帳號解鎖信。
-      send_paranoid_instructions: 如果您的電子信箱已經存在於我們的資料庫,您將在幾分鐘內收到帳號解鎖信。
-      unlocked: 已解鎖您的帳號,請登入以繼續。
+      send_instructions: 幾分鐘後您將收到解鎖帳號的指引信件。若未收到請檢查垃圾郵件資料夾。
+      send_paranoid_instructions: 若此帳號存在,您將在幾分鐘後收到解鎖指引信件。若未收到請檢查垃圾郵件資料夾。
+      unlocked: 已解鎖您的帳戶,請登入繼續。
   errors:
     messages:
       already_confirmed: 已經確認,請嘗試登入
       confirmation_period_expired: 需要在 %{period} 內完成驗證。請重新申請
-      expired: 已經過期,請重新申請
+      expired: 已經過期,請重新請求
       not_found: 找不到
       not_locked: 並未被鎖定
       not_saved:
-        one: 有 1 個錯誤讓此 %{resource} 無法儲存:
-        other: 有 %{count} 個錯誤讓此 %{resource} 無法儲存:
+        other: 因 %{count} 錯誤導致 %{resource} 無法儲存:
diff --git a/config/locales/doorkeeper.ar.yml b/config/locales/doorkeeper.ar.yml
index 200d340a88c3e137fbf95faaa00f0aa08c5a9794..6f9e38f8b3c6e3c0a2b75ee0963bbcc1217f3c9c 100644
--- a/config/locales/doorkeeper.ar.yml
+++ b/config/locales/doorkeeper.ar.yml
@@ -29,7 +29,7 @@ ar:
       edit:
         title: تعديل التطبيق
       form:
-        error: عفوا ! تحقق من خُلوّ الاستمارة من الأخطاء من فضلك
+        error: عفوا! تحقق من خُلوّ الاستمارة من الأخطاء من فضلك
       help:
         native_redirect_uri: إستخدم %{native_redirect_uri} للاختبار و التجريب محليا
         redirect_uri: إستخدم خطا واحدا لكل رابط
@@ -46,12 +46,12 @@ ar:
       new:
         title: تطبيق جديد
       show:
-        actions: Actions
+        actions: الإجراءات
         application_id: معرف التطبيق
         callback_urls: روابط رد النداء
         scopes: المجالات
         secret: السر
-        title: 'تطبيق : %{name}'
+        title: 'تطبيق: %{name}'
     authorizations:
       buttons:
         authorize: ترخيص
@@ -72,7 +72,7 @@ ar:
       index:
         application: التطبيق
         created_at: صُرّح له في
-        date_format: "%d-%m-%Y %H:%M:%S"
+        date_format: "%Y-%m-%d %H:%M:%S"
         scopes: المجالات
         title: تطبيقاتك المرخص لها
     errors:
@@ -85,11 +85,11 @@ ar:
         invalid_resource_owner: إنّ المُعرِّفات التي قدّمها صاحب المورِد غير صحيحة أو أنه لا وجود لصاحب المورِد
         invalid_scope: المجال المطلوب غير صحيح أو مجهول أو مُعبَّر عنه بشكل خاطئ.
         invalid_token:
-          expired: إنتهت فترة صلاحيته رمز المصادقة
+          expired: انتهت فترة صلاحيته رمز المصادقة
           revoked: تم إبطال رمز المصادقة
           unknown: رمز المصادقة غير صالح
         resource_owner_authenticator_not_configured: لقد أخفقت عملية البحث عن صاحب المَورِد لغياب الضبط في Doorkeeper.configure.resource_owner_authenticator.
-        server_error: لقد صادفَ خادوم التصريحات ضروفا غير مواتية، الأمر الذي مَنَعه مِن مواصلة دراسة الطلب.
+        server_error: لقد صادفَ خادوم التصريحات ظروفا غير مواتية، الأمر الذي مَنَعه مِن مواصلة دراسة الطلب.
         temporarily_unavailable: تعذر على خادم التفويض معالجة الطلب و ذلك بسبب زيادة مؤقتة في التحميل أو عملية صيانة مبرمجة على الخادم.
         unauthorized_client: لا يصرح للعميل بتنفيذ هذا الطلب باستخدام هذه الطريقة.
         unsupported_grant_type: هذا النوع من منح التصريح غير معتمد في خادم الترخيص.
diff --git a/config/locales/doorkeeper.bg.yml b/config/locales/doorkeeper.bg.yml
index 24de4aee0a51b468bea1b024f0b5d4ce0cdb3570..f36187e1238b725cfc36c57a0501ffb699c77a83 100644
--- a/config/locales/doorkeeper.bg.yml
+++ b/config/locales/doorkeeper.bg.yml
@@ -56,8 +56,6 @@ bg:
         able_to: Ще е възможно
         prompt: Приложението %{client_name} заявява достъп до твоя акаунт
         title: Изисква се упълномощаване
-      show:
-        title: Copy this authorization code and paste it to the application.
     authorized_applications:
       buttons:
         revoke: Отмяна
@@ -66,7 +64,6 @@ bg:
       index:
         application: Приложение
         created_at: Създадено на
-        date_format: "%Y-%m-%d %H:%M:%S"
         scopes: Диапазони
         title: Твоите упълномощени приложения
     errors:
diff --git a/config/locales/doorkeeper.bn.yml b/config/locales/doorkeeper.bn.yml
new file mode 100644
index 0000000000000000000000000000000000000000..152c698290639f4688cdb5184962daafc705fc52
--- /dev/null
+++ b/config/locales/doorkeeper.bn.yml
@@ -0,0 +1 @@
+bn:
diff --git a/config/locales/doorkeeper.ca.yml b/config/locales/doorkeeper.ca.yml
index 56686e3e5b6c199b3d51b69c6a349e7a9c641d80..dde70f47a393b8e71aad4738abb28b61a0f91b35 100644
--- a/config/locales/doorkeeper.ca.yml
+++ b/config/locales/doorkeeper.ca.yml
@@ -29,7 +29,7 @@ ca:
       edit:
         title: Edita l'aplicació
       form:
-        error: Ep! Comprova el formulari
+        error: Ep! Comprova el formulari per a possibles errors
       help:
         native_redirect_uri: Utilitza %{native_redirect_uri} per a proves locals
         redirect_uri: Utilitza una línia per URI
@@ -77,9 +77,9 @@ ca:
         title: Les teves aplicacions autoritzades
     errors:
       messages:
-        access_denied: El propietari del recurs o servidor de autorizació ha denegat la petició.
+        access_denied: El propietari del recurs o servidor d'autorizació ha denegat la petició.
         credential_flow_not_configured: Les credencials de contrasenya del propietari del recurs han fallat degut a que Doorkeeper.configure.resource_owner_from_credentials està sense configurar.
-        invalid_client: La autentificació del client falló perquè és un client desconegut o no està inclòs l'autentificació del client o el mètode d'autenticació no està confirmat.
+        invalid_client: La autentificació del client ha fallat perquè és un client desconegut o no està inclòs l'autentificació del client o el mètode d'autenticació no està confirmat.
         invalid_grant: La concessió d'autorizació oferida és invàlida, ha vençut, s'ha revocat, no coincideix amb l'URI de redirecció utilizada en la petició d'autorizació, o fou emesa per a un altre client.
         invalid_redirect_uri: L'URI de redirecció inclòs no és vàlid.
         invalid_request: En la petició manca un paràmetre necessari o inclou un valor de paràmetre no suportat o te un altre tipus de format incorrecte.
@@ -114,7 +114,35 @@ ca:
       application:
         title: OAuth autorització requerida
     scopes:
+      admin:read: llegir totes les dades en el servidor
+      admin:read:accounts: llegir l'informació sensible de tots els comptes
+      admin:read:reports: llegir l'informació sensible de tots els informes i comptes reportats
+      admin:write: modificar totes les dades en el servidor
+      admin:write:accounts: fer l'acció de moderació en els comptes
+      admin:write:reports: fer l'acció de moderació en els informes
       follow: seguir, blocar, desblocar i deixar de seguir comptes
       push: rebre notificacions push del teu compte
       read: llegir les dades del teu compte
+      read:accounts: veure informació dels comptes
+      read:blocks: veure els teus bloqueijos
+      read:favourites: veure els teus favorits
+      read:filters: veure els teus filtres
+      read:follows: veure els teus seguiments
+      read:lists: veure les teves llistes
+      read:mutes: veure els teus silenciats
+      read:notifications: veure les teves notificacions
+      read:reports: veure els teus informes
+      read:search: cerca en nom teu
+      read:statuses: veure tots els toots
       write: publicar en el teu nom
+      write:accounts: modifica el teu perfil
+      write:blocks: bloqueja comptes i dominis
+      write:favourites: afavoreix toots
+      write:filters: crear filtres
+      write:follows: seguir usuaris
+      write:lists: crear llistes
+      write:media: pujar fitxers multimèdia
+      write:mutes: silencia usuaris i converses
+      write:notifications: esborra les teves notificacions
+      write:reports: informe d’altres persones
+      write:statuses: publicar toots
diff --git a/config/locales/doorkeeper.co.yml b/config/locales/doorkeeper.co.yml
index 542ad7c5747030f656a0b4b085144d9fd9a86c0c..d45041a4e1bcadc688a3a21b72ce0f4a229bd38c 100644
--- a/config/locales/doorkeeper.co.yml
+++ b/config/locales/doorkeeper.co.yml
@@ -114,6 +114,12 @@ co:
       application:
         title: Auturizazione OAuth riquestata
     scopes:
+      admin:read: leghje tutti i dati nant'à u servore
+      admin:read:accounts: leghje i cuntinuti sensibili di tutti i conti
+      admin:read:reports: leghje i cuntinuti sensibili di tutti i rapporti è conti signalati
+      admin:write: mudificà tutti i dati nant'à u servore
+      admin:write:accounts: realizà azzione di muderazione nant'à i conti
+      admin:write:reports: realizà azzione di muderazione nant'à i rapporti
       follow: Mudificà rilazione trà i conti
       push: Riceve e vostre nutificazione push
       read: leghje tutte l’infurmazioni di u vostru contu
diff --git a/config/locales/doorkeeper.cs.yml b/config/locales/doorkeeper.cs.yml
index b9e9bc034930dc6a0e9a342e0e4527ad01f1407e..cb5cd147c5a88fbc6a3f44addccd7fe13a70e7d1 100644
--- a/config/locales/doorkeeper.cs.yml
+++ b/config/locales/doorkeeper.cs.yml
@@ -31,8 +31,8 @@ cs:
       form:
         error: A jéje! Zkontrolujte svůj formulář kvůli případným chybám
       help:
-        native_redirect_uri: Použijte %{native_redirect_uri} pro místní testy
-        redirect_uri: Jedno URI na řádek
+        native_redirect_uri: Pro místní testy použijte %{native_redirect_uri}
+        redirect_uri: Jedno URI na každý řádek
         scopes: Oddělujte rozsahy mezerami. Pro použití výchozích rozsahů zanechte prázdné.
       index:
         application: Aplikace
@@ -54,7 +54,7 @@ cs:
         title: 'Aplikace: %{name}'
     authorizations:
       buttons:
-        authorize: Ověřit
+        authorize: Autorizovat
         deny: Zamítnout
       error:
         title: Vyskytla se chyba
@@ -79,7 +79,7 @@ cs:
       messages:
         access_denied: Vlastník zdroje či autorizační server zamítl požadavek.
         credential_flow_not_configured: Proud Resource Owner Password Credentials selhal, protože Doorkeeper.configure.resource_owner_from_credentials nebylo nakonfigurováno.
-        invalid_client: Ověření klienta selhalo kvůli neznámému klientovi, chybějící klientské autentikaci či nepodporované autentikační metodě.
+        invalid_client: Ověření klienta selhalo kvůli neznámému klientovi, chybějící klientské autentizaci či nepodporované autentizační metodě.
         invalid_grant: Poskytnuté oprávnění je neplatné, vypršelé, zamítnuté, neshoduje se s URI přesměrování použitým v požadavku o autorizaci, nebo bylo uděleno jinému klientu.
         invalid_redirect_uri: Přesměrovací URI není platné.
         invalid_request: Požadavku chybí pžadovaný parametr, obsahuje nepodporovanou hodnotu parametru, či je jinak malformovaný.
@@ -114,6 +114,12 @@ cs:
       application:
         title: Je požadována autorizace OAuth
     scopes:
+      admin:read: číst všechna data na serveru
+      admin:read:accounts: číst citlivé informace všech účtů
+      admin:read:reports: číst citlivé informace všech nahlášení a nahlášených účtů
+      admin:write: měnit všechna data na serveru
+      admin:write:accounts: provádět moderátorské akce s účty
+      admin:write:reports: provádět moderátorské akce s nahlášeními
       follow: upravovat vztahy mezi profily
       push: přijímat vaše push oznámení
       read: vidět všechna data vašeho účtu
@@ -123,20 +129,20 @@ cs:
       read:filters: vidět vaše filtry
       read:follows: vidět vaše sledování
       read:lists: vidět vaše seznamy
-      read:mutes: vidět vaše ignorace
+      read:mutes: vidět vaše skrytí
       read:notifications: vidět vaše oznámení
       read:reports: vidět vaše nahlášení
       read:search: vyhledávat za vás
-      read:statuses: vidět všechny příspěvky
+      read:statuses: vidět všechny tooty
       write: měnit všechna data vašeho účtu
       write:accounts: měnit váš profil
       write:blocks: blokovat účty a domény
-      write:favourites: oblibovat si příspěvky
+      write:favourites: oblibovat si tooty
       write:filters: vytvářet filtry
       write:follows: sledovat lidi
       write:lists: vytvářet seznamy
       write:media: nahrávat mediální soubory
-      write:mutes: ignorovat lidi a konverzace
+      write:mutes: skrývat lidi a konverzace
       write:notifications: vymazávat vaše oznámení
       write:reports: nahlašovat jiné uživatele
-      write:statuses: publikovat příspěvky
+      write:statuses: publikovat tooty
diff --git a/config/locales/doorkeeper.cy.yml b/config/locales/doorkeeper.cy.yml
index 87d7a86603123eb017426274c5293bd0b4502160..19798c4d9f1198e52f23f8e5e34718927f46c1a2 100644
--- a/config/locales/doorkeeper.cy.yml
+++ b/config/locales/doorkeeper.cy.yml
@@ -72,7 +72,7 @@ cy:
       index:
         application: Rhaglen
         created_at: Awdurdodedig
-        date_format: "%Y-%m-%d %H:%M:%S"
+        date_format: "%Y-%m-%d% %H:%M:%S"
         scopes: Rhinweddau
         title: Eich rhaglenni awdurdodedig
     errors:
@@ -115,7 +115,7 @@ cy:
         title: Mae awdurdodiad OAuth yn ofynnol
     scopes:
       follow: addasu perthnasau cyfrif
-      push: derbyn eich hysbysiadau PUSH
+      push: derbyn eich hysbysiadau gwthiadwy
       read: darllen holl ddata eich cyfrif
       read:accounts: gweld gwybodaeth y cyfrif
       read:blocks: gweld eich blociau
diff --git a/config/locales/doorkeeper.da.yml b/config/locales/doorkeeper.da.yml
index df964e4b1f8228214dd5d2dba31be82a18e77b72..b0f50a8931e8209fd93e01d95064ab3e38768882 100644
--- a/config/locales/doorkeeper.da.yml
+++ b/config/locales/doorkeeper.da.yml
@@ -72,7 +72,6 @@ da:
       index:
         application: Applikation
         created_at: Godkendt
-        date_format: "%Y-%m-%d %H:%M:%S"
         scopes: Omfang
         title: Dine godkendte applikationer
     errors:
diff --git a/config/locales/doorkeeper.de.yml b/config/locales/doorkeeper.de.yml
index bf4b06e7c25909751fa8abe909fe40df12e9fd7f..c41a847b2d6652d992b6f32d5a1ae0232f5a098f 100644
--- a/config/locales/doorkeeper.de.yml
+++ b/config/locales/doorkeeper.de.yml
@@ -23,7 +23,7 @@ de:
         cancel: Abbrechen
         destroy: Löschen
         edit: Bearbeiten
-        submit: Übertragen
+        submit: Speichern
       confirmations:
         destroy: Bist du sicher?
       edit:
@@ -31,8 +31,8 @@ de:
       form:
         error: Hoppla! Bitte überprüfe das Formular auf mögliche Fehler
       help:
-        native_redirect_uri: "%{native_redirect_uri} für lokale Tests benutzen"
-        redirect_uri: Bitte benutze eine Zeile pro URI
+        native_redirect_uri: Benutze %{native_redirect_uri} für lokale Tests
+        redirect_uri: Benutze eine Zeile pro URI
         scopes: Bitte die Befugnisse mit Leerzeichen trennen. Zur Verwendung der Standardwerte freilassen.
       index:
         application: Anwendung
@@ -71,25 +71,25 @@ de:
         revoke: Bist du sicher?
       index:
         application: Anwendung
-        created_at: autorisiert am
+        created_at: Autorisiert am
         date_format: "%d.%m.%Y %H:%M:%S"
         scopes: Befugnisse
         title: Deine autorisierten Anwendungen
     errors:
       messages:
-        access_denied: Der »resource owner« oder der Autorisierungs-Server hat die Anfrage verweigert.
-        credential_flow_not_configured: Die Prozedur »Resource Owner Password Credentials« schlug fehl, da Doorkeeper.configure.resource_owner_from_credentials nicht konfiguriert ist.
+        access_denied: Die Anfrage wurde durch Benutzer_in oder Autorisierungs-Server verweigert.
+        credential_flow_not_configured: Das Konto konnte nicht gefunden werden, da Doorkeeper.configure.resource_owner_from_credentials nicht konfiguriert ist.
         invalid_client: 'Client-Authentifizierung ist fehlgeschlagen: Client unbekannt, keine Authentisierung mitgeliefert oder Authentisierungsmethode wird nicht unterstützt.'
         invalid_grant: Die beigefügte Autorisierung ist ungültig, abgelaufen, wurde widerrufen, einem anderen Client ausgestellt oder der Weiterleitungs-URI stimmt nicht mit der Autorisierungs-Anfrage überein.
         invalid_redirect_uri: Der beigefügte Weiterleitungs-URI ist ungültig.
         invalid_request: Die Anfrage enthält ein nicht-unterstütztes Argument, ein Parameter fehlt, oder sie ist anderweitig fehlerhaft.
-        invalid_resource_owner: Die angegebenen Zugangsdaten für den Ressourcenbesitzer sind ungültig oder der Ressourcenbesitzer kann nicht gefunden werden
+        invalid_resource_owner: Die angegebenen Zugangsdaten für das Konto sind ungültig oder das Konto kann nicht gefunden werden
         invalid_scope: Die angeforderte Befugnis ist ungültig, unbekannt oder fehlerhaft.
         invalid_token:
           expired: Der Zugriffs-Token ist abgelaufen
           revoked: Der Zugriffs-Token wurde widerrufen
           unknown: Der Zugriffs-Token ist ungültig
-        resource_owner_authenticator_not_configured: Die Prozedur »Resource Owner find« ist fehlgeschlagen, da Doorkeeper.configure.resource_owner_authenticator nicht konfiguriert ist.
+        resource_owner_authenticator_not_configured: Das Konto konnte nicht gefunden werden, da Doorkeeper.configure.resource_owner_authenticator nicht konfiguriert ist.
         server_error: Der Autorisierungs-Server hat ein unerwartetes Problem festgestellt und konnte die Anfrage nicht bearbeiten.
         temporarily_unavailable: Der Autorisierungs-Server ist aufgrund von zwischenzeitlicher Überlastung oder Wartungsarbeiten derzeit nicht in der Lage, die Anfrage zu bearbeiten.
         unauthorized_client: Der Client ist nicht dazu autorisiert, diese Anfrage mit dieser Methode auszuführen.
@@ -114,6 +114,12 @@ de:
       application:
         title: OAuth-Autorisierung nötig
     scopes:
+      admin:read: alle Daten auf dem Server lesen
+      admin:read:accounts: sensible Daten aller Konten lesen
+      admin:read:reports: sensible Daten aller Meldungen und gemeldeten Konten lesen
+      admin:write: alle Daten auf dem Server ändern
+      admin:write:accounts: Moderationsaktionen auf Konten ausführen
+      admin:write:reports: Moderationsaktionen auf Meldungen ausführen
       follow: Kontenbeziehungen verändern
       push: deine Push-Benachrichtigungen erhalten
       read: all deine Daten lesen
diff --git a/config/locales/doorkeeper.el.yml b/config/locales/doorkeeper.el.yml
index e820ff8a6f4aea62c21e19d4b7a4abaa07c55c29..c63688adeeef71868f704b45923f58db0878fc17 100644
--- a/config/locales/doorkeeper.el.yml
+++ b/config/locales/doorkeeper.el.yml
@@ -114,6 +114,12 @@ el:
       application:
         title: Απαιτείται έγκριση OAuth
     scopes:
+      admin:read: ανάγνωση δεδομένων στον διακομιστή
+      admin:read:accounts: ανάγνωση ευαίσθητων πληροφοριών όλων των λογαριασμών
+      admin:read:reports: ανάγνωση ευαίσθητων πληροφοριών όλων των καταγγελιών και των καταγγελλομένων λογαριασμών
+      admin:write: αλλαγή δεδομένων στον διακομιστή
+      admin:write:accounts: εκτέλεση διαχειριστικών ενεργειών σε λογαριασμούς
+      admin:write:reports: εκτέλεση διαχειριστικών ενεργειών σε καταγγελίες
       follow: να αλλάζει τις σχέσεις με λογαριασμούς
       push: να λαμβάνει τις ειδοποιήσεις σου
       read: να διαβάζει όλα τα στοιχεία του λογαριασμού σου
diff --git a/config/locales/doorkeeper.en.yml b/config/locales/doorkeeper.en.yml
index f1fe03716a1605141f66cf1a973a20751f5fbddc..d9b7c2c8ebe56bcfdd8a655370f3d42e74267db1 100644
--- a/config/locales/doorkeeper.en.yml
+++ b/config/locales/doorkeeper.en.yml
@@ -114,6 +114,12 @@ en:
       application:
         title: OAuth authorization required
     scopes:
+      admin:read: read all data on the server
+      admin:read:accounts: read sensitive information of all accounts
+      admin:read:reports: read sensitive information of all reports and reported accounts
+      admin:write: modify all data on the server
+      admin:write:accounts: perform moderation actions on accounts
+      admin:write:reports: perform moderation actions on reports
       follow: modify account relationships
       push: receive your push notifications
       read: read all your account's data
diff --git a/config/locales/doorkeeper.es.yml b/config/locales/doorkeeper.es.yml
index 937ecd32ab5df5d7335b4df1eb9f641b70ef510e..752387d870d94ea205991cfbe72e0c1f7cb32b3f 100644
--- a/config/locales/doorkeeper.es.yml
+++ b/config/locales/doorkeeper.es.yml
@@ -117,3 +117,4 @@ es:
       follow: seguir, bloquear, desbloquear y dejar de seguir cuentas
       read: leer los datos de tu cuenta
       write: publicar en tu nombre
+      write:blocks: bloquear cuentas y dominios
diff --git a/config/locales/doorkeeper.fa.yml b/config/locales/doorkeeper.fa.yml
index e1912655405752566d0b41c997f0682cb421a990..b677c334676c7b7364868c9e0dd170318e2dc2af 100644
--- a/config/locales/doorkeeper.fa.yml
+++ b/config/locales/doorkeeper.fa.yml
@@ -23,7 +23,6 @@ fa:
         cancel: لغو
         destroy: پاک کردن
         edit: ویرایش
-        submit: Submit
       confirmations:
         destroy: آیا مطمئن هستید؟
       edit:
@@ -46,7 +45,6 @@ fa:
       new:
         title: برنامهٔ تازه
       show:
-        actions: Actions
         application_id: کلید کلاینت
         callback_urls: نشانی‌های Callabck
         scopes: دامنه‌ها
@@ -72,29 +70,17 @@ fa:
       index:
         application: برنامه
         created_at: مجازشده از
-        date_format: "%Y-%m-%d %H:%M:%S"
         scopes: اجازه‌ها
         title: برنامه‌های مجاز
     errors:
       messages:
         access_denied: دارندهٔ منبع یا سرور اجازه دهنده درخواست را نپذیرفت.
-        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.
         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: خطای پیش‌بینی‌نشده‌ای برای سرور اجازه‌دهنده رخ داد که جلوی اجرای این درخواست را گرفت.
         temporarily_unavailable: سرور اجازه‌دهنده به دلیل بار زیاد یا تعمیرات سرور هم‌اینک نمی‌تواند درخواست شما را بررسی کند.
-        unauthorized_client: The client is not authorized to perform this request using this method.
-        unsupported_grant_type: The authorization grant type is not supported by the authorization server.
-        unsupported_response_type: The authorization server does not support this response type.
     flash:
       applications:
         create:
diff --git a/config/locales/doorkeeper.fi.yml b/config/locales/doorkeeper.fi.yml
index a3b878b65de43ff892674296cff914c14cb5b737..10613d435df8f33fad75960815f9c8579aad2706 100644
--- a/config/locales/doorkeeper.fi.yml
+++ b/config/locales/doorkeeper.fi.yml
@@ -72,7 +72,6 @@ fi:
       index:
         application: Sovellus
         created_at: Valtuutettu
-        date_format: "%Y-%m-%d %H:%M:%S"
         scopes: Oikeudet
         title: Valtuutetut sovellukset
     errors:
diff --git a/config/locales/doorkeeper.fr.yml b/config/locales/doorkeeper.fr.yml
index eae691659f5edc62b54b3233822dda663e70c8e8..3525617680de88b67556d1215f8f57b93224c537 100644
--- a/config/locales/doorkeeper.fr.yml
+++ b/config/locales/doorkeeper.fr.yml
@@ -5,7 +5,6 @@ fr:
       doorkeeper/application:
         name: Nom
         redirect_uri: L’URL de redirection
-        scope: Portée
         scopes: Étendues
         website: Site web de l’application
     errors:
diff --git a/config/locales/doorkeeper.gl.yml b/config/locales/doorkeeper.gl.yml
index 0dc45d5a38084af900553f2fa25ac554f297bcba..90cbd9b38d1817d0e62d88e382550db32741d16d 100644
--- a/config/locales/doorkeeper.gl.yml
+++ b/config/locales/doorkeeper.gl.yml
@@ -114,6 +114,12 @@ gl:
       application:
         title: Precisa autorización OAuth
     scopes:
+      admin:read: ler todos os datos no servidor
+      admin:read:accounts: ler información sensible de todas as contas
+      admin:read:reports: ler información sensible de todos os informes e contas reportadas
+      admin:write: modificar todos os datos no servidor
+      admin:write:accounts: executar accións de moderación nas contas
+      admin:write:reports: executar accións de moderación nos informes
       follow: modificar as relacións da conta
       push: recibir notificacións push
       read: ler todos os datos da súa conta
diff --git a/config/locales/doorkeeper.he.yml b/config/locales/doorkeeper.he.yml
index d797b0ac9e000e3ab4b69b96c0abff4e8f0d154c..78bb0a1426300ba58d5f8af0c0b86b93d9a23c45 100644
--- a/config/locales/doorkeeper.he.yml
+++ b/config/locales/doorkeeper.he.yml
@@ -72,7 +72,6 @@ he:
       index:
         application: ישום
         created_at: מאושר
-        date_format: "%Y-%m-%d %H:%M:%S"
         scopes: תחומים
         title: ישומיך המאושרים
     errors:
diff --git a/config/locales/doorkeeper.hr.yml b/config/locales/doorkeeper.hr.yml
index e0240938eab42887caa783742837f9d199cedff8..221ec27e94284d0d3191a5e24f9a1718e75c3ddf 100644
--- a/config/locales/doorkeeper.hr.yml
+++ b/config/locales/doorkeeper.hr.yml
@@ -4,7 +4,6 @@ hr:
     attributes:
       doorkeeper/application:
         name: Ime
-        redirect_uri: Redirect URI
     errors:
       models:
         doorkeeper/application:
@@ -33,7 +32,6 @@ hr:
         redirect_uri: Koristi jednu liniju po URI
         scopes: Odvoji scopes sa razmacima. Ostavi prazninu kako bi koristio zadane scopes.
       index:
-        callback_url: Callback URL
         name: Ime
         new: Nova Aplikacija
         title: Tvoje aplikacije
@@ -43,7 +41,6 @@ hr:
         actions: Akcije
         application_id: Id Aplikacije
         callback_urls: Callback urls
-        scopes: Scopes
         secret: Tajna
         title: 'Aplikacija: %{name}'
     authorizations:
@@ -56,8 +53,6 @@ hr:
         able_to: Moći će
         prompt: Aplikacija %{client_name} je zatražila pristup tvom računu
         title: Traži se autorizacija
-      show:
-        title: Copy this authorization code and paste it to the application.
     authorized_applications:
       buttons:
         revoke: Odbij
@@ -66,15 +61,11 @@ hr:
       index:
         application: Aplikacija
         created_at: Ovlašeno
-        date_format: "%Y-%m-%d %H:%M:%S"
-        scopes: Scopes
         title: Tvoje autorizirane aplikacije
     errors:
       messages:
         access_denied: Vlasnik resursa / autorizacijski server je odbio zahtjev.
-        credential_flow_not_configured: Resource Owner Password Credentials flow failed due to Doorkeeper.configure.resource_owner_from_credentials being unconfigured.
         invalid_client: Autentifikacija klijenta nije uspjela zbog nepoznatog klijenta, neuključene autentifikacije od strane klijenta, ili nepodržane metode autentifikacije.
-        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 nije valjan.
         invalid_request: Zahtjevu nedostaje traženi parametar, uključuje nepodržanu vrijednost parametra, ili je na neki drugi način neispravno formiran.
         invalid_resource_owner: The provided resource owner credentials nisu valjani, ili vlasnik resursa ne može biti nađen
@@ -83,7 +74,6 @@ hr:
           expired: Pristupni token je istekao
           revoked: Pristupni token je odbijen
           unknown: Pristupni token nije valjan
-        resource_owner_authenticator_not_configured: Resource Owner find failed due to Doorkeeper.configure.resource_owner_authenticator being unconfiged.
         server_error: Autorizacijski server naišao je na neočekivani uvjet, što ga je onemogućilo da ispuni zahtjev.
         temporarily_unavailable: Autorizacijski server trenutno nije u mogućnosti  izvesti zahtjev zbog privremenog preopterećenja ili održavanja servera.
         unauthorized_client: Klijent nije ovlašten izvesti zahtjev koristeći ovu metodu.
@@ -104,7 +94,6 @@ hr:
       admin:
         nav:
           applications: Aplikacije
-          oauth2_provider: OAuth2 Provider
       application:
         title: Traži se OAuth autorizacija
     scopes:
diff --git a/config/locales/doorkeeper.hu.yml b/config/locales/doorkeeper.hu.yml
index fa706e100bc5ceb31b189e1ca1f8de98d569312c..122392864d91feec13706834e5342c1ff90c7557 100644
--- a/config/locales/doorkeeper.hu.yml
+++ b/config/locales/doorkeeper.hu.yml
@@ -3,8 +3,8 @@ hu:
   activerecord:
     attributes:
       doorkeeper/application:
-        name: Név
-        redirect_uri: Visszairányító URI
+        name: Alkalmazás neve
+        redirect_uri: Átirányító URI
         scopes: Hatáskör
         website: Az alkalmazás weboldala
     errors:
@@ -33,7 +33,7 @@ hu:
       help:
         native_redirect_uri: Használj %{native_redirect_uri} a helyi tesztekhez
         redirect_uri: Egy sor URI-nként
-        scopes: A nézeteket szóközzel válaszd el. Hagyd üresen az alapértelmezett nézetekhez.
+        scopes: A hatásköröket szóközzel válaszd el. Hagyd üresen az alapértelmezett hatáskörökhöz.
       index:
         application: Alkalmazás
         callback_url: Callback URL
@@ -42,14 +42,14 @@ hu:
         new: Új alkalmazás
         scopes: Hatáskör
         show: Mutat
-        title: Alkalmazásod
+        title: Alkalmazásaid
       new:
         title: Új alkalmazás
       show:
         actions: Műveletek
         application_id: Alkalmazás azonosító
-        callback_urls: Callback urlek
-        scopes: Nézetek
+        callback_urls: Callback URL-ek
+        scopes: Hatáskörök
         secret: Titok
         title: 'Alkalmazás: %{name}'
     authorizations:
@@ -63,7 +63,7 @@ hu:
         prompt: "%{client_name} nevű alkalmazás engedélyt kér a fiókodhoz való hozzáféréshez."
         title: Engedély szükséges
       show:
-        title: Copy this authorization code and paste it to the application.
+        title: Másold le ezt az engedélyező kódot és írd be az alkalmazásba.
     authorized_applications:
       buttons:
         revoke: Visszavonás
@@ -71,28 +71,28 @@ hu:
         revoke: Biztos vagy benne?
       index:
         application: Alkalmazás
-        created_at: Készítve
+        created_at: Felhatalmazva
         date_format: "%Y-%m-%d %H:%M:%S"
         scopes: Hatáskör
         title: Engedélyezett alkalmazásaid
     errors:
       messages:
-        access_denied: Az erőforrás tulajdonosa vagy hitelesítő kiszolgálója megtakadta a kérést.
+        access_denied: Az erőforrás tulajdonosa vagy hitelesítő kiszolgálója megtagadta a kérést.
         credential_flow_not_configured: Az erőforrás tulajdonos jelszóadatainak átadása megszakadt, mert a Doorkeeper.configure.resource_owner_from_credentials beállítatlan.
-        invalid_client: A kliens hitelesítése megszakadt, mert a ismeretlen a kliens, kliens nem küldött hitelesítést, vagy ismeretlen a kliens
-        invalid_grant: A biztosított hitelesítés érvénytelen, lejárt, visszavont, vagy nem egyezik a hitelesítéi kérésben használt URIval, vagy más kliensnek lett címezve.
-        invalid_redirect_uri: A redirect uri nem valós.
-        invalid_request: A kérésből hiányzik egy szükséges paraméter, nem támogatott paramétert tartalmaz, vagy egyéb módon hibás.
+        invalid_client: A kliens hitelesítése megszakadt, mert ismeretlen a kliens, a kliens nem küldött hitelesítést, vagy a hitelesítés módja nem támogatott.
+        invalid_grant: A biztosított hitelesítés érvénytelen, lejárt, visszavont, vagy nem egyezik a hitelesítési kérésben használt URI-val, vagy más kliensnek címezték.
+        invalid_redirect_uri: Az átirányító URI nem valós.
+        invalid_request: A kérésből hiányzik egy szükséges paraméter, nem támogatott paramétert tartalmaz, vagy máshogy sérült.
         invalid_resource_owner: A biztosított erőforrás tulajdonosának hitelesítő adatai nem valósak, vagy az erőforrás tulajdonosa nem található.
         invalid_scope: A kért nézet érvénytelen, ismeretlen, vagy hibás.
         invalid_token:
           expired: Hozzáférési kulcs lejárt
-          revoked: Hozzáférési kulcs vissza lett vonva
+          revoked: Hozzáférési kulcsot visszavonták
           unknown: Hozzáférési kulcs érvénytelen
         resource_owner_authenticator_not_configured: Erőforrás tulajdonos keresés megszakadt, ugyanis a Doorkeeper.configure.resource_owner_authenticator beállítatlan.
         server_error: Hitelesítő szervert váratlan esemény érte, mely meggátolta a kérés teljesítését.
-        temporarily_unavailable: A hitelesítő szerver jelenleg nem tudja teljesíteni a kérést egy átmeneti túlterheltség vagy a kiszolgáló karbantartása miatt.
-        unauthorized_client: A kliens nincs feljogosítva a kérés teljesítésére.
+        temporarily_unavailable: A hitelesítő szerver jelenleg nem tudja teljesíteni a kérést átmeneti túlterheltség vagy a kiszolgáló karbantartása miatt.
+        unauthorized_client: A kliens nincs feljogosítva erre a kérésre.
         unsupported_grant_type: A hitelesítés módja nem támogatott a hitelesítő kiszolgálón.
         unsupported_response_type: A hitelesítő kiszolgáló nem támogatja ezt a választ.
     flash:
@@ -114,6 +114,29 @@ hu:
       application:
         title: OAuth engedély szükséges
     scopes:
-      follow: fiókok követése, blokkoláse, blokkolás feloldása és követés abbahagyása
+      follow: fiókok követése, letiltása, tiltás feloldása és követés abbahagyása
+      push: push értesítések fogadása
       read: fiókod adatainak olvasása
-      write: bejegyzés írása a nevedben
+      read:accounts: fiók adatainak megtekintése
+      read:blocks: letiltások megtekintése
+      read:favourites: kedvencek megtekintése
+      read:filters: szűrök megtekintése
+      read:follows: követések megtekintése
+      read:lists: listák megtekintése
+      read:mutes: némítások megtekintése
+      read:notifications: értesítések megtekintése
+      read:reports: bejelentések megtekintése
+      read:search: nevedben keresés
+      read:statuses: tülkök megtekintése
+      write: fiókod adatainak megváltoztatása
+      write:accounts: profilod megváltoztatása
+      write:blocks: fiókok és domainek letiltása
+      write:favourites: tülkök kedvencnek jelölése
+      write:filters: szűrők létrehozása
+      write:follows: mások követése
+      write:lists: listák létrehozása
+      write:media: média feltöltése
+      write:mutes: emberek és beszélgetések némítása
+      write:notifications: értesítések törlése
+      write:reports: mások bejelentése
+      write:statuses: tülkök közzététele
diff --git a/config/locales/doorkeeper.hy.yml b/config/locales/doorkeeper.hy.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c406540162aa8f9ae59ae2d79f75097ce1af0c26
--- /dev/null
+++ b/config/locales/doorkeeper.hy.yml
@@ -0,0 +1 @@
+hy:
diff --git a/config/locales/doorkeeper.id.yml b/config/locales/doorkeeper.id.yml
index 0a99b86c0822080359a848a11988cc71d98ba869..3f9dee2ac80173912c0bf3876c915d15385ad6a2 100644
--- a/config/locales/doorkeeper.id.yml
+++ b/config/locales/doorkeeper.id.yml
@@ -62,8 +62,6 @@ id:
         able_to: Mempunyai akses untuk
         prompt: Aplikasi %{client_name} meminta akses pada akun anda
         title: Izin diperlukan
-      show:
-        title: Copy this authorization code and paste it to the application.
     authorized_applications:
       buttons:
         revoke: Cabut izin
@@ -72,7 +70,6 @@ id:
       index:
         application: Aplikasi
         created_at: Diizinkan pada
-        date_format: "%Y-%m-%d %H:%M:%S"
         scopes: Scope
         title: Aplikasi yang anda izinkan
     errors:
diff --git a/config/locales/doorkeeper.io.yml b/config/locales/doorkeeper.io.yml
index 28466d3aefc4cc1481a36fceaf57db65009a0711..ff1fdf9c252a4b8fec9d638af2971f1bd4a4e3d5 100644
--- a/config/locales/doorkeeper.io.yml
+++ b/config/locales/doorkeeper.io.yml
@@ -31,82 +31,14 @@ io:
       help:
         native_redirect_uri: Uzez %{native_redirect_uri} por lokala probi
         redirect_uri: Uzez un lineo por singla URI
-        scopes: Separate scopes with spaces. Leave blank to use the default scopes.
       index:
-        callback_url: Callback URL
-        name: Name
         new: New Application
-        title: Your applications
       new:
         title: New Application
       show:
-        actions: Actions
         application_id: Application Id
         callback_urls: Callback urls
-        scopes: Scopes
         secret: Secret
-        title: 'Application: %{name}'
-    authorizations:
-      buttons:
-        authorize: Authorize
-        deny: Deny
-      error:
-        title: An error has occurred
-      new:
-        able_to: It will be able to
-        prompt: Application %{client_name} requests access to your account
-        title: Authorization required
-      show:
-        title: Copy this authorization code and paste it to the application.
-    authorized_applications:
-      buttons:
-        revoke: Revoke
-      confirmations:
-        revoke: Are you sure?
-      index:
-        application: Application
-        created_at: Authorized
-        date_format: "%Y-%m-%d %H:%M:%S"
-        scopes: Scopes
-        title: Your authorized applications
-    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.
-        invalid_token:
-          expired: The access token expired
-          revoked: The access token was revoked
-          unknown: The access token is invalid
-        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: The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.
-        unauthorized_client: The client is not authorized to perform this request using this method.
-        unsupported_grant_type: The authorization grant type is not supported by the authorization server.
-        unsupported_response_type: The authorization server does not support this response type.
-    flash:
-      applications:
-        create:
-          notice: Application created.
-        destroy:
-          notice: Application deleted.
-        update:
-          notice: Application updated.
-      authorized_applications:
-        destroy:
-          notice: Application revoked.
-    layouts:
-      admin:
-        nav:
-          applications: Applications
-          oauth2_provider: OAuth2 Provider
-      application:
-        title: OAuth authorization required
     scopes:
       follow: follow, block, unblock and unfollow accounts
       read: read your account's data
diff --git a/config/locales/doorkeeper.it.yml b/config/locales/doorkeeper.it.yml
index a76130bb94e384b5a0070b7575a3bdddd46d1049..361d0bd75ce50cfee705319e07d74a8d9889738c 100644
--- a/config/locales/doorkeeper.it.yml
+++ b/config/locales/doorkeeper.it.yml
@@ -36,11 +36,11 @@ it:
         scopes: Dividi gli scopes con spazi. Lascia vuoto per utilizzare gli scopes di default.
       index:
         application: Applicazione
-        callback_url: Callback URL
+        callback_url: URL di callback
         delete: Elimina
         name: Nome
         new: Nuova applicazione
-        scopes: Scopes
+        scopes: Visibilità
         show: Mostra
         title: Le tue applicazioni
       new:
@@ -114,6 +114,12 @@ it:
       application:
         title: Autorizzazione OAuth richiesta
     scopes:
+      admin:read: leggere tutti i dati dal server
+      admin:read:accounts: leggere dati sensibili di tutti gli account
+      admin:read:reports: leggere dati sensibili di tutte le segnalazioni e gli account segnalati
+      admin:write: modificare tutti i dati sul server
+      admin:write:accounts: eseguire azioni di moderazione sugli account
+      admin:write:reports: eseguire azioni di moderazione sulle segnalazioni
       follow: modificare relazioni tra account
       push: ricevere le tue notifiche push
       read: leggere tutte le informazioni del tuo account
diff --git a/config/locales/doorkeeper.ja.yml b/config/locales/doorkeeper.ja.yml
index 9bc2d9a80fcf27f6e41b046b61bac4289c10ed91..d80212f82fa87883358499a0d99e47bd648e60dc 100644
--- a/config/locales/doorkeeper.ja.yml
+++ b/config/locales/doorkeeper.ja.yml
@@ -114,6 +114,12 @@ ja:
       application:
         title: OAuth認証
     scopes:
+      admin:read: サーバーのすべてのデータの読み取り
+      admin:read:accounts: すべてのアカウントの機密情報の読み取り
+      admin:read:reports: すべての通報と通報されたアカウントの機密情報の読み取り
+      admin:write: サーバーのすべてのデータの変更
+      admin:write:accounts: アカウントに対するアクションの実行
+      admin:write:reports: 通報に対するアクションの実行
       follow: アカウントのつながりを変更
       push: プッシュ通知の受信
       read: アカウントのすべてのデータの読み取り
diff --git a/config/locales/doorkeeper.ka.yml b/config/locales/doorkeeper.ka.yml
index e462e66f1585657bdd7486935809d8ebca166a42..f4178a75234d4c55d6120b4afe683071bc613a71 100644
--- a/config/locales/doorkeeper.ka.yml
+++ b/config/locales/doorkeeper.ka.yml
@@ -72,7 +72,6 @@ ka:
       index:
         application: აპლიკაცია
         created_at: ავტორიზებული
-        date_format: "%Y-%m-%d %H:%M:%S"
         scopes: ფარგლები
         title: თქვენი ავტორიზებული აპლიკაციები
     errors:
diff --git a/config/locales/doorkeeper.kk.yml b/config/locales/doorkeeper.kk.yml
new file mode 100644
index 0000000000000000000000000000000000000000..97897cdcbecf25aa4c242aa4988ef19f258a2a95
--- /dev/null
+++ b/config/locales/doorkeeper.kk.yml
@@ -0,0 +1,141 @@
+---
+kk:
+  activerecord:
+    attributes:
+      doorkeeper/application:
+        name: Application аты
+        redirect_uri: Redirеct URI
+        scopes: Scopеs
+        website: Application сайты
+    errors:
+      models:
+        doorkeeper/application:
+          attributes:
+            redirect_uri:
+              fragment_present: cannot contain a frаgment.
+              invalid_uri: must be a vаlid URI.
+              relative_uri: must be an аbsolute URI.
+              secured_uri: must be аn HTTPS/SSL URI.
+  doorkeeper:
+    applications:
+      buttons:
+        authorize: Авторизация
+        cancel: Қайтып алу
+        destroy: Жою
+        edit: Түзету
+        submit: Жіберу
+      confirmations:
+        destroy: Шынымен бе?
+      edit:
+        title: Қосымшаны түзету
+      form:
+        error: Whoops! Check your form for pоssible errors
+      help:
+        native_redirect_uri: Use %{native_redirect_uri} fоr local tests
+        redirect_uri: Use one line pеr URI
+        scopes: Separate scopes with spаces. Leave blank to use the default scopes.
+      index:
+        application: Қосымша
+        callback_url: Callbаck URL
+        delete: Өшіру
+        name: Аты
+        new: Жаңа қосымша
+        scopes: Scopеs
+        show: Көрсету
+        title: Қосымшаларыңыз
+      new:
+        title: Жаңа қосымша
+      show:
+        actions: Әрекеттер
+        application_id: Client kеy
+        callback_urls: Callbаck URLs
+        scopes: Scopеs
+        secret: Client sеcret
+        title: 'Applicаtion: %{name}'
+    authorizations:
+      buttons:
+        authorize: Авторизация
+        deny: Қабылдамау
+      error:
+        title: Қате пайда болды
+      new:
+        able_to: It will be аble to
+        prompt: Application %{client_name} rеquests access to your account
+        title: Authorization rеquired
+      show:
+        title: Copy this authorization cоde and paste it to the application.
+    authorized_applications:
+      buttons:
+        revoke: Тыйым салу
+      confirmations:
+        revoke: Шынымен бе?
+      index:
+        application: Қосымша
+        created_at: Авторизацияланды
+        scopes: Scopеs
+        title: Your authorized applicаtions
+    errors:
+      messages:
+        access_denied: The resource owner or authоrization server denied the request.
+        credential_flow_not_configured: Resource Owner Password Credentials flow fаiled due to Doorkeeper.configure.resource_owner_from_credentials being unconfigured.
+        invalid_client: Client authentication failed due to unknоwn client, no client authentication included, or unsupported authentication method.
+        invalid_grant: The provided authorization grant is invаlid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
+        invalid_redirect_uri: The redirеct uri included is not valid.
+        invalid_request: The request is missing a required parameter, includes an unsupported parameter vаlue, or is otherwise malformed.
+        invalid_resource_owner: The provided resource owner credentials are not valid, or rеsource owner cannot be found
+        invalid_scope: The requested scope is invаlid, unknown, or malformed.
+        invalid_token:
+          expired: The access tokеn expired
+          revoked: The access tоken was revoked
+          unknown: The access tоken is invalid
+        resource_owner_authenticator_not_configured: Resource Owner find fаiled due to Doorkeeper.configure.resource_owner_authenticator being unconfiged.
+        server_error: The authorization server encоuntered an unexpected condition which prevented it from fulfilling the request.
+        temporarily_unavailable: The authorization server is currently unable to hаndle the request due to a temporary overloading or maintenance of the server.
+        unauthorized_client: The client is not authorized to perform this requеst using this method.
+        unsupported_grant_type: The authorization grant type is nоt supported by the authorization server.
+        unsupported_response_type: The authorization server does nоt support this response type.
+    flash:
+      applications:
+        create:
+          notice: Application crеated.
+        destroy:
+          notice: Application dеleted.
+        update:
+          notice: Application updаted.
+      authorized_applications:
+        destroy:
+          notice: Application revоked.
+    layouts:
+      admin:
+        nav:
+          applications: Applicatiоns
+          oauth2_provider: OAuth2 Prоvider
+      application:
+        title: OAuth authorizatiоn required
+    scopes:
+      follow: modify accоunt relationships
+      push: receive your push nоtifications
+      read: read all your accоunt's data
+      read:accounts: see accounts infоrmation
+      read:blocks: see your blоcks
+      read:favourites: see your favоurites
+      read:filters: see yоur filters
+      read:follows: see your follоws
+      read:lists: see yоur lists
+      read:mutes: see yоur mutes
+      read:notifications: see your nоtifications
+      read:reports: see your repоrts
+      read:search: search on yоur behalf
+      read:statuses: see all stаtuses
+      write: modify all your accоunt's data
+      write:accounts: modify your prоfile
+      write:blocks: block accounts and dоmains
+      write:favourites: favourite stаtuses
+      write:filters: creаte filters
+      write:follows: follow peоple
+      write:lists: creatе lists
+      write:media: upload mеdia files
+      write:mutes: mute pеople and conversations
+      write:notifications: clear yоur notifications
+      write:reports: report оther people
+      write:statuses: publish stаtuses
diff --git a/config/locales/doorkeeper.ko.yml b/config/locales/doorkeeper.ko.yml
new file mode 100644
index 0000000000000000000000000000000000000000..76e725debc8b0b17aa755c8ec9d9d809f50af470
--- /dev/null
+++ b/config/locales/doorkeeper.ko.yml
@@ -0,0 +1,131 @@
+---
+ko:
+  activerecord:
+    attributes:
+      doorkeeper/application:
+        name: 애플리케이션 이름
+        redirect_uri: 리디렉션 URI
+        scopes: 범위
+        website: 애플리케이션 웹사이트
+    errors:
+      models:
+        doorkeeper/application:
+          attributes:
+            redirect_uri:
+              fragment_present: fragment를 포함할 수 없습니다
+              invalid_uri: 올바른 URI여야 합니다.
+              relative_uri: 절대경로 URI여야 합니다
+              secured_uri: HTTPS/SSL URI여야 합니다.
+  doorkeeper:
+    applications:
+      buttons:
+        authorize: 승인
+        cancel: 취소
+        destroy: 제거
+        edit: 수정
+        submit: 제출
+      confirmations:
+        destroy: 확실합니까?
+      edit:
+        title: 애플리케이션 수정
+      form:
+        error: 이런! 에러를 확인하세요
+      help:
+        native_redirect_uri: "%{native_redirect_uri}를 이용해 로컬 테스트를 할 수 있습니다"
+        redirect_uri: 한 줄에 하나의 URI를 작성하세요
+        scopes: 스페이스로 범위를 구분하세요. 빈 칸으로 놔두면 기본 범위를 사용합니다.
+      index:
+        application: 애플리케이션
+        callback_url: 콜백 URL
+        delete: 삭제
+        name: 이름
+        new: 새 애플리케이션
+        scopes: 범위
+        show: 표시
+        title: 당신의 애플리케이션들
+      new:
+        title: 새 애플리케이션
+      show:
+        actions: 동작
+        application_id: 클라이언트 키
+        callback_urls: 콜백 URL
+        scopes: 범위
+        secret: 클라이언트 비밀키
+        title: '애플리케이션: %{name}'
+    authorizations:
+      buttons:
+        authorize: 승인
+        deny: ê±°ë¶€
+      error:
+        title: 에러가 발생하였습니다
+      new:
+        able_to: 다음과 같은 행동들이 가능합니다
+        prompt: "%{client_name}이 당신의 계정에 접근 권한을 요청합니다"
+        title: 승인 필요
+      show:
+        title: 이 승인 코드를 복사하여 애플리케이션에 붙여넣으세요
+    authorized_applications:
+      buttons:
+        revoke: 취소
+      confirmations:
+        revoke: 확실합니까?
+      index:
+        application: 애플리케이션
+        created_at: 승인 됨
+        date_format: "%Y-%m-%d %H:%M:%S"
+        scopes: 범위
+        title: 당신의 승인 된 애플리케이션들
+    errors:
+      messages:
+        access_denied: 리소스 소유자 또는 권한 부여 서버가 요청을 거부했습니다.
+        invalid_redirect_uri: 리디렉션 URI가 올바르지 않습니다
+        invalid_request: 요청에 필요한 매개변수가 없거나, 지원 되지 않는 매개변수가 있거나, 형식이 잘못되었습니다.
+        invalid_token:
+          expired: 액세스 토큰이 만료되었습니다.
+          revoked: 액세스 토큰이 취소되었습니다.
+          unknown: 액세스 토큰이 잘못되었습니다.
+    flash:
+      applications:
+        create:
+          notice: 애플리케이션이 생성 되었습니다.
+        destroy:
+          notice: 애플리케이션이 삭제 되었습니다.
+        update:
+          notice: 애플리케이션이 갱신 되었습니다.
+      authorized_applications:
+        destroy:
+          notice: 애플리케이션이 취소 되었습니다.
+    layouts:
+      admin:
+        nav:
+          applications: 애플리케이션
+          oauth2_provider: OAuth2 제공자
+      application:
+        title: OAuth 인증이 필요합니다
+    scopes:
+      follow: 계정의 관계를 수정
+      push: 푸시 알림을 받기
+      read: 계정의 모든 데이터를 읽기
+      read:accounts: 계정의 정보를 보기
+      read:blocks: 차단을 보기
+      read:favourites: 관심글을 보기
+      read:filters: 필터를 보기
+      read:follows: 팔로우를 보기
+      read:lists: 리스트를 보기
+      read:mutes: 뮤트를 보기
+      read:notifications: 알림 보기
+      read:reports: 신고 보기
+      read:search: 당신의 권한으로 검색
+      read:statuses: 게시물 모두 보기
+      write: 계정 정보 수정
+      write:accounts: 프로필 수정
+      write:blocks: 계정이나 도메인 차단
+      write:favourites: 관심글 지정
+      write:filters: 필터 만들기
+      write:follows: 사람을 팔로우
+      write:lists: 리스트 만들기
+      write:media: 미디어 파일 업로드
+      write:mutes: 사람이나 대화 뮤트
+      write:notifications: 알림 모두 지우기
+      write:reports: 다른 사람을 신고
+      write:statuses: 게시물 게시
diff --git a/config/locales/doorkeeper.lt.yml b/config/locales/doorkeeper.lt.yml
new file mode 100644
index 0000000000000000000000000000000000000000..6c5cb837ac8c136ddd4d85ef0a39145c386d62af
--- /dev/null
+++ b/config/locales/doorkeeper.lt.yml
@@ -0,0 +1 @@
+lt:
diff --git a/config/locales/doorkeeper.lv.yml b/config/locales/doorkeeper.lv.yml
new file mode 100644
index 0000000000000000000000000000000000000000..1be0eabc091569fadd234dc415e9a399b26e32c1
--- /dev/null
+++ b/config/locales/doorkeeper.lv.yml
@@ -0,0 +1 @@
+lv:
diff --git a/config/locales/doorkeeper.ms.yml b/config/locales/doorkeeper.ms.yml
new file mode 100644
index 0000000000000000000000000000000000000000..2925688a0330ed791a036a41ffcb8fc31c75352f
--- /dev/null
+++ b/config/locales/doorkeeper.ms.yml
@@ -0,0 +1 @@
+ms:
diff --git a/config/locales/doorkeeper.nl.yml b/config/locales/doorkeeper.nl.yml
index bf6d46f4b0f511fff532348b404bb317ca27ec3c..aa37ea190ad38e4bfaef1bc39e46e812c98effd8 100644
--- a/config/locales/doorkeeper.nl.yml
+++ b/config/locales/doorkeeper.nl.yml
@@ -110,7 +110,6 @@ nl:
       admin:
         nav:
           applications: Toepassingen
-          home: Home
           oauth2_provider: OAuth2-provider
       application:
         title: OAuth-autorisatie vereist
diff --git a/config/locales/doorkeeper.no.yml b/config/locales/doorkeeper.no.yml
index 56c15fab7ce9ef8316c24a8121feaf78b2911403..263fef15ebd6ac8064238d28068cbfb00e2f48e4 100644
--- a/config/locales/doorkeeper.no.yml
+++ b/config/locales/doorkeeper.no.yml
@@ -72,7 +72,6 @@
       index:
         application: Applikasjon
         created_at: Autorisert
-        date_format: "%Y-%m-%d %H:%M:%S"
         scopes: Omfang
         title: Dine autoriserte applikasjoner
     errors:
diff --git a/config/locales/doorkeeper.pl.yml b/config/locales/doorkeeper.pl.yml
index de724f6c97bfa9f9c8c62e318a0727ec88ef46c9..2068eeef466de4038338792deaf90eab96d0c719 100644
--- a/config/locales/doorkeeper.pl.yml
+++ b/config/locales/doorkeeper.pl.yml
@@ -114,6 +114,12 @@ pl:
       application:
         title: Uwierzytelnienie OAuth jest wymagane
     scopes:
+      admin:read: odczytaj wszystkie dane na serwerze
+      admin:read:accounts: odczytaj wrażliwe informacje na wszystkich kontach
+      admin:read:reports: odczytaj wrażliwe informacje ze wszystkich zgłoszeń oraz zgłoszonych kont
+      admin:write: zmodyfikuj wszystkie dane na serwerze
+      admin:write:accounts: wykonaj działania moderacyjne na kontach
+      admin:write:reports: wykonaj działania moderacyjne na zgłoszeniach
       follow: możliwość śledzenia kont
       push: otrzymywanie powiadomień push dla Twojego konta
       read: możliwość odczytu wszystkich danych konta
diff --git a/config/locales/doorkeeper.pt.yml b/config/locales/doorkeeper.pt.yml
index e76cd01fd562c92d87c6f4a546a0342350b96173..f21e84d17f34338898398ed1641d966334b95850 100644
--- a/config/locales/doorkeeper.pt.yml
+++ b/config/locales/doorkeeper.pt.yml
@@ -72,7 +72,6 @@ pt:
       index:
         application: Aplicação
         created_at: Criada em
-        date_format: "%Y-%m-%d %H:%M:%S"
         scopes: Autorizações
         title: As tuas aplicações autorizadas
     errors:
diff --git a/config/locales/doorkeeper.ro.yml b/config/locales/doorkeeper.ro.yml
index fea4baf60dee067ea84fcf9b88fa857a86a862db..79dbaa871cae8753fe261033b12cd507f3536ad9 100644
--- a/config/locales/doorkeeper.ro.yml
+++ b/config/locales/doorkeeper.ro.yml
@@ -1,3 +1 @@
----
 ro:
-  doorkeeper: {}
diff --git a/config/locales/doorkeeper.ru.yml b/config/locales/doorkeeper.ru.yml
index f3731755959e60f738d82ba09c461af969aa2f38..ebe90a18939bd76e909f7087e426834ce7749d8b 100644
--- a/config/locales/doorkeeper.ru.yml
+++ b/config/locales/doorkeeper.ru.yml
@@ -63,7 +63,7 @@ ru:
         prompt: Приложение %{client_name} запрашивает доступ к Вашему аккаунту
         title: Требуется авторизация
       show:
-        title: Copy this authorization code and paste it to the application.
+        title: Скопируйте этот код авторизации и вставьте его в приложении.
     authorized_applications:
       buttons:
         revoke: Отозвать авторизацию
diff --git a/config/locales/doorkeeper.sk.yml b/config/locales/doorkeeper.sk.yml
index 98597ca8bafc14555bcede26d3628537532a68d2..f54eb6d48dca1f3e22cf3b1b5746c8a15694e2fb 100644
--- a/config/locales/doorkeeper.sk.yml
+++ b/config/locales/doorkeeper.sk.yml
@@ -72,7 +72,6 @@ sk:
       index:
         application: Aplikácia
         created_at: Autorizované
-        date_format: "%Y-%m-%d %H:%M:%S"
         scopes: Oprávnenia
         title: Vaše autorizované aplikácie
     errors:
diff --git a/config/locales/doorkeeper.sl.yml b/config/locales/doorkeeper.sl.yml
index c2745708942ac78a6796c4487181d3d938aa2d29..26d92ddb52903adf11504795285d4f67b656ac2e 100644
--- a/config/locales/doorkeeper.sl.yml
+++ b/config/locales/doorkeeper.sl.yml
@@ -4,3 +4,145 @@ sl:
     attributes:
       doorkeeper/application:
         name: Ime programa
+        redirect_uri: Preusmeritev URI
+        scopes: Obsegi
+        website: Spletišče programa
+    errors:
+      models:
+        doorkeeper/application:
+          attributes:
+            redirect_uri:
+              fragment_present: ne more vsebovati fragmenta.
+              invalid_uri: mora biti veljaven URI.
+              relative_uri: mora biti absolutni URI.
+              secured_uri: mora biti HTTPS/SSL URI.
+  doorkeeper:
+    applications:
+      buttons:
+        authorize: Overi
+        cancel: Prekliči
+        destroy: Uniči
+        edit: Uredi
+        submit: Pošlji
+      confirmations:
+        destroy: Ali ste prepričani?
+      edit:
+        title: Uredi aplikacijo
+      form:
+        error: Ups! Preverite obrazec za morebitne napake
+      help:
+        native_redirect_uri: Uporabite %{native_redirect_uri} za krajevne preizkuse
+        redirect_uri: Uporabite eno vrstico na URI
+        scopes: Ločite obsege s presledki. Pustite prazno, da uporabite privzete obsege.
+      index:
+        application: Program
+        callback_url: Povratni URL
+        delete: Izbriši
+        name: Ime
+        new: Nov program
+        scopes: Obsegi
+        show: Pokaži
+        title: Vaši programi
+      new:
+        title: Nov program
+      show:
+        actions: Dejanja
+        application_id: Ključ odjemalca
+        callback_urls: Povratni URL-ji
+        scopes: Obsegi
+        secret: Skrivnost odjemalca
+        title: 'Program: %{name}'
+    authorizations:
+      buttons:
+        authorize: Overi
+        deny: Zavrni
+      error:
+        title: Prišlo je do napake
+      new:
+        able_to: To bo lahko
+        prompt: Program %{client_name} zahteva dostop do vašega računa
+        title: Potrebna je pooblastitev
+      show:
+        title: Kopirajte to pooblastilno kodo in jo prilepite v program.
+    authorized_applications:
+      buttons:
+        revoke: Prekliči
+      confirmations:
+        revoke: Ali ste prepričani?
+      index:
+        application: Program
+        created_at: Odobreno
+        date_format: "%Y-%m-%d %H:%M:%S"
+        scopes: Obsegi
+        title: Vaši odobreni programi
+    errors:
+      messages:
+        access_denied: Lastnik virov ali strežnik pooblastil je zavrnil zahtevo.
+        credential_flow_not_configured: Pretok geselskih pooblastil lastnika virov ni uspel, ker Doorkeeper.configure.resource_owner_from_credentials ni nastavljen.
+        invalid_client: Overitev odjemalca ni uspelo zaradi neznanega odjemalca, zaradi nevključitve overitve odjemalca ali zaradi nepodprte metode overitve.
+        invalid_grant: Predložena odobritev za pooblastilo je neveljavna, potekla, preklicana, se ne ujema z URI preusmeritvijo, ki je uporabljena v zahtevi za pooblastilo ali je bila izdana drugemu odjemalcu.
+        invalid_redirect_uri: URI za preusmeritev ni veljaven.
+        invalid_request: Zahtevku manjka zahtevan parameter, vključuje nepodprto vrednost parametra ali je nepravilno oblikovan.
+        invalid_resource_owner: Predložene poverilnice lastnika virov niso veljavne ali pa lastnika virov ni mogoče najti
+        invalid_scope: Zahtevani obseg je neveljaven, neznan ali nepravilen.
+        invalid_token:
+          expired: Žeton za dostop je pretekel
+          revoked: Žeton za dostop je bil preklican
+          unknown: Žeton za dostop je neveljaven
+        resource_owner_authenticator_not_configured: Iskanje lastnika virov ni uspelo, ker Doorkeeper.configure.resource_owner_authenticator ni nastavljen.
+        server_error: Strežnik pooblastil je naletel na nepričakovano stanje, ki je preprečilo, da bi izpolnil zahtevo.
+        temporarily_unavailable: Strežnik pooblastil, zaradi začasne preobremenitve ali vzdrževanja, trenutno ne more obdelati zahteve.
+        unauthorized_client: Odjemalec nima pooblastila za izvajanje te zahteve po tej metodi.
+        unsupported_grant_type: Strežnik pooblastil ne podpira vrste odobritve pooblastila.
+        unsupported_response_type: Strežnik pooblastil ne podpira te vrste odziva.
+    flash:
+      applications:
+        create:
+          notice: Program je ustvarjen.
+        destroy:
+          notice: Program je izbrisan.
+        update:
+          notice: Program je posodobljen.
+      authorized_applications:
+        destroy:
+          notice: Program je preklican.
+    layouts:
+      admin:
+        nav:
+          applications: Programi
+          oauth2_provider: Ponudnik OAuth2
+      application:
+        title: Potrebna je OAuth pooblastitev
+    scopes:
+      admin:read: preberi vse podatke na strežniku
+      admin:read:accounts: preberi občutljive informacije vseh računov
+      admin:read:reports: preberi občutljive informacije vseh prijav in prijavljenih računov
+      admin:write: spremeni vse podatke na strežniku
+      admin:write:accounts: izvedi moderirana dejanja na računih
+      admin:write:reports: izvedi moderirana dejanja na prijavah
+      follow: spremeni razmerja med računi
+      push: prejmi potisna obvestila
+      read: preberi vse podatke svojega računa
+      read:accounts: oglejte si podrobnosti računov
+      read:blocks: oglejte si svoje blokirane
+      read:favourites: oglejte si svoje priljubljene
+      read:filters: oglejte si svoje filtre
+      read:follows: oglejte si svoje sledilce
+      read:lists: oglejte si svoje sezname
+      read:mutes: oglejte si svoje utišane
+      read:notifications: oglejte si svoja obvestila
+      read:reports: oglejte si svoje prijave
+      read:search: iščite v svojem imenu
+      read:statuses: oglejte si vsa stanja
+      write: spremenite vse podatke svojega računa
+      write:accounts: spremenite svoj profil
+      write:blocks: blokirajte račune in domene
+      write:favourites: priljubljena stanja
+      write:filters: ustvari filtre
+      write:follows: sledi osebam
+      write:lists: ustvarite sezname
+      write:media: pošlji medije
+      write:mutes: utišaj osebe in pogovore
+      write:notifications: počisti svoja obvestila
+      write:reports: prijavi druge osebe
+      write:statuses: objavi stanja
diff --git a/config/locales/doorkeeper.sq.yml b/config/locales/doorkeeper.sq.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a1f2121f9f70de736a20a79a5b03daf4dfdfe548
--- /dev/null
+++ b/config/locales/doorkeeper.sq.yml
@@ -0,0 +1,142 @@
+---
+sq:
+  activerecord:
+    attributes:
+      doorkeeper/application:
+        name: Emër aplikacioni
+        redirect_uri: URI Ridrejtimi
+        scopes: Fushëveprime
+        website: Sajt aplikacioni
+    errors:
+      models:
+        doorkeeper/application:
+          attributes:
+            redirect_uri:
+              fragment_present: s’mund të përmbajë një fragment.
+              invalid_uri: duhet të jetë një URI e vlefshme.
+              relative_uri: duhet të jetë një URI absolute.
+              secured_uri: duhet të jetë një URI HTTPS/SSL.
+  doorkeeper:
+    applications:
+      buttons:
+        authorize: Autorizoje
+        cancel: Anuloje
+        destroy: Asgjësoje
+        edit: Përpunoni
+        submit: Parashtroje
+      confirmations:
+        destroy: A jeni i sigurt?
+      edit:
+        title: Përpunoni aplikacion
+      form:
+        error: Oh! Kontrolloni formularin tuaj për gabime të mundshme
+      help:
+        native_redirect_uri: Përdor %{native_redirect_uri} për teste vendore
+        redirect_uri: Përdorni një URI për rresht
+        scopes: Ndajini fushëveprimet me hapësira. Që të përdoren fushëveprimet parazgjedhje, lëreni të zbrazët.
+      index:
+        application: Aplikacion
+        callback_url: URL Callback-u
+        delete: Fshije
+        name: Emër
+        new: Aplikacion i ri
+        scopes: Fushëveprime
+        show: Shfaqe
+        title: Aplikacionet tuaja
+      new:
+        title: Aplikacion i ri
+      show:
+        actions: Veprime
+        application_id: Kyç klienti
+        callback_urls: URL-ra Callback
+        scopes: Fushëveprime
+        secret: E fshehtë klienti
+        title: 'Aplikacion: %{name}'
+    authorizations:
+      buttons:
+        authorize: Autorizoje
+        deny: Mohoje
+      error:
+        title: Ndodhi një gabim
+      new:
+        able_to: Do të jetë në gjendje të
+        prompt: "%{client_name} kërkesa hyrjeje aplikacionesh te llogaria juaj"
+        title: Lypset autorizim
+      show:
+        title: Kopjojeni këtë kod autorizimi dhe ngjiteni te aplikacioni.
+    authorized_applications:
+      buttons:
+        revoke: Shfuqizoje
+      confirmations:
+        revoke: A jeni i sigurt?
+      index:
+        application: Aplikacion
+        created_at: I autorizuar
+        date_format: "%d.%m.%Y, %H:%M:%S"
+        scopes: Fushëveprime
+        title: Aplikacionet tuaja të autorizuara
+    errors:
+      messages:
+        access_denied: I zoti i burimit ose shërbyesi i autorizimit e hodhi poshtë kërkesën.
+        credential_flow_not_configured: Rrjedha e Kredencialeve të Fjalëkalimit të të Zotit të Burimit dështoi për shkak se Doorkeeper.configure.resource_owner_from_credentials është i paformësuar.
+        invalid_client: Mirëfilltësimi i klientit dështoi për shkak klienti të panjohur, mospërfshirjeje mirëfilltësimi klienti, ose metode të pambuluar mirëfilltësimi.
+        invalid_grant: Autorizimi i dhënë është i pavlefshëm, ka skaduar, është shfuqizuar, nuk përputhet me URI-n e ridrejtimit të përdorur te kërkesa e autorizimit, ose është emetuar për klient tjetër.
+        invalid_redirect_uri: URI e ridrejtimit s’është e vlefshme.
+        invalid_request: Kërkesës i mungon një parametër i domosdoshëm, përfshin një vlerë të pambuluar parametri, ose përndryshe është e keqformuar.
+        invalid_resource_owner: Kredencialet e dhëna për të zotin e burimit s’janë të vlefshme, ose s’gjendet i zoti i burimit
+        invalid_scope: Fushëveprimi i kërkuar është i pavlefshëm, i panjohur ose i keqformuar.
+        invalid_token:
+          expired: Token-i i hyrjeve skadoi
+          revoked: Token-i i hyrjeve u shfuqizua
+          unknown: Token-i i hyrjeve është i pavlefshëm
+        resource_owner_authenticator_not_configured: Gjetja e të Zotit të Burimit dështoi, ngaqë Doorkeeper.configure.resource_owner_authenticator s’është i formësuar.
+        server_error: Shërbyesi i autorizimit hasi një kusht të papritur, i cili e pengoi të plotësonte kërkesën.
+        temporarily_unavailable: Shërbyesi i mirëfilltësimeve hëpërhë s’është në gjendje të trajtojë kërkesën, për shkak të një mbingarkese të përkohshme ose ndonjë mirëmbajtjeje të shërbyesit.
+        unauthorized_client: Klienti s’është i autorizuar të kryejë këtë kërkesë duke përdorur këtë metodë.
+        unsupported_grant_type: Lloji i autorizimit të dhënë nuk mbulohet nga shërbyesi i autorizimeve.
+        unsupported_response_type: Shërbyesi i autorizimeve nuk e mbulon këtë lloj përgjigjeje.
+    flash:
+      applications:
+        create:
+          notice: Aplikacioni u krijua.
+        destroy:
+          notice: Aplikacioni u fshi.
+        update:
+          notice: Aplikacioni u përditësua.
+      authorized_applications:
+        destroy:
+          notice: Aplikacioni u shfuqizua.
+    layouts:
+      admin:
+        nav:
+          applications: Aplikacione
+          oauth2_provider: Furnizues OAuth2
+      application:
+        title: Lypset autorizim OAuth
+    scopes:
+      follow: të ndryshojë marrëdhënies llogarish
+      push: të marrë njoftime push për ju
+      read: të lexojë krejt të dhënat e llogarisë tuaj
+      read:accounts: të shohë të dhëna llogarish
+      read:blocks: të shohë blloqet tuaja
+      read:favourites: të shohë të parapëlqyerit tuaj
+      read:filters: të shohë filtrat tuaj
+      read:follows: të shohë ndjekësit tuaj
+      read:lists: të shohë listat tuaja
+      read:mutes: të shohë ç’keni heshtuar
+      read:notifications: të shohë njoftimet tuaja
+      read:reports: të shohë raportet tuaja
+      read:search: të bëjë kërkime në emrin tuaj
+      read:statuses: të shohë krejt gjendjet
+      write: të ndryshojë krejt të dhënat e llogarisë tuaj
+      write:accounts: të ndryshojë profilin tuaj
+      write:blocks: të bllokojë llogari dhe përkatësi
+      write:favourites: të parapëlqejë gjendje
+      write:filters: të krijojë filtra
+      write:follows: të ndjekë persona
+      write:lists: të krijojë lista
+      write:media: të ngarkojë kartela media
+      write:mutes: të heshtojë persona dhe biseda
+      write:notifications: të pastrojë njoftimet tuaja
+      write:reports: të raportojë persona të tjerë
+      write:statuses: të botojë gjendje
diff --git a/config/locales/doorkeeper.sv.yml b/config/locales/doorkeeper.sv.yml
index 25440cbb0b9b23f651b9f604a4ff2e1cd813f670..4fd246eff2fb3b3375e9aca13d4e5502fb90d7fb 100644
--- a/config/locales/doorkeeper.sv.yml
+++ b/config/locales/doorkeeper.sv.yml
@@ -72,7 +72,6 @@ sv:
       index:
         application: Applikation
         created_at: Auktoriserad
-        date_format: "%Y-%m-%d %H:%M:%S"
         scopes: Omfattning
         title: Dina behöriga ansökningar
     errors:
diff --git a/config/locales/doorkeeper.ta.yml b/config/locales/doorkeeper.ta.yml
new file mode 100644
index 0000000000000000000000000000000000000000..4320953ce2ab23ded9cc319b3002dfc1bc13903a
--- /dev/null
+++ b/config/locales/doorkeeper.ta.yml
@@ -0,0 +1 @@
+ta:
diff --git a/config/locales/doorkeeper.te.yml b/config/locales/doorkeeper.te.yml
new file mode 100644
index 0000000000000000000000000000000000000000..34c54f18f624c6d89026a04bd92ebc0df9c63e48
--- /dev/null
+++ b/config/locales/doorkeeper.te.yml
@@ -0,0 +1 @@
+te:
diff --git a/config/locales/doorkeeper.th.yml b/config/locales/doorkeeper.th.yml
index 60edae1e4c71ed0af93565018a8baaa9d70eb2ee..5866baa43b2108ffa871d7a3a3d4f916afaeb411 100644
--- a/config/locales/doorkeeper.th.yml
+++ b/config/locales/doorkeeper.th.yml
@@ -3,111 +3,120 @@ th:
   activerecord:
     attributes:
       doorkeeper/application:
-        name: ชื่อ
-        redirect_uri: เปลี่ยนเส้นทาง URI
+        name: ชื่อแอปพลิเคชัน
+        redirect_uri: URI การเปลี่ยนเส้นทาง
+        scopes: ขอบเขต
+        website: เว็บไซต์แอปพลิเคชัน
     errors:
       models:
         doorkeeper/application:
           attributes:
             redirect_uri:
-              fragment_present: cannot contain a fragment.
-              invalid_uri: ต้องใช้ URI ที่ถูกต้อง.
-              relative_uri: ต้องเป็น absolute URI.
-              secured_uri: ต้องใช้ HTTPS/SSL URI.
+              fragment_present: ไม่สามารถมีส่วนย่อย
+              invalid_uri: ต้องเป็น URI ที่ถูกต้อง
+              relative_uri: ต้องเป็น URI แบบเต็ม
+              secured_uri: ต้องเป็น URI แบบ HTTPS/SSL
   doorkeeper:
     applications:
       buttons:
-        authorize: Authorize
+        authorize: อนุญาต
         cancel: ยกเลิก
         destroy: ทำลาย
         edit: แก้ไข
-        submit: Submit
+        submit: ส่ง
       confirmations:
-        destroy: แน่ใจนะ?
+        destroy: คุณแน่ใจหรือไม่?
       edit:
-        title: แก้ไข แอ๊ฟพลิเคชั่น
-      form:
-        error: Whoops! Check your form for possible errors
+        title: แก้ไขแอปพลิเคชัน
       help:
-        native_redirect_uri: ใช้ %{native_redirect_uri} สำหรับการทดสอบ
-        redirect_uri: ใช้บรรทัดละหนึ่ง URI
-        scopes: Separate scopes with spaces. Leave blank to use the default scopes.
+        native_redirect_uri: ใช้ %{native_redirect_uri} สำหรับการทดสอบในเว็บ
+        redirect_uri: ใช้หนึ่งบรรทัดต่อ URI
+        scopes: แยกขอบเขตด้วยช่องว่าง เว้นว่างเพื่อใช้ขอบเขตเริ่มต้น
       index:
-        callback_url: Callback URL
+        application: แอปพลิเคชัน
+        callback_url: URL เรียกกลับ
+        delete: ลบ
         name: ชื่อ
-        new: New Application
-        title: Your applications
+        new: แอปพลิเคชันใหม่
+        scopes: ขอบเขต
+        show: แสดง
+        title: แอปพลิเคชันของคุณ
       new:
-        title: New Application
+        title: แอปพลิเคชันใหม่
       show:
-        actions: Actions
-        application_id: Application Id
-        callback_urls: Callback urls
-        scopes: Scopes
-        secret: Secret
-        title: 'Application: %{name}'
+        actions: การกระทำ
+        application_id: กุญแจไคลเอ็นต์
+        callback_urls: URL เรียกกลับ
+        scopes: ขอบเขต
+        secret: รหัสลับไคลเอ็นต์
+        title: 'แอปพลิเคชัน: %{name}'
     authorizations:
       buttons:
-        authorize: อนุญาติ
-        deny: ไม่อนุญาติ
+        authorize: อนุญาต
+        deny: ปฏิเสธ
       error:
-        title: An error has occurred
+        title: เกิดข้อผิดพลาด
       new:
-        able_to: It will be able to
-        prompt: Application %{client_name} requests access to your account
-        title: Authorization required
+        able_to: แอปจะสามารถ
+        prompt: แอปพลิเคชัน %{client_name} ขอเข้าถึงบัญชีของคุณ
+        title: ต้องมีการอนุญาต
       show:
-        title: Copy this authorization code and paste it to the application.
+        title: คัดลอกรหัสการอนุญาตนี้แล้ววางลงในแอปพลิเคชัน
     authorized_applications:
       buttons:
-        revoke: ยกเลิกการอนุญาติ
+        revoke: เพิกถอน
       confirmations:
-        revoke: Are you sure?
+        revoke: คุณแน่ใจหรือไม่?
       index:
-        application: Application
-        created_at: Authorized
-        date_format: "%Y-%m-%d %H:%M:%S"
-        scopes: Scopes
-        title: Your authorized applications
+        application: แอปพลิเคชัน
+        created_at: อนุญาตเมื่อ
+        scopes: ขอบเขต
+        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.
-        invalid_token:
-          expired: The access token expired
-          revoked: The access token was revoked
-          unknown: The access token is invalid
-        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: The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.
-        unauthorized_client: The client is not authorized to perform this request using this method.
-        unsupported_grant_type: The authorization grant type is not supported by the authorization server.
-        unsupported_response_type: The authorization server does not support this response type.
+        access_denied: เจ้าของทรัพยากรหรือเซิร์ฟเวอร์การอนุญาตปฏิเสธคำขอ
     flash:
       applications:
         create:
-          notice: Application created.
+          notice: สร้างแอปพลิเคชันแล้ว
         destroy:
-          notice: Application deleted.
+          notice: ลบแอปพลิเคชันแล้ว
         update:
-          notice: Application updated.
+          notice: อัปเดตแอปพลิเคชันแล้ว
       authorized_applications:
         destroy:
-          notice: Application revoked.
+          notice: เพิกถอนแอปพลิเคชันแล้ว
     layouts:
       admin:
         nav:
-          applications: Applications
-          oauth2_provider: OAuth2 Provider
+          applications: แอปพลิเคชัน
+          oauth2_provider: ผู้ให้บริการ OAuth2
       application:
-        title: OAuth authorization required
+        title: ต้องมีการอนุญาต OAuth
     scopes:
-      follow: follow, block, unblock and unfollow accounts
-      read: read your account's data
-      write: post on your behalf
+      follow: ปรับเปลี่ยนความสัมพันธ์ของบัญชี
+      push: รับการแจ้งเตือนแบบผลักของคุณ
+      read: อ่านข้อมูลบัญชีทั้งหมดของคุณ
+      read:accounts: ดูข้อมูลบัญชี
+      read:blocks: ดูการปิดกั้นของคุณ
+      read:favourites: ดูรายการโปรดของคุณ
+      read:filters: ดูตัวกรองของคุณ
+      read:follows: ดูการติดตามของคุณ
+      read:lists: ดูรายการของคุณ
+      read:mutes: ดูการปิดเสียงของคุณ
+      read:notifications: ดูการแจ้งเตือนของคุณ
+      read:reports: ดูรายงานของคุณ
+      read:search: ค้นหาในนามของคุณ
+      read:statuses: ดูสถานะทั้งหมด
+      write: ปรับเปลี่ยนข้อมูลบัญชีทั้งหมดของคุณ
+      write:accounts: ปรับเปลี่ยนโปรไฟล์ของคุณ
+      write:blocks: ปิดกั้นบัญชีและโดเมน
+      write:favourites: ชื่นชอบสถานะ
+      write:filters: สร้างตัวกรอง
+      write:follows: ติดตามผู้คน
+      write:lists: สร้างรายการ
+      write:media: อัปโหลดไฟล์สื่อ
+      write:mutes: ปิดเสียงผู้คนและการสนทนา
+      write:notifications: ล้างการแจ้งเตือนของคุณ
+      write:reports: รายงานผู้คนอื่น ๆ
+      write:statuses: เผยแพร่สถานะ
diff --git a/config/locales/doorkeeper.tr.yml b/config/locales/doorkeeper.tr.yml
new file mode 100644
index 0000000000000000000000000000000000000000..686a018e0a6a6355dc8b4ae02347ab199e21dc77
--- /dev/null
+++ b/config/locales/doorkeeper.tr.yml
@@ -0,0 +1,19 @@
+---
+tr:
+  activerecord:
+    attributes:
+      doorkeeper/application:
+        name: Uygulama adı
+        website: Uygulama web sitesi
+  doorkeeper:
+    applications:
+      buttons:
+        authorize: Yetki ver
+        cancel: İptal et
+        destroy: Yok et
+        edit: Düzenle
+        submit: Gönder
+      confirmations:
+        destroy: Emin misiniz?
+      edit:
+        title: Uygulamayı düzenle
diff --git a/config/locales/doorkeeper.uk.yml b/config/locales/doorkeeper.uk.yml
index 205ad026f1e69255ff069f0ad9d086efc47182b4..305a5c1d6f53052587c4fe157fbf4272dc3ed715 100644
--- a/config/locales/doorkeeper.uk.yml
+++ b/config/locales/doorkeeper.uk.yml
@@ -58,8 +58,6 @@ uk:
         able_to: Він зможе
         prompt: Податок %{client_name} просить доступу до вашого акаунту
         title: Необхідна авторизація
-      show:
-        title: Copy this authorization code and paste it to the application.
     authorized_applications:
       buttons:
         revoke: Відкликати авторизацію
diff --git a/config/locales/doorkeeper.zh-CN.yml b/config/locales/doorkeeper.zh-CN.yml
index 3c7dd99be4f7174eb96f9f2cf5b82694c64abbe7..dd9337904acc1017dee5e19b7dc11a8b6f9292db 100644
--- a/config/locales/doorkeeper.zh-CN.yml
+++ b/config/locales/doorkeeper.zh-CN.yml
@@ -72,7 +72,6 @@ zh-CN:
       index:
         application: 应用
         created_at: 授权时间
-        date_format: "%Y-%m-%d %H:%M:%S"
         scopes: 权限范围
         title: 已授权的应用列表
     errors:
@@ -114,7 +113,35 @@ zh-CN:
       application:
         title: 需要 OAuth 认证
     scopes:
+      admin:read: 读取服务器上的所有数据
+      admin:read:accounts: 读取所有账户的敏感信息
+      admin:read:reports: 读取所有举报和被举报账户的敏感信息
+      admin:write: 修改服务器上的所有数据
+      admin:write:accounts: 对账户执行管理操作
+      admin:write:reports: 对举报执行管理操作
       follow: 关注或屏蔽用户
       push: 接收你的帐户的推送通知
       read: 读取你的帐户数据
-      write: 为你发表嘟文
+      read:accounts: 查看账户信息
+      read:blocks: 查看你的屏蔽列表
+      read:favourites: 查看你的收藏
+      read:filters: 查看你的过滤器
+      read:follows: 查看你的关注
+      read:lists: 查看你的列表
+      read:mutes: 查看你的隐藏列表
+      read:notifications: 查看你的通知
+      read:reports: 查看你的举报
+      read:search: 以你的身份搜索
+      read:statuses: 查看所有嘟文
+      write: 修改你的账户数据
+      write:accounts: 修改你的个人资料
+      write:blocks: 屏蔽账户和域名
+      write:favourites: 收藏嘟文
+      write:filters: 创建过滤器
+      write:follows: 关注其他人
+      write:lists: 创建列表
+      write:media: 上传媒体文件
+      write:mutes: 隐藏用户和对话
+      write:notifications: 清除你的通知
+      write:reports: 举报他人
+      write:statuses: 发表嘟文
diff --git a/config/locales/doorkeeper.zh-HK.yml b/config/locales/doorkeeper.zh-HK.yml
index 19ed76d1a5b7f3801b37f0fce6ac820f7e1a7e55..d9c91caf0865aa689ff177e579e16cf223914a05 100644
--- a/config/locales/doorkeeper.zh-HK.yml
+++ b/config/locales/doorkeeper.zh-HK.yml
@@ -72,7 +72,6 @@ zh-HK:
       index:
         application: 應用程式
         created_at: 授權日期
-        date_format: "%Y-%m-%d %H:%M:%S"
         scopes: 權限範圍
         title: 已獲你授權的程用程式
     errors:
diff --git a/config/locales/doorkeeper.zh-TW.yml b/config/locales/doorkeeper.zh-TW.yml
index 690fc4513e436be5589595bc26dfbf0a4bf2442d..41dd17264072aa3d507391c25d6f9a3722dc034a 100644
--- a/config/locales/doorkeeper.zh-TW.yml
+++ b/config/locales/doorkeeper.zh-TW.yml
@@ -72,7 +72,6 @@ zh-TW:
       index:
         application: 應用程式
         created_at: 授權時間
-        date_format: "%Y-%m-%d %H:%M:%S"
         scopes: 權限範圍
         title: 已授權的應用程式
     errors:
diff --git a/config/locales/el.yml b/config/locales/el.yml
index 5930ef3e9ba21f8a5a0a902e78a8f5a53b29d944..a08ec71416f5f88c0cc0faf0250cfb45ed858d7c 100644
--- a/config/locales/el.yml
+++ b/config/locales/el.yml
@@ -4,36 +4,36 @@ el:
     about_hashtag_html: Αυτά είναι κάποια από τα δημόσια τουτ σημειωμένα με <strong>#%{hashtag}</strong>. Μπορείς να αλληλεπιδράσεις με αυτά αν έχεις λογαριασμό οπουδήποτε στο fediverse.
     about_mastodon_html: Το Mastodon είναι ένα κοινωνικό δίκτυο που βασίζεται σε ανοιχτά δικτυακά πρωτόκολλα και ελεύθερο λογισμικό ανοιχτού κώδικα. Είναι αποκεντρωμένο όπως το e-mail.
     about_this: Σχετικά
+    active_count_after: ενεργοί
+    active_footnote: Μηνιαίοι Ενεργοί Χρήστες (ΜΕΧ)
     administered_by: 'Διαχειριστής:'
     api: API
     apps: Εφαρμογές κινητών
-    closed_registrations: Αυτή τη στιγμή οι εγγραφές σε αυτό τον κόμβο είναι κλειστές. Αλλά! Μπορείς να βρεις έναν άλλο κόμβο για να ανοίξεις λογαριασμό και να έχεις πρόσβαση από εκεί στο ίδιο ακριβώς δίκτυο.
+    apps_platforms: Χρησιμοποίησε το Mastodon από το iOS, το Android και αλλού
+    browse_directory: Ξεφύλλισε ένα κατάλογο χρηστών και φίλτραρε ανά ενδιαφέροντα
+    browse_public_posts: Κοίταξε μια ζωντανή ροή δημοσιεύσεων στο Mastodon
     contact: Επικοινωνία
     contact_missing: Δεν έχει οριστεί
     contact_unavailable: Μ/Δ
+    discover_users: Ανακάλυψε χρήστες
     documentation: Τεκμηρίωση
     extended_description_html: |
       <h3>Ένα καλό σημείο για κανόνες</h3>
       <p>Η αναλυτική περιγραφή δεν έχει ακόμα οριστεί</p>
-    features:
-      humane_approach_body: Μαθαίνοντας από τις αποτυχίες άλλων δικτύων, το Mastodon στοχεύει να κάνει σχεδιαστικά ηθικές επιλογές για να καταπολεμήσει την κακόβουλη χρήση των κοινωνικών δικτύων.
-      humane_approach_title: Μια πιο ανθρώπινη προσέγγιση
-      not_a_product_body: Το Mastodon δεν είναι ένα εμπορικό δίκτυο. Δεν έχει διαφημίσεις, δεν έχει εξόρυξη δεδομένων, δεν έχει περιφραγμένους κήπους. Δεν υπάρχει κεντρικό σημείο ελέγχου.
-      not_a_product_title: Είσαι άνθρωπος, όχι προϊόν
-      real_conversation_body: Με 65,535 χαρακτήρες στη διάθεσή σου και υποστήριξη για λεπτομερή έλεγχο και προειδοποιήσεις πολυμέσων, μπορείς να εκφραστείς με τον τρόπο που θέλεις.
-      real_conversation_title: Φτιαγμένο για αληθινή συζήτηση
-      within_reach_body: Οι πολλαπλές εφαρμογές για το iOS, το Android και τις υπόλοιπες πλατφόρμες, χάρη σε ένα φιλικό προς τους προγραμματιστές οικοσύστημα API, σου επιτρέπουν να κρατάς επαφή με τους φίλους και τις φίλες σου οπουδήποτε.
-      within_reach_title: Πάντα προσβάσιμο
+    federation_hint_html: Με ένα λογαριασμό στο %{instance} θα μπορείς να ακολουθείς ανθρώπους σε οποιοδήποτε κόμβο στο Mastodon αλλά και αλλού.
     generic_description: "%{domain} είναι ένας εξυπηρετητής στο δίκτυο"
+    get_apps: Δοκίμασε μια εφαρμογή κινητού
     hosted_on: Το Mastodon φιλοξενείται στο %{domain}
     learn_more: Μάθε περισσότερα
-    other_instances: Λίστα κόμβων
     privacy_policy: Πολιτική απορρήτου
+    see_whats_happening: Μάθε τι συμβαίνει
+    server_stats: 'Στατιστικά κόμβου:'
     source_code: Πηγαίος κώδικας
     status_count_after:
       one: δημοσίευση
       other: δημοσιεύσεις
     status_count_before: Που έγραψαν
+    tagline: Ακολούθησε τους γνωστούς σου και ανακάλυψε νέους ανθρώπους
     terms: Όροι χρήσης
     user_count_after:
       one: χρήστης
@@ -41,7 +41,7 @@ el:
     user_count_before: Σπίτι για
     what_is_mastodon: Τι είναι το Mastodon;
   accounts:
-    choices_html: 'Επιλογές του/της %{name}:'
+    choices_html: 'Επιλογές από %{name}:'
     follow: Ακολούθησε
     followers:
       one: Ακόλουθος
@@ -68,6 +68,7 @@ el:
       admin: Διαχειριστής
       bot: Μποτ (αυτόματος λογαριασμός)
       moderator: Μεσολαβητής
+    unavailable: Το προφίλ δεν είναι διαθέσιμο
     unfollow: Διακοπή παρακολούθησης
   admin:
     account_actions:
@@ -79,6 +80,8 @@ el:
       delete: Διαγραφή
       destroyed_msg: Επιτυχής καταστροφή σημειώματος μεσολάβησης!
     accounts:
+      approve: Έγκριση
+      approve_all: Έγκριση όλων
       are_you_sure: Σίγουρα;
       avatar: Αβατάρ
       by_domain: Τομέας
@@ -115,7 +118,7 @@ el:
       joined: Γράφτηκε
       location:
         all: Όλες
-        local: Τοπικά
+        local: Τοπική
         remote: Απομακρυσμένα
         title: Τοποθεσία
       login_status: Κατάσταση σύνδεσης
@@ -124,15 +127,18 @@ el:
       moderation:
         active: Ενεργός/ή
         all: Όλα
+        pending: Εκκρεμούν
         silenced: Αποσιωπημένα
         suspended: Σε αναστολή
         title: Μεσολάβηση
       moderation_notes: Σημειώσεις μεσολάβησης
       most_recent_activity: Πιο πρόσφατη δραστηριότητα
       most_recent_ip: Πιο πρόσφατη IP
+      no_account_selected: Κανείς λογαριασμός δεν ενημερώθηκε αφού κανείς δεν ήταν επιλεγμένος
       no_limits_imposed: Χωρίς όρια
       not_subscribed: Άνευ συνδρομής
       outbox_url: URL εξερχομένων
+      pending: Εκκρεμεί έγκριση
       perform_full_suspension: Αναστολή
       profile_url: URL προφίλ
       promote: Προβίβασε
@@ -140,6 +146,8 @@ el:
       public: Δημόσιο
       push_subscription_expires: Η εγγραφή PuSH λήγει
       redownload: Ανανέωση αβατάρ
+      reject: Απόρριψη
+      reject_all: Απόρριψη όλων
       remove_avatar: Απομακρυσμένο αβατάρ
       remove_header: Αφαίρεση επικεφαλίδας
       resend_confirmation:
@@ -166,6 +174,7 @@ el:
       statuses: Καταστάσεις
       subscribe: Εγγραφή
       suspended: Σε αναστολή
+      time_in_queue: Σε αναμονή για %{time}
       title: Λογαριασμοί
       unconfirmed_email: Ανεπιβεβαίωτο email
       undo_silenced: Αναίρεση αποσιώπησης
@@ -241,6 +250,7 @@ el:
       feature_profile_directory: Κατάλογος χρηστών
       feature_registrations: Εγγραφές
       feature_relay: Ανταποκριτής ομοσπονδίας
+      feature_timeline_preview: Προεπισκόπιση ροής
       features: Λειτουργίες
       hidden_service: Ομοσπονδία με κρυμμένες υπηρεσίες
       open_reports: ανοιχτές καταγγελίες
@@ -260,6 +270,7 @@ el:
       created_msg: Ο αποκλεισμός τομέα είναι υπό επεξεργασία
       destroyed_msg: Ο αποκλεισμός τομέα άρθηκε
       domain: Τομέας
+      existing_domain_block_html: Έχεις ήδη επιβάλλει αυστηρότερους περιορισμούς στο %{name}, πρώτα θα πρέπει να τους <a href="%{unblock_url}">αναιρέσεις</a>.
       new:
         create: Δημιουργία αποκλεισμού
         hint: Ο αποκλεισμός τομέα δεν θα αποτρέψει νέες καταχωρίσεις λογαριασμών στην βάση δεδομένων, αλλά θα εφαρμόσει αναδρομικά και αυτόματα συγκεκριμένες πολιτικές μεσολάβησης σε αυτούς τους λογαριασμούς.
@@ -302,6 +313,7 @@ el:
       back_to_account: Επιστροφή στον λογαριασμό
       title: Ακόλουθοι του/της %{acct}
     instances:
+      by_domain: Τομέας
       delivery_available: Διαθέσιμη παράδοση
       known_accounts:
         one: "%{count} γνωστός λογαριασμός"
@@ -324,6 +336,8 @@ el:
         expired: Ληγμένες
         title: Φίλτρο
       title: Προσκλήσεις
+    pending_accounts:
+      title: Λογαριασμοί σε αναμονή (%{count})
     relays:
       add_new: Πρόσθεσε νέο ανταποκριτή (relay)
       delete: Διαγραφή
@@ -410,9 +424,12 @@ el:
         min_invite_role:
           disabled: Κανείς
           title: Επέτρεψε προσκλήσεις από
-        open:
-          desc_html: Επέτρεψε σε οποιονδήποτε να δημιουργήσει λογαριασμό
-          title: Άνοιξε τις εγγραφές
+      registrations_mode:
+        modes:
+          approved: Απαιτείται έγκριση για εγγραφή
+          none: Δεν μπορεί να εγγραφεί κανείς
+          open: Μπορεί να εγγραφεί ο οποιοσδήποτε
+        title: Μέθοδος εγγραφής
       show_known_fediverse_at_about_page:
         desc_html: Όταν αντιστραφεί, θα δείχνει τα τουτ από όλο το γνωστό fediverse στην προεπισκόπηση. Διαφορετικά θα δείχνει μόνο τοπικά τουτ.
         title: Εμφάνιση του γνωστού fediverse στην προεπισκόπηση ροής
@@ -423,10 +440,10 @@ el:
         desc_html: Εισαγωγική παράγραφος στην αρχική σελίδα. Περιέγραψε τι κάνει αυτό τον διακομιστή Mastodon διαφορετικό και ό,τι άλλο ενδιαφέρον. Μπορείς να χρησιμοποιήσεις HTML tags, συγκεκριμένα <code>&lt; a&gt;</code> και <code> &lt; em&gt;</code>.
         title: Περιγραφή κόμβου
       site_description_extended:
-        desc_html: Ένα καλό μέρος για τον κώδικα δεοντολογίας, τους κανόνες, τις οδηγίες και ό,τι άλλο διαφοροποιεί τον κόμβο σου. Δέχεται και κώδικα HTML
+        desc_html: Ένα καλό μέρος για τον κώδικα δεοντολογίας, τους κανόνες, τις οδηγίες και ό,τι άλλο διαφοροποιεί τον κόμβο σου. Μπορείς να χρησιμοποιήσεις και κώδικα HTML
         title: Προσαρμοσμένες εκτεταμένες πληροφορίες
       site_short_description:
-        desc_html: Εμφανίζεται στην πλαϊνή μπάρα και στα meta tags. Περιέγραψε τι είναι το Mastodon και τι κάνει αυτό τον διακομιστή ιδιαίτερο σε μια παράγραφο. Αν μείνει κενό, θα πάρει την προκαθορισμένη περιγραφή του κόμβου.
+        desc_html: Εμφανίζεται στην πλαϊνή μπάρα και στα meta tags. Περιέγραψε τι είναι το Mastodon και τι κάνει αυτό τον διακομιστή ιδιαίτερο σε μια παράγραφο. Αν μείνει κενό, θα χρησιμοποιήσει την προκαθορισμένη περιγραφή του κόμβου.
         title: Σύντομη περιγραφή του κόμβου
       site_terms:
         desc_html: Μπορείς να γράψεις τη δική σου πολιτική απορρήτου, όρους χρήσης ή άλλους νομικούς όρους. Μπορείς να χρησιμοποιήσεις HTML tags
@@ -457,7 +474,7 @@ el:
       confirmed: Επιβεβαιωμένες
       expires_in: Λήγει σε
       last_delivery: Τελευταία παράδοση
-      title: WebSub
+      title: Πρωτόκολλο WebSub
       topic: Θέμα
     tags:
       accounts: Λογαριασμοί
@@ -475,10 +492,19 @@ el:
       edit_preset: Ενημέρωση προκαθορισμένης προειδοποίησης
       title: Διαχείριση προκαθορισμένων προειδοποιήσεων
   admin_mailer:
+    new_pending_account:
+      body: Τα στοιχεία του νέου λογαριασμού είναι παρακάτω. Μπορείς να εγκρίνεις ή να απορρίψεις αυτή την αίτηση.
+      subject: Νέος λογαριασμός προς έγκριση στο %{instance} (%{username})
     new_report:
       body: Ο/Η %{reporter} κατήγγειλε τον/την %{target}
       body_remote: Κάποιος/α από τον τομέα %{domain} κατήγγειλε τον/την %{target}
       subject: Νέα καταγγελία για %{instance} (#%{id})
+  appearance:
+    advanced_web_interface: Προηγμένη λειτουργία χρήσης
+    advanced_web_interface_hint: 'Αν θέλεις να χρησιμοποιήσεις ολόκληρο το πλάτος της οθόνης σου, η προηγμένη λειτουργία χρήσης σου επιτρέπει να ορίσεις πολλαπλές κολώνες ώστε να βλέπεις ταυτόχρονα όση πληροφορία θέλεις: Την αρχική ροή, τις ειδοποιήσεις, την ομοσπονδιακή ροή και όσες λίστες και ταμπέλες θέλεις.'
+    animations_and_accessibility: Κίνηση και προσβασιμότητα
+    confirmation_dialogs: Ερωτήσεις επιβεβαίωσης
+    sensitive_content: Ευαίσθητο περιεχόμενο
   application_mailer:
     notification_preferences: Αλλαγή προτιμήσεων email
     salutation: "%{name},"
@@ -495,8 +521,9 @@ el:
     warning: Μεγάλη προσοχή με αυτά τα στοιχεία. Μην τα μοιραστείς ποτέ με κανέναν!
     your_token: Το διακριτικό πρόσβασής σου (access token)
   auth:
-    agreement_html: Επιλέγοντας το "Εγγραφή", συμφωνείς πως δέχεσαι <a href="%{rules_path}">τους κανόνες αυτού του κόμβου</a> και <a href="%{terms_path}">τους όρους χρήσης του</a>.
+    apply_for_account: Αίτηση πρόσκλησης
     change_password: Συνθηματικό
+    checkbox_agreement_html: Συμφωνώ με τους <a href="%{rules_path}" target="_blank">κανονισμούς του κόμβου</a> και <a href="%{terms_path}" target="_blank">τους όρους χρήσης</a>
     confirm_email: Επιβεβαίωση email
     delete_account: Διαγραφή email
     delete_account_html: Αν θέλεις να διαγράψεις το λογαριασμό σου, μπορείς <a href="%{path}">να συνεχίσεις εδώ</a>. Θα σου ζητηθεί επιβεβαίωση.
@@ -507,17 +534,17 @@ el:
     logout: Αποσύνδεση
     migrate_account: Μετακόμισε σε διαφορετικό λογαριασμό
     migrate_account_html: Αν θέλεις να ανακατευθύνεις αυτό τον λογαριασμό σε έναν διαφορετικό, μπορείς να το <a href="%{path}">διαμορφώσεις εδώ</a>.
-    or: ή
     or_log_in_with: Ή συνδέσου με
     providers:
       cas: Υπηρεσία Κεντρικής Πιστοποίησης (CAS)
-      saml: SAML
+      saml: Πρωτόκολλο SAML
     register: Εγγραφή
-    register_elsewhere: Εγγραφή σε διαφορετικό εξυπηρετητή
+    registration_closed: Το %{instance} δεν δέχεται νέα μέλη
     resend_confirmation: Στείλε ξανά τις οδηγίες επιβεβαίωσης
     reset_password: Επαναφορά συνθηματικού
     security: Ασφάλεια
     set_new_password: Ορισμός νέου συνθηματικού
+    trouble_logging_in: Πρόβλημα σύνδεσης;
   authorize_follow:
     already_following: Ήδη ακολουθείς αυτό το λογαριασμό
     error: Δυστυχώς παρουσιάστηκε ένα σφάλμα κατά την αναζήτηση του απομακρυσμένου λογαριασμού
@@ -556,7 +583,7 @@ el:
     enabled: Περιλαμβάνεσαι στον κατάλογο.
     enabled_but_waiting: Έχεις επιλέξει να εμφανίζεσαι στον κατάλογο μεν, αλλά ακόμα δεν έχεις τον ελάχιστο αριθμό ακόλουθων (%{min_followers}) που απαιτείται για να συμπεριληφθείς.
     explanation: Βρες χρήστες βάσει των ενδιαφερόντων τους
-    explore_mastodon: Εξερεύνησε %{title}
+    explore_mastodon: Εξερεύνησε το %{title}
     how_to_enable: Δεν έχεις επιλέξει να συμπεριληφθείς στον καταλογο. Μπορείς να επιλέξεις παρακάτω. Χρησιμοποίησε ταμπέλες στο κείμενο του βιογραφικού σου για να εμφανίζεσαι κάτω από συγκεκριμένες ταμπέλες!
     people:
       one: "%{count} άτομο"
@@ -564,7 +591,7 @@ el:
   errors:
     '403': Δεν έχεις δικαίωμα πρόσβασης σε αυτή τη σελίδα.
     '404': Η σελίδα που ψάχνεις δεν υπάρχει.
-    '410': Η σελίδα που έψαχνες δεν υπάρχει πια.
+    '410': Η σελίδα που έψαχνες δεν υπάρχει πια εδώ.
     '422':
       content: Απέτυχε η επιβεβαίωση ασφαλείας. Μήπως μπλοκάρεις τα cookies;
       title: Η επιβεβαίωση ασφαλείας απέτυχε
@@ -573,6 +600,9 @@ el:
       content: Λυπούμαστε, κάτι πήγε στραβά από τη δική μας μεριά.
       title: Η σελίδα αυτή δεν είναι σωστή
     noscript_html: Για να χρησιμοποιήσετε τη δικτυακή εφαρμογή του Mastodon, ενεργοποίησε την Javascript. Εναλλακτικά, δοκίμασε μια από τις <a href="%{apps_path}">εφαρμογές</a> για το Mastodon στην πλατφόρμα σου.
+  existing_username_validator:
+    not_found: δεν βρέθηκε τοπικός χρήστης με αυτό το όνομα
+    not_found_multiple: δεν βρέθηκε %{usernames}
   exports:
     archive_takeout:
       date: Ημερομηνία
@@ -588,6 +618,10 @@ el:
     lists: Λίστες
     mutes: Αποσιωπάς
     storage: Αποθήκευση πολυμέσων
+  featured_tags:
+    add_new: Προσθήκη νέας
+    errors:
+      limit: Έχεις ήδη προσθέσει το μέγιστο αριθμό ταμπελών
   filters:
     contexts:
       home: Αρχική ροή
@@ -604,34 +638,50 @@ el:
       title: Φίλτρα
     new:
       title: Πρόσθεσε νέο φίλτρο
-  followers:
-    domain: Τομέας
-    explanation_html: Αν θέλεις να διασφαλίσεις την ιδιωτικότητα των ενημερώσεών σου, πρέπει να ξέρεις ποιος σε ακολουθεί. <strong>Οι ιδιωτικές ενημερώσεις σου μεταφέρονται σε όλους τους κόμβους στους οποίους έχεις ακόλουθους</strong>. Ίσως να θέλεις να κάνεις μια ανασκόπηση σε αυτούς και να αφαιρέσεις ακολούθους αν δεν εμπιστεύεσαι το προσωπικό αυτών των κόμβων πως θα σεβαστούν την ιδιωτικότητά σου.
-    followers_count: Πλήθος ακολούθων
-    lock_link: Κλείδωσε το λογαριασμό σου
-    purge: Αφαίρεσε από ακόλουθο
-    success:
-      one: Ημι-μπλοκάροντας τους ακόλουθους από έναν τομέα...
-      other: Ημι-μπλοκάροντας τους ακόλουθους από %{count} τομείς...
-    true_privacy_html: Έχε υπ' όψιν σου πως <strong>η πραγματική ιδιωτικότητα επιτυγχάνεται μόνο με κρυπτογράφηση από άκρη σε άκρη</strong>.
-    unlocked_warning_html: Μπορεί ο οποιοσδήποτε να σε ακολουθήσει και να βλέπει κατευθείαν τις ιδιωτικές ενημερώσεις σου. %{lock_link} για να αναθεωρήσεις και απορρίψεις ακόλουθους.
-    unlocked_warning_title: Ο λογαριασμός σου δεν είναι κλειδωμένος
   footer:
     developers: Ανάπτυξη
     more: Περισσότερα…
     resources: Πόροι
   generic:
+    all: Όλα
     changes_saved_msg: Οι αλλαγές αποθηκεύτηκαν!
     copy: Αντιγραφή
+    order_by: Ταξινόμηση κατά
     save_changes: Αποθήκευσε τις αλλαγές
     validation_errors:
       one: Κάτι δεν είναι εντάξει ακόμα! Για κοίταξε το παρακάτω σφάλμα
       other: Κάτι δεν είναι εντάξει ακόμα! Για κοίταξε τα παρακάτω %{count} σφάλματα
+  html_validator:
+    invalid_markup: 'περιέχει λάθος μορφοποίηση HTML: %{error}'
+  identity_proofs:
+    active: Ενεργή
+    authorize: Ναι, εξουσιοδότησε
+    authorize_connection_prompt: Εξουσιοδότηση αυτής της κρυπτογραφικής σύνδεσης;
+    errors:
+      failed: Η κρυπτογραφική σύνδεση απέτυχε. Παρακαλώ ξανά δοκίμασε μέσω %{provider}.
+      keybase:
+        invalid_token: Τα κλειδιά Keybase είναι κατακερματισμένες υπογραφές και πρέπει να έχουν μήκος 66 δεκαεξαδικών χαρακτήρων
+        verification_failed: Το Keybase δεν δέχτηκε αυτό το κλειδί ως υπογραφή του χρήστη %{kb_username}. Παρακαλούμε δοκίμασε μέσω Keybase.
+      wrong_user: Δεν επιτρέπεται να δημιουργηθεί ένα αποδεικτικό για %{proving} υπό τη σύνδεση ως %{current}. Συνδέσου ως %{proving} και δοκίμασε ξανά.
+    explanation_html: Εδώ μπορείς να συνδέσεις κρυπτογραφικά τις υπόλοιπες ταυτοτητές σου, όπως για παράδειγμα ένα προφίλ στο Keybase. Αυτό επιτρέπει σε άλλους ανθρώπους να σου στέλνουν κρυπτογραφημένα μηνύματα και να μπορούν να εμπιστευτούν το περιεχόμενο που τους στέλνεις εσύ.
+    i_am_html: Είμαι ο/η %{username} στην υπηρεσία %{service}.
+    identity: Ταυτότητα
+    inactive: Ανενεργή
+    publicize_checkbox: 'Και κάνε τουτ αυτό:'
+    publicize_toot: 'Αποδείχτηκε! Λέγομαι %{username} στο %{service}: %{url}'
+    status: Κατάσταση επαλήθευσης
+    view_proof: Εμφάνιση απόδειξης
   imports:
+    modes:
+      merge: Συγχώνευση
+      merge_long: Διατήρηση των εγγράφων που υπάρχουν και προσθηκη των νέων
+      overwrite: Αντικατάσταση
+      overwrite_long: Αντικατάσταση των υπαρχόντων εγγράφων με τις καινούργιες
     preface: Μπορείς να εισάγεις τα δεδομένα που έχεις εξάγει από άλλο κόμβο, όπως τη λίστα των ανθρώπων που ακολουθείς ή μπλοκάρεις.
     success: Τα δεδομένα σου μεταφορτώθηκαν επιτυχώς και θα επεξεργαστούν εν καιρώ
     types:
       blocking: Λίστα αποκλεισμού
+      domain_blocking: Λίστα αποκλεισμένων τομέων
       following: Λίστα ακολούθων
       muting: Λίστα αποσιωπήσεων
     upload: Ανέβασμα
@@ -657,7 +707,7 @@ el:
     table:
       expires_at: Λήγει
       uses: Χρήσεις
-    title: Προσκάλεσε άτομα
+    title: Προσκάλεσε κόσμο
   lists:
     errors:
       limit: Έχεις φτάσει το μέγιστο πλήθος επιτρεπτών λιστών
@@ -722,18 +772,40 @@ el:
     older: Παλιότερο
     prev: Προηγούμενο
     truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: Έχεις ήδη ψηφίσει σε αυτή την ψηφοφορία
+      duplicate_options: περιέχει επαναλαμβανόμενες επιλογές
+      duration_too_long: είναι πολύ μακριά στο μέλλον
+      duration_too_short: είναι πολύ σύντομα
+      expired: Η ψηφοφορία έχει ήδη λήξει
+      over_character_limit: δε μπορεί να υπερβαίνει τους %{max} χαρακτήρες έκαστη
+      too_few_options: πρέπει να έχει περισσότερες από μια επιλογές
+      too_many_options: δεν μπορεί να έχει περισσότερες από %{max} επιλογές
   preferences:
-    languages: Γλώσσες
     other: Άλλο
-    publishing: Δημοσίευση
-    web: Διαδίκτυο
+    posting_defaults: Προεπιλογές δημοσίευσης
+    public_timelines: Δημόσιες ροές
+  relationships:
+    activity: Δραστηριότητα λογαριασμού
+    dormant: Αδρανής
+    last_active: Τελευταία δραστηριότητα
+    most_recent: Πιο πρόσφατα
+    moved: Μετακόμισε
+    mutual: Αμοιβαίος
+    primary: Βασικός
+    relationship: Σχέση
+    remove_selected_domains: Αφαίρεση ακόλουθων που βρίσκονται στους επιλεγμένους κόμβους
+    remove_selected_followers: Αφαίρεση επιλεγμένων ακόλουθων
+    remove_selected_follows: Διακοπή παρακολούθησης επιλεγμένων χρηστών
+    status: Κατάσταση λογαριασμού
   remote_follow:
     acct: Γράψε το ΌνομαΧρήστη@τομέα από όπου θέλεις να εκτελέσεις την ενέργεια αυτή
     missing_resource: Δεν βρέθηκε το απαιτούμενο URL ανακατεύθυνσης για το λογαριασμό σου
     no_account_html: Δεν έχεις λογαριασμό; Μπορείς <a href='%{sign_up_path}' target='_blank'>να γραφτείς εδώ</a>
     proceed: Συνέχισε για να ακολουθήσεις
     prompt: 'Ετοιμάζεσαι να ακολουθήσεις:'
-    reason_html: "<strong>Γιατί χρειάζεται αυτό το βήμα;</strong> Το <code>%{instance}</code> πορεία να μην είναι ο κόμβος που είσαι γραμμένος, έτσι πρέπει να σε ανακατευθύνουμε στο δικό σου."
+    reason_html: "<strong>Γιατί χρειάζεται αυτό το βήμα;</strong> Το <code>%{instance}</code> μπορεί να μην είναι ο κόμβος που έχεις γραφτεί, έτσι πρέπει να σε ανακατευθύνουμε στο δικό σου."
   remote_interaction:
     favourite:
       proceed: Συνέχισε για σημείωση ως αγαπημένου
@@ -794,20 +866,25 @@ el:
     revoke_success: Η σύνδεση ανακλήθηκε επιτυχώς
     title: Σύνδεση
   settings:
+    account: Λογαριασμός
+    account_settings: Ρυθμίσεις λογαριασμού
+    appearance: Εμφάνιση
     authorized_apps: Εγκεκριμένες εφαρμογές
     back: Πίσω στο Mastodon
     delete: Διαγραφή λογαριασμού
     development: Ανάπτυξη
     edit_profile: Επεξεργασία προφίλ
     export: Εξαγωγή δεδομένων
-    followers: Εγκεκριμένοι ακόλουθοι
+    featured_tags: Χαρακτηριστικές ταμπέλες
+    identity_proofs: Αποδείξεις ταυτοτήτων
     import: Εισαγωγή
+    import_and_export: Εισαγωγή & Εξαγωγή
     migrate: Μετακόμιση λογαριασμού
     notifications: Ειδοποιήσεις
     preferences: Προτιμήσεις
-    settings: Ρυθμίσεις
+    profile: Προφίλ
+    relationships: Ακολουθεί και ακολουθείται
     two_factor_authentication: Πιστοποίηση 2 παραγόντων (2FA)
-    your_apps: Οι εφαρμογές σου
   statuses:
     attached:
       description: 'Συνημμένα: %{attached}'
@@ -830,6 +907,11 @@ el:
       ownership: Δεν μπορείς να καρφιτσώσεις μη δικό σου τουτ
       private: Τα μη δημόσια τουτ δεν καρφιτσώνονται
       reblog: Οι προωθήσεις δεν καρφιτσώνονται
+    poll:
+      total_votes:
+        one: "%{count} ψήφος"
+        other: "%{count} ψήφοι"
+      vote: Ψήφισε
     show_more: Δείξε περισσότερα
     sign_in_to_participate: Εγγράφου για να συμμετάσχεις στη συζήτηση
     title: '%{name}: "%{quote}"'
@@ -850,10 +932,10 @@ el:
       <h3 id="collect">Ποιες πληροφορίες συλλέγουμε;</h3>
 
       <ul>
-        <li><em>Βασικά στοιχεία λογαριασμού</em>: Όταν εγγραφείς σε αυτό τον διακομιστή, μπορεί να σου ζητηθεί όνομα χρήστη, διεύθυνση email και ένας κωδικός. Μπορεί επίσης να εισάγεις επιπλέον πληροφορίες λογαριασμού όπως ένα όνομα λογαριασμού και σύντομο βιογραφικό και να ανεβάσεις εικόνα προφίλ και επικεφαλίδας. Το όνομα χρήστη, το όνομα λογαριασμού, το βιογραφικό και οι εικόνες προφίλ και επικεφαλίδας είναι πάντα δημόσια εμφανείς.</li>
-        <li><em>Δημοσιεύσεις, ακόλουθοι και λοιπά δημόσια στοιχεία</em>: Η λίστα των ανθρώπων που ακολουθείς εμφανίζεται δημόσια, το ίδιο και οι ακόλουθοί σου. Όταν υποβάλλεις ένα μήνυμα, η ημερομηνία και ώρα αποθηκεύονται καθώς και η εφαρμογή που χρησιμοποίησες για την υποβολή του. Τα μηνύματα μπορεί να περιέχουν συνημμένα πολυμέσα όπως εικόνες και βίντεο. Τα δημόσια και τα μη καταχωρημένα μηνύματα είναι δημόσια διαθέσιμα. Όταν προβάλεις μια δημοσίευση στο προφίλ σου, είναι και αυτό δημόσια διαθέσιμο. Οι δημοσιεύσεις σου παραδίδονται στους ακολούθους σου, σε κάποιες περιπτώσεις αυτό σημαίνει ότι παραδίδονται σε διαφορετικούς διακομιστές (servers) και αντίγραφά τους αποθηκεύονται σε αυτούς. Παρομοίως, όταν διαγράψεις δημοσιεύσεις, αυτό μεταφέρεται στους ακόλουθους σου. Η αναδημοσίευση και η σημείωση ως αγαπημένης μιας δημοσίευσης είναι πάντα δημόσια.</li>
-        <li><em>Προσωπικές δημοσιεύσεις και προς ακόλουθους</em>: Όλες οι δημοσιεύσεις αποθηκεύονται και επεξεργάζονται στον διακομιστή. Οι δημοσιεύσεις προς τους ακόλουθους παραδίδονται στους ακόλουθους σου και σε όσους χρήστες αναφέρονται σε αυτές. Σε κάποιες περιπτώσεις αυτό σημαίνει πως παραδίδονται σε διαφορετικούς διακομιστές και αντίγραφά τους αποθηκεύονται σε αυτούς. Καταβάλουμε ειλικρινή προσπάθεια περιορισμού πρόσβασης σε αυτές τις δημοσιεύσεις μόνο σε εγκεκριμένα άτομα, όμως διαφορετικοί διακομιστές μπορεί να μην το πετυχαίνουν αυτό. Για αυτό, είναι σημαντικό να ελέγχεις τους διακομιστές στους οποίους ανήκουν οι ακόλουθοί σου. Μπορείς να ενεργοποιήσεις την επιλογή χειροκίνητης αποδοχής ή απόρριψης των νέων ακόλουθών σου στις ρυθμίσεις. <em>Παρακαλούμε έχε υπόψιν σου πως οι διαχειριστές του διακομιστή και των αποδεκτών διακομιστών πιθανόν να κοιτάνε αυτά τα μηνύματα</em>, και πως οι τελικοί αποδέκτες μπορούν να αποθηκεύσουν την οθόνη, το μήνυμα ή να το αναμεταδώσουν με άλλους τρόπους. <em>Μην μοιράζεσαι επικύνδυνες πληροφορίες μέσω του Mastodon.</em></li>
-        <li><em>Διευθύνσεις IP και άλλα metadata</em>: Όταν συνδέεσαι, καταγράφουμε την διεύθυνση IP σου, καθώς και το όνομα της εφαρμογής του φυλλομετρητή σου (browser). Όλες οι τρέχουσες συνδέσεις στον λογαριασμό σου είναι διαθέσιμες προς ανασκόπηση στις ρυθμίσεις. Η πιο πρόσφατη διεύθυνση IP αποθηκεύεται για μέχρι 12 μήνες. Επίσης μπορεί να διατηρήσουμε ιστορικό του διακομιστή (log files) που να περιέχει την διεύθυνση ΙΡ κάθε κλήσης προς τον διακομιστή μας.</li>
+      <li><em>Βασικά στοιχεία λογαριασμού</em>: Όταν εγγραφείς σε αυτό τον διακομιστή, μπορεί να σου ζητηθεί όνομα χρήστη, διεύθυνση email και ένας κωδικός. Μπορεί επίσης να εισάγεις επιπλέον πληροφορίες λογαριασμού όπως ένα όνομα λογαριασμού και σύντομο βιογραφικό και να ανεβάσεις εικόνα προφίλ και επικεφαλίδας. Το όνομα χρήστη, το όνομα λογαριασμού, το βιογραφικό και οι εικόνες προφίλ και επικεφαλίδας είναι πάντα δημόσια εμφανείς.</li>
+      <li><em>Δημοσιεύσεις, ακόλουθοι και λοιπά δημόσια στοιχεία</em>: Η λίστα των ανθρώπων που ακολουθείς εμφανίζεται δημόσια, το ίδιο και οι ακόλουθοί σου. Όταν υποβάλλεις ένα μήνυμα, η ημερομηνία και ώρα αποθηκεύονται καθώς και η εφαρμογή που χρησιμοποίησες για την υποβολή του. Τα μηνύματα μπορεί να περιέχουν συνημμένα πολυμέσα όπως εικόνες και βίντεο. Τα δημόσια και τα μη καταχωρημένα μηνύματα είναι δημόσια διαθέσιμα. Όταν προβάλεις μια δημοσίευση στο προφίλ σου, είναι και αυτό δημόσια διαθέσιμο. Οι δημοσιεύσεις σου παραδίδονται στους ακολούθους σου, σε κάποιες περιπτώσεις αυτό σημαίνει ότι παραδίδονται σε διαφορετικούς διακομιστές (servers) και αντίγραφά τους αποθηκεύονται σε αυτούς. Παρομοίως, όταν διαγράψεις δημοσιεύσεις, αυτό μεταφέρεται στους ακόλουθους σου. Η αναδημοσίευση και η σημείωση ως αγαπημένης μιας δημοσίευσης είναι πάντα δημόσια.</li>
+      <li><em>Προσωπικές δημοσιεύσεις και προς ακόλουθους</em>: Όλες οι δημοσιεύσεις αποθηκεύονται και επεξεργάζονται στον διακομιστή. Οι δημοσιεύσεις προς τους ακόλουθους παραδίδονται στους ακόλουθους σου και σε όσους χρήστες αναφέρονται σε αυτές. Σε κάποιες περιπτώσεις αυτό σημαίνει πως παραδίδονται σε διαφορετικούς διακομιστές και αντίγραφά τους αποθηκεύονται σε αυτούς. Καταβάλουμε ειλικρινή προσπάθεια περιορισμού πρόσβασης σε αυτές τις δημοσιεύσεις μόνο σε εγκεκριμένα άτομα, όμως διαφορετικοί διακομιστές μπορεί να μην το πετυχαίνουν αυτό. Για αυτό, είναι σημαντικό να ελέγχεις τους διακομιστές στους οποίους ανήκουν οι ακόλουθοί σου. Μπορείς να ενεργοποιήσεις την επιλογή χειροκίνητης αποδοχής ή απόρριψης των νέων ακόλουθών σου στις ρυθμίσεις. <em>Παρακαλούμε έχε υπόψιν σου πως οι διαχειριστές του διακομιστή και των αποδεκτών διακομιστών πιθανόν να κοιτάνε αυτά τα μηνύματα</em>, και πως οι τελικοί αποδέκτες μπορούν να αποθηκεύσουν την οθόνη, το μήνυμα ή να το αναμεταδώσουν με άλλους τρόπους. <em>Μην μοιράζεσαι επικύνδυνες πληροφορίες μέσω του Mastodon.</em></li>
+      <li><em>Διευθύνσεις IP και άλλα metadata</em>: Όταν συνδέεσαι, καταγράφουμε την διεύθυνση IP σου, καθώς και το όνομα της εφαρμογής του φυλλομετρητή σου (browser). Όλες οι τρέχουσες συνδέσεις στον λογαριασμό σου είναι διαθέσιμες προς ανασκόπηση στις ρυθμίσεις. Η πιο πρόσφατη διεύθυνση IP αποθηκεύεται για μέχρι 12 μήνες. Επίσης μπορεί να διατηρήσουμε ιστορικό του διακομιστή (log files) που να περιέχει την διεύθυνση ΙΡ κάθε κλήσης προς τον διακομιστή μας.</li>
       </ul>
 
       <hr class="spacer" />
@@ -863,9 +945,9 @@ el:
       <p>Οι πληροφορίες σου που συλλέγουμε μπορεί να χρησιμοποιηθούν με τους ακόλουθους τρόπους:</p>
 
       <ul>
-        <li>Για να παρέχουμε την βασική λειτουργικότητα του Mastodon. Μπορείς να αλληλεπιδράσεις με τις δημοσιεύσεις άλλων και να κάνεις τις δικές σου μόνο αφού συνδεθείς. Για παράδειγμα, μπορείς να ακολουθήσεις άλλους χρήστες για να βλέπεις τις συνολικές δημοσιεύσεις τους στη δική σου, προσωπική αρχική ροή.</li>
-        <li>Για να διευκολύνουμε τη διαχείριση της κοινότητας, για παράδειγμα συγκρίνοντας τη δική σου διεύθυνση IP με άλλες γνωστές διευθύνσεις για να καθορίσουμε περιπτώσεις αποφυγής αποκλεισμού ή άλλων παραβάσεων.</li>
-        <li>Η διεύθυνση email που δίνεις μπορεί να χρησιμοποιηθεί για να σου στείλουμε πληροφορίες, ειδοποιήσεις για αλληλεπιδράσεις άλλων χρηστών με τις δημοσιεύσεις σου και να ανταποκριθούμε σε ερωτήματά σου.</li>
+      <li>Για να παρέχουμε την βασική λειτουργικότητα του Mastodon. Μπορείς να αλληλεπιδράσεις με τις δημοσιεύσεις άλλων και να κάνεις τις δικές σου μόνο αφού συνδεθείς. Για παράδειγμα, μπορείς να ακολουθήσεις άλλους χρήστες για να βλέπεις τις συνολικές δημοσιεύσεις τους στη δική σου, προσωπική αρχική ροή.</li>
+      <li>Για να διευκολύνουμε τη διαχείριση της κοινότητας, για παράδειγμα συγκρίνοντας τη δική σου διεύθυνση IP με άλλες γνωστές διευθύνσεις για να καθορίσουμε περιπτώσεις αποφυγής αποκλεισμού ή άλλων παραβάσεων.</li>
+      <li>Η διεύθυνση email που δίνεις μπορεί να χρησιμοποιηθεί για να σου στείλουμε πληροφορίες, ειδοποιήσεις για αλληλεπιδράσεις άλλων χρηστών με τις δημοσιεύσεις σου και να ανταποκριθούμε σε ερωτήματά σου.</li>
       </ul>
 
       <hr class="spacer" />
@@ -881,8 +963,8 @@ el:
       <p>Καταβάλουμε κάθε δυνατή προσπάθεια να:</p>
 
       <ul>
-        <li>Διατηρήσουμε αρχεία ενεργειών των διακομιστών (servers) για όλα τα αιτήματα σε αυτόν τον διακομιστή, και αυτά τα αρχεία διατηρούνται για μέγιστο χρόνο 90 ημερών.</li>
-        <li>Διατηρήσουμε τις διευθύνσεις IP που σχετίζονται με εγγεγραμμένους χρήστες για μέγιστο χρόνο 12 μηνών.</li>
+      <li>Διατηρήσουμε αρχεία ενεργειών των διακομιστών (servers) για όλα τα αιτήματα σε αυτόν τον διακομιστή, και αυτά τα αρχεία διατηρούνται για μέγιστο χρόνο 90 ημερών.</li>
+      <li>Διατηρήσουμε τις διευθύνσεις IP που σχετίζονται με εγγεγραμμένους χρήστες για μέγιστο χρόνο 12 μηνών.</li>
       </ul>
 
       <p>Μπορείς να αιτηθείς και να αποθηκεύσεις τοπικά ένα αρχείο του περιεχομένου σου που περιλαμβάνει τις δημοσιεύσεις, τα συνημμένα πολυμέσα, την εικόνα προφίλ και την εικόνα επικεφαλίδας.</p>
@@ -928,9 +1010,9 @@ el:
       <p>Οι παραπάνω όροι έχουν προσαρμοστεί από τους αντίστοιχους όρους του <a href="https://github.com/discourse/discourse">Discourse</a>.</p>
     title: Όροι Χρήσης και Πολιτική Απορρήτου του κόμβου %{instance}
   themes:
-    contrast: Υψηλή αντίθεση
-    default: Mastodon
-    mastodon-light: Mastodon (ανοιχτόχρωμο)
+    contrast: Mastodon (Υψηλή αντίθεση)
+    default: Mastodon (Σκοτεινό)
+    mastodon-light: Mastodon (Ανοιχτόχρωμο)
   time:
     formats:
       default: "%b %d, %Y, %H:%M"
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 078c5b20f5bfd29f67e17ecb2a8a56a7c14f6f3c..8e9abf9904062f22d88a5396825f9deda0bb00b4 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -4,36 +4,36 @@ en:
     about_hashtag_html: These are public toots tagged with <strong>#%{hashtag}</strong>. You can interact with them if you have an account anywhere in the fediverse.
     about_mastodon_html: Mastodon is a social network based on open web protocols and free, open-source software. It is decentralized like e-mail.
     about_this: About
+    active_count_after: active
+    active_footnote: Monthly Active Users (MAU)
     administered_by: 'Administered by:'
     api: API
     apps: Mobile apps
-    closed_registrations: Registrations are currently closed on this instance. However! You can find a different instance to make an account on and get access to the very same network from there.
+    apps_platforms: Use Mastodon from iOS, Android and other platforms
+    browse_directory: Browse a profile directory and filter by interests
+    browse_public_posts: Browse a live stream of public posts on Mastodon
     contact: Contact
     contact_missing: Not set
     contact_unavailable: N/A
+    discover_users: Discover users
     documentation: Documentation
     extended_description_html: |
       <h3>A good place for rules</h3>
       <p>The extended description has not been set up yet.</p>
-    features:
-      humane_approach_body: Learning from failures of other networks, Mastodon aims to make ethical design choices to combat the misuse of social media.
-      humane_approach_title: A more humane approach
-      not_a_product_body: Mastodon is not a commercial network. No advertising, no data mining, no walled gardens. There is no central authority.
-      not_a_product_title: You’re a person, not a product
-      real_conversation_body: With 65,535 characters at your disposal and support for granular content and media warnings, you can express yourself the way you want to.
-      real_conversation_title: Built for real conversation
-      within_reach_body: Multiple apps for iOS, Android, and other platforms thanks to a developer-friendly API ecosystem allow you to keep up with your friends anywhere.
-      within_reach_title: Always within reach
+    federation_hint_html: With an account on %{instance} you'll be able to follow people on any Mastodon server and beyond.
     generic_description: "%{domain} is one server in the network"
+    get_apps: Try a mobile app
     hosted_on: Mastodon hosted on %{domain}
     learn_more: Learn more
-    other_instances: Instance list
     privacy_policy: Privacy policy
+    see_whats_happening: See what's happening
+    server_stats: 'Server stats:'
     source_code: Source code
     status_count_after:
       one: status
       other: statuses
     status_count_before: Who authored
+    tagline: Follow friends and discover new ones
     terms: Terms of service
     user_count_after:
       one: user
@@ -68,6 +68,7 @@ en:
       admin: Admin
       bot: Bot
       moderator: Mod
+    unavailable: Profile unavailable
     unfollow: Unfollow
   admin:
     account_actions:
@@ -79,6 +80,8 @@ en:
       delete: Delete
       destroyed_msg: Moderation note successfully destroyed!
     accounts:
+      approve: Approve
+      approve_all: Approve all
       are_you_sure: Are you sure?
       avatar: Avatar
       by_domain: Domain
@@ -124,15 +127,18 @@ en:
       moderation:
         active: Active
         all: All
+        pending: Pending
         silenced: Silenced
         suspended: Suspended
         title: Moderation
       moderation_notes: Moderation notes
       most_recent_activity: Most recent activity
       most_recent_ip: Most recent IP
+      no_account_selected: No accounts were changed as none were selected
       no_limits_imposed: No limits imposed
       not_subscribed: Not subscribed
       outbox_url: Outbox URL
+      pending: Pending review
       perform_full_suspension: Suspend
       profile_url: Profile URL
       promote: Promote
@@ -140,6 +146,8 @@ en:
       public: Public
       push_subscription_expires: PuSH subscription expires
       redownload: Refresh profile
+      reject: Reject
+      reject_all: Reject all
       remove_avatar: Remove avatar
       remove_header: Remove header
       resend_confirmation:
@@ -166,6 +174,7 @@ en:
       statuses: Statuses
       subscribe: Subscribe
       suspended: Suspended
+      time_in_queue: Waiting in queue %{time}
       title: Accounts
       unconfirmed_email: Unconfirmed email
       undo_silenced: Undo silence
@@ -241,6 +250,7 @@ en:
       feature_profile_directory: Profile directory
       feature_registrations: Registrations
       feature_relay: Federation relay
+      feature_timeline_preview: Timeline preview
       features: Features
       hidden_service: Federation with hidden services
       open_reports: open reports
@@ -260,6 +270,7 @@ en:
       created_msg: Domain block is now being processed
       destroyed_msg: Domain block has been undone
       domain: Domain
+      existing_domain_block_html: You have already imposed stricter limits on %{name}, you need to <a href="%{unblock_url}">unblock it</a> first.
       new:
         create: Create block
         hint: The domain block will not prevent creation of account entries in the database, but will retroactively and automatically apply specific moderation methods on those accounts.
@@ -283,8 +294,8 @@ en:
           one: One account in the database affected
           other: "%{count} accounts in the database affected"
         retroactive:
-          silence: Unsilence all existing accounts from this domain
-          suspend: Unsuspend all existing accounts from this domain
+          silence: Unsilence existing affected accounts from this domain
+          suspend: Unsuspend existing affected accounts from this domain
         title: Undo domain block for %{domain}
         undo: Undo
       undo: Undo domain block
@@ -302,6 +313,7 @@ en:
       back_to_account: Back To Account
       title: "%{acct}'s Followers"
     instances:
+      by_domain: Domain
       delivery_available: Delivery is available
       known_accounts:
         one: "%{count} known account"
@@ -324,6 +336,8 @@ en:
         expired: Expired
         title: Filter
       title: Invites
+    pending_accounts:
+      title: Pending accounts (%{count})
     relays:
       add_new: Add new relay
       delete: Delete
@@ -386,14 +400,14 @@ en:
         desc_html: Modify the look with CSS loaded on every page
         title: Custom CSS
       hero:
-        desc_html: Displayed on the frontpage. At least 600x100px recommended. When not set, falls back to instance thumbnail
+        desc_html: Displayed on the frontpage. At least 600x100px recommended. When not set, falls back to server thumbnail
         title: Hero image
       mascot:
         desc_html: Displayed on multiple pages. At least 293×205px recommended. When not set, falls back to default mascot
         title: Mascot image
       peers_api_enabled:
-        desc_html: Domain names this instance has encountered in the fediverse
-        title: Publish list of discovered instances
+        desc_html: Domain names this server has encountered in the fediverse
+        title: Publish list of discovered servers
       preview_sensitive_media:
         desc_html: Link previews on other websites will display a thumbnail even if the media is marked as sensitive
         title: Show sensitive media in OpenGraph previews
@@ -410,9 +424,12 @@ en:
         min_invite_role:
           disabled: No one
           title: Allow invitations by
-        open:
-          desc_html: Allow anyone to create an account
-          title: Open registration
+      registrations_mode:
+        modes:
+          approved: Approval required for sign up
+          none: Nobody can sign up
+          open: Anyone can sign up
+        title: Registrations mode
       show_known_fediverse_at_about_page:
         desc_html: When toggled, it will show toots from all the known fediverse on preview. Otherwise it will only show local toots.
         title: Show known fediverse on timeline preview
@@ -420,21 +437,21 @@ en:
         desc_html: Show a staff badge on a user page
         title: Show staff badge
       site_description:
-        desc_html: Introductory paragraph on the frontpage. Describe what makes this Mastodon server special and anything else important. You can use HTML tags, in particular <code>&lt;a&gt;</code> and <code>&lt;em&gt;</code>.
-        title: Instance description
+        desc_html: Introductory paragraph on the API. Describe what makes this Mastodon server special and anything else important. You can use HTML tags, in particular <code>&lt;a&gt;</code> and <code>&lt;em&gt;</code>.
+        title: Server description
       site_description_extended:
-        desc_html: A good place for your code of conduct, rules, guidelines and other things that set your instance apart. You can use HTML tags
+        desc_html: A good place for your code of conduct, rules, guidelines and other things that set your server apart. You can use HTML tags
         title: Custom extended information
       site_short_description:
-        desc_html: Displayed in sidebar and meta tags. Describe what Mastodon is and what makes this server special in a single paragraph. If empty, defaults to instance description.
-        title: Short instance description
+        desc_html: Displayed in sidebar and meta tags. Describe what Mastodon is and what makes this server special in a single paragraph.
+        title: Short server description
       site_terms:
         desc_html: You can write your own privacy policy, terms of service or other legalese. You can use HTML tags
         title: Custom terms of service
-      site_title: Instance name
+      site_title: Server name
       thumbnail:
         desc_html: Used for previews via OpenGraph and API. 1200x630px recommended
-        title: Instance thumbnail
+        title: Server thumbnail
       timeline_preview:
         desc_html: Display public timeline on landing page
         title: Timeline preview
@@ -475,16 +492,25 @@ en:
       edit_preset: Edit warning preset
       title: Manage warning presets
   admin_mailer:
+    new_pending_account:
+      body: The details of the new account are below. You can approve or reject this application.
+      subject: New account up for review on %{instance} (%{username})
     new_report:
       body: "%{reporter} has reported %{target}"
       body_remote: Someone from %{domain} has reported %{target}
       subject: New report for %{instance} (#%{id})
+  appearance:
+    advanced_web_interface: Advanced web interface
+    advanced_web_interface_hint: 'If you want to make use of your entire screen width, the advanced web interface allows you to configure many different columns to see as much information at the same time as you want: Home, notifications, federated timeline, any number of lists and hashtags.'
+    animations_and_accessibility: Animations and accessibility
+    confirmation_dialogs: Confirmation dialogs
+    sensitive_content: Sensitive content
   application_mailer:
     notification_preferences: Change e-mail preferences
     salutation: "%{name},"
     settings: 'Change e-mail preferences: %{link}'
     view: 'View:'
-    view_profile: View Profile
+    view_profile: View profile
     view_status: View status
   applications:
     created: Application successfully created
@@ -495,8 +521,9 @@ en:
     warning: Be very careful with this data. Never share it with anyone!
     your_token: Your access token
   auth:
-    agreement_html: By clicking "Sign up" below you agree to follow <a href="%{rules_path}">the rules of the instance</a> and <a href="%{terms_path}">our terms of service</a>.
+    apply_for_account: Request an invite
     change_password: Password
+    checkbox_agreement_html: I agree to the <a href="%{rules_path}" target="_blank">server rules</a> and <a href="%{terms_path}" target="_blank">terms of service</a>
     confirm_email: Confirm email
     delete_account: Delete account
     delete_account_html: If you wish to delete your account, you can <a href="%{path}">proceed here</a>. You will be asked for confirmation.
@@ -507,17 +534,17 @@ 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
       saml: SAML
     register: Sign up
-    register_elsewhere: Sign up on another server
+    registration_closed: "%{instance} is not accepting new members"
     resend_confirmation: Resend confirmation instructions
     reset_password: Reset password
     security: Security
     set_new_password: Set new password
+    trouble_logging_in: Trouble logging in?
   authorize_follow:
     already_following: You are already following this account
     error: Unfortunately, there was an error looking up the remote account
@@ -549,7 +576,7 @@ en:
     description_html: This will <strong>permanently, irreversibly</strong> remove content from your account and deactivate it. Your username will remain reserved to prevent future impersonations.
     proceed: Delete account
     success_msg: Your account was successfully deleted
-    warning_html: Only deletion of content from this particular instance is guaranteed. Content that has been widely shared is likely to leave traces. Offline servers and servers that have unsubscribed from your updates will not update their databases.
+    warning_html: Only deletion of content from this particular server is guaranteed. Content that has been widely shared is likely to leave traces. Offline servers and servers that have unsubscribed from your updates will not update their databases.
     warning_title: Disseminated content availability
   directories:
     directory: Profile directory
@@ -561,10 +588,12 @@ en:
     people:
       one: "%{count} person"
       other: "%{count} people"
+  domain_validator:
+    invalid_domain: is not a valid domain name
   errors:
     '403': You don't have permission to view this page.
-    '404': The page you were looking for doesn't exist.
-    '410': The page you were looking for doesn't exist anymore.
+    '404': The page you are looking for isn't here.
+    '410': The page you were looking for doesn't exist here anymore.
     '422':
       content: Security verification failed. Are you blocking cookies?
       title: Security verification failed
@@ -573,11 +602,14 @@ en:
       content: We're sorry, but something went wrong on our end.
       title: This page is not correct
     noscript_html: To use the Mastodon web application, please enable JavaScript. Alternatively, try one of the <a href="%{apps_path}">native apps</a> for Mastodon for your platform.
+  existing_username_validator:
+    not_found: could not find a local user with that username
+    not_found_multiple: could not find %{usernames}
   exports:
     archive_takeout:
       date: Date
       download: Download your archive
-      hint_html: You can request an archive of your <strong>toots and uploaded media</strong>. The exported data will be in ActivityPub format, readable by any compliant software. You can request an archive every 7 days.
+      hint_html: You can request an archive of your <strong>toots and uploaded media</strong>. The exported data will be in the ActivityPub format, readable by any compliant software. You can request an archive every 7 days.
       in_progress: Compiling your archive...
       request: Request your archive
       size: Size
@@ -588,6 +620,10 @@ en:
     lists: Lists
     mutes: You mute
     storage: Media storage
+  featured_tags:
+    add_new: Add new
+    errors:
+      limit: You have already featured the maximum amount of hashtags
   filters:
     contexts:
       home: Home timeline
@@ -604,34 +640,50 @@ en:
       title: Filters
     new:
       title: Add new filter
-  followers:
-    domain: Domain
-    explanation_html: If you want to ensure the privacy of your statuses, you must be aware of who is following you. <strong>Your private statuses are delivered to all instances where you have followers</strong>. You may wish to review them, and remove followers if you do not trust your privacy to be respected by the staff or software of those instances.
-    followers_count: Number of followers
-    lock_link: Lock your account
-    purge: Remove from followers
-    success:
-      one: In the process of soft-blocking followers from one domain...
-      other: In the process of soft-blocking followers from %{count} domains...
-    true_privacy_html: Please mind that <strong>true privacy can only be achieved with end-to-end encryption</strong>.
-    unlocked_warning_html: Anyone can follow you to immediately view your private statuses. %{lock_link} to be able to review and reject followers.
-    unlocked_warning_title: Your account is not locked
   footer:
     developers: Developers
     more: More…
     resources: Resources
   generic:
+    all: All
     changes_saved_msg: Changes successfully saved!
     copy: Copy
+    order_by: Order by
     save_changes: Save changes
     validation_errors:
       one: Something isn't quite right yet! Please review the error below
       other: Something isn't quite right yet! Please review %{count} errors below
+  html_validator:
+    invalid_markup: 'contains invalid HTML markup: %{error}'
+  identity_proofs:
+    active: Active
+    authorize: Yes, authorize
+    authorize_connection_prompt: Authorize this cryptographic connection?
+    errors:
+      failed: The cryptographic connection failed. Please try again from %{provider}.
+      keybase:
+        invalid_token: Keybase tokens are hashes of signatures and must be 66 hex characters
+        verification_failed: Keybase does not recognize this token as a signature of Keybase user %{kb_username}. Please retry from Keybase.
+      wrong_user: Cannot create a proof for %{proving} while logged in as %{current}. Log in as %{proving} and try again.
+    explanation_html: Here you can cryptographically connect your other identities, such as a Keybase profile. This lets other people send you encrypted messages and trust content you send them.
+    i_am_html: I am %{username} on %{service}.
+    identity: Identity
+    inactive: Inactive
+    publicize_checkbox: 'And toot this:'
+    publicize_toot: 'It is proven! I am %{username} on %{service}: %{url}'
+    status: Verification status
+    view_proof: View proof
   imports:
-    preface: You can import data that you have exported from another instance, such as a list of the people you are following or blocking.
+    modes:
+      merge: Merge
+      merge_long: Keep existing records and add new ones
+      overwrite: Overwrite
+      overwrite_long: Replace current records with the new ones
+    preface: You can import data that you have exported from another server, such as a list of the people you are following or blocking.
     success: Your data was successfully uploaded and will now be processed in due time
     types:
       blocking: Blocking list
+      domain_blocking: Domain blocking list
       following: Following list
       muting: Muting list
     upload: Upload
@@ -653,7 +705,7 @@ en:
       one: 1 use
       other: "%{count} uses"
     max_uses_prompt: No limit
-    prompt: Generate and share links with others to grant access to this instance
+    prompt: Generate and share links with others to grant access to this server
     table:
       expires_at: Expires
       uses: Uses
@@ -723,11 +775,33 @@ en:
     older: Older
     prev: Prev
     truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: You have already voted on this poll
+      duplicate_options: contain duplicate items
+      duration_too_long: is too far into the future
+      duration_too_short: is too soon
+      expired: The poll has already ended
+      over_character_limit: cannot be longer than %{max} characters each
+      too_few_options: must have more than one item
+      too_many_options: can't contain more than %{max} items
   preferences:
-    languages: Languages
     other: Other
-    publishing: Publishing
-    web: Web
+    posting_defaults: Posting defaults
+    public_timelines: Public timelines
+  relationships:
+    activity: Account activity
+    dormant: Dormant
+    last_active: Last active
+    most_recent: Most recent
+    moved: Moved
+    mutual: Mutual
+    primary: Primary
+    relationship: Relationship
+    remove_selected_domains: Remove all followers from the selected domains
+    remove_selected_followers: Remove selected followers
+    remove_selected_follows: Unfollow selected users
+    status: Account status
   remote_follow:
     acct: Enter your username@domain you want to act from
     missing_resource: Could not find the required redirect URL for your account
@@ -795,20 +869,25 @@ en:
     revoke_success: Session successfully revoked
     title: Sessions
   settings:
+    account: Account
+    account_settings: Account settings
+    appearance: Appearance
     authorized_apps: Authorized apps
     back: Back to Mastodon
     delete: Account deletion
     development: Development
     edit_profile: Edit profile
     export: Data export
-    followers: Authorized followers
+    featured_tags: Featured hashtags
+    identity_proofs: Identity proofs
     import: Import
+    import_and_export: Import and export
     migrate: Account migration
     notifications: Notifications
     preferences: Preferences
-    settings: Settings
+    profile: Profile
+    relationships: Follows and followers
     two_factor_authentication: Two-factor Auth
-    your_apps: Your applications
   statuses:
     attached:
       description: 'Attached: %{attached}'
@@ -831,6 +910,11 @@ en:
       ownership: Someone else's toot cannot be pinned
       private: Non-public toot cannot be pinned
       reblog: A boost cannot be pinned
+    poll:
+      total_votes:
+        one: "%{count} vote"
+        other: "%{count} votes"
+      vote: Vote
     show_more: Show more
     sign_in_to_participate: Sign in to participate in the conversation
     title: '%{name}: "%{quote}"'
@@ -929,16 +1013,16 @@ en:
       <p>Originally adapted from the <a href="https://github.com/discourse/discourse">Discourse privacy policy</a>.</p>
     title: "%{instance} Terms of Service and Privacy Policy"
   themes:
-    contrast: High contrast
-    default: Qoto Default Theme (light)
     mastodon: Mastodon Default Theme (dark)
-    mastodon-light: Mastodon (light)
     blue: The Blue Theme (light)
     mastoblue: The Masto Blue Theme (light)
     material-light: Material Theme (light)
     material-dark: Material Theme (dark)
     mastodon-wide-light: Mastodon Default Theme, Full Width (light)
     mastodon-wide-dark: Mastodon Default Theme, Full Width (dark)
+    contrast: Mastodon (High contrast)
+    default: Mastodon (Dark)
+    mastodon-light: Mastodon (Light)
   time:
     formats:
       default: "%b %d, %Y, %H:%M"
@@ -987,7 +1071,7 @@ en:
       final_action: Start posting
       final_step: 'Start posting! Even without followers your public messages may be seen by others, for example on the local timeline and in hashtags. You may want to introduce yourself on the #introductions hashtag.'
       full_handle: Your full handle
-      full_handle_hint: This is what you would tell your friends so they can message or follow you from another instance.
+      full_handle_hint: This is what you would tell your friends so they can message or follow you from another server.
       review_preferences_action: Change preferences
       review_preferences_step: Make sure to set your preferences, such as which emails you'd like to receive, or what privacy level you’d like your posts to default to. If you don’t have motion sickness, you could choose to enable GIF autoplay.
       subject: Welcome to Mastodon
diff --git a/config/locales/en_GB.yml b/config/locales/en_GB.yml
index d9e1a256f6c9a5842d1647e5207699a27c1afc83..33ba1621001f576e932e171946ab48722ffe8f6d 100644
--- a/config/locales/en_GB.yml
+++ b/config/locales/en_GB.yml
@@ -1,2 +1,1050 @@
 ---
-{}
+en_GB:
+  about:
+    about_hashtag_html: These are public toots tagged with <strong>#%{hashtag}</strong>. You can interact with them if you have an account anywhere in the fediverse.
+    about_mastodon_html: Mastodon is a social network based on open web protocols and free, open-source software. It is decentralized like e-mail.
+    about_this: About
+    active_count_after: active
+    active_footnote: Monthly Active Users (MAU)
+    administered_by: 'Administered by:'
+    api: API
+    apps: Mobile apps
+    apps_platforms: Use Mastodon from iOS, Android and other platforms
+    browse_directory: Browse a profile directory and filter by interests
+    browse_public_posts: Browse a live stream of public posts on Mastodon
+    contact: Contact
+    contact_missing: Not set
+    contact_unavailable: N/A
+    discover_users: Discover users
+    documentation: Documentation
+    extended_description_html: |
+      <h3>1A good place for rules</h3>2
+      <p>3The extended description has not been set up yet.</p>4
+    federation_hint_html: With an account on %{instance} you'll be able to follow people on any Mastodon server and beyond.
+    generic_description: "%{domain} is one server in the network"
+    get_apps: Try a mobile app
+    hosted_on: Mastodon hosted on %{domain}
+    learn_more: Learn more
+    privacy_policy: Privacy policy
+    see_whats_happening: See what's happening
+    server_stats: 'Server stats:'
+    source_code: Source code
+    status_count_after:
+      one: status
+      other: statuses
+    status_count_before: Who authored
+    tagline: Follow friends and discover new ones
+    terms: Terms of service
+    user_count_after:
+      one: user
+      other: users
+    user_count_before: Home to
+    what_is_mastodon: What is Mastodon?
+  accounts:
+    choices_html: "%{name}'s choices:"
+    follow: Follow
+    followers:
+      one: Follower
+      other: Follower
+    following: Following
+    joined: Joined %{date}
+    last_active: last active
+    link_verified_on: Ownership of this link was checked on %{date}
+    media: Media
+    moved_html: "%{name} has moved to %{new_profile_link}:"
+    network_hidden: This information is not available
+    nothing_here: There is nothing here!
+    people_followed_by: People whom %{name} follows
+    people_who_follow: People who follow %{name}
+    pin_errors:
+      following: You must be already following the person you want to endorse
+    posts:
+      one: Toot
+      other: Toots
+    posts_tab_heading: Toots
+    posts_with_replies: Toots and replies
+    reserved_username: The username is reserved
+    roles:
+      admin: Admin
+      bot: Bot
+      moderator: Mod
+    unfollow: Unfollow
+  admin:
+    account_actions:
+      action: Perform action
+      title: Perform moderation action on %{acct}
+    account_moderation_notes:
+      create: Leave note
+      created_msg: Moderation note successfully created!
+      delete: Delete
+      destroyed_msg: Moderation note successfully destroyed!
+    accounts:
+      approve: Approve
+      are_you_sure: Are you sure?
+      avatar: Avatar
+      by_domain: Domain
+      change_email:
+        changed_msg: Account email successfully changed!
+        current_email: Current email
+        label: Change email
+        new_email: New email
+        submit: Change email
+        title: Change email for %{username}
+      confirm: Confirm
+      confirmed: Confirmed
+      confirming: Confirming
+      deleted: Deleted
+      demote: Demote
+      disable: Disable
+      disable_two_factor_authentication: Disable 2FA
+      disabled: Disabled
+      display_name: Display name
+      domain: Domain
+      edit: Edit
+      email: Email
+      email_status: Email status
+      enable: Enable
+      enabled: Enabled
+      feed_url: Feed URL
+      followers: Followers
+      followers_url: Followers URL
+      follows: Follows
+      header: Header
+      inbox_url: Inbox URL
+      invited_by: Invited by
+      ip: IP
+      joined: Joined
+      location:
+        all: All
+        local: Local
+        remote: Remote
+        title: Location
+      login_status: Login status
+      media_attachments: Media attachments
+      memorialize: Turn into memoriam
+      moderation:
+        active: Active
+        all: All
+        pending: Pending
+        silenced: Silenced
+        suspended: Suspended
+        title: Moderation
+      moderation_notes: Moderation notes
+      most_recent_activity: Most recent activity
+      most_recent_ip: Most recent IP
+      no_limits_imposed: No limits imposed
+      not_subscribed: Not subscribed
+      outbox_url: Outbox URL
+      pending: Pending review
+      perform_full_suspension: Suspend
+      profile_url: Profile URL
+      promote: Promote
+      protocol: Protocol
+      public: Public
+      push_subscription_expires: PuSH subscription expires
+      redownload: Refresh profile
+      reject: Reject
+      remove_avatar: Remove avatar
+      remove_header: Remove header
+      resend_confirmation:
+        already_confirmed: This user is already confirmed
+        send: Resend confirmation email
+        success: Confirmation email successfully sent!
+      reset: Reset
+      reset_password: Reset password
+      resubscribe: Resubscribe
+      role: Permissions
+      roles:
+        admin: Administrator
+        moderator: Moderator
+        staff: Staff
+        user: User
+      salmon_url: Salmon URL
+      search: Search
+      shared_inbox_url: Shared inbox URL
+      show:
+        created_reports: Made reports
+        targeted_reports: Reported by others
+      silence: Silence
+      silenced: Silenced
+      statuses: Statuses
+      subscribe: Subscribe
+      suspended: Suspended
+      title: Accounts
+      unconfirmed_email: Unconfirmed email
+      undo_silenced: Undo silence
+      undo_suspension: Undo suspension
+      unsubscribe: Unsubscribe
+      username: Username
+      warn: Warn
+      web: Web
+    action_logs:
+      actions:
+        assigned_to_self_report: "%{name} assigned report %{target} to themselves"
+        change_email_user: "%{name} changed the e-mail address of user %{target}"
+        confirm_user: "%{name} confirmed e-mail address of user %{target}"
+        create_account_warning: "%{name} sent a warning to %{target}"
+        create_custom_emoji: "%{name} uploaded new emoji %{target}"
+        create_domain_block: "%{name} blocked domain %{target}"
+        create_email_domain_block: "%{name} blacklisted e-mail domain %{target}"
+        demote_user: "%{name} demoted user %{target}"
+        destroy_custom_emoji: "%{name} destroyed emoji %{target}"
+        destroy_domain_block: "%{name} unblocked domain %{target}"
+        destroy_email_domain_block: "%{name} whitelisted e-mail domain %{target}"
+        destroy_status: "%{name} removed status by %{target}"
+        disable_2fa_user: "%{name} disabled two factor requirement for user %{target}"
+        disable_custom_emoji: "%{name} disabled emoji %{target}"
+        disable_user: "%{name} disabled login for user %{target}"
+        enable_custom_emoji: "%{name} enabled emoji %{target}"
+        enable_user: "%{name} enabled login for user %{target}"
+        memorialize_account: "%{name} turned %{target}'s account into a memoriam page"
+        promote_user: "%{name} promoted user %{target}"
+        remove_avatar_user: "%{name} removed %{target}'s avatar"
+        reopen_report: "%{name} reopened report %{target}"
+        reset_password_user: "%{name} reset password of user %{target}"
+        resolve_report: "%{name} resolved report %{target}"
+        silence_account: "%{name} silenced %{target}'s account"
+        suspend_account: "%{name} suspended %{target}'s account"
+        unassigned_report: "%{name} unassigned report %{target}"
+        unsilence_account: "%{name} unsilenced %{target}'s account"
+        unsuspend_account: "%{name} unsuspended %{target}'s account"
+        update_custom_emoji: "%{name} updated emoji %{target}"
+        update_status: "%{name} updated status by %{target}"
+      deleted_status: "(deleted status)"
+      title: Audit log
+    custom_emojis:
+      by_domain: Domain
+      copied_msg: Successfully created local copy of the emoji
+      copy: Copy
+      copy_failed_msg: Could not make a local copy of that emoji
+      created_msg: Emoji successfully created!
+      delete: Delete
+      destroyed_msg: Emojo successfully destroyed!
+      disable: Disable
+      disabled_msg: Successfully disabled that emoji
+      emoji: Emoji
+      enable: Enable
+      enabled_msg: Successfully enabled that emoji
+      image_hint: PNG up to 50KB
+      listed: Listed
+      new:
+        title: Add new custom emoji
+      overwrite: Overwrite
+      shortcode: Shortcode
+      shortcode_hint: At least 2 characters, only alphanumeric characters and underscores
+      title: Custom emojis
+      unlisted: Unlisted
+      update_failed_msg: Could not update that emoji
+      updated_msg: Emoji successfully updated!
+      upload: Upload
+    dashboard:
+      backlog: backlogged jobs
+      config: Configuration
+      feature_deletions: Account deletions
+      feature_invites: Invite links
+      feature_profile_directory: Profile directory
+      feature_registrations: Registrations
+      feature_relay: Federation relay
+      features: Features
+      hidden_service: Federation with hidden services
+      open_reports: open reports
+      recent_users: Recent users
+      search: Full-text search
+      single_user_mode: Single user mode
+      software: Software
+      space: Space usage
+      title: Dashboard
+      total_users: users in total
+      trends: Trends
+      week_interactions: interactions this week
+      week_users_active: active this week
+      week_users_new: users this week
+    domain_blocks:
+      add_new: Add new domain block
+      created_msg: Domain block is now being processed
+      destroyed_msg: Domain block has been undone
+      domain: Domain
+      new:
+        create: Create block
+        hint: The domain block will not prevent creation of account entries in the database, but will retroactively and automatically apply specific moderation methods on those accounts.
+        severity:
+          desc_html: "<strong>Silence</strong> will make the account's posts invisible to anyone who isn't following them. <strong>Suspend</strong> will remove all of the account's content, media, and profile data. Use <strong>None</strong> if you just want to reject media files."
+          noop: None
+          silence: Silence
+          suspend: Suspend
+        title: New domain block
+      reject_media: Reject media files
+      reject_media_hint: Removes locally stored media files and refuses to download any in the future. Irrelevant for suspensions
+      reject_reports: Reject reports
+      reject_reports_hint: Ignore all reports coming from this domain. Irrelevant for suspensions
+      rejecting_media: rejecting media files
+      rejecting_reports: rejecting reports
+      severity:
+        silence: silenced
+        suspend: suspended
+      show:
+        affected_accounts:
+          one: One account in the database affected
+          other: "%{count} accounts in the database affected"
+        retroactive:
+          silence: Unsilence all existing accounts from this domain
+          suspend: Unsuspend all existing accounts from this domain
+        title: Undo domain block for %{domain}
+        undo: Undo
+      undo: Undo domain block
+    email_domain_blocks:
+      add_new: Add new
+      created_msg: Successfully added e-mail domain to blacklist
+      delete: Delete
+      destroyed_msg: Successfully deleted e-mail domain from blacklist
+      domain: Domain
+      new:
+        create: Add domain
+        title: New e-mail blacklist entry
+      title: E-mail blacklist
+    followers:
+      back_to_account: Back To Account
+      title: "%{acct}'s Followers"
+    instances:
+      by_domain: Domain
+      delivery_available: Delivery is available
+      known_accounts:
+        one: "%{count} known account"
+        other: "%{count} known accounts"
+      moderation:
+        all: All
+        limited: Limited
+        title: Moderation
+      title: Federation
+      total_blocked_by_us: Blocked by us
+      total_followed_by_them: Followed by them
+      total_followed_by_us: Followed by us
+      total_reported: Reports about them
+      total_storage: Media attachments
+    invites:
+      deactivate_all: Deactivate all
+      filter:
+        all: All
+        available: Available
+        expired: Expired
+        title: Filter
+      title: Invites
+    relays:
+      add_new: Add new relay
+      delete: Delete
+      description_html: A <strong>federation relay</strong> is an intermediary server that exchanges large volumes of public toots between servers that subscribe and publish to it. <strong>It can help small and medium servers discover content from the fediverse</strong>, which would otherwise require local users manually following other people on remote servers.
+      disable: Disable
+      disabled: Disabled
+      enable: Enable
+      enable_hint: Once enabled, your server will subscribe to all public toots from this relay, and will begin sending this server's public toots to it.
+      enabled: Enabled
+      inbox_url: Relay URL
+      pending: Waiting for relay's approval
+      save_and_enable: Save and enable
+      setup: Setup a relay connection
+      status: Status
+      title: Relays
+    report_notes:
+      created_msg: Report note successfully created!
+      destroyed_msg: Report note successfully deleted!
+    reports:
+      account:
+        note: note
+        report: report
+      action_taken_by: Action taken by
+      are_you_sure: Are you sure?
+      assign_to_self: Assign to me
+      assigned: Assigned moderator
+      comment:
+        none: None
+      created_at: Reported
+      mark_as_resolved: Mark as resolved
+      mark_as_unresolved: Mark as unresolved
+      notes:
+        create: Add note
+        create_and_resolve: Resolve with note
+        create_and_unresolve: Reopen with note
+        delete: Delete
+        placeholder: Describe what actions have been taken, or any other related updates...
+      reopen: Reopen report
+      report: 'Report #%{id}'
+      reported_account: Reported account
+      reported_by: Reported by
+      resolved: Resolved
+      resolved_msg: Report successfully resolved!
+      status: Status
+      title: Reports
+      unassign: Unassign
+      unresolved: Unresolved
+      updated_at: Updated
+    settings:
+      activity_api_enabled:
+        desc_html: Counts of locally posted statuses, active users, and new registrations in weekly buckets
+        title: Publish aggregate statistics about user activity
+      bootstrap_timeline_accounts:
+        desc_html: Separate multiple usernames by comma. Only local and unlocked accounts will work. Default when empty is all local admins.
+        title: Default follows for new users
+      contact_information:
+        email: Business e-mail
+        username: Contact username
+      custom_css:
+        desc_html: Modify the look with CSS loaded on every page
+        title: Custom CSS
+      hero:
+        desc_html: Displayed on the frontpage. At least 600x100px recommended. When not set, falls back to server thumbnail
+        title: Hero image
+      mascot:
+        desc_html: Displayed on multiple pages. At least 293×205px recommended. When not set, falls back to default mascot
+        title: Mascot image
+      peers_api_enabled:
+        desc_html: Domain names this server has encountered in the fediverse
+        title: Publish list of discovered servers
+      preview_sensitive_media:
+        desc_html: Link previews on other websites will display a thumbnail even if the media is marked as sensitive
+        title: Show sensitive media in OpenGraph previews
+      profile_directory:
+        desc_html: Allow users to be discoverable
+        title: Enable profile directory
+      registrations:
+        closed_message:
+          desc_html: Displayed on frontpage when registrations are closed. You can use HTML tags
+          title: Closed registration message
+        deletion:
+          desc_html: Allow anyone to delete their account
+          title: Open account deletion
+        min_invite_role:
+          disabled: No one
+          title: Allow invitations by
+      registrations_mode:
+        modes:
+          approved: Approval required for sign up
+          none: Nobody can sign up
+          open: Anyone can sign up
+        title: Registrations mode
+      show_known_fediverse_at_about_page:
+        desc_html: When toggled, it will show toots from all the known fediverse on preview. Otherwise it will only show local toots.
+        title: Show known fediverse on timeline preview
+      show_staff_badge:
+        desc_html: Show a staff badge on a user page
+        title: Show staff badge
+      site_description:
+        desc_html: Introductory paragraph on the frontpage. Describe what makes this Mastodon server special and anything else important. You can use HTML tags, in particular <code>&lt;a&gt;</code> and <code>&lt;em&gt;</code>.
+        title: Server description
+      site_description_extended:
+        desc_html: A good place for your code of conduct, rules, guidelines and other things that set your server apart. You can use HTML tags
+        title: Custom extended information
+      site_short_description:
+        desc_html: Displayed in sidebar and meta tags. Describe what Mastodon is and what makes this server special in a single paragraph. If empty, defaults to server description.
+        title: Short server description
+      site_terms:
+        desc_html: You can write your own privacy policy, terms of service or other legalese. You can use HTML tags
+        title: Custom terms of service
+      site_title: Server name
+      thumbnail:
+        desc_html: Used for previews via OpenGraph and API. 1200x630px recommended
+        title: Server thumbnail
+      timeline_preview:
+        desc_html: Display public timeline on landing page
+        title: Timeline preview
+      title: Site settings
+    statuses:
+      back_to_account: Back to account page
+      batch:
+        delete: Delete
+        nsfw_off: Mark as not sensitive
+        nsfw_on: Mark as sensitive
+      failed_to_execute: Failed to execute
+      media:
+        title: Media
+      no_media: No media
+      no_status_selected: No statuses were changed as none were selected
+      title: Account statuses
+      with_media: With media
+    subscriptions:
+      callback_url: Callback URL
+      confirmed: Confirmed
+      expires_in: Expires in
+      last_delivery: Last delivery
+      title: WebSub
+      topic: Topic
+    tags:
+      accounts: Accounts
+      hidden: Hidden
+      hide: Hide from directory
+      name: Hashtag
+      title: Hashtags
+      unhide: Show in directory
+      visible: Visible
+    title: Administration
+    warning_presets:
+      add_new: Add new
+      delete: Delete
+      edit: Edit
+      edit_preset: Edit warning preset
+      title: Manage warning presets
+  admin_mailer:
+    new_pending_account:
+      body: The details of the new account are below. You can approve or reject this application.
+      subject: New account up for review on %{instance} (%{username})
+    new_report:
+      body: "%{reporter} has reported %{target}"
+      body_remote: Someone from %{domain} has reported %{target}
+      subject: New report for %{instance} (#%{id})
+  application_mailer:
+    notification_preferences: Change e-mail preferences
+    salutation: "%{name},"
+    settings: 'Change e-mail preferences: %{link}'
+    view: 'View:'
+    view_profile: View Profile
+    view_status: View status
+  applications:
+    created: Application successfully created
+    destroyed: Application successfully deleted
+    invalid_url: The provided URL is invalid
+    regenerate_token: Regenerate access token
+    token_regenerated: Access token successfully regenerated
+    warning: Be very careful with this data. Never share it with anyone!
+    your_token: Your access token
+  auth:
+    apply_for_account: Request an invite
+    change_password: Password
+    checkbox_agreement_html: I agree to the <a href="%{rules_path}" target="_blank">server rules</a> and <a href="%{terms_path}" target="_blank">terms of service</a>
+    confirm_email: Confirm email
+    delete_account: Delete account
+    delete_account_html: If you wish to delete your account, you can <a href="%{path}">proceed here</a>. You will be asked for confirmation.
+    didnt_get_confirmation: Didn't receive confirmation instructions?
+    forgot_password: Forgot your password?
+    invalid_reset_password_token: Password reset token is invalid or expired. Please request a new one.
+    login: Log in
+    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_log_in_with: Or log in with
+    providers:
+      cas: CAS
+      saml: SAML
+    register: Sign up
+    registration_closed: "%{instance} is not accepting new members"
+    resend_confirmation: Resend confirmation instructions
+    reset_password: Reset password
+    security: Security
+    set_new_password: Set new password
+    trouble_logging_in: Trouble logging in?
+  authorize_follow:
+    already_following: You are already following this account
+    error: Unfortunately, there was an error looking up the remote account
+    follow: Follow
+    follow_request: 'You have sent a follow request to:'
+    following: 'Success! You are now following:'
+    post_follow:
+      close: Or, you can just close this window.
+      return: Show the user's profile
+      web: Go to web
+    title: Follow %{acct}
+  datetime:
+    distance_in_words:
+      about_x_hours: "%{count}h"
+      about_x_months: "%{count}mo"
+      about_x_years: "%{count}y"
+      almost_x_years: "%{count}y"
+      half_a_minute: Just now
+      less_than_x_minutes: "%{count}m"
+      less_than_x_seconds: Just now
+      over_x_years: "%{count}y"
+      x_days: "%{count}d"
+      x_minutes: "%{count}m"
+      x_months: "%{count}mo"
+      x_seconds: "%{count}s"
+  deletes:
+    bad_password_msg: Nice try, hackers! Incorrect password
+    confirm_password: Enter your current password to verify your identity
+    description_html: This will <strong>permanently, irreversibly</strong> remove content from your account and deactivate it. Your username will remain reserved to prevent future impersonations.
+    proceed: Delete account
+    success_msg: Your account was successfully deleted
+    warning_html: Only deletion of content from this particular server is guaranteed. Content that has been widely shared is likely to leave traces. Offline servers and servers that have unsubscribed from your updates will not update their databases.
+    warning_title: Disseminated content availability
+  directories:
+    directory: Profile directory
+    enabled: You are currently listed in the directory.
+    enabled_but_waiting: You have opted-in to be listed in the directory, but you do not have the minimum number of followers (%{min_followers}) to be listed yet.
+    explanation: Discover users based on their interests
+    explore_mastodon: Explore %{title}
+    how_to_enable: You are not currently opted-in to the directory. You can opt-in below. Use hashtags in your bio text to be listed under specific hashtags!
+    people:
+      one: "%{count} person"
+      other: "%{count} people"
+  errors:
+    '403': You don't have permission to view this page.
+    '404': The page you are looking for isn't here.
+    '410': The page you were looking for doesn't exist here anymore.
+    '422':
+      content: Security verification failed. Are you blocking cookies?
+      title: Security verification failed
+    '429': Throttled
+    '500':
+      content: We're sorry, but something went wrong on our end.
+      title: This page is not correct
+    noscript_html: To use the Mastodon web application, please enable JavaScript. Alternatively, try one of the <a href="%{apps_path}">native apps</a> for Mastodon for your platform.
+  exports:
+    archive_takeout:
+      date: Date
+      download: Download your archive
+      hint_html: You can request an archive of your <strong>toots and uploaded media</strong>. The exported data will be in the ActivityPub format, readable by any compliant software. You can request an archive every 7 days.
+      in_progress: Compiling your archive...
+      request: Request your archive
+      size: Size
+    blocks: You block
+    csv: CSV
+    domain_blocks: Domain blocks
+    follows: You follow
+    lists: Lists
+    mutes: You mute
+    storage: Media storage
+  featured_tags:
+    add_new: Add new
+    errors:
+      limit: You have already featured the maximum amount of hashtags
+  filters:
+    contexts:
+      home: Home timeline
+      notifications: Notifications
+      public: Public timelines
+      thread: Conversations
+    edit:
+      title: Edit filter
+    errors:
+      invalid_context: None or invalid context supplied
+      invalid_irreversible: Irreversible filtering only works with home or notifications context
+    index:
+      delete: Delete
+      title: Filters
+    new:
+      title: Add new filter
+  footer:
+    developers: Developers
+    more: More…
+    resources: Resources
+  generic:
+    all: All
+    changes_saved_msg: Changes successfully saved!
+    copy: Copy
+    save_changes: Save changes
+    validation_errors:
+      one: Something isn't quite right yet! Please review the error below
+      other: Something isn't quite right yet! Please review %{count} errors below
+  identity_proofs:
+    active: Active
+    authorize: Yes, authorize
+    authorize_connection_prompt: Authorize this cryptographic connection?
+    errors:
+      failed: The cryptographic connection failed. Please try again from %{provider}.
+      keybase:
+        invalid_token: Keybase tokens are hashes of signatures and must be 66 hex characters
+        verification_failed: Keybase does not recognize this token as a signature of Keybase user %{kb_username}. Please retry from Keybase.
+    explanation_html: Here you can cryptographically connect your other identities, such as a Keybase profile. This lets other people send you encrypted messages and trust content you send them.
+    i_am_html: I am %{username} on %{service}.
+    identity: Identity
+    inactive: Inactive
+    status: Verification status
+    view_proof: View proof
+  imports:
+    modes:
+      merge: Merge
+      merge_long: Keep existing records and add new ones
+      overwrite: Overwrite
+      overwrite_long: Replace current records with the new ones
+    preface: You can import data that you have exported from another server, such as a list of the people you are following or blocking.
+    success: Your data was successfully uploaded and will now be processed in due time
+    types:
+      blocking: Blocking list
+      domain_blocking: Domain blocking list
+      following: Following list
+      muting: Muting list
+    upload: Upload
+  in_memoriam_html: In Memoriam.
+  invites:
+    delete: Deactivate
+    expired: Expired
+    expires_in:
+      '1800': 30 minutes
+      '21600': 6 hours
+      '3600': 1 hour
+      '43200': 12 hours
+      '604800': 1 week
+      '86400': 1 day
+    expires_in_prompt: Never
+    generate: Generate
+    invited_by: 'You were invited by:'
+    max_uses:
+      one: 1 use
+      other: "%{count} uses"
+    max_uses_prompt: No limit
+    prompt: Generate and share links with others to grant access to this server
+    table:
+      expires_at: Expires
+      uses: Uses
+    title: Invite people
+  lists:
+    errors:
+      limit: You have reached the maximum amount of lists
+  media_attachments:
+    validations:
+      images_and_video: Cannot attach a video to a status that already contains images
+      too_many: Cannot attach more than 4 files
+  migrations:
+    acct: username@domain of the new account
+    currently_redirecting: 'Your profile is set to redirect to:'
+    proceed: Save
+    updated_msg: Your account migration setting successfully updated!
+  moderation:
+    title: Moderation
+  notification_mailer:
+    digest:
+      action: View all notifications
+      body: Here is a brief summary of the messages you missed since your last visit on %{since}
+      mention: "%{name} mentioned you in:"
+      new_followers_summary:
+        one: Also, you have acquired one new follower while being away! Yay!
+        other: Also, you have acquired %{count} new followers while being away! Amazing!
+      subject:
+        one: "1 new notification since your last visit \U0001F418"
+        other: "%{count} new notifications since your last visit \U0001F418"
+      title: In your absence...
+    favourite:
+      body: 'Your status was favourited by %{name}:'
+      subject: "%{name} favourited your status"
+      title: New favourite
+    follow:
+      body: "%{name} is now following you!"
+      subject: "%{name} is now following you"
+      title: New follower
+    follow_request:
+      action: Manage follow requests
+      body: "%{name} has requested to follow you"
+      subject: 'Pending follower: %{name}'
+      title: New follow request
+    mention:
+      action: Reply
+      body: 'You were mentioned by %{name} in:'
+      subject: You were mentioned by %{name}
+      title: New mention
+    reblog:
+      body: 'Your status was boosted by %{name}:'
+      subject: "%{name} boosted your status"
+      title: New boost
+  number:
+    human:
+      decimal_units:
+        format: "%n%u"
+        units:
+          billion: B
+          million: M
+          quadrillion: Q
+          thousand: K
+          trillion: T
+  pagination:
+    newer: Newer
+    next: Next
+    older: Older
+    prev: Prev
+    truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: You have already voted on this poll
+      duplicate_options: contain duplicate items
+      duration_too_long: is too far into the future
+      duration_too_short: is too soon
+      expired: The poll has already ended
+      over_character_limit: cannot be longer than %{max} characters each
+      too_few_options: must have more than one item
+      too_many_options: can't contain more than %{max} items
+  preferences:
+    other: Other
+  relationships:
+    activity: Account activity
+    dormant: Dormant
+    moved: Moved
+    mutual: Mutual
+    primary: Primary
+    relationship: Relationship
+    remove_selected_domains: Remove all followers from the selected domains
+    remove_selected_followers: Remove selected followers
+    remove_selected_follows: Unfollow selected users
+    status: Account status
+  remote_follow:
+    acct: Enter your username@domain you want to act from
+    missing_resource: Could not find the required redirect URL for your account
+    no_account_html: Don't have an account? You can <a href='%{sign_up_path}' target='_blank'>sign up here</a>
+    proceed: Proceed to follow
+    prompt: 'You are going to follow:'
+    reason_html: "<strong>Why is this step necessary?</strong> <code>%{instance}</code> might not be the server where you are registered, so we need to redirect you to your home server first."
+  remote_interaction:
+    favourite:
+      proceed: Proceed to favourite
+      prompt: 'You want to favourite this toot:'
+    reblog:
+      proceed: Proceed to boost
+      prompt: 'You want to boost this toot:'
+    reply:
+      proceed: Proceed to reply
+      prompt: 'You want to reply to this toot:'
+  remote_unfollow:
+    error: Error
+    title: Title
+    unfollowed: Unfollowed
+  scheduled_statuses:
+    over_daily_limit: You have exceeded the limit of %{limit} scheduled toots for that day
+    over_total_limit: You have exceeded the limit of %{limit} scheduled toots
+    too_soon: The scheduled date must be in the future
+  sessions:
+    activity: Last activity
+    browser: Browser
+    browsers:
+      alipay: Alipay
+      blackberry: Blackberry
+      chrome: Chrome
+      edge: Microsoft Edge
+      electron: Electron
+      firefox: Firefox
+      generic: Unknown browser
+      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: Current session
+    description: "%{browser} on %{platform}"
+    explanation: These are the web browsers currently logged in to your Mastodon account.
+    ip: IP
+    platforms:
+      adobe_air: Adobe Air
+      android: Android
+      blackberry: Blackberry
+      chrome_os: ChromeOS
+      firefox_os: Firefox OS
+      ios: iOS
+      linux: Linux
+      mac: Mac
+      other: unknown platform
+      windows: Windows
+      windows_mobile: Windows Mobile
+      windows_phone: Windows Phone
+    revoke: Revoke
+    revoke_success: Session successfully revoked
+    title: Sessions
+  settings:
+    authorized_apps: Authorized apps
+    back: Back to Mastodon
+    delete: Account deletion
+    development: Development
+    edit_profile: Edit profile
+    export: Data export
+    featured_tags: Featured hashtags
+    identity_proofs: Identity proofs
+    import: Import
+    migrate: Account migration
+    notifications: Notifications
+    preferences: Preferences
+    relationships: Follows and followers
+    two_factor_authentication: Two-factor Auth
+  statuses:
+    attached:
+      description: 'Attached: %{attached}'
+      image:
+        one: "%{count} image"
+        other: "%{count} images"
+      video:
+        one: "%{count} video"
+        other: "%{count} videos"
+    boosted_from_html: Boosted from %{acct_link}
+    content_warning: 'Content warning: %{warning}'
+    disallowed_hashtags:
+      one: 'contained a disallowed hashtag: %{tags}'
+      other: 'contained the disallowed hashtags: %{tags}'
+    language_detection: Automatically detect language
+    open_in_web: Open in web
+    over_character_limit: character limit of %{max} exceeded
+    pin_errors:
+      limit: You have already pinned the maximum number of toots
+      ownership: Someone else's toot cannot be pinned
+      private: Non-public toot cannot be pinned
+      reblog: A boost cannot be pinned
+    poll:
+      total_votes:
+        one: "%{count} vote"
+        other: "%{count} votes"
+      vote: Vote
+    show_more: Show more
+    sign_in_to_participate: Sign in to participate in the conversation
+    title: '%{name}: "%{quote}"'
+    visibilities:
+      private: Followers-only
+      private_long: Only show to followers
+      public: Public
+      public_long: Everyone can see
+      unlisted: Unlisted
+      unlisted_long: Everyone can see, but not listed on public timelines
+  stream_entries:
+    pinned: Pinned toot
+    reblogged: boosted
+    sensitive_content: Sensitive content
+  terms:
+    body_html: |
+      <h2>Privacy Policy</h2>
+      <h3 id="collect">What information do we collect?</h3>
+
+      <ul>
+        <li><em>Basic account information</em>: If you register on this server, you may be asked to enter a username, an e-mail address and a password. You may also enter additional profile information such as a display name and biography, and upload a profile picture and header image. The username, display name, biography, profile picture and header image are always listed publicly.</li>
+        <li><em>Posts, following and other public information</em>: The list of people you follow is listed publicly, the same is true for your followers. When you submit a message, the date and time is stored as well as the application you submitted the message from. Messages may contain media attachments, such as pictures and videos. Public and unlisted posts are available publicly. When you feature a post on your profile, that is also publicly available information. Your posts are delivered to your followers, in some cases it means they are delivered to different servers and copies are stored there. When you delete posts, this is likewise delivered to your followers. The action of reblogging or favouriting another post is always public.</li>
+        <li><em>Direct and followers-only posts</em>: All posts are stored and processed on the server. Followers-only posts are delivered to your followers and users who are mentioned in them, and direct posts are delivered only to users mentioned in them. In some cases it means they are delivered to different servers and copies are stored there. We make a good faith effort to limit the access to those posts only to authorized persons, but other servers may fail to do so. Therefore it's important to review servers your followers belong to. You may toggle an option to approve and reject new followers manually in the settings. <em>Please keep in mind that the operators of the server and any receiving server may view such messages</em>, and that recipients may screenshot, copy or otherwise re-share them. <em>Do not share any dangerous information over Mastodon.</em></li>
+        <li><em>IPs and other metadata</em>: When you log in, we record the IP address you log in from, as well as the name of your browser application. All the logged in sessions are available for your review and revocation in the settings. The latest IP address used is stored for up to 12 months. We also may retain server logs which include the IP address of every request to our server.</li>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="use">What do we use your information for?</h3>
+
+      <p>Any of the information we collect from you may be used in the following ways:</p>
+
+      <ul>
+        <li>To provide the core functionality of Mastodon. You can only interact with other people's content and post your own content when you are logged in. For example, you may follow other people to view their combined posts in your own personalized home timeline.</li>
+        <li>To aid moderation of the community, for example comparing your IP address with other known ones to determine ban evasion or other violations.</li>
+        <li>The email address you provide may be used to send you information, notifications about other people interacting with your content or sending you messages, and to respond to inquiries, and/or other requests or questions.</li>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="protect">How do we protect your information?</h3>
+
+      <p>We implement a variety of security measures to maintain the safety of your personal information when you enter, submit, or access your personal information. Among other things, your browser session, as well as the traffic between your applications and the API, are secured with SSL, and your password is hashed using a strong one-way algorithm. You may enable two-factor authentication to further secure access to your account.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="data-retention">What is our data retention policy?</h3>
+
+      <p>We will make a good faith effort to:</p>
+
+      <ul>
+        <li>Retain server logs containing the IP address of all requests to this server, in so far as such logs are kept, no more than 90 days.</li>
+        <li>Retain the IP addresses associated with registered users no more than 12 months.</li>
+      </ul>
+
+      <p>You can request and download an archive of your content, including your posts, media attachments, profile picture, and header image.</p>
+
+      <p>You may irreversibly delete your account at any time.</p>
+
+      <hr class="spacer"/>
+
+      <h3 id="cookies">Do we use cookies?</h3>
+
+      <p>Yes. Cookies are small files that a site or its service provider transfers to your computer's hard drive through your Web browser (if you allow). These cookies enable the site to recognize your browser and, if you have a registered account, associate it with your registered account.</p>
+
+      <p>We use cookies to understand and save your preferences for future visits.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="disclose">Do we disclose any information to outside parties?</h3>
+
+      <p>We do not sell, trade, or otherwise transfer to outside parties your personally identifiable information. This does not include trusted third parties who assist us in operating our site, conducting our business, or servicing you, so long as those parties agree to keep this information confidential. We may also release your information when we believe release is appropriate to comply with the law, enforce our site policies, or protect ours or others rights, property, or safety.</p>
+
+      <p>Your public content may be downloaded by other servers in the network. Your public and followers-only posts are delivered to the servers where your followers reside, and direct messages are delivered to the servers of the recipients, in so far as those followers or recipients reside on a different server than this.</p>
+
+      <p>When you authorize an application to use your account, depending on the scope of permissions you approve, it may access your public profile information, your following list, your followers, your lists, all your posts, and your favourites. Applications can never access your e-mail address or password.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="children">Site usage by children</h3>
+
+      <p>If this server is in the EU or the EEA: Our site, products and services are all directed to people who are at least 16 years old. If you are under the age of 16, per the requirements of the GDPR (<a href="https://en.wikipedia.org/wiki/General_Data_Protection_Regulation">General Data Protection Regulation</a>) do not use this site.</p>
+
+      <p>If this server is in the USA: Our site, products and services are all directed to people who are at least 13 years old. If you are under the age of 13, per the requirements of COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) do not use this site.</p>
+
+      <p>Law requirements can be different if this server is in another jurisdiction.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="changes">Changes to our Privacy Policy</h3>
+
+      <p>If we decide to change our privacy policy, we will post those changes on this page.</p>
+
+      <p>This document is CC-BY-SA. It was last updated March 7, 2018.</p>
+
+      <p>Originally adapted from the <a href="https://github.com/discourse/discourse">Discourse privacy policy</a>.</p>
+    title: "%{instance} Terms of Service and Privacy Policy"
+  themes:
+    contrast: Mastodon (High contrast)
+    default: Mastodon (Dark)
+    mastodon-light: Mastodon (Light)
+  time:
+    formats:
+      default: "%b %d, %Y, %H:%M"
+      month: "%b %Y"
+  two_factor_authentication:
+    code_hint: Enter the code generated by your authenticator app to confirm
+    description_html: If you enable <strong>two-factor authentication</strong>, logging in will require you to be in possession of your phone, which will generate tokens for you to enter.
+    disable: Disable
+    enable: Enable
+    enabled: Two-factor authentication is enabled
+    enabled_success: Two-factor authentication successfully enabled
+    generate_recovery_codes: Generate recovery codes
+    instructions_html: "<strong>Scan this QR code into Google Authenticator or a similiar TOTP app on your phone</strong>. From now on, that app will generate tokens that you will have to enter when logging in."
+    lost_recovery_codes: Recovery codes allow you to regain access to your account if you lose your phone. If you've lost your recovery codes, you can regenerate them here. Your old recovery codes will be invalidated.
+    manual_instructions: 'If you can''t scan the QR code and need to enter it manually, here is the plain-text secret:'
+    recovery_codes: Backup recovery codes
+    recovery_codes_regenerated: Recovery codes successfully regenerated
+    recovery_instructions_html: If you ever lose access to your phone, you can use one of the recovery codes below to regain access to your account. <strong>Keep the recovery codes safe</strong>. For example, you may print them and store them with other important documents.
+    setup: Set up
+    wrong_code: The entered code was invalid! Are server time and device time correct?
+  user_mailer:
+    backup_ready:
+      explanation: You requested a full backup of your Mastodon account. It's now ready for download!
+      subject: Your archive is ready for download
+      title: Archive takeout
+    warning:
+      explanation:
+        disable: While your account is frozen, your account data remains intact, but you cannot perform any actions until it is unlocked.
+        silence: While your account is limited, only people who are already following you will see your toots on this server, and you may be excluded from various public listings. However, others may still manually follow you.
+        suspend: Your account has been suspended, and all of your toots and your uploaded media files have been irreversibly removed from this server, and servers where you had followers.
+      review_server_policies: Review server policies
+      subject:
+        disable: Your account %{acct} has been frozen
+        none: Warning for %{acct}
+        silence: Your account %{acct} has been limited
+        suspend: Your account %{acct} has been suspended
+      title:
+        disable: Account frozen
+        none: Warning
+        silence: Account limited
+        suspend: Account suspended
+    welcome:
+      edit_profile_action: Setup profile
+      edit_profile_step: You can customize your profile by uploading an avatar, header, changing your display name and more. If you’d like to review new followers before they’re allowed to follow you, you can lock your account.
+      explanation: Here are some tips to get you started
+      final_action: Start posting
+      final_step: 'Start posting! Even without followers your public messages may be seen by others, for example on the local timeline and in hashtags. You may want to introduce yourself on the #introductions hashtag.'
+      full_handle: Your full handle
+      full_handle_hint: This is what you would tell your friends so they can message or follow you from another server.
+      review_preferences_action: Change preferences
+      review_preferences_step: Make sure to set your preferences, such as which emails you'd like to receive, or what privacy level you’d like your posts to default to. If you don’t have motion sickness, you could choose to enable GIF autoplay.
+      subject: Welcome to Mastodon
+      tip_federated_timeline: The federated timeline is a firehose view of the Mastodon network. But it only includes people your neighbours are subscribed to, so it's not complete.
+      tip_following: You follow your server's admin(s) by default. To find more interesting people, check the local and federated timelines.
+      tip_local_timeline: The local timeline is a firehose view of people on %{instance}. These are your immediate neighbours!
+      tip_mobile_webapp: If your mobile browser offers you to add Mastodon to your homescreen, you can receive push notifications. It acts like a native app in many ways!
+      tips: Tips
+      title: Welcome aboard, %{name}!
+  users:
+    follow_limit_reached: You cannot follow more than %{limit} people
+    invalid_email: The e-mail address is invalid
+    invalid_otp_token: Invalid two-factor code
+    otp_lost_help_html: If you lost access to both, you may get in touch with %{email}
+    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:'
+  verification:
+    explanation_html: 'You can <strong>verify yourself as the owner of the links in your profile metadata</strong>. For that, the linked website must contain a link back to your Mastodon profile. The link back <strong>must</strong> have a <code>rel="me"</code> attribute. The text content of the link does not matter. Here is an example:'
+    verification: Verification
diff --git a/config/locales/eo.yml b/config/locales/eo.yml
index aaa943185659d2eb925fd91afa38712e1375b8f5..c71b42fdd8161feef7ab8ab12f3ddb897fbff9a7 100644
--- a/config/locales/eo.yml
+++ b/config/locales/eo.yml
@@ -1,39 +1,39 @@
 ---
 eo:
   about:
-    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_hashtag_html: Ĉi tiuj estas la publikaj fajfoj 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
+    active_count_after: aktiva
+    active_footnote: Monate Aktivaj Uzantoj (MAU)
     administered_by: 'Administrata de:'
     api: API
     apps: Poŝtelefonaj aplikaĵoj
-    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.
+    apps_platforms: Uzu Mastodon ĉe iOS, Android kaj aliajn platformojn
+    browse_directory: Esplori profilujo kaj filtri per interesoj
+    browse_public_posts: Vidi vivantan fluon de publikaj mesaĝoj al Mastodon
     contact: Kontakti
     contact_missing: Ne elektita
     contact_unavailable: Ne disponebla
+    discover_users: Malkovri uzantojn
     documentation: Dokumentado
     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 65535 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
+    federation_hint_html: Per konto ĉe %{instance}, vi povos sekvi homojn ĉe iu ajn Mastodon nodo kaj preter.
     generic_description: "%{domain} estas unu servilo en la reto"
+    get_apps: Provu telefonan aplikaĵon
     hosted_on: "%{domain} estas nodo de Mastodon"
     learn_more: Lerni pli
-    other_instances: Listo de nodoj
     privacy_policy: Privateca politiko
+    see_whats_happening: Vidi kio okazas
+    server_stats: Servo statuso
     source_code: Fontkodo
     status_count_after:
       one: mesaĝo
       other: mesaĝoj
     status_count_before: Kie skribiĝis
+    tagline: Sekvi amikojn kaj trovi novan onin
     terms: Uzkondiĉoj
     user_count_after:
       one: uzanto
@@ -68,14 +68,20 @@ eo:
       admin: Administranto
       bot: Roboto
       moderator: Kontrolanto
+    unavailable: Profilo ne disponebla
     unfollow: Ne plu sekvi
   admin:
+    account_actions:
+      action: Plenumi agon
+      title: Plenumi kontrolan agon al %{acct}
     account_moderation_notes:
       create: Lasi noton
       created_msg: Kontrola noto sukcese kreita!
       delete: Forigi
       destroyed_msg: Kontrola noto sukcese detruita!
     accounts:
+      approve: Aprobi
+      approve_all: Aprobi ĉiujn
       are_you_sure: Ĉu vi certas?
       avatar: Profilbildo
       by_domain: Domajno
@@ -89,6 +95,7 @@ eo:
       confirm: Konfirmi
       confirmed: Konfirmita
       confirming: Konfirmante
+      deleted: Forigita
       demote: Degradi
       disable: Malebligi
       disable_two_factor_authentication: Malebligi 2FA
@@ -96,44 +103,53 @@ eo:
       display_name: Montrata nomo
       domain: Domajno
       edit: Redakti
-      email: Retpoŝto
-      email_status: Retpoŝto Stato
+      email: Retadreso
+      email_status: Retadreso Stato
       enable: Ebligi
       enabled: Ebligita
       feed_url: URL de la fluo
       followers: Sekvantoj
       followers_url: URL de la sekvantoj
       follows: Sekvatoj
+      header: Kapa bildo
       inbox_url: Enira URL
+      invited_by: Invitita de
       ip: IP
+      joined: Aliĝis
       location:
         all: Ĉio
-        local: Loka
-        remote: Fora
+        local: Lokaj
+        remote: Foraj
         title: Loko
       login_status: Ensaluta stato
       media_attachments: Ligitaj aŭdovidaĵoj
       memorialize: Ŝanĝi al memoro
       moderation:
-        active: Aktiva
+        active: Aktivaj
         all: Ĉio
+        pending: Pritraktata
         silenced: Silentigitaj
         suspended: Haltigitaj
         title: Kontrolado
       moderation_notes: Kontrolaj notoj
       most_recent_activity: Lasta ago
       most_recent_ip: Lasta IP
+      no_account_selected: Neniu konto estis ŝanĝita ĉar neniu estis selektita
       no_limits_imposed: Neniu limito trudita
       not_subscribed: Ne abonita
       outbox_url: Elira URL
+      pending: Pritraktata recenzo
       perform_full_suspension: Haltigi
       profile_url: Profila URL
       promote: Plirangigi
       protocol: Protokolo
       public: Publika
       push_subscription_expires: Eksvalidiĝo de la abono al PuSH
-      redownload: Aktualigi profilbildon
+      redownload: Aktualigi profilon
+      reject: Malakcepti
+      reject_all: Malaprobi ĉiujn
       remove_avatar: Forigi profilbildon
+      remove_header: Forigi kapan bildon
       resend_confirmation:
         already_confirmed: Ĉi tiu uzanto jam estas konfirmita
         send: Esend konfirmi retpoŝton
@@ -151,8 +167,8 @@ eo:
       search: Serĉi
       shared_inbox_url: URL de kunhavigita leterkesto
       show:
-        created_reports: Signaloj kreitaj de ĉi tiu konto
-        targeted_reports: Signaloj kreitaj de ĉi tiu konto
+        created_reports: Kreitaj signaloj
+        targeted_reports: Signalitaj de aliaj
       silence: Kaŝi
       silenced: Silentigita
       statuses: Mesaĝoj
@@ -164,12 +180,14 @@ eo:
       undo_suspension: Malfari haltigon
       unsubscribe: Malaboni
       username: Uzantnomo
+      warn: Averti
       web: Reto
     action_logs:
       actions:
         assigned_to_self_report: "%{name} asignis signalon %{target} al si mem"
         change_email_user: "%{name} ŝanĝis retadreson de uzanto %{target}"
         confirm_user: "%{name} konfirmis retadreson de uzanto %{target}"
+        create_account_warning: "%{name} sendis averton al %{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}"
@@ -231,6 +249,7 @@ eo:
       feature_profile_directory: Profilujo
       feature_registrations: Registriĝoj
       feature_relay: Federacia ripetilo
+      feature_timeline_preview: Templinio antaÅ­vidi
       features: Funkcioj
       hidden_service: Federacio kun kaŝitaj servoj
       open_reports: nefermitaj raportoj
@@ -261,6 +280,13 @@ eo:
         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
+      reject_reports: Malakcepti raportojn
+      reject_reports_hint: Ignori ĉiujn raportojn el tiu domajno. Nur gravas por silentigoj
+      rejecting_media: aŭdovidaj dosieroj malakceptiĝas
+      rejecting_reports: raportoj malakceptiĝas
+      severity:
+        silence: silentigita
+        suspend: haltigita
       show:
         affected_accounts:
           one: Unu konto en la datumbazo esta influita
@@ -281,8 +307,25 @@ eo:
         create: Aldoni domajnon
         title: Nova blokado de retadresa domajno
       title: Nigra listo de retadresaj domajnoj
+    followers:
+      back_to_account: Reen al la konto
+      title: Sekvantoj de %{acct}
     instances:
-      title: Konataj nodoj
+      by_domain: Domajno
+      delivery_available: Liverado disponeblas
+      known_accounts:
+        one: "%{count} konata konto"
+        other: "%{count} konataj kontoj"
+      moderation:
+        all: Ĉiuj
+        limited: Limigita
+        title: Kontrolo
+      title: Federacio
+      total_blocked_by_us: Blokitaj de ni
+      total_followed_by_them: Sekvataj de ili
+      total_followed_by_us: Sekvataj de ni
+      total_reported: Raportoj pri ili
+      total_storage: Aŭdovidaj kunsendaĵoj
     invites:
       deactivate_all: Malaktivigi ĉion
       filter:
@@ -301,6 +344,7 @@ eo:
       enable_hint: Post ebligo, via servilo abonos ĉiujn publikajn mesaĝojn de tiu ripetilo, kaj komencos sendi publikajn mesaĝojn de la servilo al ĝi.
       enabled: Malebligita
       inbox_url: URL de la ripetilo
+      pending: Atendante aprobon de la ripetilo
       save_and_enable: Konservi kaj ebligi
       setup: Agordi konekton al ripetilo
       status: Stato
@@ -331,12 +375,12 @@ eo:
       report: 'Signalo #%{id}'
       reported_account: Signalita konto
       reported_by: Signalita de
-      resolved: Solvita
+      resolved: Solvitaj
       resolved_msg: Signalo sukcese solvita!
       status: Mesaĝoj
       title: Signaloj
       unassign: Malasigni
-      unresolved: Nesolvita
+      unresolved: Nesolvitaj
       updated_at: Äœisdatigita
     settings:
       activity_api_enabled:
@@ -352,11 +396,14 @@ eo:
         desc_html: Ŝanĝi la aspekton per CSS ŝargita en ĉiu pago
         title: Propra CSS
       hero:
-        desc_html: Montrata en la ĉefpaĝo. Almenaŭ 600x100px rekomendita. Kiam ne agordita, la bildeto de la nodo estos uzata
+        desc_html: Montrata en la ĉefpaĝo. Almenaŭ 600x100px rekomendita. Kiam ne agordita, la bildeto de la servilo estos uzata
         title: Kapbildo
+      mascot:
+        desc_html: Montrata en pluraj paĝoj. Rekomendataj estas almenaŭ 293x205px. Se ĉi tio ne estas agordita, la defaŭlta maskoto uziĝas
+        title: Maskota bildo
       peers_api_enabled:
-        desc_html: Nomoj de domajnoj, kiujn ĉi tiu nodo renkontis en la fediverse
-        title: Publikigi liston de malkovritaj nodoj
+        desc_html: Nomoj de domajnoj, kiujn ĉi tiu servilo renkontis en la federauniverso
+        title: Publikigi liston de malkovritaj serviloj
       preview_sensitive_media:
         desc_html: Antaŭvido de ligiloj en aliaj retejoj montros bildeton eĉ se la aŭdovidaĵo estas markita kiel tikla
         title: Montri tiklajn aŭdovidaĵojn en la antaŭvidoj de OpenGraph
@@ -373,9 +420,12 @@ eo:
         min_invite_role:
           disabled: Neniu
           title: Permesi invitojn de
-        open:
-          desc_html: Permesi iun ajn krei konton
-          title: Malfermi registriĝojn
+      registrations_mode:
+        modes:
+          approved: Bezonas aprobi por aliĝi
+          none: Neniu povas aliĝi
+          open: Iu povas aliĝi
+        title: Registrado modo
       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
@@ -384,22 +434,22 @@ eo:
         title: Montri teaman insignon
       site_description:
         desc_html: Enkonduka alineo en la ĉefpaĝo. Priskribu la unikaĵojn de ĉi tiu nodo de Mastodon, kaj ĉiujn aliajn gravaĵojn. Vi povas uzi HTML-etikedojn, kiel <code>&lt;a&gt;</code> kaj <code>&lt;em&gt;</code>.
-        title: Priskribo de la nodo
+        title: Priskribo de la servilo
       site_description_extended:
-        desc_html: Bona loko por viaj sintenaj reguloj, aliaj reguloj, gvidlinioj kaj aliaj aferoj, kiuj apartigas vian nodon. Vi povas uzi HTML-etikedojn
+        desc_html: Bona loko por viaj sintenaj reguloj, aliaj reguloj, gvidlinioj kaj aliaj aferoj, kiuj apartigas vian serilon. Vi povas uzi HTML-etikedojn
         title: Propraj detalaj informoj
       site_short_description:
-        desc_html: Afiŝita en la flankpanelo kaj metadatumaj etikedoj. Priskribu kio estas Mastodon, kaj kio specialas en ĉi tiu nodo, per unu alineo. Se malplena, la priskribo de la nodo estos uzata.
-        title: Mallonga priskribo de la nodo
+        desc_html: Afiŝita en la flankpanelo kaj metadatumaj etikedoj. Priskribu kio estas Mastodon, kaj kio specialas en ĉi tiu nodo, per unu alineo. Se malplena, la priskribo de la servilo estos uzata.
+        title: Mallonga priskribo de la servilo
       site_terms:
         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
+      site_title: Nomo de la servilo
       thumbnail:
         desc_html: Uzata por antaÅ­vidoj per OpenGraph kaj per API. 1200x630px rekomendita
-        title: Bildeto de la nodo
+        title: Bildeto de la servilo
       timeline_preview:
-        desc_html: Montri publikan tempolinion en komenca paĝo
+        desc_html: Montri publikan templinion en komenca paĝo
         title: Tempolinia antaÅ­vido
       title: Retejaj agordoj
     statuses:
@@ -423,17 +473,32 @@ eo:
       title: WebSub
       topic: Temo
     tags:
+      accounts: Kontoj
+      hidden: Kaŝitaj
       hide: Kaŝi de la profilujo
       name: Kradvorto
       title: Kradvortoj
       unhide: Montri en la profilujo
-      visible: Videbla
+      visible: Videblaj
     title: Administrado
+    warning_presets:
+      add_new: Aldoni novan
+      delete: Forigi
+      edit: Redakti
+      edit_preset: Redakti avertan antaÅ­agordon
+      title: Administri avertajn antaÅ­agordojn
   admin_mailer:
+    new_pending_account:
+      body: La detaloj de la nova konto estas sube. Vi povas aprobi aŭ Malakcepti ĉi kandidatiĝo.
+      subject: Nova konto atendas por recenzo en %{instance} (%{username})
     new_report:
       body: "%{reporter} signalis %{target}"
       body_remote: Iu de %{domain} signalis %{target}
       subject: Nova signalo por %{instance} (#%{id})
+  appearance:
+    advanced_web_interface: Altnivela retpaĝa interfaco
+    confirmation_dialogs: Konfirmaj dialogoj
+    sensitive_content: Tikla enhavo
   application_mailer:
     notification_preferences: Ŝanĝi retmesaĝajn preferojn
     salutation: "%{name},"
@@ -450,8 +515,9 @@ eo:
     warning: Estu tre atenta kun ĉi tiu datumo. Neniam diskonigu ĝin al iu ajn!
     your_token: Via alira ĵetono
   auth:
-    agreement_html: Klakante “Registriĝi” sube, vi konsentas kun <a href="%{rules_path}">la reguloj de la nodo</a> kaj <a href="%{terms_path}">niaj uzkondiĉoj</a>.
+    apply_for_account: Peti inviton
     change_password: Pasvorto
+    checkbox_agreement_html: Mi samopinii al la <a href="%{rules_path}" target="_blank">Servo reguloj</a> kaj <a href="%{terms_path}" target="_blank">kondiĉo al servadon</a>
     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.
@@ -462,17 +528,17 @@ eo:
     logout: Elsaluti
     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: aÅ­
     or_log_in_with: AÅ­ ensaluti per
     providers:
       cas: CAS
       saml: SAML
     register: Registriĝi
-    register_elsewhere: Registriĝi en alia servilo
+    registration_closed: "%{instance} ne estas akcepti nova uzantojn"
     resend_confirmation: Resendi la instrukciojn por konfirmi
     reset_password: Ŝanĝi pasvorton
     security: Sekureco
     set_new_password: Elekti novan pasvorton
+    trouble_logging_in: Äœeni ensaluti?
   authorize_follow:
     already_following: Vi jam sekvas tiun konton
     error: Bedaŭrinde, estis eraro en la serĉado de la fora konto
@@ -504,19 +570,22 @@ eo:
     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_html: La forigo de la enhavo estas certa nur por ĉi tiu aparta servilo. 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
   directories:
     directory: Profilujo
+    enabled: Vi estas listigata en la profilujo.
+    enabled_but_waiting: Vi elektis esti listigata en la profilujo, sed vi ankoraÅ­ ne havas la minimuman kvanton da sekvantoj (%{min_followers}) por esti listigata.
     explanation: Malkovru uzantojn per iliaj interesoj
     explore_mastodon: Esplori %{title}
+    how_to_enable: Vi ankoraŭ ne donis permeson listigi vin en la profilujo. Vi povas doni permeson ĉi-sube. Uzu kradvortojn en via biografia teksto por esti listigata sub specifaj kradvortoj!
     people:
-      one: "%{count} personoj"
+      one: "%{count} persono"
       other: "%{count} personoj"
   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.
+    '404': La paĝo ke kiun vi serĉas ne ekzistas ĉi tie.
+    '410': La paĝo, kiun vi serĉas, ne plu ekzistas ĉi tie.
     '422':
       content: Sekureca konfirmo malsukcesa. Ĉu vi blokas kuketojn?
       title: Sekureca konfirmo malsukcesa
@@ -527,6 +596,9 @@ eo:
     noscript_html: |-
       Por uzi la retan aplikaĵon de Mastodon, bonvolu ebligi JavaScript. Alimaniere, provu unu el la
       <a href="%{apps_path}">operaciumaj aplikaĵoj</a> por Mastodon por via platformo.
+  existing_username_validator:
+    not_found: Ne povas trovi lokaj uzanto kun tiu uzantnomo
+    not_found_multiple: Ne povas trovi %{usernames}
   exports:
     archive_takeout:
       date: Dato
@@ -537,14 +609,20 @@ eo:
       size: Grandeco
     blocks: Vi blokas
     csv: CSV
+    domain_blocks: Blokoj de domajnoj
     follows: Vi sekvas
+    lists: Listoj
     mutes: Vi silentigas
     storage: Aŭdovidaĵa konservado
+  featured_tags:
+    add_new: Aldoni novan
+    errors:
+      limit: Vi jam elstarigis la maksimuman kvanton da kradvortoj
   filters:
     contexts:
-      home: Hejma tempolinio
+      home: Hejma templinio
       notifications: Sciigoj
-      public: Publikaj tempolinioj
+      public: Publika templinio
       thread: Konversacioj
     edit:
       title: Ŝanĝi filtrilojn
@@ -556,34 +634,50 @@ eo:
       title: Filtriloj
     new:
       title: Aldoni novan filtrilon
-  followers:
-    domain: Domajno
-    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 la sekvantojn de la nodoj, kie vi ne certas ĉu via privateco estos respektita de la tiea teamo aŭ programo.
-    followers_count: Nombro de sekvantoj
-    lock_link: Åœlosu 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
   footer:
     developers: Programistoj
     more: Pli…
     resources: Rimedoj
   generic:
+    all: Ĉio
     changes_saved_msg: Ŝanĝoj sukcese konservitaj!
     copy: Kopii
+    order_by: Ordigi de
     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
+  html_validator:
+    invalid_markup: 'havas malvalida HTML markado: %{error}'
+  identity_proofs:
+    active: Aktiva
+    authorize: Jes, permesi
+    authorize_connection_prompt: Permesi ĉi tiu ĉifrikan conekton?
+    errors:
+      failed: La ĉifrika conekto nefaris. Peti provu denove el %{provider}.
+      keybase:
+        invalid_token: Keybase signo estas haŝoj de subskribo kaj devi 66 deksesuma leteroj
+        verification_failed: Keybase ne rekoni ĉi tiu signo kiel subskribo de Keybase uzanto %{kb_username}. Peti provu denove el Keybase.
+      wrong_user: Ne povas krei por %{proving} dum ensalutis kiel %{current}. Ensaluti kiel %{proving} kaj provu denove.
+    explanation_html: Ĉi tie vi povas ĉifrika konekti via alia identicoj, kiel Keybase profilon. ĉi tiu igi aliaj popoloj sendi al vi ĉifritaj mesaĝoj kaj fidi kontento vi sendi al ilin.
+    i_am_html: Mi estas %{username} en %{service}.
+    identity: Identeco
+    inactive: Malaktiva
+    publicize_checkbox: 'Kaj fajfi ĉi tio:'
+    publicize_toot: 'I estas pruvita! Mi estas %{username} sur %{service}: %{url}'
+    status: Confirmo statuso
+    view_proof: Vidi pruvo
   imports:
-    preface: Vi povas importi datumojn, kiujn vi eksportis el alia nodo, kiel liston de homoj, kiujn vi sekvas aÅ­ blokas.
+    modes:
+      merge: Kunigi
+      merge_long: Konservi ekzistajn registrojn kaj aldoni novajn
+      overwrite: AnstataÅ­igi
+      overwrite_long: AnstataÅ­igi la nunajn registrojn per la novaj
+    preface: Vi povas importi datumojn, kiujn vi eksportis el alia servilo, 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
+      domain_blocking: Listo de blokitaj domajnoj
       following: Listo de sekvatoj
       muting: Listo de silentigitoj
     upload: Alŝuti
@@ -605,7 +699,7 @@ eo:
       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
+    prompt: Krei kaj diskonigi ligilojn al aliaj por doni aliron al ĉi tiu servilo
     table:
       expires_at: Eksvalidiĝas je
       uses: Uzoj
@@ -668,28 +762,58 @@ eo:
           quadrillion: Dd
           thousand: m
           trillion: Dn
-          unit: " "
   pagination:
     newer: Pli nova
     next: Sekva
     older: Malpli nova
     prev: AntaÅ­a
     truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: Vi jam voĉdonis al ĉi tiu enketa
+      duplicate_options: enhavas duoblaĵojn
+      duration_too_long: estas tro for en la estonteco
+      duration_too_short: estas tro frue
+      expired: La enketo jam finiĝis
+      over_character_limit: ne povas esti po pli longa ol %{max} signoj
+      too_few_options: devas enhavi pli da unu propono
+      too_many_options: ne povas enhavi pli da %{max} proponoj
   preferences:
-    languages: Lingvoj
     other: Aliaj aferoj
-    publishing: Publikado
-    web: Reto
+  relationships:
+    dormant: Dormanta
+    last_active: Lasta aktiva
+    most_recent: Plej lasta
+    moved: Moviĝita
+    mutual: Reciproka
+    primary: Primara
+    relationship: Rilato
+    status: Statuso de la konto
   remote_follow:
     acct: Enmetu vian uzantnomo@domajno de kie vi volas agi
     missing_resource: La URL de plusendado ne estis trovita
     no_account_html: Ĉu vi ne havas konton? Vi povas <a href='%{sign_up_path}' target='_blank'>registriĝi tie</a>
     proceed: DaÅ­rigi por eksekvi
     prompt: 'Vi eksekvos:'
+    reason_html: "<strong>Kial necesas ĉi tiu paŝo?</strong><code>%{instance}</code> povus ne esti la servilo, kie vi registriĝis, do ni unue bezonas alidirekti vin al via hejma servilo."
+  remote_interaction:
+    favourite:
+      proceed: Konfirmi la stelumon
+      prompt: 'Vi volas stelumi ĉi tiun mesaĝon:'
+    reblog:
+      proceed: Konfirmi la diskonigon
+      prompt: 'Vi volas diskonigi ĉi tiun mesaĝon:'
+    reply:
+      proceed: Konfirmi la respondon
+      prompt: 'Vi volas respondi al ĉi tiu mesaĝo:'
   remote_unfollow:
     error: Eraro
     title: Titolo
     unfollowed: Ne plu sekvita
+  scheduled_statuses:
+    over_daily_limit: Vi transpasis la limigon al %{limit} samtage planitaj mesaĝoj
+    over_total_limit: Vi transpasis la limigon al %{limit} planitaj mesaĝoj
+    too_soon: La planita dato devas esti en la estonteco
   sessions:
     activity: Lasta ago
     browser: Retumilo
@@ -732,20 +856,25 @@ eo:
     revoke_success: Seanco sukcese malvalidigita
     title: Seancoj
   settings:
+    account: Konto
+    account_settings: Agordoj de konto
+    appearance: Apero
     authorized_apps: Rajtigitaj aplikaĵoj
     back: Reveni al Mastodon
     delete: Konta forigo
     development: Evoluigado
     edit_profile: Redakti profilon
     export: Eksporti datumojn
-    followers: Rajtigitaj sekvantoj
+    featured_tags: Elstarigitaj kradvortoj
+    identity_proofs: Pruvo de identeco
     import: Importi
+    import_and_export: Alporto kaj elporto
     migrate: Konta migrado
     notifications: Sciigoj
     preferences: Preferoj
-    settings: Agordoj
+    profile: Profilo
+    relationships: Sekvatoj kaj sekvantoj
     two_factor_authentication: Dufaktora aÅ­tentigo
-    your_apps: Viaj aplikaĵoj
   statuses:
     attached:
       description: 'Ligita: %{attached}'
@@ -768,16 +897,21 @@ eo:
       ownership: Mesaĝo de iu alia ne povas esti alpinglita
       private: Mesaĝo nepublika ne povas esti alpinglita
       reblog: Diskonigo ne povas esti alpinglita
+    poll:
+      total_votes:
+        one: "%{count} voĉdono"
+        other: "%{count} voĉdonoj"
+      vote: Voĉdoni
     show_more: Montri pli
     sign_in_to_participate: Ensaluti por partopreni en la konversacio
-    title: '%{name}: "%{quote}"'
+    title: "%{name}: “%{quote}”"
     visibilities:
       private: Montri nur al sekvantoj
       private_long: Montri nur al sekvantoj
       public: Publika
       public_long: Ĉiuj povas vidi
       unlisted: Nelistigita
-      unlisted_long: Ĉiuj povas vidi, sed nelistigita en publikaj tempolinioj
+      unlisted_long: Ĉiuj povas vidi, sed nelistigita en publikaj templinioj
   stream_entries:
     pinned: Alpinglita
     reblogged: diskonigita
@@ -785,9 +919,9 @@ eo:
   terms:
     title: Uzkondiĉoj kaj privateca politiko de %{instance}
   themes:
-    contrast: Forta kontrasto
-    default: Mastodon
-    mastodon-light: Mastodon (hela)
+    contrast: Mastodon (Forta kontrasto)
+    default: Mastodon (Malluma)
+    mastodon-light: Mastodon (Luma)
   time:
     formats:
       default: "%Y-%m-%d %H:%M"
@@ -813,20 +947,36 @@ eo:
       explanation: Vi petis kompletan arkivon de via Mastodon-konto. Ĝi nun pretas por elŝutado!
       subject: Via arkivo estas preta por elŝutado
       title: Arkiva elŝuto
+    warning:
+      explanation:
+        disable: Dum via konto estas frostigita, via kontaj datumoj restas intaktaj, sed vi ne povas plenumi iujn agojn ĝis ĝi estas malhaltigita.
+        silence: Dum via konto estas limigita, nur tiuj, kiuj jam sekvas vin, vidos viajn mesaĝojn en ĉi tiu servilo, kaj vi povus esti ekskludita de diversaj publikaj listoj. Tamen, aliaj ankoraŭ povas mane sekvi vin.
+        suspend: Via konto estis haltigita, kaj ĉiuj el viaj mesaĝoj kaj alŝutitaj aŭdovidaj dosieroj estis nemalfareble forigitaj de ĉi tiu servilo, kaj de la serviloj, kie vi havis sekvantojn.
+      review_server_policies: Superrigardi servilajn politikojn
+      subject:
+        disable: Via konto %{acct} estas frostigita
+        none: Averto por %{acct}
+        silence: Via konto %{acct} estas limigita
+        suspend: Via konto %{acct} estas haltigita
+      title:
+        disable: Konto frostigita
+        none: Averto
+        silence: Konto limigita
+        suspend: Konto haltigita
     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.'
+      final_step: 'Ekmesaĝu! Eĉ sen sekvantoj, viaj publikaj mesaĝoj povas esti vidataj de aliaj, ekzemple en la loka templinio 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.
+      full_handle_hint: Jen kion vi dirus al viaj amikoj, por ke ili mesaĝu aŭ sekvu vin de alia servilo.
       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_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_federated_timeline: La fratara templinio 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 templiniojn.
+      tip_local_timeline: La loka templinio 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}!
@@ -838,4 +988,5 @@ eo:
     seamless_external_login: Vi estas ensalutinta per ekstera servo, do pasvortaj kaj retadresaj agordoj ne estas disponeblaj.
     signed_in_as: 'Ensalutinta kiel:'
   verification:
+    explanation_html: 'Vi povas <strong>pruvi, ke vi estas la posedanto de la ligiloj en viaj profilaj metadatumoj</strong>. Por fari tion, la alligita retejo devas enhavi ligilon reen al via Mastodon-profilo. La religilo <strong>devas</strong> havi la atributon <code>rel="me"</code>. Ne gravas la teksta enhavo de la religilo. Jen ekzemplo:'
     verification: Kontrolo
diff --git a/config/locales/es.yml b/config/locales/es.yml
index e3106291d9517497bf1754aa509a282f91618164..49765cd0a300477c95dee7608cd19951645cb9d9 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -4,36 +4,32 @@ es:
     about_hashtag_html: Estos son toots públicos etiquetados con <strong>#%{hashtag}</strong>. Puedes interactuar con ellos si tienes una cuenta en cualquier parte del fediverso.
     about_mastodon_html: Mastodon es un servidor de red social <em>libre y de código abierto</em>. Una alternativa <em>descentralizada</em> a plataformas comerciales, que evita el riesgo de que una única compañía monopolice tu comunicación. Cualquiera puede ejecutar Mastodon y participar sin problemas en la <em>red social</em>.
     about_this: Acerca de esta instancia
+    active_count_after: activo
     administered_by: 'Administrado por:'
     api: API
     apps: Aplicaciones móviles
-    closed_registrations: Los registros están actualmente cerrados en esta instancia.
     contact: Contacto
     contact_missing: No especificado
     contact_unavailable: N/A
+    discover_users: Descubrir usuarios
     documentation: Documentación
     extended_description_html: |
       <h3>Un buen lugar para las reglas</h3>
       <p>La descripción extendida no se ha colocado aún.</p>
-    features:
-      humane_approach_body: Aprendiendo de los errores de otras redes, Mastodon apunta a las decisiones de diseño ético para combatir el desuso de las redes sociales.
-      humane_approach_title: Una misión más humana
-      not_a_product_body: Mastodon no es una red comercial. Nada de publicidad, nada de minado de datos, nada de jardines murados. No hay ninguna autoridad central.
-      not_a_product_title: Eres una persona, no un producto
-      real_conversation_body: Con 65535 caracteres a tu disposición y soporte para contenido granular y advertencias de contenido, puedes expresarte como quieras.
-      real_conversation_title: Hecho para verdaderas conversaciones
-      within_reach_body: Aplicaciones múltiples para iOS, Android, y otras plataformas gracias a un ecosistema de APIs amigable al desarrollador para permitirte estar con tus amigos donde sea.
-      within_reach_title: Siempre al alcance
+    federation_hint_html: Con una cuenta en %{instance} usted podrá seguir a las personas en cualquier servidor de Mastodon y más allá.
     generic_description: "%{domain} es un servidor en la red"
+    get_apps: Probar una aplicación móvil
     hosted_on: Mastodon hosteado en %{domain}
     learn_more: Aprende más
-    other_instances: Otras instancias
     privacy_policy: Política de privacidad
+    see_whats_happening: Ver lo que está pasando
+    server_stats: 'Datos del servidor:'
     source_code: Código fuente
     status_count_after:
       one: estado
       other: estados
     status_count_before: Qué han escrito
+    tagline: Seguir a amigos existentes y descubre nuevos
     terms: Condiciones de servicio
     user_count_after:
       one: usuario
@@ -48,8 +44,9 @@ es:
       other: Seguidores
     following: Siguiendo
     joined: Se unió el %{date}
+    last_active: última conexión
     link_verified_on: La propiedad de este vínculo fue verificada el %{date}
-    media: Media
+    media: Multimedia
     moved_html: "%{name} se ha trasladado a %{new_profile_link}:"
     network_hidden: Esta información no está disponible
     nothing_here: "¡No hay nada aquí!"
@@ -67,14 +64,20 @@ es:
       admin: Administrador
       bot: Bot
       moderator: Moderador
+    unavailable: Perfil no disponible
     unfollow: Dejar de seguir
   admin:
+    account_actions:
+      action: Realizar acción
+      title: Moderar %{acct}
     account_moderation_notes:
       create: Crear
       created_msg: "¡Nota de moderación creada con éxito!"
       delete: Borrar
       destroyed_msg: "¡Nota de moderación destruida con éxito!"
     accounts:
+      approve: Aprobar
+      approve_all: Aprobar todos
       are_you_sure: "¿Estás seguro?"
       avatar: Avatar
       by_domain: Dominio
@@ -88,6 +91,7 @@ es:
       confirm: Confirmar
       confirmed: Confirmado
       confirming: Confirmando
+      deleted: Borrado
       demote: Degradar
       disable: Deshabilitar
       disable_two_factor_authentication: Desactivar autenticación de dos factores
@@ -103,7 +107,9 @@ es:
       followers: Seguidores
       followers_url: URL de los seguidores
       follows: Sigue
+      header: Cabecera
       inbox_url: URL de la bandeja de entrada
+      invited_by: Invitado por
       ip: IP
       location:
         all: Todos
@@ -114,16 +120,20 @@ es:
       media_attachments: Multimedia
       memorialize: Convertir en memorial
       moderation:
+        active: Activo
         all: Todos
+        pending: Pendiente
         silenced: Silenciados
         suspended: Suspendidos
         title: Moderación
       moderation_notes: Notas de moderación
       most_recent_activity: Actividad más reciente
       most_recent_ip: IP más reciente
+      no_account_selected: Ninguna cuenta se cambió como ninguna fue seleccionada
       no_limits_imposed: Sin límites impuestos
       not_subscribed: No se está suscrito
       outbox_url: URL de bandeja de salida
+      pending: Revisión pendiente
       perform_full_suspension: Suspender
       profile_url: URL del perfil
       promote: Promocionar
@@ -131,7 +141,10 @@ es:
       public: Público
       push_subscription_expires: Expiración de la suscripción PuSH
       redownload: Refrescar avatar
+      reject: Rechazar
+      reject_all: Rechazar todos
       remove_avatar: Eliminar el avatar
+      remove_header: Eliminar cabecera
       resend_confirmation:
         already_confirmed: Este usuario ya está confirmado
         send: Reenviar el correo electrónico de confirmación
@@ -156,18 +169,21 @@ es:
       statuses: Estados
       subscribe: Suscribir
       suspended: Susependido
+      time_in_queue: Esperando en cola %{time}
       title: Cuentas
       unconfirmed_email: Correo electrónico sin confirmar
       undo_silenced: Des-silenciar
       undo_suspension: Des-suspender
       unsubscribe: Desuscribir
       username: Nombre de usuario
+      warn: Adevertir
       web: Web
     action_logs:
       actions:
         assigned_to_self_report: "%{name} se ha asignado la denuncia %{target} a sí mismo"
         change_email_user: "%{name} ha cambiado la dirección de correo del usuario %{target}"
         confirm_user: "%{name} confirmó la dirección de correo del usuario %{target}"
+        create_account_warning: "%{name} envió una advertencia a %{target}"
         create_custom_emoji: "%{name} subió un nuevo emoji %{target}"
         create_domain_block: "%{name} bloqueó el dominio %{target}"
         create_email_domain_block: "%{name} puso en lista negra el dominio de correos %{target}"
@@ -226,6 +242,7 @@ es:
       config: Configuración
       feature_deletions: Borrados de cuenta
       feature_invites: Enlaces de invitación
+      feature_profile_directory: Directorio de perfil
       feature_registrations: Registros
       feature_relay: Relés de federación
       features: Características
@@ -247,6 +264,7 @@ es:
       created_msg: El bloque de dominio está siendo procesado
       destroyed_msg: El bloque de dominio se deshizo
       domain: Dominio
+      existing_domain_block_html: Ya ha impuesto límites más estrictos a %{name}, necesita <a href="%{unblock_url}">desbloquearlo primero</a>.
       new:
         create: Crear bloque
         hint: El bloque de dominio no prevendrá la creación de entradas de cuenta en la base de datos, pero aplicará retroactiva y automáticamente métodos de moderación específica en dichas cuentas.
@@ -260,6 +278,10 @@ es:
       reject_media_hint: Remueve localmente archivos multimedia almacenados para descargar cualquiera en el futuro. Irrelevante para suspensiones
       reject_reports: Rechazar informes
       reject_reports_hint: Ignore todos los reportes de este dominio. Irrelevante para suspensiones
+      rejecting_media: rechazar archivos multimedia
+      severity:
+        silence: silenciado
+        suspend: susependido
       show:
         affected_accounts:
           one: Una cuenta en la base de datos afectada
@@ -280,8 +302,19 @@ es:
         create: Añadir dominio
         title: Nueva entrada en la lista negra de correo
       title: Lista negra de correo
+    followers:
+      back_to_account: Volver a la cuenta
     instances:
+      by_domain: Dominio
+      moderation:
+        all: Todos
+        limited: Limitado
+        title: Moderación
       title: Instancias conocidas
+      total_blocked_by_us: Bloqueado por nosotros
+      total_followed_by_them: Seguidos por ellos
+      total_followed_by_us: Seguido por nosotros
+      total_storage: Archivos multimedia
     invites:
       deactivate_all: Desactivar todos
       filter:
@@ -373,9 +406,10 @@ es:
         min_invite_role:
           disabled: Nadie
           title: Permitir invitaciones de
-        open:
-          desc_html: Permite a cualquiera a registrar una cuenta
-          title: Registro abierto
+      registrations_mode:
+        modes:
+          none: Nadie puede registrarse
+          open: Cualquiera puede registrarse
       show_known_fediverse_at_about_page:
         desc_html: Cuando esté activado, se mostrarán toots de todo el fediverso conocido en la vista previa. En otro caso, se mostrarán solamente toots locales.
         title: Mostrar fediverso conocido en la vista previa de la historia
@@ -420,17 +454,21 @@ es:
       confirmed: Confirmado
       expires_in: Expira en
       last_delivery: Última entrega
-      title: WebSub
       topic: Tópico
     title: Administración
+    warning_presets:
+      add_new: Añadir nuevo
+      delete: Borrar
+      edit: Editar
   admin_mailer:
+    new_pending_account:
+      body: Los detalles de la nueva cuenta están abajos. Puedes aprobar o rechazar esta aplicación.
     new_report:
       body: "%{reporter} ha reportado a %{target}"
       body_remote: Alguien de %{domain} a reportado a %{target}
       subject: Nuevo reporte para la %{instance} (#%{id})
   application_mailer:
     notification_preferences: Cambiar preferencias de correo electrónico
-    salutation: "%{name},"
     settings: 'Cambiar preferencias de correo: %{link}'
     view: 'Vista:'
     view_profile: Ver perfil
@@ -444,8 +482,8 @@ es:
     warning: Ten mucho cuidado con estos datos. ¡No los compartas con nadie!
     your_token: Tu token de acceso
   auth:
-    agreement_html: Al hacer click en "Registrarse" acepta seguir <a href="%{rules_path}">las reglas de la instancia</a> y <a href="%{terms_path}">nuestros términos de servicio</a>.
     change_password: Contraseña
+    checkbox_agreement_html: Acepto <a href="%{rules_path}" target="_blank">las reglas del servidor</a> y <a href="%{terms_path}" target="_blank">términos de servicio</a>
     confirm_email: Confirmar email
     delete_account: Borrar cuenta
     delete_account_html: Si desea eliminar su cuenta, puede <a href="%{path}">proceder aquí</a>. Será pedido de una confirmación.
@@ -456,13 +494,9 @@ es:
     logout: Cerrar sesión
     migrate_account: Mudarse a otra cuenta
     migrate_account_html: Si deseas redireccionar esta cuenta a otra distinta, puedes <a href="%{path}">configurarlo aquí</a>.
-    or: o
     or_log_in_with: O inicia sesión con
-    providers:
-      cas: CAS
-      saml: SAML
     register: Registrarse
-    register_elsewhere: Registrarse en otro servidor
+    registration_closed: "%{instance} no está aceptando nuevos miembros"
     resend_confirmation: Volver a enviar el correo de confirmación
     reset_password: Restablecer contraseña
     security: Cambiar contraseña
@@ -480,18 +514,10 @@ es:
     title: Seguir a %{acct}
   datetime:
     distance_in_words:
-      about_x_hours: "%{count}h"
       about_x_months: "%{count}m"
-      about_x_years: "%{count}y"
-      almost_x_years: "%{count}y"
       half_a_minute: Justo ahora
-      less_than_x_minutes: "%{count}m"
       less_than_x_seconds: Justo ahora
-      over_x_years: "%{count}y"
-      x_days: "%{count}d"
-      x_minutes: "%{count}m"
       x_months: "%{count}m"
-      x_seconds: "%{count}s"
   deletes:
     bad_password_msg: "¡Buen intento, hackers! Contraseña incorrecta"
     confirm_password: Ingresa tu contraseña actual para demostrar tu identidad
@@ -500,6 +526,12 @@ es:
     success_msg: Tu cuenta se eliminó con éxito
     warning_html: Se garantiza únicamente la eliminación del contenido de esta instancia. El contenido que se haya compartido extensamente dejará sus huellas. Los servidores fuera de línea y los que se hayan desuscrito de tus actualizaciones ya no actualizarán sus bases de datos.
     warning_title: Disponibilidad diseminada del contenido
+  directories:
+    explore_mastodon: Explorar %{title}
+    how_to_enable: Usted no está registrado por el directorio. Puede registrar por abajo. ¡Utilice hashtags en su bio para aparecer bajo hashtags específicos!
+    people:
+      one: "%{count} persona"
+      other: "%{count} personas"
   errors:
     '403': No tienes permiso para acceder a esta página.
     '404': La página que estabas buscando no existe.
@@ -512,6 +544,9 @@ es:
       content: Lo sentimos, algo ha funcionado mal por nuestra parte.
       title: Esta página no es correcta
     noscript_html: Para usar la aplicación web de Mastodon, por favor activa Javascript. Alternativamente, prueba alguna de las <a href="%{apps_path}">aplicaciones nativas</a> para Mastodon para tu plataforma.
+  existing_username_validator:
+    not_found: no pudo encontrar un usuario local con ese nombre de usuario
+    not_found_multiple: no pudo encontrar %{usernames}
   exports:
     archive_takeout:
       date: Fecha
@@ -523,8 +558,13 @@ es:
     blocks: Personas que has bloqueado
     csv: CSV
     follows: Personas que sigues
+    lists: Listas
     mutes: Tienes en silencio
     storage: Almacenamiento
+  featured_tags:
+    add_new: Añadir nuevo
+    errors:
+      limit: Ya has alcanzado la cantidad máxima de hashtags
   filters:
     contexts:
       home: Timeline propio
@@ -541,30 +581,36 @@ es:
       title: Filtros
     new:
       title: Añadir un nuevo filtro
-  followers:
-    domain: Dominio
-    explanation_html: Si deseas asegurar la privacidad de tus estados, tienes que cuidarte de quién te sigue. <strong>Tus estados privados son enviados a todas las instancias de tus seguidores</strong>. Puede que desees revisarlas, y remover seguidores si no confías en tu privacidad para ser respetado por el staff o software de esas instancias.
-    followers_count: Número de seguidores
-    lock_link: Bloquear tu cuenta
-    purge: Remover de los seguidores
-    success:
-      one: En el proceso de bloquear suavemente usuarios de un solo dominio...
-      other: En el proceso de bloquear suavemente usuarios de %{count} dominios...
-    true_privacy_html: Por favor ten en cuenta que <strong>la verdadera privacidad se consigue con encriptación de punto a punto</strong>.
-    unlocked_warning_html: Todos pueden seguirte  para ver tus estados privados inmediatamente. %{lock_link} para poder chequear y rechazar seguidores.
-    unlocked_warning_title: Tu cuenta no está bloqueada
   footer:
     developers: Desarrolladores
     more: Mas…
     resources: Recursos
   generic:
+    all: Todos
     changes_saved_msg: "¡Cambios guardados con éxito!"
     copy: Copiar
+    order_by: Ordenar por
     save_changes: Guardar cambios
     validation_errors:
       one: "¡Algo no está bien! Por favor, revisa el error"
       other: "¡Algo no está bien! Por favor, revise %{count} errores más abajo"
+  identity_proofs:
+    active: Activo
+    authorize: Sí, autorizar
+    authorize_connection_prompt: "¿Autorizar esta conexión criptográfica?"
+    errors:
+      failed: La conexión criptográfica falló. Por favor, inténtalo de nuevo desde %{provider}.
+      keybase:
+        invalid_token: Los tokens de Keybase son hashes de firmas y deben tener 66 caracteres hex
+        verification_failed: Keybase no reconoce este token como una firma del usuario de Keybase %{kb_username}. Por favor, inténtelo de nuevo desde Keybase.
+    identity: Identidad
+    inactive: Inactivo
+    status: Estado de la verificación
+    view_proof: Ver prueba
   imports:
+    modes:
+      merge: Unir
+      overwrite: Sobrescribir
     preface: Puedes importar ciertos datos, como todas las personas que estás siguiendo o bloqueando en tu cuenta en esta instancia, desde archivos exportados de otra instancia.
     success: Sus datos se han cargado correctamente y serán procesados en brevedad
     types:
@@ -643,28 +689,16 @@ es:
       body: "%{name} ha retooteado tu estado:"
       subject: "%{name} ha retooteado tu estado"
       title: Nueva difusión
-  number:
-    human:
-      decimal_units:
-        format: "%n%u"
-        units:
-          billion: B
-          million: M
-          quadrillion: Q
-          thousand: K
-          trillion: T
-          unit: " "
   pagination:
     newer: Más nuevo
     next: Próximo
     older: Más antiguo
     prev: Anterior
-    truncate: "&hellip;"
   preferences:
-    languages: Idiomas
     other: Otros
-    publishing: Publicación
-    web: Web
+  relationships:
+    last_active: Última actividad
+    most_recent: Más reciente
   remote_follow:
     acct: Ingesa tu usuario@dominio desde el que quieres seguir
     missing_resource: No se pudo encontrar la URL de redirección requerida para tu cuenta
@@ -688,11 +722,11 @@ es:
       generic: Desconocido
       ie: Internet Explorer
       micro_messenger: MicroMessenger
-      nokia: Nokia S40 Ovi Browser
+      nokia: Navegador de Nokia S40 Ovi
       opera: Opera
       otter: Otter
       phantom_js: PhantomJS
-      qq: QQ Browser
+      qq: Navegador QQ
       safari: Safari
       uc_browser: UCBrowser
       weibo: Weibo
@@ -717,20 +751,21 @@ es:
     revoke_success: Sesión revocada exitosamente
     title: Sesiones
   settings:
+    account: Cuenta
+    account_settings: Ajustes de la cuenta
+    appearance: Apariencia
     authorized_apps: Aplicaciones autorizadas
     back: Volver al inicio
     delete: Borrar cuenta
     development: Desarrollo
     edit_profile: Editar perfil
     export: Exportar información
-    followers: Seguidores autorizados
+    featured_tags: Hashtags destacados
     import: Importar
     migrate: Migración de cuenta
     notifications: Notificaciones
     preferences: Preferencias
-    settings: Ajustes
     two_factor_authentication: Autenticación de dos factores
-    your_apps: Tus aplicaciones
   statuses:
     attached:
       description: 'Adjunto: %{attached}'
@@ -755,7 +790,6 @@ es:
       reblog: Un boost no puede fijarse
     show_more: Mostrar más
     sign_in_to_participate: Regístrate para participar en la conversación
-    title: '%{name}: "%{quote}"'
     visibilities:
       private: Sólo mostrar a seguidores
       private_long: Solo mostrar a tus seguidores
@@ -776,7 +810,6 @@ es:
   time:
     formats:
       default: "%d de %b del %Y, %H:%M"
-      month: "%b %Y"
   two_factor_authentication:
     code_hint: Ingresa el código generado por tu aplicación de autenticación para confirmar
     description_html: Si habilitas la <strong>autenticación de dos factores</strong>, se requerirá estar en posesión de su teléfono, lo que generará tokens para que usted pueda iniciar sesión.
@@ -813,7 +846,6 @@ es:
       tip_following: Sigues a tus administradores de servidor por defecto. Para encontrar más gente interesante, revisa las lineas de tiempo local y federada.
       tip_local_timeline: La linea de tiempo local is una vista de la gente en %{instance}. Estos son tus vecinos inmediatos!
       tip_mobile_webapp: Si el navegador de tu dispositivo móvil ofrece agregar Mastodon a tu página de inicio, puedes recibir notificaciones. Actúa como una aplicación nativa en muchas formas!
-      tips: Tips
       title: Te damos la bienvenida a bordo, %{name}!
   users:
     follow_limit_reached: No puedes seguir a más de %{limit} personas
diff --git a/config/locales/eu.yml b/config/locales/eu.yml
index cae83e158d0bb02fb67c1b9efaa181d86bf7e911..9b9c2c02719f731bbeb227af5a9af0233cea0575 100644
--- a/config/locales/eu.yml
+++ b/config/locales/eu.yml
@@ -4,36 +4,36 @@ eu:
     about_hashtag_html: Hauek  <strong>#%{hashtag}</strong> traola duten toot publikoak dira. Fedibertsoko edozein kontu baduzu harremanetan jarri zaitezke.
     about_mastodon_html: Mastodon web protokolo ireki eta libreak darabiltzan gizarte sare bat da. E-mail sarea bezala deszentralizatua da.
     about_this: Honi buruz
+    active_count_after: aktiboa
+    active_footnote: Hilabeteko erabiltzaile aktiboak (HEA)
     administered_by: 'Administratzailea(k):'
     api: APIa
     apps: Aplikazio mugikorrak
-    closed_registrations: Harpidetza itxita dago orain instantzia honetan. Hala ere, beste instantzia bat aurkitu dezakezu kontua egiteko eta hona ere sarbidea izan.
+    apps_platforms: Erabili Mastodon, iOS, Android eta beste plataformetatik
+    browse_directory: Arakatu profilen direktorio bat eta iragazi interesen arabera
+    browse_public_posts: Arakatu Mastodoneko mezu publikoen zuzeneko jario bat
     contact: Kontaktua
     contact_missing: Ezarri gabe
     contact_unavailable: E/E
+    discover_users: Aurkitu erabiltzaileak
     documentation: Dokumentazioa
     extended_description_html: |
       <h3>Arauentzako toki egoki bat</h3>
       <p>Azalpen luzea ez da ezarri oraindik.</p>
-    features:
-      humane_approach_body: Beste sareen akatsetatik ikasiz, Mastodon diseinu erabaki etikoak hartzen saiatzen da gizarte sareen erabilera okerrak borrokatzeko.
-      humane_approach_title: Ikuspuntu humanoago bat
-      not_a_product_body: Mastodon ez da sare komertzial bat. Ez du iragarkirik, eta ditu datuak mehatzen, ez da hormaz babestutako lorategi bat. Ez dago autoritate zentralik.
-      not_a_product_title: Pertsona bat zara, ez produktu bat
-      real_conversation_body: 65535 karaktere dituzu eskura, edukia xehetasunez kudeatu daiteke eta multimediari abisuak jarri, adierazi zure burua zure erara.
-      real_conversation_title: Egiazko elkarrizketarako eraikia
-      within_reach_body: iOS, Android eta beste plataformetarako aplikazio ugari, eta garatzaileentzako erabilterraza den API ekosistema bati esker beste plataforma batzuetako lagunekin aritzeko aukera.
-      within_reach_title: Beti eskura
+    federation_hint_html: "%{instance} instantzian kontu bat izanda edozein Mastodon zerbitzariko jendea jarraitu ahal izango duzu, eta harago ere."
     generic_description: "%{domain} sareko zerbitzari bat da"
+    get_apps: Probatu mugikorrerako aplikazio bat
     hosted_on: Mastodon %{domain} domeinuan ostatatua
     learn_more: Ikasi gehiago
-    other_instances: Instantzien zerrenda
     privacy_policy: Pribatutasun politika
+    see_whats_happening: Ikusi zer gertatzen ari den
+    server_stats: 'Zerbitzariaren estatistikak:'
     source_code: Iturburu kodea
     status_count_after:
       one: mezu
       other: mezu
     status_count_before: Hauek
+    tagline: Jarraitu lagunak eta egin berriak
     terms: Erabilera baldintzak
     user_count_after:
       one: erabiltzaile
@@ -61,13 +61,14 @@ eu:
     posts:
       one: Toot
       other: Toot
-    posts_tab_heading: Tootak
+    posts_tab_heading: Toot
     posts_with_replies: Toot eta erantzunak
     reserved_username: Erabiltzaile-izena erreserbatuta dago
     roles:
       admin: Administratzailea
       bot: Bot-a
       moderator: Moderatzailea
+    unavailable: Profila ez dago eskuragarri
     unfollow: Utzi jarraitzeari
   admin:
     account_actions:
@@ -79,6 +80,8 @@ eu:
       delete: Ezabatu
       destroyed_msg: Moderazio ohara ongi suntsitu da!
     accounts:
+      approve: Onartu
+      approve_all: Onartu denak
       are_you_sure: Ziur zaude?
       avatar: Abatarra
       by_domain: Domeinua
@@ -92,6 +95,7 @@ eu:
       confirm: Berretsi
       confirmed: Berretsita
       confirming: Berresten
+      deleted: Ezabatua
       demote: Jaitsi mailaz
       disable: Desgaitu
       disable_two_factor_authentication: Desgaitu 2FA
@@ -109,7 +113,9 @@ eu:
       follows: Jarraitzen du
       header: Goiburua
       inbox_url: Sarrera ontziaren URL-a
-      ip: IP
+      invited_by: 'Honek gonbidatua:'
+      ip: IP-a
+      joined: Elkartuta
       location:
         all: Denak
         local: Lokala
@@ -121,22 +127,27 @@ eu:
       moderation:
         active: Aktiboa
         all: Denak
+        pending: Zain
         silenced: Isilarazita
         suspended: Kanporatua
         title: Moderazioa
       moderation_notes: Moderazio oharrak
       most_recent_activity: Azken jarduera
       most_recent_ip: Azken IP-a
+      no_account_selected: Ez da konturik aldatu ez delako bata bera hautatu
       no_limits_imposed: Ez da mugarik ezarri
       not_subscribed: Harpidetu gabe
       outbox_url: Irteera ontziaren URL-a
+      pending: Berrikusketa egiteke
       perform_full_suspension: Kanporatu
       profile_url: Profilaren URL-a
       promote: Sustatu
       protocol: Protokoloa
       public: Publikoa
       push_subscription_expires: Push harpidetzaren iraugitzea
-      redownload: Freskatu abatarra
+      redownload: Freskatu profila
+      reject: Ukatu
+      reject_all: Ukatu denak
       remove_avatar: Kendu abatarra
       remove_header: Kendu goiburua
       resend_confirmation:
@@ -156,20 +167,22 @@ eu:
       search: Bilatu
       shared_inbox_url: Partekatutako sarrera ontziaren URL-a
       show:
-        created_reports: Kontu honek sortutako txostenak
-        targeted_reports: Kontu honek egindako salaketak
+        created_reports: Sortutako txostenak
+        targeted_reports: Besteen salaketak
       silence: Isilarazi
       silenced: Isilarazita
       statuses: Mezuak
       subscribe: Harpidetu
       suspended: Kanporatuta
+      time_in_queue: Kolan zain %{time}
       title: Kontuak
       unconfirmed_email: Baieztatu gabeko e-mail helbidea
       undo_silenced: Utzi isilarazteari
       undo_suspension: Desegin kanporatzea
       unsubscribe: Kendu harpidetza
       username: Erabiltzaile-izena
-      web: Web
+      warn: Abisatu
+      web: Weba
     action_logs:
       actions:
         assigned_to_self_report: "%{name}(e)k %{target} salaketa bere buruari esleitu dio"
@@ -214,7 +227,7 @@ eu:
       destroyed_msg: Emoji-a ongi suntsitu da!
       disable: Desgaitu
       disabled_msg: Emoji-a ongi desgaitu da
-      emoji: Emoji
+      emoji: Emojia
       enable: Gaitu
       enabled_msg: Emoji hori ongi gaitu da
       image_hint: PNG gehienez 50KB
@@ -237,13 +250,14 @@ eu:
       feature_profile_directory: Profil-direktorioa
       feature_registrations: Izen emateak
       feature_relay: Federazio haria
+      feature_timeline_preview: Denbora-lerroaren aurrebista
       features: Ezaugarriak
       hidden_service: Federazioa ezkutuko zerbitzuekin
       open_reports: salaketa irekiak
       recent_users: Azken erabiltzaileak
       search: Testu osoko bilaketa
       single_user_mode: Erabiltzaile bakarreko modua
-      software: Software
+      software: Softwarea
       space: Espazio erabilera
       title: Kontrol panela
       total_users: erabiltzaile guztira
@@ -252,10 +266,11 @@ eu:
       week_users_active: aktibo aste honetan
       week_users_new: erabiltzaile aste honetan
     domain_blocks:
-      add_new: Gehitu berria
+      add_new: Gehitu domeinuaren blokeo berria
       created_msg: Domeinuaren blokeoa orain prozesatzen ari da
       destroyed_msg: Domeinuaren blokeoa desegin da
       domain: Domeinua
+      existing_domain_block_html: '%{name} domeinuan muga zorrotzagoak ezarri dituzu jada, aurretik <a href="%{unblock_url}">desblokeatu</a> beharko duzu.'
       new:
         create: Sortu blokeoa
         hint: Domeinuaren blokeoak ez du eragotziko kontuen sarrerak sortzea datu-basean, baina automatikoki ezarriko zaizkie moderazio metodo bereziak iraganeko mezuetan ere.
@@ -264,11 +279,16 @@ eu:
           noop: Bat ere ez
           silence: Isilarazi
           suspend: Kanporatu
-        title: Domeinu blokeo berria
+        title: Domeinuaren blokeo berria
       reject_media: Ukatu multimedia fitxategiak
       reject_media_hint: Lokalki gordetako multimedia fitxategiak ezabatzen ditu eta etorkizunean fitxategi berriak deskargatzeari uko egingo dio. Ez du garrantzirik kanporaketetan
       reject_reports: Errefusatu salaketak
       reject_reports_hint: Ezikusi domeinu honetatik jasotako salaketak. Kanporatzeentzako garrantzirik gabekoa
+      rejecting_media: errefusatu multimedia fitxategiak
+      rejecting_reports: txostenak errefusatzen
+      severity:
+        silence: isilarazia
+        suspend: kanporatua
       show:
         affected_accounts:
           one: Datu-baseko kontu bati eragiten dio
@@ -278,7 +298,7 @@ eu:
           suspend: Kendu kanporatzeko agindua domeinu honetako kontu guztiei
         title: Desegin %{domain} domeinuko blokeoa
         undo: Desegin
-      undo: Desegin
+      undo: Desegin domeinuaren blokeoa
     email_domain_blocks:
       add_new: Gehitu berria
       created_msg: Ongi gehitu da e-mail helbidea domeinuen zerrenda beltzera
@@ -293,7 +313,21 @@ eu:
       back_to_account: Itzuli kontura
       title: "%{acct} kontuaren jarraitzaileak"
     instances:
-      title: Instantzia ezagunak
+      by_domain: Domeinua
+      delivery_available: Bidalketa eskuragarri dago
+      known_accounts:
+        one: Kontu ezagun %{count}
+        other: "%{count} kontu ezagun"
+      moderation:
+        all: Denak
+        limited: Mugatua
+        title: Moderazioa
+      title: Federazioa
+      total_blocked_by_us: Guk blokeatuta
+      total_followed_by_them: Haiek jarraitua
+      total_followed_by_us: Guk jarraitua
+      total_reported: Heiei buruzko txostenak
+      total_storage: Multimedia eranskinak
     invites:
       deactivate_all: Desgaitu guztiak
       filter:
@@ -302,6 +336,8 @@ eu:
         expired: Iraungitua
         title: Iragazi
       title: Gonbidapenak
+    pending_accounts:
+      title: Zain dauden kontuak (%{count})
     relays:
       add_new: Gehitu hari berria
       delete: Ezabatu
@@ -364,14 +400,14 @@ eu:
         desc_html: Aldatu itxura orri bakoitzean kargatutako CSS bidez
         title: CSS pertsonala
       hero:
-        desc_html: Azaleko orrian bistaratua. Gutxienez 600x100px aholkatzen da. Ezartzen ez bada, instantziaren irudia hartuko du
+        desc_html: Azaleko orrian bistaratua. Gutxienez 600x100px aholkatzen da. Ezartzen ez bada, zerbitzariaren irudia hartuko du
         title: Azaleko irudia
       mascot:
         desc_html: Hainbat orritan bistaratua. Gutxienez 293x205px aholkatzen da. Ezarri ezean lehenetsitako maskota erakutsiko da
         title: Maskotaren irudia
       peers_api_enabled:
-        desc_html: Instantzia honek fedibertsuan aurkitutako domeinu-izenak
-        title: Argitaratu aurkitutako instantzien zerrenda
+        desc_html: Zerbitzari honek fedibertsoan aurkitutako domeinu-izenak
+        title: Argitaratu aurkitutako zerbitzarien zerrenda
       preview_sensitive_media:
         desc_html: Beste webguneetako esteken aurrebistak iruditxoa izango du multimedia hunkigarri gisa markatzen bada ere
         title: Erakutsi multimedia hunkigarria OpenGraph aurrebistetan
@@ -388,9 +424,12 @@ eu:
         min_invite_role:
           disabled: Inor ez
           title: Baimendu hauen gobidapenak
-        open:
-          desc_html: Baimendu edonori kontu bat sortzea
-          title: Ireki izen ematea
+      registrations_mode:
+        modes:
+          approved: Izena emateko onarpena behar da
+          none: Ezin du inork izena eman
+          open: Edonork eman dezake izena
+        title: Erregistratzeko modua
       show_known_fediverse_at_about_page:
         desc_html: Txandakatzean, fedibertsu ezagun osoko toot-ak bistaratuko ditu aurrebistan. Bestela, toot lokalak besterik ez ditu erakutsiko.
         title: Erakutsi fedibertsu ezagun osoko denbora-lerroa aurrebistan
@@ -399,20 +438,20 @@ eu:
         title: Erakutsi langile banda
       site_description:
         desc_html: Azaleko orrian agertuko den sarrera paragrafoa. Azaldu zerk egiten duen berezi Mastodon zerbitzari hau eta garrantzizko beste edozer. HTML etiketak erabili ditzakezu, zehazki <code>&lt;a&gt;</code> eta <code>&lt;em&gt;</code>.
-        title: Instantziaren deskripzioa
+        title: Zerbitzariaren deskripzioa
       site_description_extended:
-        desc_html: Zure jokabide-koderako  toki on bat, arauak, gidalerroak eta zure instantzia desberdin egiten duten bestelakoak. HTML etiketak erabili ditzakezu
+        desc_html: Zure jokabide-koderako  toki on bat, arauak, gidalerroak eta zure zerbitzari desberdin egiten duten bestelakoak. HTML etiketak erabili ditzakezu
         title: Informazio hedatu pertsonalizatua
       site_short_description:
         desc_html: Albo-barra eta meta etiketetan bistaratua. Deskribatu zerk egiten duen Mastodon zerbitzari hau berezia paragrafo batean. Hutsik lagatzekotan lehenetsitako deskripzioa agertuko da.
-        title: Instantziaren deskripzio laburra
+        title: Zerbitzariaren deskripzio laburra
       site_terms:
         desc_html: Zure pribatutasun politika, erabilera baldintzak eta bestelako testu legalak idatzi ditzakezu. HTML etiketak erabili ditzakezu
         title: Erabilera baldintza pertsonalizatuak
-      site_title: Instantziaren izena
+      site_title: Zerbitzariaren izena
       thumbnail:
         desc_html: Aurrebistetarako erabilia OpenGraph eta API bidez. 1200x630px aholkatzen da
-        title: Instantziaren iruditxoa
+        title: Zerbitzariaren iruditxoa
       timeline_preview:
         desc_html: Bistaratu denbora-lerro publikoa hasiera orrian
         title: Denbora-lerroaren aurrebista
@@ -453,10 +492,19 @@ eu:
       edit_preset: Editatu abisu aurre-ezarpena
       title: Kudeatu abisu aurre-ezarpenak
   admin_mailer:
+    new_pending_account:
+      body: Kontu berriaren xehetasunak azpian daude. Eskaera hau onartu edo ukatu dezakezu.
+      subject: Kontu berria berrikusteko %{instance} instantzian (%{username})
     new_report:
       body: "%{reporter}(e)k %{target} salatu du"
       body_remote: "%{domain} domeinuko norbaitek %{target} salatu du"
       subject: Salaketa berria %{instance} instantzian (#%{id})
+  appearance:
+    advanced_web_interface: Web interfaze aurreratua
+    advanced_web_interface_hint: 'Pantaila bere zabalera osoan erabili nahi baduzu, web interfaze aurreratuak hainbat zutabe desberdin konfiguratzea ahalbidetzen dizu, aldi berean nahi beste informazio ikusteko: Hasiera, jakinarazpenak, federatutako denbora-lerroa, edo nahi beste zerrenda eta traola.'
+    animations_and_accessibility: Animazioak eta irisgarritasuna
+    confirmation_dialogs: Berrespen dialogoak
+    sensitive_content: Eduki hunkigarria
   application_mailer:
     notification_preferences: Aldatu e-mail hobespenak
     salutation: "%{name},"
@@ -473,8 +521,9 @@ eu:
     warning: Kontuz datu hauekin, ez partekatu inoiz inorekin!
     your_token: Zure sarbide token-a
   auth:
-    agreement_html: '"Izena eman" botoia sakatzean <a href="%{rules_path}">instantziaren arauak</a> eta <a href="%{terms_path}">erabilera baldintzak</a> onartzen dituzu.'
+    apply_for_account: Eskatu gonbidapen bat
     change_password: Pasahitza
+    checkbox_agreement_html: <a href="%{rules_path}" target="_blank">Zerbitzariaren arauak</a> eta <a href="%{terms_path}" target="_blank">erabilera baldintzak</a> onartzen ditut
     confirm_email: Berretsi e-mail helbidea
     delete_account: Ezabatu kontua
     delete_account_html: Kontua ezabatu nahi baduzu, <a href="%{path}">jarraitu hemen</a>. Berrestea eskatuko zaizu.
@@ -485,17 +534,17 @@ eu:
     logout: Amaitu saioa
     migrate_account: Lekualdatu beste kontu batera
     migrate_account_html: Kontu hau beste batera birbideratu nahi baduzu, <a href="%{path}">hemen konfiguratu</a> dezakezu.
-    or: edo
     or_log_in_with: Edo hasi saioa honekin
     providers:
       cas: CAS
       saml: SAML
     register: Eman izena
-    register_elsewhere: Eman izena beste zerbitzari batean
+    registration_closed: "%{instance} instantziak ez ditu kide berriak onartzen"
     resend_confirmation: Birbidali berresteko argibideak
     reset_password: Berrezarri pasahitza
     security: Segurtasuna
     set_new_password: Ezarri pasahitza berria
+    trouble_logging_in: Arazoak saioa hasteko?
   authorize_follow:
     already_following: Kontu hau aurretik jarraitzen duzu
     error: Zoritxarrez, urruneko kontua bilatzean errore bat gertatu da
@@ -509,7 +558,7 @@ eu:
     title: Jarraitu %{acct}
   datetime:
     distance_in_words:
-      about_x_hours: "%{count}h"
+      about_x_hours: "%{count}o"
       about_x_months: "%{count} hilabete"
       about_x_years: "%{count} urte"
       almost_x_years: "%{count} urte"
@@ -527,19 +576,22 @@ eu:
     description_html: Honek <strong>behin betirako eta atzera egiteko aukera gabe</strong> zure kontuko edukia kendu eta hau desaktibatuko du. Zure erabiltzaile-izena erreserbatuko da etorkizunean inork zure itxurak ez egiteko.
     proceed: Ezabatu kontua
     success_msg: Zure kontua ongi ezabatu da
-    warning_html: Instantzia honetako edukiak ezabatzea besterik ezin da bermatu. Asko partekatu den edukiaren arrastoak geratzea izan liteke. Deskonektatuta dauden zerbitzariak edo zure eguneraketetatik harpidetza kendu duten zerbitzariek ez dituzte beraien datu-baseak eguneratuko.
+    warning_html: Zerbitzari honetako edukiak ezabatzea besterik ezin da bermatu. Asko partekatu den edukiaren arrastoak geratzea izan liteke. Deskonektatuta dauden zerbitzariak edo zure eguneraketetatik harpidetza kendu duten zerbitzariek ez dituzte beraien datu-baseak eguneratuko.
     warning_title: Sakabanatutako edukiaren eskuragarritasuna
   directories:
     directory: Profilen direktorioa
+    enabled: Direktorioan zerrendatuta zaude orain.
+    enabled_but_waiting: Direktorioan zerrendatuta izatea aukeratu duzu, baina ez duzu oraindik gutxieneko jarraitzaile kopurua (%{min_followers}) zerrendan agertzeko.
     explanation: Deskubritu erabiltzaileak interesen arabera
     explore_mastodon: Esploratu %{title}
+    how_to_enable: Ez duzu aukeratu direktorioan zerrendatua izatea aukeratu. Behean aukeratu dezakezu. Erabili traolak zure biografiaren testuan traola zehatzetan agertzeko!
     people:
       one: pertsona %{count}
       other: "%{count} pertsona"
   errors:
     '403': Ez duzu orri hau ikusteko baimenik.
-    '404': Bilatu duzun orria ez da existitzen.
-    '410': Bilatu duzun orria ez da existitzen jada.
+    '404': Bilatu duzun orria ez dago hemen.
+    '410': Bilatu duzun orria ez dago hemen jada.
     '422':
       content: Segurtasun egiaztaketak huts egin du. Cookie-ak blokeatzen dituzu?
       title: Segurtasun egiaztaketak huts egin du
@@ -548,6 +600,9 @@ eu:
       content: Sentitzen dugu, zerbait okerra gertatu da gure aldean.
       title: Orri hau ez da zuzena
     noscript_html: Mastodon web aplikazioa erabiltzeko, gaitu JavaScript. Bestela, probatu Mastodon plataformarako <a href="%{apps_path}">aplikazio natibo</a>ren bat.
+  existing_username_validator:
+    not_found: ezin izan da izen hori duen kide lokalik aurkitu
+    not_found_multiple: ezin izan dira aurkitu %{usernames}
   exports:
     archive_takeout:
       date: Data
@@ -558,9 +613,15 @@ eu:
       size: Tamaina
     blocks: Zuk blokeatutakoak
     csv: CSV
+    domain_blocks: Domeinuen blokeoak
     follows: Zuk jarraitutakoak
+    lists: Zerrendak
     mutes: Zuk mututukoak
     storage: Multimedia biltegiratzea
+  featured_tags:
+    add_new: Gehitu berria
+    errors:
+      limit: Gehienezko traola kopurua nabarmendu duzu jada
   filters:
     contexts:
       home: Hasierako denbora-lerroa
@@ -577,34 +638,50 @@ eu:
       title: Iragazkiak
     new:
       title: Gehitu iragazki berria
-  followers:
-    domain: Domeinua
-    explanation_html: Zure mezuen pribatutasuna bermatu nahi baduzu, nork jarraitzen zaituen jakin behar duzu. <strong>Zure mezu pribatuak zure jarraitzaileak dituzten instantzia guztietara bidaltzen dira</strong>.  Instantzia bateko langileek edo softwareak zure pribatutasunari dagokion begirunea ez dutela izango uste baduzu, berrikusi eta kendu jarraitzaileak.
-    followers_count: Jarraitzaile kopurua
-    lock_link: Giltzapetu zure kontua
-    purge: Kendu jarraitzaileetatik
-    success:
-      one: Domeinu bateko jarraitzaileei blokeo leuna ezartzen...
-      other: "%{count} domeinuetako jarraitzaileei blokeo leuna ezartzen..."
-    true_privacy_html: Kontuan izan <strong>egiazko pribatutasuna lortzeko muturretik muturrerako zifratzea ezinbestekoa dela</strong>.
-    unlocked_warning_html: Edonork jarraitu zaitzake eta berehala zure mezu pribatuak ikusi. %{lock_link} jarraitzaileak berrikusi eta ukatu ahal izateko.
-    unlocked_warning_title: Zure kontua ez dago giltzapetuta
   footer:
     developers: Garatzaileak
     more: Gehiago…
     resources: Baliabideak
   generic:
+    all: Denak
     changes_saved_msg: Aldaketak ongi gorde dira!
     copy: Kopiatu
+    order_by: Ordenatze-irizpidea
     save_changes: Gorde aldaketak
     validation_errors:
       one: Zerbait ez dabil ongi! Egiaztatu beheko errorea mesedez
       other: Zerbait ez dabil ongi! Egiaztatu beheko %{count}  erroreak mesedez
+  html_validator:
+    invalid_markup: 'HTML markaketa baliogabea du: %{error}'
+  identity_proofs:
+    active: Aktiboa
+    authorize: Bai, baimendu
+    authorize_connection_prompt: Baimendu zifratutako konexio hau?
+    errors:
+      failed: Zifratutako konexioak huts egin du. Saiatu berriro %{provider} hornitzailetik.
+      keybase:
+        invalid_token: Keybase-ko token-ak sinaduren hash-ak dira eta 66 hex karakterekoak izan beha dira
+        verification_failed: Keybase-k ez du token hau Keybase-ko %{kb_username} erabiltzailearen sinaduratzat onartzen. Saiatu berriro Keybase-tik.
+      wrong_user: Ezin izan da %{proving} erabiltzailearentzat froga sortu %{current} gisa saioa hasita. Hasi saioa %{proving} erabilita eta saiatu berriro.
+    explanation_html: Hemen modu zifratuan konektatu ditzakezu zure beste identitateak, esaterako Keybase profila. Honek beste jendeak zuri zifratutako mezuak bidaltzea ahalbidetzen du, eta zuk beraiei bidalitako edukia fidagarritzat jotzea.
+    i_am_html: "%{username} erabiltzailea naiz %{service} zerbitzuan."
+    identity: Identitatea
+    inactive: Ez aktiboa
+    publicize_checkbox: 'Eta bidali toot hau:'
+    publicize_toot: 'Frogatua dago! %{username} erabiltzailea naiz %{service} zerbitzuan: %{url}'
+    status: Egiaztatze egoera
+    view_proof: Ikusi froga
   imports:
-    preface: Beste instantzia bateko datuak inportatu ditzakezu, esaterako jarraitzen duzun edo blokeatu duzun jendearen zerrenda.
+    modes:
+      merge: Bateratu
+      merge_long: Mantendu dauden erregistroak eta gehitu berriak
+      overwrite: Gainidatzi
+      overwrite_long: Ordeztu oraingo erregistroak berriekin
+    preface: Beste zerbitzari bateko datuak inportatu ditzakezu, esaterako jarraitzen duzun edo blokeatu duzun jendearen zerrenda.
     success: Zure datuak ongi igo dira eta dagokionean prozesatuko dira
     types:
       blocking: Blokeatutakoen zerrenda
+      domain_blocking: Domeinuen blokeo zerrenda
       following: Jarraitutakoen zerrenda
       muting: Mutututakoen zerrenda
     upload: Igo
@@ -626,7 +703,7 @@ eu:
       one: Erabilera 1
       other: "%{count} erabilera"
     max_uses_prompt: Mugagabea
-    prompt: Sortu eta partekatu estekak instantzia onetara sarbidea emateko
+    prompt: Sortu eta partekatu estekak zerbitzari honetara sarbidea emateko
     table:
       expires_at: Iraungitzea
       uses: Erabilerak
@@ -689,28 +766,64 @@ eu:
           quadrillion: Q
           thousand: K
           trillion: T
-          unit: "."
   pagination:
     newer: Berriagoa
     next: Hurrengoa
     older: Zaharragoa
     prev: Aurrekoa
     truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: Inkesta honetan dagoeneko bozkatu duzu
+      duplicate_options: bikoiztutako elementuak ditu
+      duration_too_long: etorkizunean urrunegi dago
+      duration_too_short: goizegi da
+      expired: Inkesta amaitu da jada
+      over_character_limit: bakoitzak gehienez %{max} karaktere izan ditzake
+      too_few_options: elementu bat baino gehiago izan behar du
+      too_many_options: ezin ditu %{max} elementu baino gehiago izan
   preferences:
-    languages: Hizkuntzak
     other: Beste bat
-    publishing: Argitaratzea
-    web: Web
+    posting_defaults: Bidalketarako lehenetsitakoak
+    public_timelines: Denbora-lerro publikoak
+  relationships:
+    activity: Kontuaren aktibitatea
+    dormant: Ez aktiboa
+    last_active: Azkenekoz aktiboa
+    most_recent: Azkenak
+    moved: Lekuz aldatua
+    mutual: Alde bikoa
+    primary: Primarioa
+    relationship: Erlazioa
+    remove_selected_domains: Kendu hautatutako domeinuetako jarraitzaile guztiak
+    remove_selected_followers: Kendu hautatutako jarraitzaileak
+    remove_selected_follows: Utzi hautatutako erabiltzaileak jarraitzeari
+    status: Kontuaren egoera
   remote_follow:
     acct: Sartu jarraitzeko erabili nahi duzun erabiltzaile@domeinua
     missing_resource: Ezin izan da zure konturako behar den birbideratze URL-a
     no_account_html: Ez duzu konturik? <a href='%{sign_up_path}' target='_blank'>Izena eman</a> dezakezu
     proceed: Ekin jarraitzeari
     prompt: 'Hau jarraituko duzu:'
+    reason_html: "<strong>Zergaitik eman behar da urrats hau?</strong><code>%{instance}</code> agian ez da izena eman duzun zerbitzaria, eta zure hasiera-zerbitzarira eraman behar zaitugu aurretik."
+  remote_interaction:
+    favourite:
+      proceed: Bihurtu gogoko
+      prompt: 'Toot hau gogoko bihurtu nahi duzu:'
+    reblog:
+      proceed: Eman bultzada
+      prompt: 'Toot honi bultzada eman nahi diozu:'
+    reply:
+      proceed: Ekin erantzuteari
+      prompt: 'Toot honi erantzun nahi diozu:'
   remote_unfollow:
     error: Errorea
     title: Izenburua
     unfollowed: Jarraitzeari utzita
+  scheduled_statuses:
+    over_daily_limit: Egun horretarako programatutako toot kopuruaren muga gainditu duzu (%{limit})
+    over_total_limit: Programatutako toot kopuruaren muga gainditu duzu (%{limit})
+    too_soon: Programatutako data etorkizunean egon behar du
   sessions:
     activity: Azken jarduera
     browser: Nabigatzailea
@@ -735,7 +848,7 @@ eu:
     current_session: Uneko saioa
     description: "%{browser} - %{platform}"
     explanation: Zure Mastodon kontuan saioa hasita duten nabigatzaileak daude.
-    ip: IP
+    ip: IP-a
     platforms:
       adobe_air: Adobe Air
       android: Android
@@ -753,20 +866,25 @@ eu:
     revoke_success: Saioa ongi indargabetu da
     title: Saioak
   settings:
+    account: Kontua
+    account_settings: Kontuaren ezarpenak
+    appearance: Itxura
     authorized_apps: Baimendutako aplikazioak
     back: Itzuli Mastodon-era
     delete: Kontuaren ezabaketa
     development: Garapena
     edit_profile: Aldatu profila
     export: Datuen esportazioa
-    followers: Baimendutako jarraitzaileak
+    featured_tags: Nabarmendutako traolak
+    identity_proofs: Identitate frogak
     import: Inportazioa
+    import_and_export: Inportatu eta esportatu
     migrate: Kontuaren migrazioa
     notifications: Jakinarazpenak
     preferences: Hobespenak
-    settings: Ezarpenak
+    profile: Profila
+    relationships: Jarraitutakoak eta jarraitzaileak
     two_factor_authentication: Bi faktoreetako autentifikazioa
-    your_apps: Zure aplikazioak
   statuses:
     attached:
       description: 'Erantsita: %{attached}'
@@ -789,6 +907,11 @@ eu:
       ownership: Ezin duzu beste norbaiten toot bat finkatu
       private: Ezin dira publikoak ez diren toot-ak finkatu
       reblog: Bultzada bat ezin da finkatu
+    poll:
+      total_votes:
+        one: Boto %{count}
+        other: "%{count} boto"
+      vote: Bozkatu
     show_more: Erakutsi gehiago
     sign_in_to_participate: Eman izena elkarrizketan parte hartzeko
     title: '%{name}: "%{quote}"'
@@ -809,10 +932,10 @@ eu:
       <h3 id="collect">Zer informazio biltzen dugu?</h3>
 
       <ul>
-        <li><em>Kontuaren oinarrizko informazioa</em>: Zerbitzari honetan izena ematen baduzu, erabiltzaile-izena, e-mail helbidea eta pasahitza sartzea galdetu dakizuke.  Profilean bestelako informazioa sartu dezakezu esaterako pantaila.-izena eta biografia, eta profileko eta goiburuko irudiak igo ditzakezu. Erabiltzaile-izena, pantaiula-izena, biografia, profileko irudia eta goiburuko irudia beti dira publikoak.</li>
-        <li><em>Mezuak, jarraitzea eta beste informazioa</em>: Jarraitzen duzun jendearen zerrenda publikoa da, baita zure jarraitzaileena.  Mezu bat bidaltzean, data eta ordua eta mezua bidaltzeko erabilitako aplikazioa gordetzen dira. Mezuen eranskinak izan ditzakete, esaterako irudiak eta bideoak. Mezu publikoak eta zerrendatu gabeak publikoki ikusi daitezke. Zure profilean mezu bat sustatzen duzunean, informazio hori ere publikoki eskuragarri dago. Zure mezuak zure jarraitzaileei bidaltzen zaie, kasu batzuetan honek esan nahi du beste zerbitzari batzuetara bidaltzen dela eta han kopiak gordetzen dituzte. Mezuak ezabatzen dituzunean, hau zure jarraitzaileei bidaltzen zaie ere, beste mezu batzuk zabaltzea edo gogoko izatea beti da informazio publikoa.</li>
-        <li><em>Mezu zuzenak eta soilik jarraitzaileentzako mezuak</em>: Mezu guztiak zerbitzarian gorde eta prozesatzen dira. Soilik jarraitzaileentzako diren mezuak  zure jarraitzaileei bidaltzen zaie eta bertan aipatutako erabiltzaileei, mezu zuzenak soilik aipatutako erabiltzaileei bidaltzen zaie. Honek esan nahi du kasu batzuetan beste zerbitzari batzuetara bidaltzen dela mezua eta han kopiak gordetzen direla. Borondate oneko ahalegin bat egiten dugu mezuok soilik baimena duten pertsonek ikus ditzaten, baina beste zerbitzariek agian ez. Hortaz,  zure jarraitzaileen zerbitzaria zein den egiaztatzea garrantzitsua da.  Jarraitzaileak eskuz onartu eta ukatzeko aukera aldatu dezakezu. <em>Kontuan izan zerbitzariaren operadoreak eta mezua jasotzen duen edozein zerbitzarik operadoreek mezuok ikus ditzaketela</em> eta edonork atera dezakeela pantaila argazki bat, kopiatu edo beste modu batean partekatu.<em>Ez partekatu informazio arriskutsua Mastodon bidez.</em></li>
-        <li><em>IP-ak eta bestelako meta-datuak</em>: Saioa hasten duzunean, zure IP helbidea gordetzen dugu, eta erabiltzen duzun nabigatzaile edo aplikazioa. Hasitako saio guztiak zuk ikusteko mopduan daude eta ezarpenetan indargabetu ditzakezu. Erabilitako azken IP helbidea 12 hilabetez gordetzen da. Gure zerbitzariak jasotako eskari guztiak eta IP-a duten zerbitzariko egunkariak gorde genitzake.</li>
+      <li><em>Kontuaren oinarrizko informazioa</em>: Zerbitzari honetan izena ematen baduzu, erabiltzaile-izena, e-mail helbidea eta pasahitza sartzea galdetu dakizuke. Profilean bestelako informazioa sartu dezakezu esaterako pantaila.-izena eta biografia, eta profileko eta goiburuko irudiak igo ditzakezu. Erabiltzaile-izena, pantaila-izena, biografia, profileko irudia eta goiburuko irudia beti dira publikoak.</li>
+      <li><em>Mezuak, jarraitzea eta beste informazioa</em>: Jarraitzen duzun jendearen zerrenda publikoa da, baita zure jarraitzaileena. Mezu bat bidaltzean, data eta ordua eta mezua bidaltzeko erabilitako aplikazioa gordetzen dira. Mezuen eranskinak izan ditzakete, esaterako irudiak eta bideoak. Mezu publikoak eta zerrendatu gabeak publikoki ikusi daitezke. Zure profilean mezu bat sustatzen duzunean, informazio hori ere publikoki eskuragarri dago. Zure mezuak zure jarraitzaileei bidaltzen zaie, kasu batzuetan honek esan nahi du beste zerbitzari batzuetara bidaltzen dela eta han kopiak gordetzen dituzte. Mezuak ezabatzen dituzunean, hau zure jarraitzaileei bidaltzen zaie ere, beste mezu batzuk zabaltzea edo gogoko izatea beti da informazio publikoa.</li>
+      <li><em>Mezu zuzenak eta soilik jarraitzaileentzako mezuak</em>: Mezu guztiak zerbitzarian gorde eta prozesatzen dira. Soilik jarraitzaileentzako diren mezuak zure jarraitzaileei bidaltzen zaie eta bertan aipatutako erabiltzaileei, mezu zuzenak soilik aipatutako erabiltzaileei bidaltzen zaie. Honek esan nahi du kasu batzuetan beste zerbitzari batzuetara bidaltzen dela mezua eta han kopiak gordetzen direla. Borondate oneko ahalegin bat egiten dugu mezuok soilik baimena duten pertsonek ikus ditzaten, baina beste zerbitzariek agian ez. Hortaz, zure jarraitzaileen zerbitzaria zein den egiaztatzea garrantzitsua da. Jarraitzaileak eskuz onartu eta ukatzeko aukera aldatu dezakezu. <em>Kontuan izan zerbitzariaren operadoreak eta mezua jasotzen duen edozein zerbitzarik operadoreek mezuok ikus ditzaketela</em> eta edonork atera dezakeela pantaila argazki bat, kopiatu edo beste modu batean partekatu.<em>Ez partekatu informazio arriskutsua Mastodon bidez.</em></li>
+      <li><em>IP-ak eta bestelako meta-datuak</em>: Saioa hasten duzunean, zure IP helbidea gordetzen dugu, eta erabiltzen duzun nabigatzaile edo aplikazioa. Hasitako saio guztiak zuk ikusteko moduan daude eta ezarpenetan indargabetu ditzakezu. Erabilitako azken IP helbidea 12 hilabetez gordetzen da. Gure zerbitzariak jasotako eskari guztiak eta IP-a duten zerbitzariko egunkariak gorde genitzake.</li>
       </ul>
 
       <hr class="spacer" />
@@ -822,9 +945,9 @@ eu:
       <p>Biltzen dugun informazio guztia honela erabiltzen da:</p>
 
       <ul>
-        <li>Mastodon zerbitzuko funtzio nagusietarako. Beste pertsonen edukiarekin harremanetan sartzeko edo zure edukia argitaratzeko saioa hasi behar duzu. Adibidez, beste pertsona batzuk jarraitu ditzakezu zure denbora-lerro pertsonalizatu bat izateko.</li>
-        <li>Komunitatearen moderazioari laguntzeko, esaterako zure IP-a ezagutzen ditugun beste batzuekin alderatu dezakegu, debekuak ekiditea edo bestelako arau-urraketak eragozteko.</li>
-        <li>Emandako e-mail helbidea informazioa bidaltzeko erabili genezake, beste pertsonek zure edukiekin harremanetan jartzean jakinarazteko, edo mezu bat bidaltzen dizutenean, galderak erantzutean eta bestelako eskari eta galderetarako.</li>
+      <li>Mastodon zerbitzuko funtzio nagusietarako. Beste pertsonen edukiarekin harremanetan sartzeko edo zure edukia argitaratzeko saioa hasi behar duzu. Adibidez, beste pertsona batzuk jarraitu ditzakezu zure denbora-lerro pertsonalizatu bat izateko.</li>
+      <li>Komunitatearen moderazioari laguntzeko, esaterako zure IP-a ezagutzen ditugun beste batzuekin alderatu dezakegu, debekuak ekiditea edo bestelako arau-urraketak eragozteko.</li>
+      <li>Emandako e-mail helbidea informazioa bidaltzeko erabili genezake, beste pertsonek zure edukiekin harremanetan jartzean jakinarazteko, edo mezu bat bidaltzen dizutenean, galderak erantzutean eta bestelako eskari eta galderetarako.</li>
       </ul>
 
       <hr class="spacer" />
@@ -840,8 +963,8 @@ eu:
       <p>Borondate oneko ahalegina egingo dugu honetarako:</p>
 
       <ul>
-        <li>Zerbitzari honetara egindako eskari guztien egunkaria IP helbidearekin, 90 egunez gehienez.</li>
-        <li>Izena eman duten erabiltzaileen eskariekin lotutako IP helbideak, 12 hilabetez gehienez..</li>
+      <li>Zerbitzari honetara egindako eskari guztien egunkaria IP helbidearekin, 90 egunez gehienez.</li>
+      <li>Izena eman duten erabiltzaileen eskariekin lotutako IP helbideak, 12 hilabetez gehienez..</li>
       </ul>
 
       <p>Zure edukiaren kopia duen artxibo bat eskatu eta deskargatu dezakezu, bertan mezuak multimedia eranskinak, profileko irudia eta goiburuko irudia daude.</p>
@@ -860,7 +983,7 @@ eu:
 
       <h3 id="disclose">Informazioa kanpoko inorekin partekatzen dugu?</h3>
 
-      <p>Ez dugu identifikatu zaitzakeen informazio pertsonala, saltzen, trukatzen edo kanpora bidaltzen. Salbuespena konfidatzako hiirugarrengoak dira, gunea martxan izaten laguntzen digutenak, negozioa aurrera eramateko aholkua ematen digutenak edo zuri zerbitzua ematen laguntzen digutenak, hauek informazioaren konfidentzialtasuna errespetatzea onartzen dutenean., Agian legearekin betetzeko beharrezkoa den informazioa ere eman genezake, gunearen politika indarrean jartzeko behar dena, edo gure eskubideak, jabetzak, edo segurtasuna babesteko beharrezkoa dena.</p>
+      <p>Ez dugu identifikatu zaitzakeen informazio pertsonala saltzen, trukatzen edo kanpora bidaltzen. Salbuespena konfiantzako hirugarrengoak dira, gunea martxan izaten laguntzen digutenak, negozioa aurrera eramateko aholkua ematen digutenak edo zuri zerbitzua ematen laguntzen digutenak, hauek informazioaren konfidentzialtasuna errespetatzea onartzen dutenean. Agian legearekin betetzeko beharrezkoa den informazioa ere eman genezake, gunearen politika indarrean jartzeko behar dena, edo gure eskubideak, jabetzak, edo segurtasuna babesteko beharrezkoa dena.</p>
 
       <p>Zure eduki publikoak sareko beste zerbitzariek deskargatu dezakete. Zure mezu publikoak eta soilik jarraitzaileentzat diren mezuak zure jarraitzaileen zerbitzarietara bidaltzen dira, jarraitzaile edo hartzaile horiek beste zerbitzari batean badute kontua.</p>
 
@@ -872,7 +995,7 @@ eu:
 
       <p>Zerbitzari hau Europar Batasunean edo Europako Ekonomia-Eremuan badago: Gure gunea, produktua eta zerbitzuak 16 urte edo gehiago dituztenei zuzenduta daude. 16 urte baino gazteagoa bazara, GDPR legearen arabera ezin duzu gune hau erabili (<a href="https://en.wikipedia.org/wiki/General_Data_Protection_Regulation">General Data Protection Regulation</a>) </p>
 
-      <p>Zerbitzari hau Amerikako Estatu Batuetan badago:  Gure gunea, produktua eta zerbitzuak 13 urte edo gehiago dituztenei zuzenduta daude. 13 urte baino gazteagoa bazara, COPPA legearen arabera ezin duzu gune hau erabili (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>).</p>
+      <p>Zerbitzari hau Amerikako Estatu Batuetan badago: Gure gunea, produktua eta zerbitzuak 13 urte edo gehiago dituztenei zuzenduta daude. 13 urte baino gazteagoa bazara, COPPA legearen arabera ezin duzu gune hau erabili (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>).</p>
 
       <p>Zerbitzari hau beste eremu legal batean badago, legearen eskariak desberdinak izan daitezke.</p>
 
@@ -880,20 +1003,20 @@ eu:
 
       <h3 id="changes">Aldaketak gure pribatutasun politikan</h3>
 
-      <p>Guire pribatutasun politika aldatzea erabakitzen badugu, aldaketak orri honetan argitaratuko ditugu.</p>
+      <p>Gure pribatutasun politika aldatzea erabakitzen badugu, aldaketak orri honetan argitaratuko ditugu.</p>
 
       <p>Dokumentu honek CC-BY-SA lizentzia du. Eta azkenekoz 2019ko martxoak 7an eguneratu zen</p>
 
       <p>Jatorrian <a href="https://github.com/discourse/discourse">Discourse sarearen pribatutasun politikatik</a> moldatua.</p>
     title: "%{instance} instantziaren erabilera baldintzak eta pribatutasun politika"
   themes:
-    contrast: Kontraste altua
-    default: Mastodon
-    mastodon-light: Mastodon (argia)
+    contrast: Mastodon (Kontraste altua)
+    default: Mastodon (Iluna)
+    mastodon-light: Mastodon (Argia)
   time:
     formats:
       default: "%Y(e)ko %b %d, %H:%M"
-      month: "%b %Y"
+      month: "%Y(e)ko %b"
   two_factor_authentication:
     code_hint: Sartu zure autentifikazio aplikazioak sortutako kodea berresteko
     description_html: "<strong>Bi faktoreetako autentifikazioa</strong> gaitzen baduzu, saioa hasteko telefonoa eskura izan beharko duzu, honek zuk sartu behar dituzun kodeak sortuko dituelako."
@@ -919,15 +1042,18 @@ eu:
       explanation:
         disable: Zure kontua izoztuta dagoen bitartean, zure kontua bere horretan dirau, baina ezin duzu ekintzarik burutu desblokeatzen den arte.
         silence: Zure kontua murriztua dagoen bitartean, jada zu jarraitzen zaituztenak besterik ez dituzte zure Toot-ak ikusiko zerbitzari honetan, eta agian zerrenda publikoetatik kenduko zaizu. Hala ere besteek oraindik zu jarraitu zaitzakete.
+        suspend: Zure kontua kanporatua izan da, zure toot guztiak eta multimedia fitxategiak behin betiko ezabatu dira zerbitzari honetatik, eta zure jarraitzaileen zerbitzarietatik.
       review_server_policies: Berrikusi zerbitzariko politikak
       subject:
         disable: Zure  %{acct} kontua izoztu da
         none: "%{acct} konturako abisua"
         silence: Zure  %{acct} kontua murriztu da
+        suspend: Zure %{acct} kontua kanporatua izan da
       title:
         disable: Kontu izoztua
         none: Abisua
         silence: Kontu murriztua
+        suspend: Kontu kanporatua
     welcome:
       edit_profile_action: Ezarri profila
       edit_profile_step: Pertsonalizatu profila abatar bat igoz, goiburu bat, zure pantaila-izena aldatuz eta gehiago. Jarraitzaile berriak onartu aurretik gainbegiratu nahi badituzu, kontua giltzaperatu dezakezu.
@@ -935,7 +1061,7 @@ eu:
       final_action: Hasi mezuak bidaltzen
       final_step: 'Hasi argitaratzen! Jarraitzailerik ez baduzu ere zure mezu publikoak besteek ikusi ditzakete, esaterako denbora-lerro lokalean eta traoletan. Zure burua aurkeztu nahi baduzu #aurkezpenak traola erabili zenezake.'
       full_handle: Zure erabiltzaile-izen osoa
-      full_handle_hint: Hau da lagunei esango zeniena beste instantzia batetik zu jarraitzeko edo zuri mezuak bidaltzeko.
+      full_handle_hint: Hau da lagunei esango zeniekeena beste zerbitzari batetik zu jarraitzeko edo zuri mezuak bidaltzeko.
       review_preferences_action: Aldatu hobespenak
       review_preferences_step: Ziurtatu hobespenak ezartzen dituzula, jaso nahi dituzu e-mail mezuak, lehenetsitako pribatutasuna mezu berrietarako. Mareatzen ez bazaitu GIF-ak automatikoki abiatzea ezarri dezakezu ere.
       subject: Ongi etorri Mastodon-era
diff --git a/config/locales/fa.yml b/config/locales/fa.yml
index e7dd86025f288fdd4b358510ff7a37fb421eaac7..d37dbdeb49ecf34693635cac02e2f24e716d12d6 100644
--- a/config/locales/fa.yml
+++ b/config/locales/fa.yml
@@ -4,36 +4,36 @@ fa:
     about_hashtag_html: این‌ها نوشته‌های عمومی هستند که برچسب (هشتگ) <strong>#%{hashtag}</strong> را دارند. اگر شما روی هر سروری حساب داشته باشید می‌توانید به این نوشته‌ها واکنش نشان دهید.
     about_mastodon_html: ماستدون (Mastodon) یک شبکهٔ اجتماعی است که بر اساس پروتکل‌های آزاد وب و نرم‌افزارهای آزاد و کدباز ساخته شده است. این شبکه مانند ایمیل غیرمتمرکز است.
     about_this: درباره
+    active_count_after: فعال
+    active_footnote: کاربران فعال در ماه گذشته
     administered_by: 'با مدیریت:'
     api: رابط برنامه‌نویسی کاربردی
     apps: اپ‌های موبایل
-    closed_registrations: ثبت‌نام روی این سرور هم‌اینک فعال نیست. اما شما می‌توانید سرور دیگری بیابید و با حسابی که آن‌جا می‌سازید دقیقاً به همین شبکه دسترسی داشته باشید.
+    apps_platforms: ماستدون را در iOS، اندروید، و سایر سیستم‌ها داشته باشید
+    browse_directory: در فهرست گزیدهٔ کاربران این سرور چرخی بزنید و کاربران را بر اساس علاقه‌مندی‌هایشان پیدا کنید
+    browse_public_posts: فهرست لحظه‌ای نوشته‌های عمومی در ماستدون را ببینید
     contact: تماس
     contact_missing: تعیین نشده
     contact_unavailable: موجود نیست
+    discover_users: یافتن کاربران
     documentation: مستندات
     extended_description_html: |
       <h3>جای خوبی برای قانون‌ها</h3>
       <p>توضیحات تکمیلی نوشته نشده است.</p>
-    features:
-      humane_approach_body: با آموختن از کاستی‌های شبکه‌های دیگر، ماستدون می‌خواهد به کمک انتخاب‌های اخلاقی‌تر در طراحی خودش با آسیب‌های شبکه‌های اجتماعی مبارزه کند.
-      humane_approach_title: رویکردی انسانی‌تر
-      not_a_product_body: ماستدون یک شبکهٔ تجاری نیست. بدون تبلیغات، بدون داده‌کاوی، بدون حصارکشی. هیچ قدرت مرکزی‌ای وجود ندارد.
-      not_a_product_title: شما یک انسان هستید، نه یک محصول
-      real_conversation_body: با ۵۰۰ نویسه برای هر نوشته و با پشتیبانی از هشدارهای موردی برای نوشته‌ها و تصاویر، می‌توانید خود را همان گونه که می‌خواهید ابراز کنید.
-      real_conversation_title: برای گفتگوهای واقعی
-      within_reach_body: اپ‌های متنوع برای iOS، اندروید، و سیستم‌های دیگر به خاطر وجود یک اکوسیستم API دوستانه برای برنامه‌نویسان. از همه جا با دوستان خود ارتباط داشته باشید.
-      within_reach_title: همیشه در دسترس
+    federation_hint_html: با داشتن حساب روی %{instance} می‌توانید کاربران همهٔ سرورهای دیگر ماستدون (و سایر شبکه‌های سازگار با آن) را پی بگیرید.
     generic_description: "%{domain} یک سرور روی شبکه است"
+    get_apps: یک اپ موبایل را امتحان کنید
     hosted_on: ماستدون، میزبانی‌شده روی %{domain}
     learn_more: بیشتر بدانید
-    other_instances: فهرست سرورها
     privacy_policy: سیاست رازداری
+    see_whats_happening: ببینید چه خبر است
+    server_stats: 'آمار سرور:'
     source_code: کدهای منبع
     status_count_after:
       one: چیز نوشته‌اند
       other: چیز نوشته‌اند
     status_count_before: که در کنار هم
+    tagline: با دوستان خود در ارتباط باشید و دوستان تازه پیدا کنید
     terms: شرایط کاربری
     user_count_after:
       one: کاربر
@@ -48,6 +48,7 @@ fa:
       other: پیگیر
     following: پی می‌گیرد
     joined: کاربر از %{date}
+    last_active: آخرین فعالیت
     link_verified_on: مالکیت این نشانی در تاریخ %{date} بررسی شد
     media: عکس و ویدیو
     moved_html: "%{name} حساب خود را به %{new_profile_link} منتقل کرده است:"
@@ -60,21 +61,27 @@ fa:
     posts:
       one: بوق
       other: بوق
-    posts_tab_heading: بوق‌ها
+    posts_tab_heading: نوشته‌ها
     posts_with_replies: نوشته‌ها و پاسخ‌ها
     reserved_username: این نام کاربری در دسترس نیست
     roles:
       admin: مدیر
       bot: ربات
       moderator: ناظم
+    unavailable: نمایهٔ ناموجود
     unfollow: پایان پیگیری
   admin:
+    account_actions:
+      action: انجام تغییر
+      title: انجام تغییر مدیریتی روی %{acct}
     account_moderation_notes:
       create: افزودن یادداشت
       created_msg: یادداشت مدیر با موفقیت ساخته شد!
       delete: پاک کردن
       destroyed_msg: یادداشت مدیر با موفقیت پاک شد!
     accounts:
+      approve: پذیرفتن
+      approve_all: پذیرفتن همه
       are_you_sure: آیا مطمئن هستید؟
       avatar: تصویر نمایه
       by_domain: دامین
@@ -88,6 +95,7 @@ fa:
       confirm: تأیید
       confirmed: تأیید شد
       confirming: تأیید
+      deleted: پاک‌شده
       demote: تنزل‌دادن
       disable: غیرفعال
       disable_two_factor_authentication: غیرفعال‌سازی ورود دومرحله‌ای
@@ -103,8 +111,11 @@ fa:
       followers: پیگیران
       followers_url: نشانی پیگیران
       follows: پی می‌گیرد
+      header: زمینه
       inbox_url: نشانی صندوق ورودی
+      invited_by: دعوت‌شده از طرف
       ip: IP
+      joined: عضویت از
       location:
         all: همه
         local: محلی
@@ -114,24 +125,31 @@ fa:
       media_attachments: ضمیمه‌های تصویری
       memorialize: تبدیل به یادمان
       moderation:
+        active: فعال
         all: همه
+        pending: در انتظار
         silenced: بی‌صدا شده
         suspended: معلق شده
         title: وضعیت
       moderation_notes: یادداشت مدیر
       most_recent_activity: آخرین فعالیت‌ها
       most_recent_ip: آخرین IP ها
+      no_account_selected: هیچ حسابی تغییر نکرد زیرا حسابی انتخاب نشده بود
       no_limits_imposed: بدون محدودیت
       not_subscribed: عضو نیست
       outbox_url: نشانی صندوق خروجی
+      pending: در انتظار بررسی
       perform_full_suspension: تعلیق
       profile_url: نشانی نمایه
       promote: ترفیع‌دادن
       protocol: پروتکل
       public: عمومی
       push_subscription_expires: عضویت از راه PuSH منقضی شد
-      redownload: به‌روزرسانی تصویر نمایه
+      redownload: به‌روزرسانی نمایه
+      reject: نپذیرفتن
+      reject_all: نپذیرفتن هیچکدام
       remove_avatar: حذف تصویر نمایه
+      remove_header: برداشتن تصویر زمینه
       resend_confirmation:
         already_confirmed: این کاربر قبلا تایید شده است
         send: ایمیل تایید را دوباره بفرستید
@@ -149,25 +167,28 @@ fa:
       search: جستجو
       shared_inbox_url: نشانی صندوق ورودی مشترک
       show:
-        created_reports: گزارش‌ها از طرف این حساب
-        targeted_reports: گزارش‌ها دربارهٔ این حساب
+        created_reports: گزارش‌های ثبت کرده
+        targeted_reports: گزارش‌های دیگران
       silence: بی‌صدا
       silenced: بی‌صداشده
       statuses: نوشته‌ها
       subscribe: اشتراک
       suspended: تعلیق‌شده
+      time_in_queue: در حال انتظار %{time}
       title: حساب‌ها
       unconfirmed_email: ایمیل تأییدنشده
       undo_silenced: واگردانی بی‌صداکردن
       undo_suspension: واگردانی تعلیق
       unsubscribe: لغو اشتراک
       username: نام کاربری
+      warn: هشدار
       web: وب
     action_logs:
       actions:
         assigned_to_self_report: "%{name} رسیدگی به گزارش %{target} را به عهده گرفت"
         change_email_user: "%{name} نشانی ایمیل کاربر %{target} را تغییر داد"
         confirm_user: "%{name} نشانی ایمیل کاربر %{target} را تأیید کرد"
+        create_account_warning: "%{name} هشداری برای %{target} فرستاد"
         create_custom_emoji: "%{name} شکلک تازهٔ %{target} را بارگذاشت"
         create_domain_block: "%{name} دامین %{target} را مسدود کرد"
         create_email_domain_block: "%{name} دامین ایمیل %{target} را مسدود کرد"
@@ -226,8 +247,10 @@ fa:
       config: پیکربندی
       feature_deletions: حساب‌های حذف‌شده
       feature_invites: دعوت‌نامه‌ها
+      feature_profile_directory: فهرست گزیدهٔ کاربران
       feature_registrations: ثبت‌نام‌ها
       feature_relay: رله
+      feature_timeline_preview: پیش‌نمایش نوشته‌ها
       features: ویژگی‌ها
       hidden_service: ارتباط میان‌سروری با سرویس‌های نهفته
       open_reports: گزارش‌های فعال
@@ -243,10 +266,11 @@ fa:
       week_users_active: کاربران فعال هفتهٔ اخیر
       week_users_new: کاربران هفتهٔ اخیر
     domain_blocks:
-      add_new: افزودن تازه
+      add_new: افزودن مسدودسازی دامین تازه
       created_msg: مسدودکردن دامین در حال انجام است
       destroyed_msg: مسدودکردن دامین واگردانده شد
       domain: دامین
+      existing_domain_block_html: شما پیش‌تر محدودیت‌های سخت‌تری روی %{name} اعمال کرده‌اید، و باید نخست <a href="%{unblock_url}">مسدودسازی را لغو کنید</a>.
       new:
         create: مسدودسازی
         hint: مسدودسازی دامین جلوی فهرست‌شدن حساب‌ها در پایگاه داده را نمی‌گیرد، بلکه به طور خودکار روش‌های مدیریتی را روی فعالیت‌های فعلی و گذشتهٔ آن حساب‌ها اعمال می‌کند.
@@ -260,6 +284,11 @@ fa:
       reject_media_hint: تصویرهای ذخیره‌شده در این‌جا را پاک می‌کند و جلوی دریافت تصویرها را در آینده می‌گیرد. بی‌تأثیر برای معلق‌شده‌ها
       reject_reports: نپذیرفتن گزارش‌ها
       reject_reports_hint: گزارش‌هایی را که از این دامین می‌آید نادیده می‌گیرد. بی‌تأثیر برای معلق‌شده‌ها
+      rejecting_media: رسانه‌ها نادیده گرفته می‌شوند
+      rejecting_reports: گزارش‌ها نادیده گرفته می‌شوند
+      severity:
+        silence: بی‌صداشده
+        suspend: معلق‌شده
       show:
         affected_accounts:
           one: روی یک حساب در پایگاه داده تأثیر گذاشت
@@ -269,19 +298,36 @@ fa:
           suspend: معلق‌شدن همهٔ حساب‌های این دامین را لغو کن
         title: واگردانی مسدودسازی دامنه برای %{domain}
         undo: واگردانی
-      undo: واگردانی
+      undo: واگردانی مسدودسازی دامین
     email_domain_blocks:
       add_new: افزودن تازه
       created_msg: مسدودسازی دامین ایمیل با موفقیت ساخته شد
-      delete: Delete
+      delete: پاک‌کردن
       destroyed_msg: مسدودسازی دامین ایمیل با موفقیت پاک شد
       domain: دامین
       new:
         create: ساختن مسدودسازی
         title: مسدودسازی دامین ایمیل تازه
       title: مسدودسازی دامین‌های ایمیل
+    followers:
+      back_to_account: بازگشت به حساب
+      title: پیگیران %{acct}
     instances:
-      title: سرورهای شناخته‌شده
+      by_domain: دامین
+      delivery_available: پیام آماده است
+      known_accounts:
+        one: "%{count} حساب شناخته‌شده"
+        other: "%{count} حساب شناخته‌شده"
+      moderation:
+        all: همه
+        limited: محدود
+        title: مدیریت
+      title: ارتباط میان‌سروری
+      total_blocked_by_us: مسدودشده از طرف ما
+      total_followed_by_them: ما را پی می‌گیرند
+      total_followed_by_us: ما پیگیرشان هستیم
+      total_reported: گزارش درباره‌شان
+      total_storage: عکس‌ها و ویدیوها
     invites:
       deactivate_all: غیرفعال‌کردن همه
       filter:
@@ -290,6 +336,8 @@ fa:
         expired: منقضی‌شده
         title: فیلتر
       title: دعوت‌ها
+    pending_accounts:
+      title: حساب‌های منتظر (%{count})
     relays:
       add_new: افزودن رلهٔ تازه
       delete: حذف
@@ -363,6 +411,9 @@ fa:
       preview_sensitive_media:
         desc_html: پیوند به سایت‌های دیگر پیش‌نمایشی خواهد داشت که یک تصویر کوچک را نشان می‌دهد، حتی اگر نوشته به عنوان حساس علامت‌گذاری شده باشد
         title: نمایش تصاویر حساسیت‌برانگیز در پیش‌نمایش‌های OpenGraph
+      profile_directory:
+        desc_html: به کاربران اجازه دهید تا بتوانند خود را روی فهرست گزیدهٔ کاربران این سرور نمایش دهند
+        title: فعال‌سازی فهرست گزیدهٔ کاربران
       registrations:
         closed_message:
           desc_html: وقتی امکان ثبت نام روی سرور فعال نباشد در صفحهٔ اصلی نمایش می‌یابد<br>می‌توانید HTML بنویسید
@@ -373,9 +424,12 @@ fa:
         min_invite_role:
           disabled: هیچ کس
           title: اجازهٔ دعوت به
-        open:
-          desc_html: همه بتوانند حساب باز کنند
-          title: امکان ثبت نام
+      registrations_mode:
+        modes:
+          approved: ثبت نام نیازمند تأیید مدیران است
+          none: کسی نمی‌تواند ثبت نام کند
+          open: همه می‌توانند ثبت نام کنند
+        title: شرایط ثبت نام
       show_known_fediverse_at_about_page:
         desc_html: اگر انتخاب شود، بوق‌های همهٔ سرورهای دیگر نیز در پیش‌نمایش این سرور نمایش می‌یابد. وگرنه فقط بوق‌های محلی نشان داده می‌شوند.
         title: نمایش سرورهای دیگر در پیش‌نمایش این سرور
@@ -383,21 +437,21 @@ fa:
         desc_html: نمایش علامت همکار روی صفحهٔ کاربر
         title: نمایش علامت همکار
       site_description:
-        desc_html: معرفی کوتاهی که روی صفحهٔ اصلی نمایش می‌یابد. دربارهٔ این که چه چیزی دربارهٔ این سرور ماستدون ویژه است یا هر چیز مهم دیگری بنویسید. می‌توانید HTML بنویسید، به‌ویژه <code>&lt;a&gt;</code> و <code>&lt;em&gt;</code>.
-        title: دربارهٔ سایت
+        desc_html: معرفی کوتاهی دربارهٔ رابط برنامه‌نویسی کاربردی. دربارهٔ این که چه چیزی دربارهٔ این سرور ماستدون ویژه است یا هر چیز مهم دیگری بنویسید. می‌توانید HTML بنویسید، به‌ویژه <code>&lt;a&gt;</code> و <code>&lt;em&gt;</code>.
+        title: دربارهٔ این سرور
       site_description_extended:
         desc_html: جای خوبی برای نوشتن سیاست‌های کاربری، قانون‌ها، راهنماها، و هر چیزی که ویژهٔ این سرور است. تگ‌های HTML هم مجاز است
         title: اطلاعات تکمیلی سفارشی
       site_short_description:
-        desc_html: روی نوار کناری و همچنین به عنوان فرادادهٔ صفحه‌ها نمایش می‌یابد. در یک بند توضیح دهید که ماستدون چیست و چرا این سرور با بقیه فرق دارد. اگر خالی بگذارید، به جایش «دربارهٔ سایت» نمایش می‌یابد.
-        title: توضیح کوتاه دربارهٔ سایت
+        desc_html: روی نوار کناری و همچنین به عنوان فرادادهٔ صفحه‌ها نمایش می‌یابد. در یک بند توضیح دهید که ماستدون چیست و چرا این سرور با بقیه فرق دارد.
+        title: توضیح کوتاه دربارهٔ سرور
       site_terms:
         desc_html: می‌توانید سیاست رازداری، شرایط استفاده، یا سایر مسائل قانونی را به دلخواه خود بنویسید. تگ‌های HTML هم مجاز است
         title: شرایط استفادهٔ سفارشی
       site_title: نام سرور
       thumbnail:
         desc_html: برای دیدن با OpenGraph و رابط برنامه‌نویسی. وضوح پیشنهادی ۱۲۰۰×۶۳۰ پیکسل
-        title: تصویر کوچک فوری
+        title: تصویر کوچک سرور
       timeline_preview:
         desc_html: نوشته‌های عمومی این سرور را در صفحهٔ آغازین نشان دهید
         title: پیش‌نمایش نوشته‌ها
@@ -422,12 +476,35 @@ fa:
       last_delivery: آخرین ارسال
       title: WebSub
       topic: موضوع
+    tags:
+      accounts: حساب‌ها
+      hidden: پنهان‌شده
+      hide: در فهرست گزیدهٔ کاربران نشان نده
+      name: برچسب
+      title: برچسب‌ها
+      unhide: نمایش در فهرست گزیدهٔ کاربران
+      visible: نمایان
     title: مدیریت سرور
+    warning_presets:
+      add_new: افزودن تازه
+      delete: زدودن
+      edit: ویرایش
+      edit_preset: ویرایش هشدار پیش‌فرض
+      title: مدیریت هشدارهای پیش‌فرض
   admin_mailer:
+    new_pending_account:
+      body: جزئیات حساب تازه این‌جاست. شما می‌توانید آن را تأیید یا رد کنید.
+      subject: حساب تازه‌ای در %{instance} نیازمند بررسی است (%{username})
     new_report:
       body: کاربر %{reporter} کاربر %{target} را گزارش داد
       body_remote: کسی از %{domain} گزارش %{target} را فرستاده
       subject: گزارش تازه‌ای برای %{instance} (#%{id})
+  appearance:
+    advanced_web_interface: رابط کاربری پیشرفته
+    advanced_web_interface_hint: 'اگر می‌خواهید همهٔ فضای نمایشگر خود را به کار ببرید، می‌توانید به کمک رابط کاربری پیشرفته ستون‌های گوناگونی داشته باشید تا در یک نگاه همهٔ اطلاعاتی را که می‌خواهید ببینید: نوشته‌های دیگران، اعلان‌ها، فهرست نوشته‌های همه‌جا، و هر تعداد فهرست و برچسب که بخواهید.'
+    animations_and_accessibility: پویانمایی‌های و دسترسی‌پذیری
+    confirmation_dialogs: پیغام‌های تأیید
+    sensitive_content: محتوای حساس
   application_mailer:
     notification_preferences: تغییر ترجیحات ایمیل
     salutation: "%{name}،"
@@ -444,8 +521,9 @@ fa:
     warning: خیلی مواظب این اطلاعات باشید و آن را به هیچ کس ندهید!
     your_token: کد دسترسی شما
   auth:
-    agreement_html: با کلیک روی دکمهٔ عضو شدن، شما <a href="%{rules_path}">قوانین این سرور</a> و <a href="%{terms_path}">شرایط استفادهٔ</a> ما را می‌پذیرید.
+    apply_for_account: درخواست دعوت‌نامه
     change_password: رمز
+    checkbox_agreement_html: من <a href="%{rules_path}" target="_blank">قانون‌های این سرور</a> و <a href="%{terms_path}" target="_blank">شرایط کاربری</a> را می‌پذیرم
     confirm_email: تأیید ایمیل
     delete_account: پاک‌کردن حساب
     delete_account_html: اگر می‌خواهید حساب خود را پاک کنید، از <a href="%{path}">این‌جا</a> پیش بروید. از شما درخواست تأیید خواهد شد.
@@ -456,17 +534,17 @@ fa:
     logout: خروج
     migrate_account: نقل مکان به یک حساب دیگر
     migrate_account_html: اگر می‌خواهید این حساب را به حساب دیگری منتقل کنید، <a href="%{path}">این‌جا را کلیک کنید</a>.
-    or: یا
     or_log_in_with: یا ورود به وسیلهٔ
     providers:
       cas: CAS
       saml: SAML
     register: عضو شوید
-    register_elsewhere: ثبت نام روی یک سرور دیگر
+    registration_closed: سرور %{instance} عضو تازه‌ای نمی‌پذیرد
     resend_confirmation: راهنمایی برای تأیید را دوباره بفرست
     reset_password: بازنشانی رمز
     security: امنیت
     set_new_password: تعیین رمز تازه
+    trouble_logging_in: برای ورود مشکلی دارید؟
   authorize_follow:
     already_following: شما همین الان هم این حساب را پی‌می‌گیرید
     error: متأسفانه حین یافتن آن حساب خطایی رخ داد
@@ -500,10 +578,20 @@ fa:
     success_msg: حساب شما با موفقیت پاک شد
     warning_html: تنها پاک‌شدن محتوای حساب در این سرور خاص تضمین می‌شود. محتوایی که به گستردگی هم‌رسانی شده باشد ممکن است ردش همچنان باقی بماند. سرورهای آفلاین یا سرورهایی که دیگر مشترک شما نیستند پایگاه‌های دادهٔ خود را به‌روز نخواهند کرد.
     warning_title: دسترس‌پذیری محتوای هم‌رسان‌شده
+  directories:
+    directory: فهرست گزیدهٔ کاربران
+    enabled: شما هم‌اینک در فهرست گزیدهٔ کاربران نمایش می‌یابید.
+    enabled_but_waiting: شما می‌خواهید در فهرست گزیدهٔ کاربران این سرور باشید، ولی تعداد پیگیران شما هنوز به مقدار لازم (%{min_followers}) نرسیده است.
+    explanation: کاربران این سرور را بر اساس علاقه‌مندی‌هایشان پیدا کنید
+    explore_mastodon: گشت و گذار در %{title}
+    how_to_enable: شما هنوز در فهرست گزیدهٔ کاربران این سرور نشان داده نمی‌شوید. این‌جا می‌توانید انتخابش کنید. اگر در بخش معرفی خود در نمایه‌تان برچسب (هشتگ) داشته باشد، نام شما هم برای آن هشتگ‌ها فهرست می‌شود!
+    people:
+      one: "%{count} نفر"
+      other: "%{count} نفر"
   errors:
     '403': شما اجازهٔ دیدن این صفحه را ندارید.
-    '404': صفحه‌ای که به دنبالش بودید وجود ندارد.
-    '410': صفحه‌ای که به دنبالش بودید دیگر وجود ندارد.
+    '404': صفحه‌ای که به دنبالش هستید این‌جا نیست.
+    '410': صفحه‌ای که به دنبالش بودید دیگر این‌جا وجود ندارد.
     '422':
       content: تأیید امنیتی انجام نشد. آیا مرورگر شما کوکی‌ها را مسدود می‌کند؟
       title: تأیید امنیتی کار نکرد
@@ -512,6 +600,9 @@ fa:
       content: شرمنده، یک چیزی از سمت ما اشتباه شده.
       title: این صفحه درست نیست
     noscript_html: برای استفاده از نسخهٔ تحت وب ماستدون، لطفاً جاوااسکریپت را فعال کنید. یا به جایش می‌توانید <a href="%{apps_path}">یک اپ ماستدون</a> را به‌کار ببرید.
+  existing_username_validator:
+    not_found: کاربری در این سرور با این نام کاربری پیدا نشد
+    not_found_multiple: "%{usernames} پیدا نشد"
   exports:
     archive_takeout:
       date: تاریخ
@@ -522,9 +613,15 @@ fa:
       size: اندازه
     blocks: حساب‌های مسدودشده
     csv: CSV
+    domain_blocks: دامین‌های مسدودشده
     follows: حساب‌های پی‌گرفته
+    lists: فهرست‌ها
     mutes: حساب‌های بی‌صداشده
     storage: تصویرهای ذخیره‌شده
+  featured_tags:
+    add_new: افزودن تازه
+    errors:
+      limit: شما بیشترین تعداد مجاز برچسب‌ها را دارید
   filters:
     contexts:
       home: خانه
@@ -541,34 +638,50 @@ fa:
       title: فیلترها
     new:
       title: افزودن فیلتر تازه
-  followers:
-    domain: دامین
-    explanation_html: اگر می‌خواهید از خصوصی‌بودن نوشته‌های خود مطمئن شوید، باید بدانید که چه کسانی پیگیر شما هستند. <strong>نوشته‌های خصوصی شما به همهٔ سرورهایی که در آن‌ها پیگیر دارید فرستاده می‌شود</strong>. شاید بخواهید این سرورها را بررسی کنید، و اگر به مسئولان یا نرم‌افزارهای آن‌ها در رعایت حریم خصوصی خود اعتماد ندارید، می‌توانید آن‌ها را حذف کنید.
-    followers_count: تعداد پیگیران
-    lock_link: حساب خود را خصوصی کنید
-    purge: برداشتن پیگیری
-    success:
-      one: در حال انجام مسدودسازی نرم روی کاربران یک دامین...
-      other: در حال انجام مسدودسازی نرم روی کاربران %{count} دامین...
-    true_privacy_html: لطفاً بدانید که <strong>داشتن حریم خصوصی واقعی تنها با رمزگذاری سرتاسر (end-to-end encryption) ممکن است</strong>.
-    unlocked_warning_html: هر کسی می‌تواند پیگیر شما شود تا بلافاصله نوشته‌های خصوصی شما را ببیند. اگر  %{lock_link} خواهید توانست درخواست‌های پیگیری را بررسی کرده و نپذیرید.
-    unlocked_warning_title: حساب شما خصوصی نیست
   footer:
     developers: برنامه‌نویسان
     more: بیشتر…
     resources: منابع
   generic:
+    all: همه
     changes_saved_msg: تغییرات با موفقیت ذخیره شدند!
     copy: رونوشت
+    order_by: مرتب‌سازی
     save_changes: ذخیرهٔ تغییرات
     validation_errors:
       one: یک چیزی هنوز درست نیست! لطفاً خطاهای زیر را ببینید
       other: یک چیزی هنوز درست نیست! لطفاً %{count} خطای زیر را ببینید
+  html_validator:
+    invalid_markup: 'دارای نشانه‌گذاری نامعتبر HTML است: %{error}'
+  identity_proofs:
+    active: فعال
+    authorize: بله، اجازه بده
+    authorize_connection_prompt: آیا اجازهٔ این ارتباط رمزگذاری را می‌دهید؟
+    errors:
+      failed: برقراری ارتباط  رمزگذاری شکست خورد. لطفاً دوباره از %{provider} تلاش کنید.
+      keybase:
+        invalid_token: کدهای Keybase چکیده (هش) امضاهای دیجیتال هستند و دست‌کم ۶۶ نویسه در مبنای ۱۶ دارند
+        verification_failed: این کد را Keybase به عنوان امضای دیجیتال کاربر %{kb_username} تأیید نمی‌کند. لطفاً دوباره از Keybase تلاش کنید.
+      wrong_user: نمی‌توان تأییدی برای %{proving} در حالی که به عنوان %{current} وارد شده‌اید. به عنوان %{proving} وارد شوید و دوباره تلاش کنید.
+    explanation_html: این‌جا می‌توانید به شناسه‌های دیگر خود مانند نمایهٔ Keybase خودتان به طور رمزنگارانه متصل شوید. با این کار دیگران می‌توانند به شما پیغام‌های رمزشده بفرستند و به چیزی که شما به آن‌ها می‌فرستید اعتماد کنند.
+    i_am_html: من %{username} روی %{service} هستم.
+    identity: شناسه
+    inactive: غیرفعال
+    publicize_checkbox: 'این را ببوقید:'
+    publicize_toot: 'تأیید شد! من %{username} روی %{service} هستم: %{url}'
+    status: وضعیت تأیید
+    view_proof: دیدن مدرک
   imports:
+    modes:
+      merge: ادغام
+      merge_long: داده‌های فعلی را داشته باشید و داده‌های تازه‌ای بیفزایید
+      overwrite: بازنویسی
+      overwrite_long: داده‌های فعلی را پاک کنید و داده‌های تازه‌ای بیفزایید
     preface: شما می‌توانید داده‌هایی از قبیل کاربرانی که پی می‌گرفتید یا مسدود می‌کردید را در حساب خود روی این سرور درون‌ریزی کنید. برای این کار پرونده‌هایی که از سرور دیگر برون‌سپاری کرده‌اید را به‌کار ببرید.
     success: داده‌های شما با موفقیت بارگذاری شد و به زودی پردازش می‌شود
     types:
       blocking: فهرست مسدودشده‌ها
+      domain_blocking: فهرست دامین‌های مسدودشده
       following: فهرست پی‌گیری‌ها
       muting: فهرست بی‌صداشده‌ها
     upload: بارگذاری
@@ -653,47 +766,83 @@ fa:
           quadrillion: Q
           thousand: K
           trillion: T
-          unit: ''
   pagination:
     newer: تازه‌تر
     next: بعدی
     older: قدیمی‌تر
     prev: قبلی
     truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: شما قبلاً در این نظرسنجی رأی داده‌اید
+      duplicate_options: دارای موارد تکراری است
+      duration_too_long: در آیندهٔ خیلی دور است
+      duration_too_short: در آیندهٔ خیلی نزدیک است
+      expired: این نظرسنجی به پایان رسیده است
+      over_character_limit: هر کدام نمی‌تواند از %{max} نویسه طولانی‌تر باشد
+      too_few_options: حتماً باید بیش از یک گزینه داشته باشد
+      too_many_options: نمی‌تواند بیشتر از %{max} گزینه داشته باشد
   preferences:
-    languages: تنظیمات زبان
     other: سایر تنظیمات
-    publishing: تنظیمات انتشار مطالب
-    web: وب
+    posting_defaults: تنظیمات پیش‌فرض انتشار
+    public_timelines: فهرست عمومی نوشته‌ها
+  relationships:
+    activity: فعالیت حساب
+    dormant: غیرفعال
+    last_active: آخرین فعالیت
+    most_recent: تازه‌ترین
+    moved: منتقل‌شده
+    mutual: دوطرفه
+    primary: اصلی
+    relationship: رابطه
+    remove_selected_domains: همهٔ پیگیران از طرف این سرور را بردار
+    remove_selected_followers: پیگیران انتخاب‌شده را بردار
+    remove_selected_follows: به پیگیری از کاربران انتخاب‌شده پایان بده
+    status: وضعیت حساب
   remote_follow:
     acct: نشانی حساب username@domain خود را این‌جا بنویسید
     missing_resource: نشانی اینترنتی برای رسیدن به حساب شما پیدا نشد
     no_account_html: هنوز عضو نیستید؟ <a href='%{sign_up_path}' target='_blank'>این‌جا می‌توانید حساب باز کنید</a>
     proceed: درخواست پیگیری
     prompt: 'شما قرار است این حساب را پیگیری کنید:'
+    reason_html: "<strong>چرا این مرحله لازم است؟</strong> ممکن است <code>%{instance}</code> سروری نباشد که شما روی آن حساب باز کرده‌اید، بنابراین ما باید پیش از هرچیز شما را به سرور خودتان منتقل کنیم."
+  remote_interaction:
+    favourite:
+      proceed: به سمت پسندیدن این بوق
+      prompt: 'شما می‌خواهید این بوق را بپسندید:'
+    reblog:
+      proceed: به سمت بازبوقیدن
+      prompt: 'شما می‌خواهید این بوق را بازببوقید:'
+    reply:
+      proceed: به سمت پاسخ‌دادن
+      prompt: 'شما می‌خواهید به این بوق پاسخ دهید:'
   remote_unfollow:
     error: خطا
     title: عنوان
     unfollowed: پایان پیگیری
+  scheduled_statuses:
+    over_daily_limit: شما از حد مجاز %{limit} بوق زمان‌بندی‌شده در آن روز فراتر رفته‌اید
+    over_total_limit: شما از حد مجاز %{limit} بوق زمان‌بندی‌شده فراتر رفته‌اید
+    too_soon: زمان تعیین‌شده باید در آینده باشد
   sessions:
-    activity: آخرین کنش
+    activity: آخرین فعالیت
     browser: مرورگر
     browsers:
       alipay: Alipay
-      blackberry: Blackberry
-      chrome: Chrome
-      edge: Microsoft Edge
-      electron: Electron
-      firefox: Firefox
+      blackberry: بلک‌بری
+      chrome: کروم
+      edge: مایکروسافت اج
+      electron: الکترون
+      firefox: فایرفاکس
       generic: مرورگر ناشناخته
-      ie: Internet Explorer
-      micro_messenger: MicroMessenger
+      ie: اینترنت اکسپلورر
+      micro_messenger: مایکرومسنجر
       nokia: Nokia S40 Ovi Browser
-      opera: Opera
+      opera: اپرا
       otter: Otter
       phantom_js: PhantomJS
       qq: QQ Browser
-      safari: Safari
+      safari: سافاری
       uc_browser: UCBrowser
       weibo: Weibo
     current_session: نشست فعلی
@@ -702,35 +851,40 @@ fa:
     ip: IP
     platforms:
       adobe_air: Adobe Air
-      android: Android
-      blackberry: Blackberry
+      android: اندروید
+      blackberry: بلک‌بری
       chrome_os: ChromeOS
       firefox_os: Firefox OS
       ios: iOS
-      linux: Linux
-      mac: Mac
+      linux: لینوکس
+      mac: Ù…Ú©
       other: سیستم ناشناخته
-      windows: Windows
+      windows: ویندوز
       windows_mobile: Windows Mobile
       windows_phone: Windows Phone
     revoke: لغو کردن
     revoke_success: نشست با موفقیت لغو شد
     title: نشست‌ها
   settings:
+    account: حساب
+    account_settings: تنظیمات حساب
+    appearance: نما
     authorized_apps: برنامه‌های مجاز
     back: بازگشت به ماستدون
     delete: پاک‌کردن حساب
     development: فرابری
     edit_profile: ویرایش نمایه
     export: برون‌سپاری داده‌ها
-    followers: پیگیران مورد تأیید
+    featured_tags: برچسب‌های منتخب
+    identity_proofs: مدرک شناسه‌ها
     import: درون‌ریزی
+    import_and_export: درون‌ریزی و برون‌بری
     migrate: انتقال حساب
     notifications: اعلان‌ها
     preferences: ترجیحات
-    settings: تنظیمات
+    profile: نمایه
+    relationships: پیگیری‌ها و پیگیران
     two_factor_authentication: ورود دومرحله‌ای
-    your_apps: برنامهٔ شما
   statuses:
     attached:
       description: 'پیوست‌شده: %{attached}'
@@ -753,6 +907,11 @@ fa:
       ownership: نوشته‌های دیگران را نمی‌توان ثابت کرد
       private: نوشته‌های غیرعمومی را نمی‌توان ثابت کرد
       reblog: بازبوق‌ها را نمی‌توان ثابت کرد
+    poll:
+      total_votes:
+        one: "%{count} رأی"
+        other: "%{count} رأی"
+      vote: رأی
     show_more: نمایش
     sign_in_to_participate: برای شرکت در گفتگو وارد حساب خود شوید
     title: '%{name}: "%{quote}"'
@@ -768,10 +927,91 @@ fa:
     reblogged: بازبوقید
     sensitive_content: محتوای حساس
   terms:
+    body_html: |
+      <h2>سیاست رازداری</h2>
+      <h3 id="collect">What information do we collect?</h3>
+
+      <ul>
+      <li><em>Basic account information</em>: If you register on this server, you may be asked to enter a username, an e-mail address and a password. You may also enter additional profile information such as a display name and biography, and upload a profile picture and header image. The username, display name, biography, profile picture and header image are always listed publicly.</li>
+      <li><em>Posts, following and other public information</em>: The list of people you follow is listed publicly, the same is true for your followers. When you submit a message, the date and time is stored as well as the application you submitted the message from. Messages may contain media attachments, such as pictures and videos. Public and unlisted posts are available publicly. When you feature a post on your profile, that is also publicly available information. Your posts are delivered to your followers, in some cases it means they are delivered to different servers and copies are stored there. When you delete posts, this is likewise delivered to your followers. The action of reblogging or favouriting another post is always public.</li>
+      <li><em>Direct and followers-only posts</em>: All posts are stored and processed on the server. Followers-only posts are delivered to your followers and users who are mentioned in them, and direct posts are delivered only to users mentioned in them. In some cases it means they are delivered to different servers and copies are stored there. We make a good faith effort to limit the access to those posts only to authorized persons, but other servers may fail to do so. Therefore it's important to review servers your followers belong to. You may toggle an option to approve and reject new followers manually in the settings. <em>Please keep in mind that the operators of the server and any receiving server may view such messages</em>, and that recipients may screenshot, copy or otherwise re-share them. <em>Do not share any dangerous information over Mastodon.</em></li>
+      <li><em>IPs and other metadata</em>: When you log in, we record the IP address you log in from, as well as the name of your browser application. All the logged in sessions are available for your review and revocation in the settings. The latest IP address used is stored for up to 12 months. We also may retain server logs which include the IP address of every request to our server.</li>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="use">What do we use your information for?</h3>
+
+      <p>Any of the information we collect from you may be used in the following ways:</p>
+
+      <ul>
+      <li>To provide the core functionality of Mastodon. You can only interact with other people's content and post your own content when you are logged in. For example, you may follow other people to view their combined posts in your own personalized home timeline.</li>
+      <li>To aid moderation of the community, for example comparing your IP address with other known ones to determine ban evasion or other violations.</li>
+      <li>The email address you provide may be used to send you information, notifications about other people interacting with your content or sending you messages, and to respond to inquiries, and/or other requests or questions.</li>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="protect">How do we protect your information?</h3>
+
+      <p>We implement a variety of security measures to maintain the safety of your personal information when you enter, submit, or access your personal information. Among other things, your browser session, as well as the traffic between your applications and the API, are secured with SSL, and your password is hashed using a strong one-way algorithm. You may enable two-factor authentication to further secure access to your account.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="data-retention">What is our data retention policy?</h3>
+
+      <p>We will make a good faith effort to:</p>
+
+      <ul>
+      <li>Retain server logs containing the IP address of all requests to this server, in so far as such logs are kept, no more than 90 days.</li>
+      <li>Retain the IP addresses associated with registered users no more than 12 months.</li>
+      </ul>
+
+      <p>You can request and download an archive of your content, including your posts, media attachments, profile picture, and header image.</p>
+
+      <p>You may irreversibly delete your account at any time.</p>
+
+      <hr class="spacer"/>
+
+      <h3 id="cookies">Do we use cookies?</h3>
+
+      <p>Yes. Cookies are small files that a site or its service provider transfers to your computer's hard drive through your Web browser (if you allow). These cookies enable the site to recognize your browser and, if you have a registered account, associate it with your registered account.</p>
+
+      <p>We use cookies to understand and save your preferences for future visits.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="disclose">Do we disclose any information to outside parties?</h3>
+
+      <p>We do not sell, trade, or otherwise transfer to outside parties your personally identifiable information. This does not include trusted third parties who assist us in operating our site, conducting our business, or servicing you, so long as those parties agree to keep this information confidential. We may also release your information when we believe release is appropriate to comply with the law, enforce our site policies, or protect ours or others rights, property, or safety.</p>
+
+      <p>Your public content may be downloaded by other servers in the network. Your public and followers-only posts are delivered to the servers where your followers reside, and direct messages are delivered to the servers of the recipients, in so far as those followers or recipients reside on a different server than this.</p>
+
+      <p>When you authorize an application to use your account, depending on the scope of permissions you approve, it may access your public profile information, your following list, your followers, your lists, all your posts, and your favourites. Applications can never access your e-mail address or password.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="children">Site usage by children</h3>
+
+      <p>If this server is in the EU or the EEA: Our site, products and services are all directed to people who are at least 16 years old. If you are under the age of 16, per the requirements of the GDPR (<a href="https://en.wikipedia.org/wiki/General_Data_Protection_Regulation">General Data Protection Regulation</a>) do not use this site.</p>
+
+      <p>If this server is in the USA: Our site, products and services are all directed to people who are at least 13 years old. If you are under the age of 13, per the requirements of COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) do not use this site.</p>
+
+      <p>Law requirements can be different if this server is in another jurisdiction.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="changes">Changes to our Privacy Policy</h3>
+
+      <p>If we decide to change our privacy policy, we will post those changes on this page.</p>
+
+      <p>This document is CC-BY-SA. It was last updated March 7, 2018.</p>
+
+      <p>Originally adapted from the <a href="https://github.com/discourse/discourse">Discourse privacy policy</a>.</p>
     title: شرایط استفاده و سیاست رازداری %{instance}
   themes:
-    contrast: کنتراست بالا
-    default: ماستدون
+    contrast: ماستدون (کنتراست بالا)
+    default: ماستدون (تیره)
     mastodon-light: ماستدون (روشن)
   time:
     formats:
@@ -798,6 +1038,22 @@ fa:
       explanation: شما یک نسخهٔ پشتیبان کامل از حساب خود را درخواست کردید. این پشتیبان الان آمادهٔ بارگیری است!
       subject: بایگانی شما آمادهٔ دریافت است
       title: گرفتن بایگانی
+    warning:
+      explanation:
+        disable: تا وقتی حساب شما متوقف باشد، داده‌های شما دست‌نخورده باقی می‌مانند، ولی تا وقتی که حسابتان باز نشده، نمی‌توانید هیچ کاری با آن بکنید.
+        silence: تا وقتی حساب شما محدود باشد، تنها کسانی که از قبل پیگیر شما بودند نوشته‌های شما در این سرور را می‌بینند و شما در فهرست‌های عمومی دیده نمی‌شوید. ولی دیگران همچنان می‌توانند به دلخواه خودشان پیگیر شما شوند.
+        suspend: حساب شما معلق شده است، و همهٔ نوشته‌ها و رسانه‌های تصویری شما به طور بازگشت‌ناپذیری پاک شده‌اند؛ چه از این سرور و چه از سرورهای دیگری که از آن‌ها پیگیر داشتید.
+      review_server_policies: مرور سیاست‌های این سرور
+      subject:
+        disable: حساب %{acct} شما متوقف شده است
+        none: هشدار برای %{acct}
+        silence: حساب %{acct} شما محدود شده است
+        suspend: حساب %{acct}  شما معلق شده است
+      title:
+        disable: حساب متوقف شده است
+        none: هشدار
+        silence: حساب محدود شده است
+        suspend: حساب معلق شده است
     welcome:
       edit_profile_action: تنظیم نمایه
       edit_profile_step: 'شما می‌توانید نمایهٔ خود را به دلخواه خود تغییر دهید: می‌توانید تصویر نمایه، تصویر پس‌زمینه، نام، و چیزهای دیگری را تعیین کنید. اگر بخواهید، می‌توانید حساب خود را خصوصی کنید تا فقط کسانی که شما اجازه می‌دهید بتوانند پیگیر حساب شما شوند.'
diff --git a/config/locales/fi.yml b/config/locales/fi.yml
index 4b5635622877f3d91c8ef77fbcad8b607b0de2fd..e0dc0f756e5912420bf5243aa4c761aaa13d27b2 100644
--- a/config/locales/fi.yml
+++ b/config/locales/fi.yml
@@ -5,43 +5,46 @@ fi:
     about_mastodon_html: Mastodon on sosiaalinen verkosto. Se on toteutettu avoimilla verkkoprotokollilla ja vapailla, avoimen lähdekoodin ohjelmistoilla, ja se toimii hajautetusti samaan tapaan kuin sähköposti.
     about_this: Tietoja tästä palvelimesta
     administered_by: 'Ylläpitäjä:'
-    closed_registrations: Tähän instanssiin ei voi tällä hetkellä rekisteröityä. Voit kuitenkin luoda tilin johonkin toiseen instanssiin ja käyttää samaa verkostoa sitä kautta.
+    apps: Mobiili sovellukset
     contact: Ota yhteyttä
     contact_missing: Ei asetettu
     contact_unavailable: Ei saatavilla
+    documentation: Dokumentaatio
     extended_description_html: |
       <h3>Hyvä paikka säännöille</h3>
       <p>Pidempää kuvausta ei ole vielä laadittu.</p>
-    features:
-      humane_approach_body: Mastodonissa otetaan oppia muiden verkostojen virheistä, ja sen suunnittelussa pyritään toimimaan eettisesti ja ehkäisemään sosiaalisen median väärinkäyttöä.
-      humane_approach_title: Ihmisläheisempi ote
-      not_a_product_body: Mastodon ei ole kaupallinen verkosto. Ei mainoksia, ei tiedonlouhintaa, ei suljettuja protokollia. Mastodonissa ei ole keskusjohtoa.
-      not_a_product_title: Olet henkilö, et tuote
-      real_conversation_body: 'Voit ilmaista itseäsi niin kuin itse haluat: tilaa on 65535 merkkiä, ja sisältövaroituksia voi tehdä monin tavoin.'
-      real_conversation_title: Tehty oikeaa keskustelua varten
-      within_reach_body: Rajapintoja on tarjolla moniin eri kehitysympäristöihin, minkä ansiosta iOS:lle, Androidille ja muille alustoille on saatavana useita eri sovelluksia. Näin voit pitää yhteyttä ystäviisi missä vain.
-      within_reach_title: Aina lähellä
     generic_description: "%{domain} on yksi verkostoon kuuluvista palvelimista"
     hosted_on: Mastodon palvelimella %{domain}
     learn_more: Lisätietoja
-    other_instances: Muut palvelimet
+    privacy_policy: Tietosuojaseloste
     source_code: Lähdekoodi
-    status_count_after: statusta
+    status_count_after:
+      one: tila
+      other: tilanne
     status_count_before: He ovat luoneet
-    user_count_after: käyttäjälle
+    terms: Käyttöehdot
+    user_count_after:
+      one: käyttäjä
+      other: käyttäjät
     user_count_before: Koti
     what_is_mastodon: Mikä on Mastodon?
   accounts:
+    choices_html: "%{name} valinnat:"
     follow: Seuraa
-    followers: Seuraajat
+    followers:
+      one: Seuraaja
+      other: Seuraajat
     following: Seuratut
-    media: Media
+    joined: Liittynyt %{date}
+    last_active: viimeksi aktiivinen
+    link_verified_on: Tämän linkin omistus on tarkastettu %{date}
     moved_html: "%{name} on muuttanut osoitteeseen %{new_profile_link}:"
     network_hidden: Nämä tiedot eivät ole käytettävissä
     nothing_here: Täällä ei ole mitään!
     people_followed_by: Henkilöt, joita %{name} seuraa
     people_who_follow: Käyttäjän %{name} seuraajat
-    posts: Tuuttaukset
+    pin_errors:
+      following: Sinun täytyy seurata henkilöä jota haluat tukea
     posts_with_replies: Tuuttaukset ja vastaukset
     reserved_username: Käyttäjänimi on varattu
     roles:
@@ -84,7 +87,6 @@ fi:
       followers_url: Seuraajien osoite
       follows: Seuraa
       inbox_url: Saapuvan postilaatikon osoite
-      ip: IP
       location:
         all: Kaikki
         local: Paikalliset
@@ -139,7 +141,6 @@ fi:
       undo_suspension: Peru jäähy
       unsubscribe: Lopeta tilaus
       username: Käyttäjänimi
-      web: Web
     action_logs:
       actions:
         assigned_to_self_report: "%{name} otti raportin %{target} tehtäväkseen"
@@ -180,7 +181,6 @@ fi:
       destroyed_msg: Emojon poisto onnistui!
       disable: Poista käytöstä
       disabled_msg: Emojin poisto käytöstä onnistui
-      emoji: Emoji
       enable: Ota käyttöön
       enabled_msg: Emojin käyttöönotto onnistui
       image_hint: PNG enintään 50 kt
@@ -297,9 +297,6 @@ fi:
         min_invite_role:
           disabled: Ei kukaan
           title: Salli kutsut käyttäjältä
-        open:
-          desc_html: Salli kenen tahansa luoda tili
-          title: Avoin rekisteröinti
       show_known_fediverse_at_about_page:
         desc_html: Kun tämä on valittu, esikatselussa näytetään tuuttaukset kaikkialta tunnetusta fediversumista. Muutoin näytetään vain paikalliset tuuttaukset.
         title: Näytä aikajanan esikatselussa koko tunnettu fediversumi
@@ -330,8 +327,6 @@ fi:
         nsfw_off: NSFW POIS
         nsfw_on: NSFW PÄÄLLÄ
       failed_to_execute: Suoritus epäonnistui
-      media:
-        title: Media
       no_media: Ei mediaa
       title: Tilin tilat
       with_media: Sisältää mediaa
@@ -340,7 +335,6 @@ fi:
       confirmed: Vahvistettu
       expires_in: Vanhenee
       last_delivery: Viimeisin toimitus
-      title: WebSub
       topic: Aihe
     title: Ylläpito
   admin_mailer:
@@ -350,7 +344,6 @@ fi:
       subject: Uusi raportti instanssista %{instance} (nro %{id})
   application_mailer:
     notification_preferences: Muuta sähköpostiasetuksia
-    salutation: "%{name},"
     settings: 'Muuta sähköpostiasetuksia: %{link}'
     view: 'Näytä:'
     view_profile: Näytä profiili
@@ -364,7 +357,6 @@ fi:
     warning: Säilytä tietoa hyvin. Älä milloinkaan jaa sitä muille!
     your_token: Pääsytunnus
   auth:
-    agreement_html: Rekisteröityessäsi sitoudut noudattamaan <a href="%{rules_path}">instanssin sääntöjä</a> ja <a href="%{terms_path}">käyttöehtoja</a>.
     change_password: Salasana
     confirm_email: Vahvista sähköpostiosoite
     delete_account: Poista tili
@@ -376,13 +368,8 @@ fi:
     logout: Kirjaudu ulos
     migrate_account: Muuta toiseen tiliin
     migrate_account_html: Jos haluat ohjata tämän tilin toiseen tiliin, voit <a href="%{path}">asettaa toisen tilin tästä</a>.
-    or: tai
     or_log_in_with: Tai käytä kirjautumiseen
-    providers:
-      cas: CAS
-      saml: SAML
     register: Rekisteröidy
-    register_elsewhere: Rekisteröidy toiselle palvelimelle
     resend_confirmation: Lähetä vahvistusohjeet uudestaan
     reset_password: Palauta salasana
     security: Tunnukset
@@ -441,22 +428,9 @@ fi:
       request: Pyydä arkisto
       size: Koko
     blocks: Estot
-    csv: CSV
     follows: Seurattavat
     mutes: Mykistetyt
     storage: Media-arkisto
-  followers:
-    domain: Verkkotunnus
-    explanation_html: Jos haluat olla varma tilapäivitystesi yksityisyydestä, sinun täytyy tietää, ketkä seuraavat sinua. <strong>Yksityiset tilapäivityksesi lähetetään kaikkiin niihin instansseihin, joissa sinulla on seuraajia</strong>. Jos et luota siihen, että näiden instanssien ylläpitäjät tai ohjelmisto kunnioittavat yksityisyyttäsi, käy läpi seuraajaluettelosi ja poista tarvittaessa käyttäjiä.
-    followers_count: Seuraajien määrä
-    lock_link: Lukitse tili
-    purge: Poista seuraajista
-    success:
-      one: Estetään kevyesti seuraajia yhdestä verkkotunnuksesta...
-      other: Estetään kevyesti seuraajia %{count} verkkotunnuksesta...
-    true_privacy_html: Muista, että <strong>kunnollinen yksityisyys voidaan varmistaa vain päästä päähän -salauksella</strong>.
-    unlocked_warning_html: Kuka tahansa voi seurata sinua ja nähdä saman tien yksityiset tilapäivityksesi. %{lock_link}, niin voit tarkastaa ja torjua seuraajia.
-    unlocked_warning_title: Tiliäsi ei ole lukittu
   generic:
     changes_saved_msg: Muutosten tallennus onnistui!
     save_changes: Tallenna muutokset
@@ -547,22 +521,16 @@ fi:
         format: "%n %u"
         units:
           billion: Mrd
-          million: M
           quadrillion: Brd
           thousand: k
           trillion: B
-          unit: ''
   pagination:
     newer: Uudemmat
     next: Seuraava
     older: Vanhemmat
     prev: Edellinen
-    truncate: "&hellip;"
   preferences:
-    languages: Kielet
     other: Muut
-    publishing: Julkaiseminen
-    web: Web
   remote_follow:
     acct: Syötä se käyttäjätunnus@verkkotunnus, josta haluat seurata
     missing_resource: Vaadittavaa uudelleenohjaus-URL:ää tiliisi ei löytynyt
@@ -574,40 +542,13 @@ fi:
     activity: Viimeisin toiminta
     browser: Selain
     browsers:
-      alipay: Alipay
-      blackberry: Blackberry
-      chrome: Chrome
-      edge: Microsoft Edge
-      electron: Electron
-      firefox: Firefox
       generic: Tuntematon selain
-      ie: Internet Explorer
-      micro_messenger: MicroMessenger
       nokia: Nokia S40 Ovi -selain
-      opera: Opera
-      otter: Otter
-      phantom_js: PhantomJS
-      qq: QQ Browser
-      safari: Safari
-      uc_browser: UCBrowser
-      weibo: Weibo
     current_session: Nykyinen istunto
     description: "%{browser}, %{platform}"
     explanation: Nämä verkkoselaimet ovat tällä hetkellä kirjautuneet Mastodon-tilillesi.
-    ip: IP
     platforms:
-      adobe_air: Adobe Air
-      android: Android
-      blackberry: Blackberry
-      chrome_os: ChromeOS
-      firefox_os: Firefox OS
-      ios: iOS
-      linux: Linux
-      mac: Mac
       other: tuntematon järjestelmä
-      windows: Windows
-      windows_mobile: Windows Mobile
-      windows_phone: Windows Phone
     revoke: Hylkää
     revoke_success: Istunnon hylkäys onnistui
     title: Istunnot
@@ -618,23 +559,17 @@ fi:
     development: Kehittäminen
     edit_profile: Muokkaa profiilia
     export: Vie tietoja
-    followers: Valtuutetut seuraajat
     import: Tuo
     migrate: Tilin muutto muualle
     notifications: Ilmoitukset
     preferences: Ominaisuudet
-    settings: Asetukset
     two_factor_authentication: Kaksivaiheinen todentaminen
-    your_apps: Omat sovellukset
   statuses:
     attached:
       description: 'Liitetty: %{attached}'
       image:
         one: "%{count} kuva"
         other: "%{count} kuvaa"
-      video:
-        one: "%{count} video"
-        other: "%{count} videota"
     content_warning: 'Sisältövaroitus: %{warning}'
     disallowed_hashtags:
       one: 'sisälsi aihetunnisteen jota ei sallita: %{tags}'
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index cbff58d918085e62404dffb2860deeac018bc3de..5c15ab6a4282870b9a29a07d68884187df335823 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -4,37 +4,37 @@ fr:
     about_hashtag_html: Figurent ci-dessous les pouets tagués avec <strong>#%{hashtag}</strong>. Vous pouvez interagir avec eux si vous avez un compte n’importe où dans le Fediverse.
     about_mastodon_html: Mastodon est un réseau social utilisant des formats ouverts et des logiciels libres. Comme le courriel, il est décentralisé.
     about_this: À propos
+    active_count_after: actif·ve·s
+    active_footnote: Utilisateur·rice·s actif·ve·s mensuels (MAU)
     administered_by: 'Administrée par :'
     api: API
     apps: Applications mobiles
-    closed_registrations: Les inscriptions sont actuellement fermées sur cette instance. Cependant, vous pouvez trouver une autre instance sur laquelle vous créer un compte et à partir de laquelle vous pourrez accéder au même réseau.
+    apps_platforms: Utilisez Mastodon depuis iOS, Android et d’autres plates-formes
+    browse_directory: Parcourir l’annuaire des profils et filtrer par centres d’intérêt
+    browse_public_posts: Parcourir un flux en direct de messages publics sur Mastodon
     contact: Contact
     contact_missing: Manquant
     contact_unavailable: Non disponible
+    discover_users: Découvrez des utilisateur·rice·s
     documentation: Documentation
     extended_description_html: |
       <h3>Un bon endroit pour les règles</h3>
       <p>La description étendue n’a pas été remplie.</p>
-    features:
-      humane_approach_body: Ayant appris des échecs d’autres réseaux, Mastodon à l’ambition de combattre l’abus des médias sociaux en effectuant des choix de conception éthiques.
-      humane_approach_title: Une approche plus humaine
-      not_a_product_body: Mastodon n’est pas un réseau commercial. Ici, pas de publicités, pas de prospection de données et pas d’environnements fermés. Il n’y existe aucune autorité centrale.
-      not_a_product_title: Vous êtes une personne, pas un produit
-      real_conversation_body: Avec 65535 caractères à votre disposition, une grande granularité en termes de diffusion et la possibilité de masquer vos messages derrière des avertissements, vous êtes libre de vous exprimer de la manière qui vous plaît.
-      real_conversation_title: Construit pour de vraies conversations
-      within_reach_body: Grâce à l’existence d’un environnement API accueillant pour les développeur·se·s, de multiples applications pour iOS, Android et d’autres plateformes vous permettent de rester en contact avec vos ami·e·s où que vous soyez.
-      within_reach_title: Toujours à portée de main
+    federation_hint_html: Avec un compte sur %{instance}, vous pourrez suivre les gens sur n’importe quel serveur Mastodon et au-delà.
     generic_description: "%{domain} est seulement un serveur du réseau"
-    hosted_on: Instance Mastodon hébergée par %{domain}
+    get_apps: Essayez une application mobile
+    hosted_on: Serveur Mastodon hébergée par %{domain}
     learn_more: En savoir plus
-    other_instances: Liste des instances
     privacy_policy: Politique de vie privée
+    see_whats_happening: Voir ce qui se passe
+    server_stats: 'Statistiques du serveur :'
     source_code: Code source
     status_count_after:
       one: Statut
       other: Statuts
     status_count_before: Ayant publié
-    terms: Conditions d'utilisation
+    tagline: Suivez vos ami·e·s et découvrez en de nouveaux·elles
+    terms: Conditions d’utilisation
     user_count_after:
       one: utilisateur
       other: utilisateurs
@@ -68,6 +68,7 @@ fr:
       admin: Admin
       bot: Robot
       moderator: Modérateur·trice
+    unavailable: Profil non disponible
     unfollow: Ne plus suivre
   admin:
     account_actions:
@@ -79,6 +80,8 @@ fr:
       delete: Supprimer
       destroyed_msg: Note de modération supprimée avec succès !
     accounts:
+      approve: Approuver
+      approve_all: Tout approuver
       are_you_sure: Êtes-vous certain⋅e ?
       avatar: Avatar
       by_domain: Domaine
@@ -92,7 +95,7 @@ fr:
       confirm: Confirmer
       confirmed: Confirmé
       confirming: Confirmation
-      deleted: Effacé
+      deleted: Supprimé
       demote: Rétrograder
       disable: Désactiver
       disable_two_factor_authentication: Désactiver l’authentification à deux facteurs
@@ -112,6 +115,7 @@ fr:
       inbox_url: URL d’entrée
       invited_by: Invité par
       ip: Adresse IP
+      joined: Inscrit·e depuis
       location:
         all: Tous
         local: Local
@@ -123,15 +127,18 @@ fr:
       moderation:
         active: Actif
         all: Tous
+        pending: En cours de traitement
         silenced: Masqués
         suspended: Suspendus
         title: Modération
       moderation_notes: Notes de modération
       most_recent_activity: Dernière activité
       most_recent_ip: Adresse IP la plus récente
+      no_account_selected: Aucun compte n’a été modifié, car aucun n’a été sélectionné
       no_limits_imposed: Aucune limite imposée
       not_subscribed: Non abonné
       outbox_url: URL de sortie
+      pending: En attente d’approbation
       perform_full_suspension: Suspendre
       profile_url: URL du profil
       promote: Promouvoir
@@ -139,8 +146,10 @@ fr:
       public: Publique
       push_subscription_expires: Expiration de l’abonnement PuSH
       redownload: Rafraîchir le profil
+      reject: Rejeter
+      reject_all: Tout rejeter
       remove_avatar: Supprimer l’avatar
-      remove_header: Supprimer l'entête
+      remove_header: Supprimer l’entête
       resend_confirmation:
         already_confirmed: Cet·te utilisateur·ice est déjà confirmé·e
         send: Renvoyer un courriel de confirmation
@@ -159,18 +168,20 @@ fr:
       shared_inbox_url: URL de la boite de réception partagée
       show:
         created_reports: Signalements faits
-        targeted_reports: Signalés par d'autres
+        targeted_reports: Signalés par d’autres
       silence: Masquer
       silenced: Silencié
       statuses: Statuts
       subscribe: S’abonner
       suspended: Suspendu
+      time_in_queue: En file d’attente %{time}
       title: Comptes
       unconfirmed_email: Courriel non-confirmé
       undo_silenced: Démasquer
       undo_suspension: Annuler la suspension
       unsubscribe: Se désabonner
       username: Nom d’utilisateur⋅ice
+      warn: Avertissement
       web: Web
     action_logs:
       actions:
@@ -182,7 +193,7 @@ fr:
         create_domain_block: "%{name} a bloqué le domaine %{target}"
         create_email_domain_block: "%{name} a mis le domaine du courriel %{target} sur liste noire"
         demote_user: "%{name} a rétrogradé l’utilisateur·ice %{target}"
-        destroy_custom_emoji: "%{name} a détruit l'émoticône %{target}"
+        destroy_custom_emoji: "%{name} a détruit l’émoticône %{target}"
         destroy_domain_block: "%{name} a débloqué le domaine %{target}"
         destroy_email_domain_block: "%{name} a mis le domaine du courriel %{target} sur liste blanche"
         destroy_status: "%{name} a enlevé le statut de %{target}"
@@ -239,6 +250,7 @@ fr:
       feature_profile_directory: Annuaire des profils
       feature_registrations: Inscriptions
       feature_relay: Relais de fédération
+      feature_timeline_preview: Aperçu du fil public
       features: Fonctionnalités
       hidden_service: Fédération avec des services cachés
       open_reports: signalements non résolus
@@ -258,21 +270,22 @@ fr:
       created_msg: Le blocage de domaine est désormais activé
       destroyed_msg: Le blocage de domaine a été désactivé
       domain: Domaine
+      existing_domain_block_html: Vous avez déjà imposé des limites plus strictes à %{name}, vous devez d’abord le <a href="%{unblock_url}">débloquer</a>.
       new:
         create: Créer le blocage
         hint: Le blocage de domaine n’empêchera pas la création de comptes dans la base de données, mais il appliquera automatiquement et rétrospectivement des méthodes de modération spécifiques sur ces comptes.
         severity:
-          desc_html: "<strong>Silence</strong> rendra les messages des comptes concernés invisibles à ceux qui ne les suivent pas. <strong>Suspendre</strong> supprimera tout le contenu des comptes concernés, les médias, et les données du profil. Utilisez <strong>Aucun</strong> si vous voulez simplement rejeter les fichiers multimédia."
+          desc_html: "<strong>Masqué</strong> rendra les messages des comptes concernés invisibles à ceux qui ne les suivent pas. <strong>Suspendre</strong> supprimera tout le contenu des comptes concernés, les médias, et les données du profil. Utilisez <strong>Aucune</strong> si vous voulez simplement rejeter les fichiers multimédia."
           noop: Aucune
           silence: Masqué
           suspend: Suspendre
         title: Nouveau blocage de domaine
       reject_media: Fichiers média rejetés
       reject_media_hint: Supprime localement les fichiers média stockés et refuse d’en télécharger ultérieurement. Ne concerne pas les suspensions
-      reject_reports: Rapports de rejet
-      reject_reports_hint: Ignorez tous les rapports provenant de ce domaine. Sans objet pour les suspensions
+      reject_reports: Rejeter les signalements
+      reject_reports_hint: Ignorez tous les signalements provenant de ce domaine. Ne concerne pas les suspensions
       rejecting_media: rejet des fichiers multimédia
-      rejecting_reports: rejet de rapports
+      rejecting_reports: rejet des signalements
       severity:
         silence: silencié
         suspend: suspendu
@@ -300,6 +313,8 @@ fr:
       back_to_account: Retour au compte
       title: Abonné⋅e⋅s de %{acct}
     instances:
+      by_domain: Domaine
+      delivery_available: Livraison disponible
       known_accounts:
         one: "%{count} compte connu"
         other: "%{count} comptes connus"
@@ -321,17 +336,19 @@ fr:
         expired: Expiré
         title: Filtre
       title: Invitations
+    pending_accounts:
+      title: Comptes en attente (%{count})
     relays:
       add_new: Ajouter un nouveau relais
       delete: Effacer
-      description_html: Un <strong>relai de fédération</strong> est un serveur intermédiaire qui échange de grandes quantités de pouets entre les serveurs qui publient dessus et ceux qui y sont abonnés. <strong>Il peut aider les petites et moyennes instances à découvrir du contenu sur le fediverse</strong>, ce qui normalement nécessiterait que les membres locaux suivent des gens inscrits sur des serveurs distants.
+      description_html: Un <strong>relai de fédération</strong> est un serveur intermédiaire qui échange de grandes quantités de pouets entre les serveurs qui publient dessus et ceux qui y sont abonnés. <strong>Il peut aider les petits et moyen serveurs à découvrir du contenu sur le fediverse</strong>, ce qui normalement nécessiterait que les membres locaux suivent des gens inscrits sur des serveurs distants.
       disable: Désactiver
       disabled: Désactivé
       enable: Activé
       enable_hint: Une fois activé, votre serveur souscrira à tous les pouets publics présents sur ce relais et y enverra ses propres pouets publics.
       enabled: Activé
       inbox_url: URL de relais
-      pending: En attente de l'approbation du relai
+      pending: En attente de l’approbation du relai
       save_and_enable: Sauvegarder et activer
       setup: Paramétrer une connexion de relais
       status: Statut
@@ -380,23 +397,23 @@ fr:
         email: Entrez une adresse courriel publique
         username: Entrez un nom d’utilisateur⋅ice
       custom_css:
-        desc_html: Modifier l'apparence avec une CSS chargée sur chaque page
-        title: CSS personnalisée
+        desc_html: Modifier l’apparence avec une CSS chargée sur chaque page
+        title: CSS personnalisé
       hero:
-        desc_html: Affichée sur la page d’accueil. Au moins 600x100px recommandé. Lorsqu’elle n’est pas définie, se rabat sur la vignette de l’instance
+        desc_html: Affichée sur la page d’accueil. Au moins 600x100px recommandé. Lorsqu’elle n’est pas définie, se rabat sur la vignette du serveur
         title: Image d’en-tête
       mascot:
-        desc_html: Affiché sur plusieurs pages. Au moins 293×205px recommandé. Lorsqu'il n'est pas défini, retombe à la mascotte par défaut
+        desc_html: Affiché sur plusieurs pages. Au moins 293×205px recommandé. Lorsqu’il n’est pas défini, retombe à la mascotte par défaut
         title: Image de la mascotte
       peers_api_enabled:
-        desc_html: Noms des domaines que cette instance a découvert dans le fediverse
-        title: Publier la liste des instances découvertes
+        desc_html: Noms des domaines que ce serveur a découvert dans le fediverse
+        title: Publier la liste des serveurs découverts
       preview_sensitive_media:
         desc_html: Les liens de prévisualisation sur les autres sites web afficheront une vignette même si le média est sensible
         title: Afficher les médias sensibles dans les prévisualisations OpenGraph
       profile_directory:
-        desc_html: Permettre aux utilisateurs d'être découverts
-        title: Activer l'annuaire des profils
+        desc_html: Permettre aux utilisateurs d’être découverts
+        title: Activer l’annuaire des profils
       registrations:
         closed_message:
           desc_html: Affiché sur la page d’accueil lorsque les inscriptions sont fermées<br>Vous pouvez utiliser des balises HTML
@@ -407,35 +424,38 @@ fr:
         min_invite_role:
           disabled: Personne
           title: Autoriser les invitations par
-        open:
-          desc_html: Autoriser tout le monde à créer un compte
-          title: Ouvrir les inscriptions
+      registrations_mode:
+        modes:
+          approved: Approbation requise pour s’inscrire
+          none: Personne ne peut s’inscrire
+          open: N’importe qui peut s’inscrire
+        title: Mode d’enregistrement
       show_known_fediverse_at_about_page:
-        desc_html: Lorsque l’option est activée, les pouets provenant de toutes les instances connues sont affichés dans la prévisualisation. Sinon, seuls les pouets locaux sont affichés.
+        desc_html: Lorsque l’option est activée, les pouets provenant de toutes les serveurs connues sont affichés dans la prévisualisation. Sinon, seuls les pouets locaux sont affichés.
         title: Afficher le fediverse connu dans la prévisualisation du fil
       show_staff_badge:
         desc_html: Montrer un badge de responsable sur une page utilisateur·ice
         title: Montrer un badge de responsable
       site_description:
         desc_html: Paragraphe introductif sur la page d’accueil. Décrivez ce qui rend spécifique ce serveur Mastodon et toute autre chose importante. Vous pouvez utiliser des balises HTML, en particulier <code>&lt;a&gt;</code> et <code>&lt;em&gt;</code>.
-        title: Description du site
+        title: Description du serveur
       site_description_extended:
-        desc_html: Affichée sur la page d’informations complémentaires du site<br>Vous pouvez utiliser des balises HTML
-        title: Description étendue du site
+        desc_html: L’endroit idéal pour afficher votre code de conduite, les règles, les guides et autres choses qui rendent votre serveur différent. Vous pouvez utiliser des balises HTML
+        title: Description étendue du serveur
       site_short_description:
-        desc_html: Affichée dans la barre latérale et dans les méta-tags. Décrivez ce qui rend spécifique ce serveur Mastodon en un seul paragraphe. Si laissée vide, la description de l’instance sera affiché par défaut.
-        title: Description courte de l’instance
+        desc_html: Affichée dans la barre latérale et dans les méta-tags. Décrivez ce qui rend spécifique ce serveur Mastodon en un seul paragraphe. Si laissée vide, la description du serveur sera affiché par défaut.
+        title: Description courte du serveur
       site_terms:
         desc_html: Affichée sur la page des conditions d’utilisation du site<br>Vous pouvez utiliser des balises HTML
         title: Politique de confidentialité
-      site_title: Titre du site
+      site_title: Nom du serveur
       thumbnail:
         desc_html: Utilisée pour les prévisualisations via OpenGraph et l’API. 1200x630px recommandé
-        title: Vignette de l’instance
+        title: Vignette du serveur
       timeline_preview:
         desc_html: Afficher le fil public sur la page d’accueil
         title: Prévisualisation du fil global
-      title: Paramètres du site
+      title: Paramètres du serveur
     statuses:
       back_to_account: Retour à la page du compte
       batch:
@@ -459,23 +479,32 @@ fr:
     tags:
       accounts: Comptes
       hidden: Masqué
-      hide: Masquer dans l'annuaire
+      hide: Masquer dans l’annuaire
       name: Hashtag
       title: Hashtags
-      unhide: Afficher dans l'annuaire
+      unhide: Afficher dans l’annuaire
       visible: Visible
     title: Administration
     warning_presets:
       add_new: Ajouter un nouveau
       delete: Effacer
       edit: Éditer
-      edit_preset: Éditer la présélection d'attention
-      title: Gérer les présélections d'attention
+      edit_preset: Éditer la présélection d’avertissement
+      title: Gérer les présélections d’avertissement
   admin_mailer:
+    new_pending_account:
+      body: Les détails du nouveau compte se trouvent ci-dessous. Vous pouvez approuver ou rejeter cette demande.
+      subject: Nouveau compte à examiner sur %{instance} (%{username})
     new_report:
       body: "%{reporter} a signalé %{target}"
       body_remote: Quelqu’un de %{domain} a signalé %{target}
       subject: Nouveau signalement sur %{instance} (#%{id})
+  appearance:
+    advanced_web_interface: Interface web avancée
+    advanced_web_interface_hint: 'Si vous voulez utiliser toute la largeur de votre écran, l’interface web avancée vous permet de configurer plusieurs colonnes différentes pour voir autant d’informations que vous le souhaitez en même temps : Accueil, notifications, fil public fédéré, un nombre illimité de listes et hashtags.'
+    animations_and_accessibility: Animations et accessibilité
+    confirmation_dialogs: Dialogues de confirmation
+    sensitive_content: Contenu sensible
   application_mailer:
     notification_preferences: Modifier les préférences de courriel
     salutation: "%{name},"
@@ -492,8 +521,9 @@ fr:
     warning: Soyez prudent⋅e avec ces données. Ne les partagez pas !
     your_token: Votre jeton d’accès
   auth:
-    agreement_html: En cliquant sur "S'inscrire" ci-dessous, vous souscrivez <a href="%{rules_path}">aux règles de l’instance</a> et à <a href="%{terms_path}">nos conditions d’utilisation</a>.
+    apply_for_account: Demander une invitation
     change_password: Mot de passe
+    checkbox_agreement_html: J’accepte les <a href="%{rules_path}" target="_blank">règles du serveur</a> et les <a href="%{terms_path}" target="_blank">conditions de service</a>
     confirm_email: Confirmer mon adresse mail
     delete_account: Supprimer le compte
     delete_account_html: Si vous désirez supprimer votre compte, vous pouvez <a href="%{path}">cliquer ici</a>. Il vous sera demandé de confirmer cette action.
@@ -504,17 +534,17 @@ fr:
     logout: Se déconnecter
     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: ou
     or_log_in_with: Ou authentifiez-vous avec
     providers:
       cas: CAS
       saml: SAML
     register: S’inscrire
-    register_elsewhere: S’inscrire sur un autre serveur
+    registration_closed: "%{instance} n’accepte pas de nouveaux membres"
     resend_confirmation: Envoyer à nouveau les consignes de confirmation
     reset_password: Réinitialiser le mot de passe
     security: Sécurité
     set_new_password: Définir le nouveau mot de passe
+    trouble_logging_in: Vous avez un problème pour vous connecter ?
   authorize_follow:
     already_following: Vous suivez déjà ce compte
     error: Malheureusement, il y a eu une erreur en cherchant les détails du compte distant
@@ -546,15 +576,15 @@ fr:
     description_html: Cela va supprimer votre compte et le désactiver de manière <strong>permanente et irréversible</strong>. Votre nom d’utilisateur⋅ice restera réservé afin d’éviter la confusion.
     proceed: Supprimer compte
     success_msg: Votre compte a été supprimé avec succès
-    warning_html: Seule la suppression du contenu depuis cette instance est garantie. Le contenu qui a été partagé est susceptible de laisser des traces. Les serveurs hors-ligne ainsi que ceux n’étant plus abonnés à vos publications ne mettront pas leur base de données à jour.
+    warning_html: Seule la suppression du contenu depuis ce serveur est garantie. Le contenu qui a été partagé est susceptible de laisser des traces. Les serveurs hors-ligne ainsi que ceux n’étant plus abonnées à vos publications ne mettront pas leur base de données à jour.
     warning_title: Disponibilité du contenu disséminé
   directories:
     directory: Annuaire des profils
-    enabled: Vous êtes actuellement listé dans l'annuaire.
-    enabled_but_waiting: Vous avez choisi d'être listé dans l'annuaire, mais vous n'avez pas encore le nombre minimum de suiveurs (%{min_followers}) pour y être inscrit.
-    explanation: Découvrir des utilisateurs en se basant sur leurs centres d'intérêt
+    enabled: Vous êtes actuellement listé dans l’annuaire.
+    enabled_but_waiting: Vous avez choisi d’être listé dans l’annuaire, mais vous n’avez pas encore le nombre minimum de suiveurs (%{min_followers}) pour y être inscrit.
+    explanation: Découvrir des utilisateurs en se basant sur leurs centres d’intérêt
     explore_mastodon: Explorer %{title}
-    how_to_enable: Vous n'êtes pas encore inscrit dans l'annuaire. Vous pouvez vous inscrire ci-dessous. Utilisez des hashtags dans votre texte biographique pour être listé sous des hashtags spécifiques !
+    how_to_enable: Vous n’êtes pas encore inscrit dans l’annuaire. Vous pouvez vous inscrire ci-dessous. Utilisez des hashtags dans votre texte biographique pour être listé sous des hashtags spécifiques !
     people:
       one: "%{count} personne"
       other: "%{count} personne"
@@ -570,11 +600,14 @@ fr:
       content: Nous sommes désolé·e·s, mais quelque chose s’est mal passé de notre côté.
       title: Cette page n’est pas correcte
     noscript_html: Pour utiliser Mastodon, veuillez activer JavaScript. Sinon, essayez l’une des <a href="%{apps_path}">applications natives</a> pour Mastodon pour votre plate-forme.
+  existing_username_validator:
+    not_found: n’a pas trouvé d’utilisateur·rice local·e avec ce nom
+    not_found_multiple: n’a pas trouvé %{usernames}
   exports:
     archive_takeout:
       date: Date
       download: Télécharger votre archive
-      hint_html: Vous pouvez demander une archive de vos  <strong>pouets et médias téléversés</strong>. Les données exportées seront au format ActivityPub, lisible par tout logiciel compatible. Vous pouvez demander une archive tous les 7 jours.
+      hint_html: Vous pouvez demander une archive de vos <strong>pouets et médias téléversés</strong>. Les données exportées seront au format ActivityPub, lisible par tout logiciel compatible. Vous pouvez demander une archive tous les 7 jours.
       in_progress: Création de votre archive…
       request: Demandez vos archives
       size: Taille
@@ -585,6 +618,10 @@ fr:
     lists: Listes
     mutes: Vous masquez
     storage: Médias stockés
+  featured_tags:
+    add_new: Ajouter un nouvel hashtag
+    errors:
+      limit: Vous avez déjà mis en avant le nombre maximum de hashtags
   filters:
     contexts:
       home: Accueil
@@ -601,34 +638,50 @@ fr:
       title: Filtres
     new:
       title: Ajouter un nouveau filtre
-  followers:
-    domain: Domaine
-    explanation_html: Si vous voulez être sûr⋅e que vos statuts restent privés, vous devez savoir qui vous suit. <strong>Vos statuts privés seront diffusés à toutes les instances des utilisateur⋅ice⋅s qui vous suivent</strong>. Vous voudrez peut-être les passer en revue et les supprimer si vous n’êtes pas sûr⋅e que votre vie privée sera respectée par l’administration ou le logiciel de ces instances.
-    followers_count: Nombre d’abonné⋅e⋅s
-    lock_link: Rendez votre compte privé
-    purge: Retirer de la liste d’abonné⋅e⋅s
-    success:
-      one: Suppression des abonné⋅e⋅s venant d’un domaine en cours…
-      other: Suppression des abonné⋅e⋅s venant de %{count} domaines en cours…
-    true_privacy_html: Soyez conscient⋅e⋅s <strong>qu’une vraie confidentialité ne peut être atteinte que par un chiffrement de bout-en-bout</strong>.
-    unlocked_warning_html: N’importe qui peut vous suivre et voir vos statuts privés. %{lock_link} afin de pouvoir vérifier et rejeter des abonné⋅e⋅s.
-    unlocked_warning_title: Votre compte n’est pas privé
   footer:
     developers: Développeurs
     more: Davantage…
     resources: Ressources
   generic:
+    all: Tous
     changes_saved_msg: Les modifications ont été enregistrées avec succès !
     copy: Copier
+    order_by: Classer par
     save_changes: Enregistrer les modifications
     validation_errors:
       one: Quelque chose ne va pas ! Vérifiez l’erreur ci-dessous
       other: Certaines choses ne vont pas ! Vérifiez les %{count} erreurs ci-dessous
+  html_validator:
+    invalid_markup: 'contient un balisage HTML invalide: %{error}'
+  identity_proofs:
+    active: Actif
+    authorize: Oui, autoriser
+    authorize_connection_prompt: Autoriser cette connexion chiffrée ?
+    errors:
+      failed: La connexion chiffrée a échoué. Veuillez réessayer à partir de %{provider}.
+      keybase:
+        invalid_token: Les jetons Keybase sont des hachages de signatures et doivent comporter 66 caractères hexadécimaux
+        verification_failed: Keybase ne reconnaît pas ce jeton comme une signature de l’utilisateur Keybase %{kb_username}. Veuillez réessayer à partir de Keybase.
+      wrong_user: Impossible de créer une preuve pour %{proving} lorsque vous êtes connecté en tant que %{current}. Connectez-vous en tant que %{proving} et réessayez.
+    explanation_html: Ici, vous pouvez connecter de manière chiffrée vos autres identités, par exemple un profil Keybase. Cela permet à d’autres personnes de vous envoyer des messages chiffrés et de faire confiance au contenu que vous leur envoyez.
+    i_am_html: Je suis %{username} sur %{service}.
+    identity: Identité
+    inactive: Inactif
+    publicize_checkbox: 'Et le poueter:'
+    publicize_toot: 'C’est prouvé ! Je suis %{username} sur %{service}: %{url}'
+    status: Statut de vérification
+    view_proof: Voir la preuve
   imports:
-    preface: Vous pouvez importer certaines données comme les personnes que vous suivez ou bloquez sur votre compte sur cette instance à partir de fichiers créés sur une autre instance.
+    modes:
+      merge: Fusionner
+      merge_long: Garder les enregistrements existants et ajouter les nouveaux
+      overwrite: Réécrire
+      overwrite_long: Remplacer les enregistrements actuels par les nouveaux
+    preface: Vous pouvez importer certaines données que vous avez exporté d’un autre serveur, comme une liste des personnes que vous suivez ou bloquez sur votre compte.
     success: Vos données ont été importées avec succès et seront traitées en temps et en heure
     types:
       blocking: Liste d’utilisateur⋅ice⋅s bloqué⋅e⋅s
+      domain_blocking: Liste des serveurs bloquées
       following: Liste d’utilisateur⋅ice⋅s suivi⋅e⋅s
       muting: Liste d’utilisateur⋅ice⋅s que vous masquez
     upload: Importer
@@ -650,7 +703,7 @@ fr:
       one: 1 usage
       other: "%{count} usages"
     max_uses_prompt: Pas de limite
-    prompt: Générer et partager des liens avec les autres pour donner accès à cette instance
+    prompt: Générer et partager des liens avec les autres pour donner accès à ce serveur
     table:
       expires_at: Expire
       uses: Utilise
@@ -713,20 +766,41 @@ fr:
           quadrillion: P
           thousand: K
           trillion: T
-          unit: ''
   pagination:
     newer: Plus récent
     next: Suivant
     older: Plus ancien
     prev: Précédent
     truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: Vous avez déjà voté sur ce sondage
+      duplicate_options: contient des doublons
+      duration_too_long: est trop loin dans le futur
+      duration_too_short: est trop tôt
+      expired: Ce sondage est déjà terminé
+      over_character_limit: ne peuvent être plus long que %{max} caractères chacun
+      too_few_options: doit avoir plus qu’une proposition
+      too_many_options: ne peut contenir plus que %{max} propositions
   preferences:
-    languages: Langues
     other: Autre
-    publishing: Publication
-    web: Web
+    posting_defaults: Paramètres par défaut des pouets
+    public_timelines: Fils publics
+  relationships:
+    activity: Activité du compte
+    dormant: Dormant
+    last_active: Dernière activité
+    most_recent: Plus récent
+    moved: Déménagé
+    mutual: Mutuel
+    primary: Primaire
+    relationship: Relation
+    remove_selected_domains: Supprimer tous les abonné·e·s des domaines sélectionnés
+    remove_selected_followers: Supprimer les abonné·e·s sélectionnés
+    remove_selected_follows: Cesser de suivre les utilisateur·rice·s sélectionné·e·s
+    status: Statut du compte
   remote_follow:
-    acct: Entrez l’adresse profil@instance depuis laquelle vous voulez vous abonner
+    acct: Entrez l’adresse profil@serveur depuis laquelle vous voulez vous abonner
     missing_resource: L’URL de redirection n’a pas pu être trouvée
     no_account_html: Vous n’avez pas de compte ? Vous pouvez <a href='%{sign_up_path}' target='_blank'>vous inscrire ici</a>
     proceed: Confirmer l’abonnement
@@ -734,10 +808,13 @@ fr:
     reason_html: "<strong>Pourquoi cette étape est-elle nécessaire?</strong> <code>%{instance}</code> pourrait ne pas être le serveur où vous vous êtes inscrit, et nous devons donc vous rediriger vers votre serveur de base en premier."
   remote_interaction:
     favourite:
+      proceed: Confirmer l’ajout aux favoris
       prompt: 'Vous souhaitez mettre ce pouet en favori :'
     reblog:
+      proceed: Confirmer le repartage
       prompt: 'Vous souhaitez repartager ce pouet :'
     reply:
+      proceed: Confirmer la réponse
       prompt: 'Vous souhaitez répondre à ce pouet :'
   remote_unfollow:
     error: Erreur
@@ -789,20 +866,25 @@ fr:
     revoke_success: Session révoquée avec succès
     title: Sessions
   settings:
+    account: Compte
+    account_settings: Paramètres du compte
+    appearance: Apparence
     authorized_apps: Applications autorisées
     back: Retour vers Mastodon
     delete: Suppression de compte
     development: Développement
     edit_profile: Modifier le profil
     export: Export de données
-    followers: Abonné⋅es autorisé⋅es
+    featured_tags: Hashtags mis en avant
+    identity_proofs: Preuves d’identité
     import: Import de données
+    import_and_export: Import et export
     migrate: Migration de compte
     notifications: Notifications
     preferences: Préférences
-    settings: Réglages
+    profile: Profil
+    relationships: Abonnements et abonné·e·s
     two_factor_authentication: Identification à deux facteurs
-    your_apps: Vos applications
   statuses:
     attached:
       description: 'Attaché : %{attached}'
@@ -825,6 +907,11 @@ fr:
       ownership: Vous ne pouvez pas épingler un statut ne vous appartenant pas
       private: Les statuts non-publics ne peuvent pas être épinglés
       reblog: Un partage ne peut pas être épinglé
+    poll:
+      total_votes:
+        one: "%{count} vote"
+        other: "%{count} votes"
+      vote: Voter
     show_more: Afficher plus
     sign_in_to_participate: Inscrivez-vous pour prendre part à la conversation
     title: '%{name} : "%{quote}"'
@@ -845,10 +932,10 @@ fr:
       <h3 id="collect">Quelles informations collectons-nous ?</h3>
 
       <ul>
-        <li><em>Informations de base sur votre compte</em> : Si vous vous inscrivez sur ce serveur, il vous sera demandé de rentrer un identifiant, une adresse électronique et un mot de passe. Vous pourrez également ajouter des informations additionnelles sur votre profil, telles qu’un nom public et une biographie, ainsi que téléverser une image de profil et une image d’en-tête. Vos identifiant, nom public, biographie, image de profil et image d’en-tête seront toujours affichés publiquement.</li>
+      <li><em>Informations de base sur votre compte</em> : Si vous vous inscrivez sur ce serveur, il vous sera demandé de rentrer un identifiant, une adresse électronique et un mot de passe. Vous pourrez également ajouter des informations additionnelles sur votre profil, telles qu’un nom public et une biographie, ainsi que téléverser une image de profil et une image d’en-tête. Vos identifiant, nom public, biographie, image de profil et image d’en-tête seront toujours affichés publiquement.</li>
       <li><em>Posts, liste d’abonnements et autres informations publiques</em> : La liste de vos abonnements ainsi que la liste de vos abonné·e·s sont publiques. Quand vous postez un message, la date et l’heure d’envoi ainsi que le nom de l’application utilisée pour sa transmission sont enregistré·e·s. Des médias, tels que des images ou des vidéos, peuvent être joints aux messages. Les posts publics et non listés sont affichés publiquement. Quand vous mettez en avant un post sur votre profil, ce post est également affiché publiquement. Vos messages sont délivrés à vos abonné·e·s, ce qui, dans certains cas, signifie qu’ils sont délivrés à des serveurs tiers et que ces derniers en stockent une copie. Quand vous supprimer un post, il est probable que vos abonné·e·s en soient informé·e·s. Partager un message ou le marquer comme favori est toujours une action publique.</li>
-        <li><em>Posts directs et abonné·e·s uniquement</em> : Tous les posts sont stockés et traités par le serveur. Les messages abonné·e·s uniquement ne sont transmis qu’à vos abonné·e·s et aux personnes mentionnées dans le corps du message, tandis que les messages directs ne sont transmis qu’aux personnes mentionnées. Dans certains cas, cela signifie qu’ils sont délivrés à des serveurs tiers et que ces derniers en stockent une copie. Nous faisons un effort de bonne fois pour en limiter l’accès uniquement aux personnes autorisées, mais ce n’est pas nécessairement le cas des autres serveurs. Il est donc très important que vous vérifiiez les serveurs auxquels appartiennent vos abonné·e·s. Il vous est possible d’activer une option dans les paramètres afin d’approuver et de rejeter manuellement les nouveaux·lles abonné·e·s. <em>Gardez s’il-vous-plaît en mémoire que les opérateur·rice·s du serveur ainsi que celles et ceux de n’importe quel serveur récepteur peuvent voir ces messages</em> et qu’il est possible pour les destinataires de faire des captures d’écran, de copier et plus généralement de repartager ces messages. <em>Ne partager aucune information sensible à l’aide de Mastodon.</em></li>
-        <li><em>IP et autres métadonnées</em> : Quand vous vous connectez, nous enregistrons votre adresse IP ainsi que le nom de votre navigateur web. Toutes les sessions enregistrées peuvent être consultées dans les paramètres, afin que vous puissiez les surveiller et éventuellement les révoquer. La dernière adresse IP utilisée est conservée pour une durée de 12 mois. Nous sommes également susceptibles de conserver les journaux du serveur, ce qui inclut l’adresse IP de chaque requête reçue.</li>
+      <li><em>Posts directs et abonné·e·s uniquement</em> : Tous les posts sont stockés et traités par le serveur. Les messages abonné·e·s uniquement ne sont transmis qu’à vos abonné·e·s et aux personnes mentionnées dans le corps du message, tandis que les messages directs ne sont transmis qu’aux personnes mentionnées. Dans certains cas, cela signifie qu’ils sont délivrés à des serveurs tiers et que ces derniers en stockent une copie. Nous faisons un effort de bonne fois pour en limiter l’accès uniquement aux personnes autorisées, mais ce n’est pas nécessairement le cas des autres serveurs. Il est donc très important que vous vérifiiez les serveurs auxquels appartiennent vos abonné·e·s. Il vous est possible d’activer une option dans les paramètres afin d’approuver et de rejeter manuellement les nouveaux·lles abonné·e·s. <em>Gardez s’il-vous-plaît en mémoire que les opérateur·rice·s du serveur ainsi que celles et ceux de n’importe quel serveur récepteur peuvent voir ces messages</em> et qu’il est possible pour les destinataires de faire des captures d’écran, de copier et plus généralement de repartager ces messages. <em>Ne partager aucune information sensible à l’aide de Mastodon.</em></li>
+      <li><em>IP et autres métadonnées</em> : Quand vous vous connectez, nous enregistrons votre adresse IP ainsi que le nom de votre navigateur web. Toutes les sessions enregistrées peuvent être consultées dans les paramètres, afin que vous puissiez les surveiller et éventuellement les révoquer. La dernière adresse IP utilisée est conservée pour une durée de 12 mois. Nous sommes également susceptibles de conserver les journaux du serveur, ce qui inclut l’adresse IP de chaque requête reçue.</li>
       </ul>
 
       <hr class="spacer" />
@@ -858,9 +945,9 @@ fr:
       <p>Toutes les informations que nous collectons sur vous peuvent être utilisées d’une des manières suivantes :</p>
 
       <ul>
-        <li>Pour vous fournir les fonctionnalités de base de Mastodon. Vous ne pouvez interagir avec le contenu des autres et poster votre propre contenu que lorsque vous êtes connecté·e. Par exemple, vous pouvez vous abonner à plusieurs autres comptes pour voir l’ensemble de leurs posts dans votre fil d’accueil personnalisé.</li>
-        <li>Pour aider à la modération de la communauté, par exemple, comparer votre adresse IP à d’autres afin de déterminer si un bannissement a été contourné ou si une autre violation aux règles a été commise.</li>
-        <li>L’adresse électronique que vous nous avez fournie peut être utilisée pour vous envoyez des informations, des notifications lorsque d’autres personnes interagissent avec votre contenu ou vous envoient des messages, pour répondre à des demandes de votre part ainsi que pour tout autres requêtes ou questions.</li>
+      <li>Pour vous fournir les fonctionnalités de base de Mastodon. Vous ne pouvez interagir avec le contenu des autres et poster votre propre contenu que lorsque vous êtes connecté·e. Par exemple, vous pouvez vous abonner à plusieurs autres comptes pour voir l’ensemble de leurs posts dans votre fil d’accueil personnalisé.</li>
+      <li>Pour aider à la modération de la communauté, par exemple, comparer votre adresse IP à d’autres afin de déterminer si un bannissement a été contourné ou si une autre violation aux règles a été commise.</li>
+      <li>L’adresse électronique que vous nous avez fournie peut être utilisée pour vous envoyez des informations, des notifications lorsque d’autres personnes interagissent avec votre contenu ou vous envoient des messages, pour répondre à des demandes de votre part ainsi que pour tout autres requêtes ou questions.</li>
       </ul>
 
       <hr class="spacer" />
@@ -876,8 +963,8 @@ fr:
       <p>Nous ferons un effort de bonne foi :</p>
 
       <ul>
-        <li>Pour ne pas conserver plus de 90 jours les journaux systèmes contenant les adresses IP de toutes les requêtes reçues par ce serveur.</li>
-        <li>Pour ne pas conserver plus de 12 mois les adresses IP associées aux utilisateur·ice·s enregistré·e·s.</li>
+      <li>Pour ne pas conserver plus de 90 jours les journaux systèmes contenant les adresses IP de toutes les requêtes reçues par ce serveur.</li>
+      <li>Pour ne pas conserver plus de 12 mois les adresses IP associées aux utilisateur·ice·s enregistré·e·s.</li>
       </ul>
 
       <p>Vous pouvez demander une archive de votre contenu, incluant vos posts, vos médias joints, votre image de profil et votre image d’en-tête.</p>
@@ -923,9 +1010,9 @@ fr:
       <p>Originellement adapté de la <a href="https://github.com/discourse/discourse">politique de confidentialité de Discourse</a>.</p>
     title: "%{instance} Conditions d’utilisation et politique de confidentialité"
   themes:
-    contrast: Contraste élevé
-    default: Mastodon
-    mastodon-light: Mastodon (clair)
+    contrast: Mastodon (Contraste élevé)
+    default: Mastodon (Sombre)
+    mastodon-light: Mastodon (Clair)
   time:
     formats:
       default: "%d %b %Y, %H:%M"
@@ -953,8 +1040,8 @@ fr:
       title: Récupération de l’archive
     warning:
       explanation:
-        disable: Lorsque votre compte est gelé, les données de votre compte demeurent intactes, mais vous ne pouvez effectuer aucune action jusqu'à ce qu'il soit débloqué.
-        silence: Lorsque votre compte est limité, seulement les utilisateurs qui vous suivent déjà verront vos pouets sur ce serveur, et vous pourriez être exclu de plusieurs listes publiques. Néanmoins, d'autres utilisateurs peuvent vous suivre manuellement.
+        disable: Lorsque votre compte est gelé, les données de votre compte demeurent intactes, mais vous ne pouvez effectuer aucune action jusqu’à ce qu’il soit débloqué.
+        silence: Lorsque votre compte est limité, seulement les utilisateurs qui vous suivent déjà verront vos pouets sur ce serveur, et vous pourriez être exclu de plusieurs listes publiques. Néanmoins, d’autres utilisateurs peuvent vous suivre manuellement.
         suspend: Votre compte a été suspendu, et tous vos pouets et vos fichiers multimédia téléversés ont été supprimés irréversiblement de ce serveur, et des serveurs où vous aviez des abonné⋅e⋅s.
       review_server_policies: Passer en revue les politiques du serveur
       subject:
@@ -974,7 +1061,7 @@ fr:
       final_action: Commencer à publier
       final_step: 'Commencez à poster ! Même sans abonné·e·s, vos messages publics peuvent être vus par d’autres, par exemple sur le fil public local et dans les hashtags. Vous pouvez vous présenter sur le hashtag #introductions.'
       full_handle: Votre identifiant complet
-      full_handle_hint: C’est ce que vous diriez à vos ami·e·s pour qu’il·elle·s puissent vous envoyer un message ou vous suivre à partir d’une autre instance.
+      full_handle_hint: C’est ce que vous diriez à vos ami·e·s pour leur permettre de vous envoyer un message ou vous suivre à partir d’un autre serveur.
       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 des GIF.
       subject: Bienvenue sur Mastodon
@@ -992,5 +1079,5 @@ fr:
     seamless_external_login: Vous êtes connecté via un service externe, donc les paramètres concernant le mot de passe et le courriel ne sont pas disponibles.
     signed_in_as: 'Connecté·e en tant que :'
   verification:
-    explanation_html: 'Vous pouvez <strong>vérifier vous-même que vous êtes le propriétaire des liens dans les métadonnées de votre profil</strong>. Pour cela, le site Web lié doit contenir un lien vers votre profil Mastodon. Le lien de retour <strong>doit</strong>avoir un attribut <code>rel="me"</code>. Le contenu textuel du lien n''a pas d''importance. En voici un exemple :'
+    explanation_html: 'Vous pouvez <strong>vérifier vous-même que vous êtes le propriétaire des liens dans les métadonnées de votre profil</strong>. Pour cela, le site Web lié doit contenir un lien vers votre profil Mastodon. Le lien de retour <strong>doit</strong>avoir un attribut <code>rel="me"</code>. Le contenu textuel du lien n’a pas d’importance. En voici un exemple :'
     verification: Vérification
diff --git a/config/locales/ga.yml b/config/locales/ga.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9f586aa377b39ae8fb83bc32e5b1cf8d36cf82b5
--- /dev/null
+++ b/config/locales/ga.yml
@@ -0,0 +1,4 @@
+---
+ga:
+  about:
+    about_hashtag_html: Is toots phoiblí iad seo atá clibáilte le <strong>#%{hashtag}</strong>. Is féidir leat idirghníomhú leo má tá cuntas agat áit ar bith sa fediverse.
diff --git a/config/locales/gl.yml b/config/locales/gl.yml
index 8e0a9aeb1be78eb3bf13115d632f85acbdabcc5c..79ef993e2edab37d2bbf385f5c1860833a32151c 100644
--- a/config/locales/gl.yml
+++ b/config/locales/gl.yml
@@ -4,36 +4,36 @@ gl:
     about_hashtag_html: Estas son mensaxes públicas etiquetadas con <strong>#%{hashtag}</strong>. Pode interactuar con elas si ten unha conta nalgures do fediverso.
     about_mastodon_html: Mastodon é unha rede social que se basea en protocolos web abertos e libres, software de código aberto. É descentralizada como o correo electrónico.
     about_this: Sobre
+    active_count_after: activo
+    active_footnote: Usuarias Activas no Mes (UAM)
     administered_by: 'Administrada por:'
     api: API
     apps: Apps móbiles
-    closed_registrations: O rexistro en esta instancia está pechado en este intre. Porén! Pode atopar unha instancia diferente para obter unha conta e ter acceso exactamente a misma rede desde alí.
+    apps_platforms: Utilice Mastodon desde iOS, Android e outras plataformas
+    browse_directory: Navegue no directorio de perfís e filtre por intereses
+    browse_public_posts: Vexa o fluxo de comentarios públicos en Mastodon
     contact: Contacto
     contact_missing: Non establecido
     contact_unavailable: N/A
+    discover_users: Descubra usuarias
     documentation: Documentación
     extended_description_html: |
       <h3>Un bo lugar para regras</h3>
       <p>A descrición extendida aínda non se proporcionou.</p>
-    features:
-      humane_approach_body: Aprendendo dos erros de outras redes, Mastodon intenta tomar decisións éticas de deseño para loitar contra os usos incorrectos da rede.
-      humane_approach_title: Unha aproximación máis humana
-      not_a_product_body: Mastodon non é unha rede comercial. Sen anuncios, sen minería de datos, sen xardíns privados. Non hai autoridade centralizada.
-      not_a_product_title: Vostede é unha persoa, non un producto
-      real_conversation_body: Con 65535 caracteres a súa disposición, soporte para contido polo miúdo e avisos sobre o contido, pode expresarse vostede con libertade.
-      real_conversation_title: Construído para conversacións reais
-      within_reach_body: Existen múltiples aplicacións para iOS, Android e outras plataformas grazas a un entorno API amigable para o desenvolvedor que lle permite estar ao tanto cos seus amigos en calquer lugar.
-      within_reach_title: Sempre en contacto
+    federation_hint_html: Con unha conta en %{instance} poderá seguir a outras persoas en calquera dos servidores Mastodon e incluso máis.
     generic_description: "%{domain} é un servidor na rede"
+    get_apps: Probe cunha app móbil
     hosted_on: Mastodon aloxado en %{domain}
     learn_more: Coñeza máis
-    other_instances: Listado de instancias
     privacy_policy: Política de intimidade
+    see_whats_happening: Mire o que acontece
+    server_stats: 'Estatísticas:'
     source_code: Código fonte
     status_count_after:
       one: estado
       other: estados
     status_count_before: Que publicaron
+    tagline: Siga as amizades e faga outras novas
     terms: Termos do servizo
     user_count_after:
       one: usuaria
@@ -68,6 +68,7 @@ gl:
       admin: Admin
       bot: Bot
       moderator: Mod
+    unavailable: Perfil non dispoñible
     unfollow: Deixar de seguir
   admin:
     account_actions:
@@ -79,6 +80,8 @@ gl:
       delete: Eliminar
       destroyed_msg: Nota a moderación destruída con éxito!
     accounts:
+      approve: Aprobar
+      approve_all: Aprobar todo
       are_you_sure: Está segura?
       avatar: Avatar
       by_domain: Dominio
@@ -100,7 +103,7 @@ gl:
       display_name: Mostrar nome
       domain: Dominio
       edit: Editar
-      email: Email
+      email: Correo-e
       email_status: Estado do correo
       enable: Habilitar
       enabled: Habilitado
@@ -124,15 +127,18 @@ gl:
       moderation:
         active: Activa
         all: Todo
+        pending: Pendente
         silenced: Acalado
         suspended: Suspendido
         title: Moderación
       moderation_notes: Notas de moderación
       most_recent_activity: Actividade máis recente
       most_recent_ip: IP máis recente
+      no_account_selected: Non cambiou nada xa que non tiña nada seleccionado
       no_limits_imposed: Sen límites impostos
       not_subscribed: Non suscrita
       outbox_url: URL caixa de saída
+      pending: Pendente revisión
       perform_full_suspension: Suspender
       profile_url: URL do perfil
       promote: Promocionar
@@ -140,6 +146,8 @@ gl:
       public: Público
       push_subscription_expires: A suscrición PuSH caduca
       redownload: Actualizar perfil
+      reject: Rexeitar
+      reject_all: Rexeitar todo
       remove_avatar: Eliminar avatar
       remove_header: Eliminar cabeceira
       resend_confirmation:
@@ -166,6 +174,7 @@ gl:
       statuses: Estados
       subscribe: Subscribir
       suspended: Suspendida
+      time_in_queue: Agardando en cola %{time}
       title: Contas
       unconfirmed_email: Correo non confirmado
       undo_silenced: Desfacer acalar
@@ -241,6 +250,7 @@ gl:
       feature_profile_directory: Directorio do perfil
       feature_registrations: Rexistros
       feature_relay: Repetidores de federación
+      feature_timeline_preview: Vista previa da TL
       features: Características
       hidden_service: Federación con servizos ocultos
       open_reports: informes abertos
@@ -260,6 +270,7 @@ gl:
       created_msg: Estase a procesar o bloqueo do dominio
       destroyed_msg: Desfixose a acción de bloqueo de dominio
       domain: Dominio
+      existing_domain_block_html: Xa estableceu límites estrictos para %{name}, precisa <a href="%{unblock_url}">desbloqueala</a> primeiro.
       new:
         create: Crear bloque
         hint: O bloqueo do dominio non previrá a creación de entradas de contas na base de datos, pero aplicará de xeito retroactivo e automático regras específicas de moderación sobre esas contas.
@@ -302,6 +313,7 @@ gl:
       back_to_account: Voltar a Conta
       title: Seguidoras de %{acct}
     instances:
+      by_domain: Dominio
       delivery_available: A entrega está dispoñible
       known_accounts:
         one: "%{count} conta coñecida"
@@ -324,6 +336,8 @@ gl:
         expired: Cadudado
         title: Filtro
       title: Convida
+    pending_accounts:
+      title: Contas pendentes (%{count})
     relays:
       add_new: Engadir un novo repetidor
       delete: Eliminar
@@ -386,14 +400,14 @@ gl:
         desc_html: Modificar o aspecto con CSS cargado en cada páxina
         title: CSS persoalizado
       hero:
-        desc_html: Mostrado na portada. Recoméndase 600x100px como mínimo. Si non se establece, mostrará a imaxe por omisión da instancia
+        desc_html: Mostrado na portada. Recoméndase 600x100px como mínimo. Se non se establece, mostrará a imaxe por omisión do servidor
         title: Imáxe Heróe
       mascot:
         desc_html: Mostrado en varias páxinas. Recoméndase 293x205 como mínimo. Se non se establece publícase a mascota por omisión
         title: Imaxe da mascota
       peers_api_enabled:
-        desc_html: Nome de dominio que esta instancia atopou no fediverso
-        title: Publicar lista de instancias descubertas
+        desc_html: Nomes de dominio que este servidor atopou no fediverso
+        title: Publicar lista de servidores descubertos
       preview_sensitive_media:
         desc_html: A vista previa de ligazóns de outros sitios web mostrará unha imaxe incluso si os medios están marcados como sensibles
         title: Mostrar medios sensibles con vista previa OpenGraph
@@ -410,9 +424,12 @@ gl:
         min_invite_role:
           disabled: Ninguén
           title: Permitir convites por
-        open:
-          desc_html: Permitir que calquera poida crear unha conta
-          title: Abrir rexistro
+      registrations_mode:
+        modes:
+          approved: Precisa aprobación para rexistrarse
+          none: Rexistro pechado
+          open: Rexistro aberto
+        title: Estado do 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
@@ -421,20 +438,20 @@ gl:
         title: Mostrar insigna de membresía
       site_description:
         desc_html: Parágrafo de presentación na páxina principal. Describe o que fai especial a este servidor Mastodon e calquera outra ouca importante. Pode utilizar etiquetas HTML, en particular <code>&lt;a&gt;</code> e <code>&lt;em&gt;</code>.
-        title: Descrición da instancia
+        title: Descrición do servidor
       site_description_extended:
-        desc_html: Un bo lugar para o seu código de conducta, regras, guías e outras cousas que distingan a súa instancia. Pode utilizar etiquetas HTML
+        desc_html: Un bo lugar para o seu código de conducta, regras, guías e outras cousas que distingan ao seu servidor. Pode utilizar etiquetas HTML
         title: Información extendida da persoalización
       site_short_description:
-        desc_html: Mostrado na barra lateral e nas etiquetas meta. Describe o que é Mastodon e que fai especial a este servidor nun só parágrafo. Si está baldeiro, mostrará a descrición da instancia.
-        title: Descrición curta da instancia
+        desc_html: Mostrado na barra lateral e nas etiquetas meta. Describe o que é Mastodon e que fai especial a este servidor nun só parágrafo. Si está baldeiro, mostrará a descrición do servidor.
+        title: Descrición curta do servidor
       site_terms:
         desc_html: Pode escribir a súa propia política de intimidade, termos de servizo ou aclaracións legais. Pode utilizar etiquetas HTML
         title: Termos de servizo persoalizados
-      site_title: Nome da instancia
+      site_title: Nome do servidor
       thumbnail:
         desc_html: Utilizado para vistas previsas vía OpenGraph e API. Recoméndase 1200x630px
-        title: Icona da instancia
+        title: Icona do servidor
       timeline_preview:
         desc_html: Mostrar liña de tempo pública na páxina de inicio
         title: vista previa da liña temporal
@@ -475,10 +492,19 @@ gl:
       edit_preset: Editar aviso preestablecido
       title: Xestionar avisos preestablecidos
   admin_mailer:
+    new_pending_account:
+      body: Abaixo están os detalles da conta. Pode aprobar ou rexeitar esta solicitude.
+      subject: Hai unha conta nova para revisar en %{instance} (%{username})
     new_report:
       body: "%{reporter} informou sobre %{target}"
       body_remote: Alguén desde %{domain} informou sobre %{target}
       subject: Novo informe sobre %{instance} (#%{id})
+  appearance:
+    advanced_web_interface: Interface web avanzada
+    advanced_web_interface_hint: Se quere utilizar todo o ancho da súa pantalla, a interface web avanzada permítelle configurar diferentes columnas para ver tanta información como desexe. Inicio, notificacións, liña temporal federada, calquera número de listas e etiquetas.
+    animations_and_accessibility: Animacións e accesibilidade
+    confirmation_dialogs: Diálogos de confirmación
+    sensitive_content: Contido sensible
   application_mailer:
     notification_preferences: Cambiar os axustes de correo-e
     salutation: "%{name},"
@@ -495,8 +521,9 @@ gl:
     warning: Teña moito tino con estos datos. Nunca os comparta con ninguén!
     your_token: O seu testemuño de acceso
   auth:
-    agreement_html: Ao pulsar "Rexistrar" vostede acorda seguir <a href="%{rules_path}">as normas da instancia</a> e <a href="%{terms_path}">os termos do servizo</a>.
+    apply_for_account: Solicite un convite
     change_password: Contrasinal
+    checkbox_agreement_html: Acepto as <a href="%{rules_path}" target="_blank">regras do servidor</a> e os <a href="%{terms_path}" target="_blank">termos do servizo</a>
     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.
@@ -507,17 +534,17 @@ gl:
     logout: Desconectar
     migrate_account: Mover a unha conta diferente
     migrate_account_html: Se desexa redirixir esta conta hacia outra diferente, pode <a href="%{path}">configuralo aquí</a>.
-    or: ou
     or_log_in_with: ou conectar con
     providers:
       cas: CAS
       saml: SAML
     register: Rexistro
-    register_elsewhere: Rexístrese en outro servidor
+    registration_closed: "%{instance} non está a aceptar novas usuarias"
     resend_confirmation: Voltar a enviar intruccións de confirmación
     reset_password: Restablecer contrasinal
     security: Seguridade
     set_new_password: Establecer novo contrasinal
+    trouble_logging_in: Problemas para conectar?
   authorize_follow:
     already_following: Xa está a seguir esta conta
     error: Desgraciadamente, algo fallou ao buscar a conta remota
@@ -549,7 +576,7 @@ gl:
     description_html: Esto eliminará de xeito <strong>permanente e irreversible</strong> o contido da súa conta e será desactivada. O seu nome de usuaria permanecerá reservado para evitar futuras confusións de identidades.
     proceed: Eliminar conta
     success_msg: A súa conta eliminouse correctamente
-    warning_html: Só se garantiza a eliminación de contido de esta instancia. O contido que foi compartido con outras instancias é probable que deixe rastros. O servidores fora de liña e servidores que se desuscribiron das súas actualizacións non actualizarán as súas bases de datos.
+    warning_html: Só se garantiza a eliminación de contido de este servidor. O contido que foi compartido con outras instancias é probable que deixe rastros. O servidores fora de liña e servidores que se desuscribiron das súas actualizacións non actualizarán as súas bases de datos.
     warning_title: Dispoñibilidade do contido espallado
   directories:
     directory: Directorio de perfil
@@ -563,8 +590,8 @@ gl:
       other: "%{count} persoas"
   errors:
     '403': Non ten permiso para ver esta páxina.
-    '404': A páxina que está a buscar non existe.
-    '410': A páxina que busca xa non existe.
+    '404': A páxina que está a buscar non está aquí.
+    '410': A páxina que estaba a buscar xa non existe.
     '422':
       content: Fallou a verificación de seguridade. Está bloqueando as cookies?
       title: Fallou a verficación de seguridade
@@ -573,11 +600,14 @@ gl:
       content: Sentímolo, pero algo do noso lado falloou.
       title: Esta páxina non é correcta
     noscript_html: Para utilizar a aplicación web de Mastodon debe habilitar JavaScript. De xeito alternativo, intente unha das <a href="%{apps_path}">apps nativas</a> para Mastodon da súa plataforma.
+  existing_username_validator:
+    not_found: non se atopou unha usuaria local con ese alcume
+    not_found_multiple: non se atopou a %{usernames}
   exports:
     archive_takeout:
       date: Data
       download: Descargue o seu ficheiro
-      hint_html: Pode solicitar un ficheiro cos <strong>seus toots ficheiros de medios</strong>. Os datos estarán en formato ActivityPub e son compatibles con calquer software que o cumpla. Pode solicitar un ficheiro cada 7 días.
+      hint_html: Pode solicitar un ficheiro cos <strong>seus toots e ficheiros de medios</strong>. Os datos estarán en formato ActivityPub e son compatibles con calquer software que o siga. Pode solicitar un ficheiro cada 7 días.
       in_progress: Xerando o seu ficheiro...
       request: Solicite o ficheiro
       size: Tamaño
@@ -588,6 +618,10 @@ gl:
     lists: Listas
     mutes: Acalou
     storage: Almacenamento de medios
+  featured_tags:
+    add_new: Engadir novo
+    errors:
+      limit: Xa acadou o número máximo de etiquetas
   filters:
     contexts:
       home: Liña temporal inicial
@@ -604,34 +638,50 @@ gl:
       title: Filtros
     new:
       title: Engadir novo filtro
-  followers:
-    domain: Dominio
-    explanation_html: Se quere asegurar a intimidade dos seus estados, debe ser consciente de quen a está a seguir. <strong>Os seus estados privados son enviados a todas as instancias onde ten seguidoras</strong>. Podería querer revisalas, e elminar seguidoras si non confía que a súa intimidade sexa respetada polos administradores ou o software de esa instancia.
-    followers_count: Número de seguidoras
-    lock_link: Bloquear a súa conta
-    purge: Eliminar das seguidoras
-    success:
-      one: En proceso de bloquear seguidoras de un dominio...
-      other: No proceso de bloquear seguidoras de %{count} dominios...
-    true_privacy_html: Por favor teña en conta que <strong>a verdadeira intimidade só pode ser conseguida con cifrado de extremo-a-extremo</strong>.
-    unlocked_warning_html: Calquera pode seguila para inmediatamente ver os seus estados privados. %{lock_link} para poder revisar e rexeitar seguidoras.
-    unlocked_warning_title: A súa conta non está pechada
   footer:
     developers: Desenvolvedoras
     more: Máis…
     resources: Recursos
   generic:
+    all: Todo
     changes_saved_msg: Cambios gardados correctamente!!
     copy: Copiar
+    order_by: Ordenar por
     save_changes: Gardar cambios
     validation_errors:
       one: Algo non está ben de todo! Por favor revise abaixo o erro
       other: Algo aínda non está ben! Por favor revise os %{count} erros abaixo
+  html_validator:
+    invalid_markup: 'contén etiquetas HTML non válidas: %{error}'
+  identity_proofs:
+    active: Activo
+    authorize: Si, autorizar
+    authorize_connection_prompt: Autorizar esta conexión criptográfica?
+    errors:
+      failed: Fallou a conexión criptográfica. Por favor inténteo de novo desde %{provider}.
+      keybase:
+        invalid_token: Os testemuños Keybase son hashes de firma e deben ter 66 caracteres hexadecimais
+        verification_failed: Keybase non recoñece este testemuño como firma da usuaria de Keybase %{kb_username}. Por favor inténteo desde Keybase.
+      wrong_user: Non se puido crear a proba para %{proving} mentras está conectada como %{current}. Conéctese como %{proving} e inténteo de novo.
+    explanation_html: Aquí pódese conectar criptográficamente as suas outras identidades, como a un perfil Keybase. Esto permitelle a outras persoas enviarlle mensaxes cifradas e confiar no contido que vostede lle envía.
+    i_am_html: Eu son %{username} en %{service}.
+    identity: Identidade
+    inactive: Inactiva
+    publicize_checkbox: 'E tootee esto:'
+    publicize_toot: 'Comprobado! Eu son %{username} en %{service}: %{url}'
+    status: Estado da validación
+    view_proof: Ver proba
   imports:
-    preface: Pode importar os datos que exportou de outra instancia, tales como a lista de usuarias que está a seguir ou bloquear.
+    modes:
+      merge: Fusionar
+      merge_long: Manter os rexistros actuais e engadir novos
+      overwrite: Sobreescribir
+      overwrite_long: Sustituír rexistros actuais cos novos
+    preface: Pode importar os datos que exportou de outro servidor, tales como a lista de usuarias que está a seguir ou bloquear.
     success: Os seus datos foron correctamente subidos e serán procesados ao momento
     types:
       blocking: Lista de bloqueo
+      domain_blocking: Lista de bloqueo de dominios
       following: Lista de seguimento
       muting: Lista de usuarias acaladas
     upload: Subir
@@ -653,7 +703,7 @@ gl:
       one: 1 uso
       other: "%{count} usos"
     max_uses_prompt: Sen límite
-    prompt: Xerar e compartir ligazóns con outras para permitir acceso a esta instancia
+    prompt: Xerar e compartir ligazóns con outras para permitir acceso a este servidor
     table:
       expires_at: Caduca
       uses: Usos
@@ -716,18 +766,39 @@ gl:
           quadrillion: Q
           thousand: K
           trillion: T
-          unit: " "
   pagination:
     newer: Máis novo
     next: Seguinte
     older: Máis antigo
     prev: Previo
     truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: Xa votou en esta sondaxe
+      duplicate_options: contén elementos duplicados
+      duration_too_long: está moi lonxe no futuro
+      duration_too_short: é demasiado cedo
+      expired: A sondaxe rematou
+      over_character_limit: non poden ter máis de %{max} caracteres cada unha
+      too_few_options: debe ter máis de unha opción
+      too_many_options: non pode haber máis de %{max} opcións
   preferences:
-    languages: Idiomas
     other: Outro
-    publishing: Publicando
-    web: Web
+    posting_defaults: Valores por omisión
+    public_timelines: Liñas temporais públicas
+  relationships:
+    activity: Actividade da conta
+    dormant: En repouso
+    last_active: Último activo
+    most_recent: Máis recente
+    moved: Movida
+    mutual: Mutuo
+    primary: Principal
+    relationship: Relación
+    remove_selected_domains: Eliminar todas as seguidoras dos dominios escollidos
+    remove_selected_followers: Eliminar as seguidoras escollidas
+    remove_selected_follows: Deixar de seguir as usuarias escollidas
+    status: Estado da conta
   remote_follow:
     acct: Introduza o seu usuaria@servidor desde onde quere interactuar
     missing_resource: Non se puido atopar o URL de redirecionamento requerido para a súa conta
@@ -795,20 +866,25 @@ gl:
     revoke_success: A sesión revocouse con éxito
     title: Sesións
   settings:
+    account: Conta
+    account_settings: Axustes da conta
+    appearance: Aparencia
     authorized_apps: Apps autorizadas
     back: Voltar a Mastodon
     delete: Eliminación da conta
     development: Desenvolvemento
     edit_profile: Editar perfil
     export: Exportar datos
-    followers: Seguidoras autorizadas
+    featured_tags: Etiquetas destacadas
+    identity_proofs: Probas de identidade
     import: Importar
+    import_and_export: Importar e exportar
     migrate: Migrar conta
     notifications: Notificacións
     preferences: Preferencias
-    settings: Axustes
+    profile: Perfil
+    relationships: Seguindo e seguidoras
     two_factor_authentication: Validar Doble Factor
-    your_apps: As súas aplicacións
   statuses:
     attached:
       description: 'Axenado: %{attached}'
@@ -831,6 +907,11 @@ gl:
       ownership: Non pode fixar a mensaxe de outra usuaria
       private: As mensaxes non-públicas non poden ser fixadas
       reblog: Non se poden fixar as mensaxes promovidas
+    poll:
+      total_votes:
+        one: "%{count} voto"
+        other: "%{count} votos"
+      vote: Votar
     show_more: Mostrar máis
     sign_in_to_participate: Conéctese para participar na conversa
     title: '%{name}: "%{quote}"'
@@ -851,10 +932,10 @@ gl:
       <h3 id="collect">Qué información recollemos?</h3>
 
       <ul>
-        <li><em>Información básica da conta</em>: Si se rexistra en este servidor, pediráselle un nome de usuaria, un enderezo de correo electrónico e un contrasinal. De xeito adicional tamén poderá introducir información como un nome público e biografía, tamén subir unha fotografía de perfil e unha imaxe para a cabeceira. O nome de usuaria, o nome público, a biografía e as imaxes de perfil e cabeceira sempre se mostran publicamente.</li>
-        <li><em>Publicacións, seguimento e outra información pública</em>: O listado das persoas que segue é un listado público, o mesmo acontece coas súas seguidoras. Cando evía unha mensaxe, a data e hora gárdanse así como o aplicativo que utilizou para enviar a mensaxe. As publicacións poderían conter ficheiros de medios anexos, como fotografías e vídeos. As publicacións públicas e as non listadas están dispoñibles de xeito público. Cando destaca unha publicación no seu perfil tamén é pública. As publicacións son enviadas as súas seguidoras, en algúns casos pode acontecer que estén en diferentes servidores e gárdanse copias neles. Cando elemina unha publicación tamén se envía as súas seguidoras. A acción de voltar a publicar ou marcar como favorita outra publicación sempre é pública.</li>
-        <li><em>Mensaxes directas e só para seguidoras</em>: Todas as mensaxes gárdanse e procésanse no servidor. As mensaxes só para seguidoras son entregadas as súas seguidoras e as usuarias que son mencionadas en elas, e as mensaxes directas entréganse só as usuarias mencionadas en elas. En algúns casos esto implica que son entregadas a diferentes servidores e gárdanse copias alí. Facemos un esforzo sincero para limitar o acceso a esas publicacións só as persoas autorizadas, pero outros servidores poderían non ser tan escrupulosos. Polo tanto, é importante revisar os servidores onde se hospedan as súas seguidoras. Nos axustes pode activar a opción de aprovar ou rexeitar novas seguidoras de xeito manual.  <em>Teña en conta que a administración do servidor e todos os outros servidores implicados poden ver as mensaxes.</em>, e as destinatarias poderían facer capturas de pantalla, copiar e voltar a compartir as mensaxes. <em>Non comparta información comprometida en Mastodon.</em></li>
-        <li><em>IPs e outros metadatos</em>: Cando se conecta, gravamos o IP desde onde se conecta, así como o nome do aplicativo desde onde o fai. Todas as sesións conectadas están dispoñibles para revisar e revogar nos axustes. O último enderezo IP utilizado gárdase ate por 12 meses. Tamén poderiamos gardar informes do servidor que inclúan o enderezo IP de cada petición ao servidor.</li>
+      <li><em>Información básica da conta</em>: Si se rexistra en este servidor, pediráselle un nome de usuaria, un enderezo de correo electrónico e un contrasinal. De xeito adicional tamén poderá introducir información como un nome público e biografía, tamén subir unha fotografía de perfil e unha imaxe para a cabeceira. O nome de usuaria, o nome público, a biografía e as imaxes de perfil e cabeceira sempre se mostran publicamente.</li>
+      <li><em>Publicacións, seguimento e outra información pública</em>: O listado das persoas que segue é un listado público, o mesmo acontece coas súas seguidoras. Cando evía unha mensaxe, a data e hora gárdanse así como o aplicativo que utilizou para enviar a mensaxe. As publicacións poderían conter ficheiros de medios anexos, como fotografías e vídeos. As publicacións públicas e as non listadas están dispoñibles de xeito público. Cando destaca unha publicación no seu perfil tamén é pública. As publicacións son enviadas as súas seguidoras, en algúns casos pode acontecer que estén en diferentes servidores e gárdanse copias neles. Cando elemina unha publicación tamén se envía as súas seguidoras. A acción de voltar a publicar ou marcar como favorita outra publicación sempre é pública.</li>
+      <li><em>Mensaxes directas e só para seguidoras</em>: Todas as mensaxes gárdanse e procésanse no servidor. As mensaxes só para seguidoras son entregadas as súas seguidoras e as usuarias que son mencionadas en elas, e as mensaxes directas entréganse só as usuarias mencionadas en elas. En algúns casos esto implica que son entregadas a diferentes servidores e gárdanse copias alí. Facemos un esforzo sincero para limitar o acceso a esas publicacións só as persoas autorizadas, pero outros servidores poderían non ser tan escrupulosos. Polo tanto, é importante revisar os servidores onde se hospedan as súas seguidoras. Nos axustes pode activar a opción de aprovar ou rexeitar novas seguidoras de xeito manual.  <em>Teña en conta que a administración do servidor e todos os outros servidores implicados poden ver as mensaxes.</em>, e as destinatarias poderían facer capturas de pantalla, copiar e voltar a compartir as mensaxes. <em>Non comparta información comprometida en Mastodon.</em></li>
+      <li><em>IPs e outros metadatos</em>: Cando se conecta, gravamos o IP desde onde se conecta, así como o nome do aplicativo desde onde o fai. Todas as sesións conectadas están dispoñibles para revisar e revogar nos axustes. O último enderezo IP utilizado gárdase ate por 12 meses. Tamén poderiamos gardar informes do servidor que inclúan o enderezo IP de cada petición ao servidor.</li>
       </ul>
 
       <hr class="spacer" />
@@ -864,9 +945,9 @@ gl:
       <p>Toda a información que recollemos podería ser utilizada dos seguintes xeitos:</p>
 
       <ul>
-        <li>Para proporcionar a funcionabiliade básica de Mastodon. Só pode interactuar co contido de outra xente e publicar o seu propio contido si está conectada. Por exemplo, podería seguir outra xente e ver as súas publicacións combinadas nunha liña temporal inicial persoalizada.</li>
-        <li>Para axudar a moderar a comunidade, por exemplo comparando o seu enderezo IP con outros coñecidos para evitar esquivar os rexeitamentos ou outras infraccións.</li>
-        <li>O endero de correo electrónico que nos proporciona podería ser utilizado para enviarlle información, notificacións sobre outra xente que interactúa cos seus contidos ou lle envía mensaxes, e para respostar a consultas, e/ou outras cuestións ou peticións.</li>
+      <li>Para proporcionar a funcionabiliade básica de Mastodon. Só pode interactuar co contido de outra xente e publicar o seu propio contido si está conectada. Por exemplo, podería seguir outra xente e ver as súas publicacións combinadas nunha liña temporal inicial persoalizada.</li>
+      <li>Para axudar a moderar a comunidade, por exemplo comparando o seu enderezo IP con outros coñecidos para evitar esquivar os rexeitamentos ou outras infraccións.</li>
+      <li>O endero de correo electrónico que nos proporciona podería ser utilizado para enviarlle información, notificacións sobre outra xente que interactúa cos seus contidos ou lle envía mensaxes, e para respostar a consultas, e/ou outras cuestións ou peticións.</li>
       </ul>
 
       <hr class="spacer" />
@@ -882,8 +963,8 @@ gl:
       <p>Faremos un sincero esforzo en:</p>
 
       <ul>
-        <li>Protexer informes do servidor que conteñan direccións IP das peticións ao servidor, ate a data estos informes gárdanse por non máis de 90 días.</li>
-        <li>Reter os enderezos IP asociados con usuarias rexistradas non máis de 12 meses.</li>
+      <li>Protexer informes do servidor que conteñan direccións IP das peticións ao servidor, ate a data estos informes gárdanse por non máis de 90 días.</li>
+      <li>Reter os enderezos IP asociados con usuarias rexistradas non máis de 12 meses.</li>
       </ul>
 
       <p>Pode solicitar e descargar un ficheiro cos seus contidos, incluíndo publicacións, anexos de medios, imaxes de perfil e imaxe da cabeceira.</p>
@@ -929,9 +1010,9 @@ gl:
       <p>Adaptado do orixinal <a href="https://github.com/discourse/discourse">Discourse privacy policy</a>.</p>
     title: "%{instance} Termos do Servizo e Política de Intimidade"
   themes:
-    contrast: Alto contraste
-    default: Mastodon
-    mastodon-light: Mastodon (claro)
+    contrast: Mastodon (Alto contraste)
+    default: Mastodon (Escuro)
+    mastodon-light: Mastodon (Claro)
   time:
     formats:
       default: "%d %b, %Y, %H:%M"
@@ -980,7 +1061,7 @@ gl:
       final_action: Comece a publicar
       final_step: 'Publique! Incluso sin seguidoras as súas mensaxes serán vistas por outras, por exemplo na liña temporal local e nas etiquetas. Podería presentarse no #fediverso utilizando a etiqueta #introductions.'
       full_handle: O seu alcume completo
-      full_handle_hint: Esto é o que lle dirá aos seus amigos para que poidan seguila ou enviarlle mensaxes desde outra instancia.
+      full_handle_hint: Esto é o que lle dirá aos seus amigos para que poidan seguila ou enviarlle mensaxes desde outro servidor.
       review_preferences_action: Cambiar preferencias
       review_preferences_step: Lembre establecer as preferencias, tales como qué correos-e lle querería recibir, ou o nivel de intimidade por omisión para as súas mensaxes. Se non lle molestan as imaxes con movemento, pode escoller que os GIF se reproduzan automáticamente.
       subject: Benvida a Mastodon
diff --git a/config/locales/he.yml b/config/locales/he.yml
index 6d50ed459dfb190a43ff0bf598135af9b616c899..607bbb90b4d443e3a6626e025270bcefee9e4401 100644
--- a/config/locales/he.yml
+++ b/config/locales/he.yml
@@ -4,9 +4,7 @@ he:
     about_hashtag_html: אלו סטטוסים פומביים המתוייגים בתור<strong>#%{hashtag}</strong>. ניתן להגיב, להדהד או לחבב אותם אם יש לך חשבון בכל מקום בפדרציה.
     about_mastodon_html: מסטודון היא רשת חברתית <em>חופשית, מבוססת תוכנה חופשית ("קוד פתוח")</em>. כאלטרנטיבה <em>בלתי ריכוזית</em> לפלטפרומות המסחריות, מסטודון מאפשרת להמנע מהסיכונים הנלווים להפקדת התקשורת שלך בידי חברה יחידה. שמת את מבטחך בשרת אחד &mdash; לא משנה במי בחרת, תמיד אפשר לדבר עם כל שאר המשתמשים. לכל מי שרוצה יש את האפשרות להקים שרת מסטודון עצמאי, ולהשתתף ב<em>רשת החברתית</em> באופן חלק.
     about_this: אודות שרת זה
-    api: API
     apps: יישומונים לנייד
-    closed_registrations: הרשמות סגורות לשרת זה לעת עתה.
     contact: יצירת קשר
     contact_missing: ללא הגדרה
     contact_unavailable: לא רלוונטי/חסר
@@ -14,35 +12,21 @@ he:
     extended_description_html: |
       <h3>מקום טוב לכללים</h3>
       <p>התיאור המורחב טרם הוגדר.</p>
-    features:
-      humane_approach_body: מתוך למידה מכשלים של רשתות אחרות, מסטודון מכוונת להחלטות תכנוניות אתיות שנאבקות בשימוש לרעה של מדיה חברתית.
-      humane_approach_title: גישה הומאנית יותר
-      not_a_product_body: מסטודון איננה רשת מסחרית. אין פרסום, אין כריית מידע, אין גנים סגורים. אין סמכות מרכזית.
-      not_a_product_title: את(ה) אדם, לא מוצר
-      real_conversation_body: עם 65535 תווים לרשותך, ואפשרויות פרטניות לאזהרות תוכן והסתרת מדיה, יש לך את החופש להתבטא כרצונך.
-      real_conversation_title: בנוי לשיחות אמתיות
-      within_reach_body: שלל אפליקציות עבור iOS, אנדרואיד ופלטפורמות אחרות שיאפשרו לך לשמור על קשר עם חברים בכל מקום, תודות למערכת מנשקי תוכנה ידידותיים למפתחים.
-      within_reach_title: תמיד במרחק נגיעה
     generic_description: "%{domain} הוא שרת אחד בתוך הרשת"
     hosted_on: מסטודון שיושב בכתובת %{domain}
     learn_more: מידע נוסף
-    other_instances: שרתים אחרים
     source_code: קוד מקור
-    status_count_after: הודעות
     status_count_before: שכתבו
-    user_count_after: משתמשים
     user_count_before: ביתם של
     what_is_mastodon: מה זה מסטודון?
   accounts:
     follow: לעקוב
-    followers: עוקבים
     following: נעקבים
     media: מדיה
     moved_html: "%{name} עבר(ה) אל %{new_profile_link}:"
     nothing_here: אין פה שום דבר!
     people_followed_by: הנעקבים של %{name}
     people_who_follow: העוקבים של %{name}
-    posts: הודעות
     posts_with_replies: חצרוצים ותגובות
     reserved_username: שם המשתמש שמור
     roles:
@@ -157,9 +141,6 @@ he:
       reject_media: חסימת קבצי מדיה
       reject_media_hint: מסירה קבצי מדיה השמורים מקומית ומונעת מהורדת קבצים נוספים בעתיד. לא רלוונטי להשעיות
       show:
-        affected_accounts:
-          one: חשבון אחד במסד הנתונים מושפע
-          other: "%{count} חשהבונות במסד הנתונים מושפעים"
         retroactive:
           silence: הסרת השתקה מכל החשבונות על שרת זה
           suspend: הסרת השעייה מכל החשבונות על שרת זה
@@ -188,8 +169,6 @@ he:
         closed_message:
           desc_html: מוצג על הדף הראשי כאשר ההרשמות סגורות<br>ניתן להשתמש בתגיות HTML
           title: מסר סגירת הרשמות
-        open:
-          title: הרשמה פתוחה
       site_description:
         desc_html: מוצג כפסקה על הדף הראשי ומשמש כתגית מטא. ניתן להשתמש בתגיות HTML, ובמיוחד ב־<code> &lt; a&gt; </code> ו־<code> &lt; em&gt; </code> .
         title: תיאור האתר
@@ -247,30 +226,15 @@ he:
       content: בדיקת אבטחה נכשלה. החסמת עוגיותיך מפנינו?
       title: בדיקת בטיחות נכשלה
     '429': הוחנק
+    '500':
   exports:
     blocks: רשימת חסימות
-    csv: CSV
     follows: רשימת נעקבים
     mutes: רשימת השתקות
     storage: אחסון מדיה
-  followers:
-    domain: קהילה
-    explanation_html: אם ברצונך להבטיח את הפרטיות של הודעותיך, יש לשים לב מי עוקב אחריך. <strong>הודעותיך הפרטיות יועברו לכל השרתים בהם יש לך עוקבים</strong>. כדאי לעבור על הרשימה ולהסיר עוקבים אם אין לך אמון בתוכנה או בצוות המפעילים של השרת הרחוק שיכבד את פרטיותך.
-    followers_count: מספר העוקבים
-    lock_link: לנעול את חשבונך
-    purge: הסרה מהעוקבים
-    success:
-      one: בתהליך חסימה של עוקבים ממתחם אחד...
-      other: בתהליך חסימה של עוקבים המגיעים מ־%{count} מתחמים...
-    true_privacy_html: 'לתשומת ליבך: <strong>פרטיות אמיתית ניתן להשיג אך ורק על ידי הצפנה מקצה לקצה</strong>.'
-    unlocked_warning_html: כל אחד יכול לעקוב אחריך כדי לראות מיידית את חצרוציך הפרטיים. %{lock_link} כדי לבחון ולדחות עוקבים.
-    unlocked_warning_title: חשבונך אינו נעול
   generic:
     changes_saved_msg: השינויים נשמרו בהצלחה!
     save_changes: שמור שינויים
-    validation_errors:
-      one: משהו לא לגמרי בסדר עדיין! אנא הציצו על השגיאה מטה
-      other: משהו לא לגמרי בסדר עדיין! אנא הציצו על %{count} השגיאות מטה
   imports:
     preface: ניתן ליבא מידע מסויים כגון כל הנעקבים או המשתמשים החסומים לתוך חשבונך על שרת זה, מתוך קבצים שנוצרו על ידי יצוא משרת אחר כגון רשימת הנעקבים והחסומים שלך.
     success: כל המידע יובא בהצלחה, ויעובד בזמן הקרוב
@@ -279,6 +243,14 @@ he:
       following: רשימת נעקבים
       muting: רשימת השתקות
     upload: יבוא
+  invites:
+    expires_in:
+      '1800': 30 minutes
+      '21600': 6 hours
+      '3600': 1 hour
+      '43200': 12 hours
+      '604800': 1 week
+      '86400': 1 day
   media_attachments:
     validations:
       images_and_video: לא ניתן להוסיף וידאו לחצרוץ שכבר מכיל תמונות
@@ -287,12 +259,6 @@ he:
     digest:
       body: להלן סיכום זריז של הדברים שקרו על מאז ביקורך האחרון ב-%{since}
       mention: "%{name} פנה אליך ב:"
-      new_followers_summary:
-        one: נוסף לך עוקב! סחתיין!
-        other: נוספו לך %{count} עוקבים חדשים! מעולה!
-      subject:
-        one: "התראה חדשה אחת מאז ביקורך האחרון \U0001F418"
-        other: "%{count} התראות חדשות \U0001F418"
     favourite:
       body: 'חצרוצך חובב על ידי %{name}:'
       subject: חצרוצך חובב על ידי %{name}
@@ -308,21 +274,9 @@ he:
     reblog:
       body: 'חצרוצך הודהד על ידי %{name}:'
       subject: חצרוצך הודהד על ידי%{name}
-  number:
-    human:
-      decimal_units:
-        format: "%n%u"
-        units:
-          billion: B
-          million: M
-          quadrillion: Q
-          thousand: K
-          trillion: T
-          unit: ''
   pagination:
     next: הבא
     prev: הקודם
-    truncate: "&hellip;"
   remote_follow:
     acct: נא להקליד שם_משתמש@קהילה מהם ברצונך לעקוב
     missing_resource: לא ניתן למצוא קישורית להפניה לחשבונך
@@ -333,10 +287,8 @@ he:
     back: חזרה למסטודון
     edit_profile: עריכת פרופיל
     export: יצוא מידע
-    followers: עוקבים מאושרים
     import: יבוא
     preferences: העדפות
-    settings: הגדרות
     two_factor_authentication: אימות דו-שלבי
   statuses:
     open_in_web: פתח ברשת
diff --git a/config/locales/hr.yml b/config/locales/hr.yml
index 38971833c1fd2ac9874d433609f01d6d1cd01b85..a4fe6205538722a87471e3240a28fc58bdce3afe 100644
--- a/config/locales/hr.yml
+++ b/config/locales/hr.yml
@@ -3,22 +3,15 @@ hr:
   about:
     about_mastodon_html: Mastodon je <em>besplatna, open-source</em> socijalna mreža. <em>Decentralizirana</em> alternativa komercijalnim platformama, izbjegava rizik toga da jedna tvrtka monopolizira vašu komunikaciju. Izaberite server kojem ćete vjerovati &mdash; koji god odabrali, moći ćete komunicirati sa svima ostalima. Bilo tko može imati svoju vlastitu Mastodon instancu i sudjelovati u <em>socijalnoj mreži</em> bez problema.
     about_this: O ovoj instanci
-    closed_registrations: Registracije na ovoj instanci su trenutno zatvorene.
     contact: Kontakt
-    other_instances: Druge instance
     source_code: Izvorni kod
-    status_count_after: statusi
     status_count_before: Tko je autor
-    user_count_after: korisnici
-    user_count_before: Home to
   accounts:
     follow: Slijedi
-    followers: Sljedbenici
     following: Slijedim
     nothing_here: Ovdje nema ničeg!
     people_followed_by: Ljudi koje %{name} slijedi
     people_who_follow: Ljudi koji slijede %{name}
-    posts: Postovi
     unfollow: Prestani slijediti
   application_mailer:
     settings: 'Promijeni e-mail postavke: %{link}'
@@ -46,22 +39,24 @@ hr:
       about_x_years: "%{count}g"
       almost_x_years: "%{count}g"
       half_a_minute: upravo
-      less_than_x_minutes: "%{count}m"
       less_than_x_seconds: upravo
       over_x_years: "%{count}g"
-      x_days: "%{count}d"
-      x_minutes: "%{count}m"
       x_months: "%{count}mj"
       x_seconds: "%{count}sek"
+  errors:
+    '403': You don't have permission to view this page.
+    '404': The page you are looking for isn't here.
+    '410': The page you were looking for doesn't exist here anymore.
+    '422': 
+    '429': Throttled
+    '500': 
   exports:
     blocks: Blokirao si
-    csv: CSV
     follows: Slijediš
     storage: Pohrana media zapisa
   generic:
     changes_saved_msg: Izmjene su uspješno sačuvane!
     save_changes: Sačuvaj izmjene
-    validation_errors: Nešto još uvijek ne štima! Vidi %{count} greške ispod
   imports:
     preface: Možeš uvesti određene podatke kao što su svi ljudi koje slijediš ili blokiraš u svoj račun na ovoj instanci, sa fajlova kreiranih izvozom sa druge instance.
     success: Tvoji podaci su uspješno uploadani i bit će obrađeni u dogledno vrijeme
@@ -69,13 +64,18 @@ hr:
       blocking: Lista blokiranih
       following: Lista onih koje slijedim
       muting: Lista utišanih
-    upload: Upload
+  invites:
+    expires_in:
+      '1800': 30 minutes
+      '21600': 6 hours
+      '3600': 1 hour
+      '43200': 12 hours
+      '604800': 1 week
+      '86400': 1 day
   notification_mailer:
     digest:
       body: Ovo je kratak sažetak propuštenog od tvog prošlog posjeta %{since}
       mention: "%{name} te je spomenuo:"
-      new_followers_summary: Imaš %{count} novih sljedbenika! Prekrašno!
-      subject: "%{count} novih notifikacija od tvog prošlog posjeta \U0001F418"
     favourite:
       body: 'Tvoj status je %{name} označio kao omiljen:'
       subject: "%{name} je označio kao omiljen tvoj status"
@@ -91,17 +91,6 @@ hr:
     reblog:
       body: 'Tvoj status je potaknut od %{name}:'
       subject: "%{name} je potakao tvoj status"
-  number:
-    human:
-      decimal_units:
-        format: "%n%u"
-        units:
-          billion: B
-          million: M
-          quadrillion: Q
-          thousand: K
-          trillion: T
-          unit: ''
   pagination:
     next: Sljedeći
     prev: Prošli
@@ -117,7 +106,6 @@ hr:
     export: Izvoz podataka
     import: Uvezi
     preferences: Postavke
-    settings: Podešenja
     two_factor_authentication: Dvo-faktorska Autentifikacija
   statuses:
     open_in_web: Otvori na webu
@@ -130,9 +118,6 @@ hr:
   stream_entries:
     reblogged: potaknut
     sensitive_content: Osjetljivi sadržaj
-  time:
-    formats:
-      default: "%b %d, %Y, %H:%M"
   two_factor_authentication:
     description_html: Ako omogućiš <strong>dvo-faktorsku autentifikaciju</strong>, prijavljivanje će zahtjevati da kod sebe imaš svoj mobitel, koji će generirati tokene koje ćeš unijeti.
     disable: Onemogući
diff --git a/config/locales/hu.yml b/config/locales/hu.yml
index d093815a8c72b73683a9ba8cf58275348e25f6ee..d771b96832fd3df682c49e2aaf33eeb958a5e4e3 100644
--- a/config/locales/hu.yml
+++ b/config/locales/hu.yml
@@ -1,63 +1,101 @@
 ---
 hu:
   about:
-    about_hashtag_html: Ezek a <strong>#%{hashtag}</strong> címkével ellátott publikus tülkök. Reagálhatsz rájuk, ha már van felhasználói fiókod valahol a föderációban.
-    about_mastodon_html: Mastodon egy <em>szabad, nyílt forráskódú</em> szociális hálózati kiszolgálo. Egy <em>központosítatlan</em> alternatíva a kereskedelmi platformokra, elkerüli a kommunikációd monopolizációját veszélyét. Bárki futtathatja a Mastodon-t és részt vehet a <em>szociális hálózatban</em>.
+    about_hashtag_html: Ezek a <strong>#%{hashtag}</strong> hashtag-gel ellátott publikus tülkök. Reagálhatsz rájuk, ha már van felhasználói fiókod valahol a föderációban.
+    about_mastodon_html: A Mastodon egy szabad webes protokollokat használó, nyílt forráskódú szociális háló. Decentralizált, akár az e-mail.
     about_this: Rólunk
-    closed_registrations: A regisztráció jelenleg nem engedélyezett ezen az instancián. De ne csüggedj! Létrehozhatsz fiókot egy másik instancián és azon keresztül is hozzáférsz a teljes föderációhoz.
+    active_count_after: aktív
+    active_footnote: Havonta aktív felhasználók
+    administered_by: 'Adminisztrátor:'
+    api: API
+    apps: Mobil appok
+    apps_platforms: Használd a Mastodont iOS-ről, Androidról vagy más platformról
+    browse_directory: Böngészd a profil adatbázist és szűrj érdeklődési kör szerint
+    browse_public_posts: Nézz bele a Mastodon élő adatfolyamába
     contact: Kapcsolat
     contact_missing: Nincs megadva
     contact_unavailable: N/A
+    discover_users: Találj meg másokat
+    documentation: Dokumentáció
     extended_description_html: |
       <h3>Ez itt a szabályzat helye</h3>
       <p>Még nem állítottál be bővebb leírást.</p>
-    features:
-      humane_approach_body: Más alkalmazások hibáiból tanulva a Mastodon etikus alapokon nyugvó döntésekkel küzd a közösségi média ártalmai ellen.
-      humane_approach_title: Emberséges attitűd
-      not_a_product_body: A Mastodon nem a profitszerzésre épül, nem is privát játszótér. Nincsenek reklámok, nincs adatbányászat és központosított döntéshozatal sincsen.
-      not_a_product_title: Ember vagy, nem pedig árucikk
-      real_conversation_body: Az 65535 karakteres limit, az érzékeny tartalomként jelölés és más kifinomult eszközök segítségével tényleg egyedi módon fejezheted ki önmagad.
-      real_conversation_title: Valódi beszélgetésekre tervezve
-      within_reach_body: A fejlesztőbarát API-nak köszönhetően számos iOS, Android és egyéb platformra írt alkalmazás teszi lehetővé, hogy bármikor, bárhonnan részt vehess a társalgásban.
-      within_reach_title: Mindig elérhetőnek lenni
+    federation_hint_html: Egy %{instance} fiókkal bármely más Mastodon szerveren vagy a föderációban lévő felhasználót követni tudsz.
     generic_description: "%{domain} csak egy a számtalan szerver közül a föderációban"
-    hosted_on: "%{domain} Mastodon instancia"
+    get_apps: Próbálj ki egy mobil appot
+    hosted_on: "%{domain} Mastodon szerver"
     learn_more: Tudj meg többet
-    other_instances: Instanciák listája
+    privacy_policy: Adatvédelmi szabályzat
+    see_whats_happening: Nézd, mi történik
+    server_stats: 'Szerver statisztika:'
     source_code: Forráskód
-    status_count_after: tülköt küldött
+    status_count_after:
+      one: tülköt küldött
+      other: tülköt küldött
     status_count_before: eddig
-    user_count_after: felhasználónk
+    tagline: Kövess barátokat és találj újakat
+    terms: Felhasználási feltételek
+    user_count_after:
+      one: felhasználónk
+      other: felhasználónk
     user_count_before: Összesen
     what_is_mastodon: Mi a Mastodon?
   accounts:
+    choices_html: "%{name} választásai:"
     follow: Követés
-    followers: Követők
-    following: Követed őket
+    followers:
+      one: Követő
+      other: Követő
+    following: Követett
+    joined: Csatlakozott %{date}
+    last_active: utoljára aktív
+    link_verified_on: A link tulajdonosát %{date} -n ellenőriztük
     media: Média
     moved_html: "%{name} ide költözött: %{new_profile_link}"
+    network_hidden: Ez az információ nem elérhető
     nothing_here: Nincs itt semmi!
-    people_followed_by: "%{name} követett személyei"
+    people_followed_by: "%{name} követettjei"
     people_who_follow: "%{name} követői"
-    posts: Tülkök
-    posts_with_replies: Tülkök és válaszok
-    reserved_username: Ez egy már lefoglalt felhasználónév
+    pin_errors:
+      following: Ehhez szükséges, hogy kövesd már a felhasználót
+    posts:
+      one: Tülk
+      other: Tülk
+    posts_tab_heading: Tülkölés
+    posts_with_replies: Tülkölés válaszokkal
+    reserved_username: Ez már foglalt felhasználónév
     roles:
       admin: Adminisztrátor
+      bot: Bot
       moderator: Moderátor
-    unfollow: Követés abbahagyása
+    unavailable: Nincs ilyen profil
+    unfollow: Követés vége
   admin:
+    account_actions:
+      action: Művelet végrehajtása
+      title: "%{acct} moderálása"
     account_moderation_notes:
-      create: Új bejegyzés
+      create: Új moderációs bejegyzés
       created_msg: Moderációs bejegyzés létrehozva!
       delete: Törlés
       destroyed_msg: Moderációs bejegyzés törölve!
     accounts:
+      approve: Jóváhagyás
+      approve_all: Mindet jóváhagy
       are_you_sure: Biztos vagy benne?
+      avatar: Profilkép
       by_domain: Domain
+      change_email:
+        changed_msg: A fiókhoz tartozó e-mailt megváltoztattuk!
+        current_email: Jelenlegi e-mail
+        label: E-mail megváltoztatása
+        new_email: Új e-mail
+        submit: E-mail megváltoztatása
+        title: "%{username} felhasználó e-mail változás"
       confirm: Megerősítés
       confirmed: Megerősítve
-      confirming: Megerősítve
+      confirming: Megerősítés alatt
+      deleted: Törölve
       demote: Lefokozás
       disable: Kikapcsolás
       disable_two_factor_authentication: Kétlépcsős azonosítás kikapcsolása
@@ -67,42 +105,54 @@ hu:
       edit: Szerkesztés
       email: E-mail
       email_status: E-mail állapot
-      enable: Engedélyezés
-      enabled: Engedélyezve
+      enable: Bekapcsolás
+      enabled: Bekapcsolva
       feed_url: Hírcsatorna URL
-      followers: Követők
-      followers_url: Követők URL
-      follows: Követettek
+      followers: Követő
+      followers_url: Követő URL
+      follows: Követett
+      header: Fejléc
       inbox_url: Beérkezett üzenetek URL
+      invited_by: Meghívta
       ip: IP
+      joined: Csatlakozott
       location:
         all: Összes
         local: Helyi
         remote: Távoli
         title: Hely
-      login_status: Bejelentkezve
+      login_status: Bejelentkezési állapot
       media_attachments: Média-csatolmányok
       memorialize: Emlékállítás
       moderation:
+        active: Aktív
         all: Összes
+        pending: Függőben
         silenced: Némítva
         suspended: Felfüggesztve
         title: Moderáció
       moderation_notes: Moderációs bejegyzés
       most_recent_activity: Legutóbbi tevékenységek
       most_recent_ip: Legutóbbi IP-cím
+      no_account_selected: Nem változott meg egy fiók sem, mert semmi sem volt kiválasztva
+      no_limits_imposed: Nem állítottunk be határértéket
       not_subscribed: Nincs feliratkozás
       outbox_url: Kimenő üzenetek URL
-      perform_full_suspension: Teljes felfüggesztés
+      pending: Engedélyezés alatt
+      perform_full_suspension: Felfüggesztés
       profile_url: Profil URL
       promote: Előléptetés
       protocol: Protokoll
       public: Nyilvános
       push_subscription_expires: A PuSH feliratkozás elévül
       redownload: Profilkép frissítése
+      reject: Elutasítás
+      reject_all: Összes elutasítása
+      remove_avatar: Profilkép eltávolítása
+      remove_header: Fejléc törlése
       resend_confirmation:
         already_confirmed: Ezt a felhasználót már megerősítették
-        send: Küldd újra a megerősítő email-t
+        send: Küldd újra a megerősítő e-mailt
         success: A megerősítő e-mail sikeresen elküldve!
       reset: Visszaállítás
       reset_password: Jelszó visszaállítása
@@ -115,86 +165,130 @@ hu:
         user: Felhasználó
       salmon_url: Salmon URL
       search: Keresés
-      shared_inbox_url: Bejövő üzenetek URL keresése
+      shared_inbox_url: Megosztott bejövő üzenetek URL
       show:
-        created_reports: Ezen fiók által létrehozott jelentések
-        targeted_reports: Jelentések ezzel a fiókkal kapcsolatban
+        created_reports: Létrehozott jelentések
+        targeted_reports: Jelentések ezzel kapcsolatban
       silence: Némítás
+      silenced: Némított
       statuses: Tülkök
       subscribe: Feliratkozás
+      suspended: Felfüggesztett
+      time_in_queue: Várakozás a sorban %{time}
       title: Fiókok
+      unconfirmed_email: Nem megerősített e-mail
       undo_silenced: Némítás visszavonása
       undo_suspension: Felfüggesztés visszavonása
       unsubscribe: Leiratkozás
       username: Felhasználónév
-      web: Weboldal
+      warn: Figyelmeztetés
+      web: Web
     action_logs:
       actions:
+        assigned_to_self_report: "%{name} a %{target} bejelentést magához rendelte"
+        change_email_user: "%{name} megváltoztatta %{target} felhasználó e-mail címét"
         confirm_user: "%{name} megerősítette e-mail címét: %{target}"
-        create_custom_emoji: "%{name} új hangulatjelet töltött fel: %{target}"
+        create_account_warning: "%{name} figyelmeztetést küldött %{target} felhasználónak"
+        create_custom_emoji: "%{name} új emojit töltött fel: %{target}"
         create_domain_block: "%{name} letiltotta az alábbi domaint: %{target}"
         create_email_domain_block: "%{name} feketelistára tette az alábbi e-mail domaint: %{target}"
         demote_user: "%{name} lefokozta az alábbi felhasználót: %{target}"
+        destroy_custom_emoji: "%{name} törölte az emojit: %{target}"
         destroy_domain_block: "%{name} engedélyezte az alábbi domaint: %{target}"
         destroy_email_domain_block: "%{name} fehérlistára tette az alábbi e-mail domaint: %{target}"
         destroy_status: "%{name} eltávolította az alábbi felhasználó tülkjét: %{target}"
         disable_2fa_user: "%{name} kikapcsolta a kétlépcsős azonosítást %{target} felhasználó fiókján"
-        disable_custom_emoji: "%{name} letiltotta az alábbi hangulatjelet: %{target}"
+        disable_custom_emoji: "%{name} letiltotta az alábbi emojit: %{target}"
         disable_user: "%{name} letiltotta az alábbi felhasználó bejelentkezését: %{target}"
-        enable_custom_emoji: "%{name} engedélyezte az alábbi hangulatjelet: %{target}"
+        enable_custom_emoji: "%{name} engedélyezte az alábbi emojit: %{target}"
         enable_user: "%{name} engedélyezte az alábbi felhasználó bejelentkezését: %{target}"
         memorialize_account: "%{name} emléket állított az alábbi felhasználónak: %{target}"
         promote_user: "%{name} előléptette az alábbi felhasználót: %{target}"
+        remove_avatar_user: "%{name} törölte %{target} profilképét"
+        reopen_report: "%{name} újranyitotta a bejelentést: %{target}"
         reset_password_user: "%{name} visszaállította az alábbi felhasználó jelszavát: %{target}"
-        resolve_report: "%{name} mellőzte az alábbi jelentést: %{target}"
+        resolve_report: "%{name} megoldotta alábbi bejelentést: %{target}"
         silence_account: "%{name} lenémította %{target} felhasználói fiókját"
         suspend_account: "%{name} felfüggesztette %{target} felhasználói fiókját"
+        unassigned_report: "%{name} törölte a %{target} bejelentés hozzárendelését"
         unsilence_account: "%{name} feloldotta a némítást %{target} felhasználói fiókján"
         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_custom_emoji: "%{name} frissítette az alábbi emojit: %{target}"
         update_status: "%{name} frissítette %{target} felhasználó tülkjét"
+      deleted_status: "(törölt tülk)"
       title: Audit napló
     custom_emojis:
       by_domain: Domain
-      copied_msg: Sikeresen létrehoztuk a hangulatjel helyi másolatát
+      copied_msg: Sikeresen létrehoztuk az emoji helyi másolatát
       copy: Másolás
-      copy_failed_msg: Hangulatjel helyi másolatának létrehozása sikertelen
-      created_msg: Hangulatjel létrehozva!
+      copy_failed_msg: Emoji helyi másolatának létrehozása sikertelen
+      created_msg: Emoji létrehozva!
       delete: Törlés
-      destroyed_msg: A hangulatjel törlése sikeres!
+      destroyed_msg: Emoji törlése sikeres!
       disable: Letiltás
-      disabled_msg: Hangulatjel letiltva
-      emoji: Hangulatjel
+      disabled_msg: Emoji letiltva
+      emoji: Emoji
       enable: Engedélyezés
-      enabled_msg: Hangulatjel engedélyezve
+      enabled_msg: Emoji engedélyezve
       image_hint: PNG (maximális méret 50KB)
       listed: Listázva
       new:
-        title: Új egyedi hangulatjel hozzáadása
+        title: Új egyedi emoji hozzáadása
       overwrite: Felülírás
-      shortcode: Shortcode
+      shortcode: Rövidítés
       shortcode_hint: Legalább két karakter, csak betűk, számok és alsóvonás
-      title: Egyedi hangulatjelek
+      title: Egyedi emojik
       unlisted: Nincs listázva
-      update_failed_msg: Nem sikerült frissíteni a hangulatjelet
-      updated_msg: Hangulatjel sikeresen frissítve!
+      update_failed_msg: Nem sikerült frissíteni az emojit
+      updated_msg: Emoji sikeresen frissítve!
       upload: Feltöltés
+    dashboard:
+      backlog: hátralévő feladatok
+      config: Beállítások
+      feature_deletions: Fióktörlések
+      feature_invites: Meghívó linkek
+      feature_profile_directory: Profil adatbázis
+      feature_registrations: Regisztráció
+      feature_relay: Föderációs relé
+      feature_timeline_preview: Idővonal betekintő
+      features: Funkciók
+      hidden_service: Föderáció rejtett szolgáltatásokkal
+      open_reports: nyitott bejelentések
+      recent_users: Legutóbbi felhasználók
+      search: Keresés teljes szövegben
+      single_user_mode: Egyfelhasználós mód
+      software: Szoftver
+      space: Tárhely használat
+      title: Műszerfal
+      total_users: felhasználó összesen
+      trends: Trendek
+      week_interactions: interakció ezen a héten
+      week_users_active: aktív ezen a héten
+      week_users_new: felhasználó ezen a héten
     domain_blocks:
-      add_new: Új hozzáadása
+      add_new: Új tiltott domain hozzáadása
       created_msg: A domain-tiltás feldolgozása folyamatban
       destroyed_msg: A domain tiltása feloldva
       domain: Domain
+      existing_domain_block_html: A %{name} domainen már szorosabb korlátokat állítottál be, először <a href="%{unblock_url}">oldd fel a tiltást</a>.
       new:
         create: Tiltás létrehozása
-        hint: A domain-tiltás nem gátolja meg az új fiókok hozzáadását az abatbázishoz, de visszamenőlegesen és automatikusan aktivál bizonyos moderációs szabályokat ezen fiókok esetében.
+        hint: A domain tiltása nem gátolja meg az új fiókok hozzáadását az abatbázishoz, de visszamenőlegesen és automatikusan aktivál bizonyos moderációs szabályokat ezen fiókok esetében.
         severity:
           desc_html: A <strong>Némítás</strong> elrejti az adott felhasználó tülkjeit mindenki elől, aki nem követi az adott felhasználót. A <strong>Felfüggesztés</strong> eltávolítja az adott felhasználó által létrehozott minden tartalmat, ide értve a médiafájlokat és a fiókadatokat is. Válaszd az <strong>Egyik sem</strong> opciót, ha csupán a médiafájlokat szeretnéd elutasítani.
           noop: Egyik sem
           silence: Némítás
           suspend: Felfüggesztés
-        title: Új domain-tiltás
+        title: Új domain tiltása
       reject_media: Médiafájlok elutasítása
       reject_media_hint: Eltávolítja a helyben tárolt médiafájlokat és a továbbiakban letiltja az új médiafájlok letöltését. Felfüggesztett fiókok esetében irreleváns opció
+      reject_reports: Bejelentések elutasítása
+      reject_reports_hint: Erről a domainről származó minden bejelentés elutasítása. Felfüggesztett fiókok esetén irreleváns opció
+      rejecting_media: médiafájlok elutasítása
+      rejecting_reports: bejelentések elutasítása
+      severity:
+        silence: némítva
+        suspend: felfüggesztve
       show:
         affected_accounts:
           one: Összesen egy fiók érintett az adatbázisban
@@ -204,7 +298,7 @@ hu:
           suspend: Minden felhasználó felfüggesztésének feloldása ezen a domainen
         title: "%{domain} domain tiltásának feloldása"
         undo: Visszavonás
-      undo: Visszavonás
+      undo: Domain tiltásának visszavonása
     email_domain_blocks:
       add_new: Új hozzáadása
       created_msg: E-mail domain sikeresen hozzáadva a feketelistához
@@ -215,41 +309,111 @@ hu:
         create: Domain hozzáadása
         title: Új e-mail feketelista bejegyzés
       title: E-mail feketelista
+    followers:
+      back_to_account: Vissza a fiókhoz
+      title: "%{acct} követői"
     instances:
-      title: Nyilvántartott instanciák
+      by_domain: Domain
+      delivery_available: Kézbesítés elérhető
+      known_accounts:
+        one: "%{count} ismert fiók"
+        other: "%{count} ismert fiók"
+      moderation:
+        all: Mind
+        limited: Korlátozott
+        title: Moderáció
+      title: Föderáció
+      total_blocked_by_us: Általunk letiltott
+      total_followed_by_them: Általuk követett
+      total_followed_by_us: Általunk követett
+      total_reported: Bejelentés róluk
+      total_storage: Média csatolmány
     invites:
+      deactivate_all: Összes deaktiválása
       filter:
         all: Összes
         available: Elérhető
         expired: Elévült
         title: Szűrő
       title: Meghívások
+    pending_accounts:
+      title: Függőben lévő fiókok (%{count})
+    relays:
+      add_new: Új relé hozzáadása
+      delete: Törlés
+      description_html: A <strong>föderációs relé</strong> egy olyan köztes szerver, mely nagy mennyiségű publikus tülköt cserél az erre feliratkozó vagy publikáló szerverek között. <strong>Ezzel segíthet kis és közepes szervereknek tartalmat megtalálni a föderációban</strong>, mely egyébként csak akkor válna lehetővé, ha a saját felhasználóink más szervereken lévő fiókokat követnének.
+      disable: Kikapcsolás
+      disabled: Kikapcsolva
+      enable: Bekapcsolás
+      enable_hint: Ha bekapcsolod, a szerver minden nyilvános tülkre feliratkozik ezen a relén, valamint az összes nyilvános tülköt elküldi ennek.
+      enabled: Bekapcsolva
+      inbox_url: Relé URL
+      pending: Várakozás a relé jóváhagyására
+      save_and_enable: Mentés és engedélyezés
+      setup: Relé kapcsolat felállítása
+      status: Állapot
+      title: Relék
+    report_notes:
+      created_msg: Bejelentési feljegyzés létrehozva!
+      destroyed_msg: Bejelentési feljegyzés törölve!
     reports:
+      account:
+        note: feljegyzés
+        report: bejelentés
       action_taken_by: 'Kezelte:'
       are_you_sure: Biztos vagy benne?
+      assign_to_self: Magamhoz rendelés
+      assigned: Hozzárendelt moderátor
       comment:
         none: Egyik sem
+      created_at: Jelentve
       mark_as_resolved: Megjelölés megoldottként
+      mark_as_unresolved: Megjelölés megoldatlanként
+      notes:
+        create: Feljegyzés hozzáadása
+        create_and_resolve: Megoldás feljegyzéssel
+        create_and_unresolve: Újranyitás feljegyzéssel
+        delete: Törlés
+        placeholder: Jegyezd le, mi tettünk az ügy érdekében, vagy bármilyen változást...
+      reopen: Bejelentés újranyitása
       report: "#%{id} számú jelentés"
       reported_account: Bejelentett fiók
       reported_by: 'Jelentette:'
       resolved: Megoldott
+      resolved_msg: A bejelentést sikeresen megoldottuk!
       status: Állapot
-      title: Jelentések
+      title: Bejelentések
+      unassign: Hozzárendelés törlése
       unresolved: Megoldatlan
+      updated_at: Frissítve
     settings:
       activity_api_enabled:
         desc_html: Helyi tülkök, aktív felhasználók és új regisztrációk száma heti bontásban
         title: Felhasználói aktivitás összesített statisztikájának publikussá tétele
       bootstrap_timeline_accounts:
-        desc_html: Az egyes felhasználónevek vesszővel elválasztva. Csak helyi és aktivált fiókok esetében működik. Üresen (alapértelmezettként) minden helyi adminisztrátorra érvényes.
+        desc_html: Az egyes felhasználóneveket vesszővel válaszd el! Csak helyi és aktivált fiókok esetében működik. Üresen (alapértelmezettként) minden helyi adminisztrátorra érvényes.
         title: Alapértelmezett követések új felhasználók esetében
       contact_information:
         email: Kapcsolattartói e-mail cím
         username: Kapcsolattartó felhasználóneve
+      custom_css:
+        desc_html: Változtasd meg a kinézetet ebben a CSS-ben, mely minden oldalon be fog töltődni
+        title: Egyedi CSS
+      hero:
+        desc_html: A kezdőoldalon látszik. Legalább 600x100px méret javasolt. Ha nincs beállítva, a szerver bélyegképet használjuk
+        title: Hősi kép
+      mascot:
+        desc_html: Több oldalon is látszik. Legalább 293×205px méret javasolt. Ha nincs beállítva, az alapértelmezett kabalát használjuk
+        title: Kabala kép
       peers_api_enabled:
-        desc_html: Domainek, amelyekkel ez az instancia kapcsolatban áll
-        title: Instanciák listájának közzététele, melyekkel ez a szerver kapcsolatban áll
+        desc_html: Domainek, amelyekkel ez a szerver kapcsolatban áll
+        title: Szerverek listájának közzététele, melyekkel ez a szerver kapcsolatban áll
+      preview_sensitive_media:
+        desc_html: Más weboldalakon linkelt tartalmaink előnézetében mindenképp benne lesz egy bélyegkép még akkor is, ha a médiát szenzitívnek jelölték meg
+        title: Szenzitív média mutatása OpenGraph előnézetben
+      profile_directory:
+        desc_html: Lehetővé teszi, hogy a felhasználóinkat megtalálják
+        title: Profil adatbázis engedélyezése
       registrations:
         closed_message:
           desc_html: Ez az üzenet jelenik meg a főoldalon, ha a regisztráció nem engedélyezett. HTML-tageket is használhatsz
@@ -258,41 +422,51 @@ hu:
           desc_html: Engedélyezed a felhasználóknak, hogy töröljék fiókjukat
           title: Fiók törlésének engedélyezése
         min_invite_role:
-          disabled: Senkinek
+          disabled: Senki
           title: Meghívások engedélyezése
-        open:
-          desc_html: Bárki létrehozhat felhasználói fiókot
-          title: Nyitott regisztráció
+      registrations_mode:
+        modes:
+          approved: A regisztráció engedélyhez kötött
+          none: Senki sem regisztrálhat
+          open: Bárki regisztrálhat
+        title: Regisztrációs mód
+      show_known_fediverse_at_about_page:
+        desc_html: Ha aktív, az előnézetben minden tülk megjelenik a velünk kapcsolatban álló szerverekről, egyébként csak helyi tülköket mutatunk.
+        title: Mutassuk az általunk ismert föderációt az idővonal előnézetben
       show_staff_badge:
         desc_html: Stáb-jelvény megjelenítése a felhasználó oldalán
         title: Stáb-jelvény megjelenítése
       site_description:
-        desc_html: 'Rövid bemutatkozás a főoldalon és a meta fejlécekben. Az alábbi HTML-tageket használhatod: <code>&lt;a&gt;</code> és <code>&lt;em&gt;</code>.'
-        title: Az instancia bemutatása
+        desc_html: Rövid bemutatkozás a főoldalon és a meta fejlécekben. Írd le, mi teszi ezt a szervert különlegessé! Használhatod a <code>&lt;a&gt;</code> és <code>&lt;em&gt;</code> HTML tageket.
+        title: A szerver bemutatása
       site_description_extended:
-        desc_html: Ide teheted például a közösségi és egyéb szabályzatot, útmutatókat és mindent, ami egyedivé teszi instanciádat. HTML-tageket is használhatsz
+        desc_html: Ide teheted például a közösségi és egyéb szabályzatot, útmutatókat és mindent, ami egyedivé teszi szerveredet. HTML-tageket is használhatsz
         title: További egyedi információ
+      site_short_description:
+        desc_html: Oldalsávban és meta tag-ekben jelenik meg. Írd le, mi teszi ezt a szervert különlegessé egyetlen bekezdésben.
+        title: Rövid leírás
       site_terms:
         desc_html: Megírhatod saját adatkezelési szabályzatodat, felhasználási feltételeidet vagy más hasonló jellegű dokumentumodat. HTML-tageket is használhatsz
         title: Egyedi felhasználási feltételek
-      site_title: Az instancia neve
+      site_title: A szerver neve
       thumbnail:
-        desc_html: Az OpenGraph és API előnézetekhez használjuk. Ajánlott mérete 1200x560 pixel
-        title: Az instancia bélyegképe
+        desc_html: OpenGraph-os és API-s előnézetekben használjuk. Ajánlott mérete 1200x630 pixel
+        title: A szerver bélyegképe
       timeline_preview:
-        desc_html: Publikus időfolyam megjelenítése a főoldalon
-        title: Időfolyam előnézete
-      title: Oldal beállításai
+        desc_html: Nyilvános idővonal megjelenítése a főoldalon
+        title: Idővonal előnézete
+      title: Webhely beállításai
     statuses:
       back_to_account: Vissza a fiók oldalára
       batch:
         delete: Törlés
-        nsfw_off: Szenzitív tartalom kikapcsolva
-        nsfw_on: Szenzitív tartalom bekapcsolva
+        nsfw_off: Szenzitív megjelölés törlése
+        nsfw_on: Megjelölés szenzitív tartalomként
       failed_to_execute: Végrehajtás sikertelen
       media:
         title: Média
       no_media: Nem található médiafájl
+      no_status_selected: Nem változtattunk meg semmit, mert semmi sem volt kiválasztva
       title: Felhasználó tülkjei
       with_media: Médiafájlokkal
     subscriptions:
@@ -302,14 +476,38 @@ hu:
       last_delivery: Utolsó kézbesítés
       title: WebSub
       topic: Téma
+    tags:
+      accounts: Fiókok
+      hidden: Rejtett
+      hide: Ne jelenjen meg a profilok adatbázisában
+      name: Hashtag
+      title: Hashtagek
+      unhide: Jelenjen meg a profilok adatbázisában
+      visible: Látható
     title: Karbantartás
+    warning_presets:
+      add_new: Új hozzáadása
+      delete: Törlés
+      edit: Szerkesztés
+      edit_preset: Figyelmeztetés szerkesztése
+      title: Figyelmeztetések
   admin_mailer:
+    new_pending_account:
+      body: Az új fiók részletesen alább látható. Ezt a jelentkezést engedélyezheted vagy elutasíthatod.
+      subject: Új fiók (%{username}) engedélyezésre vár a %{instance} szerveren
     new_report:
       body: "%{reporter} jelentette: %{target}"
-      subject: 'Új jelentés az alábbi instancián: %{instance} (#%{id})'
+      body_remote: Valaki a %{domain} domainről jelentette %{target}
+      subject: 'Új jelentés az alábbi szerveren: %{instance} (#%{id})'
+  appearance:
+    advanced_web_interface: Haladó webes felület
+    advanced_web_interface_hint: 'Ha szeretnéd, a teljes képernyőszélességet felhasználhatod. A haladó webes felülettel különböző oszlopokat állíthatsz be, hogy egyszerre annyi infót láthass, amennyit csak akarsz: Saját idővonal, értesítések, föderációs idővonal, bármennyi lista vagy hashtag.'
+    animations_and_accessibility: Animáció és akadálymentesítés
+    confirmation_dialogs: Megerősítő párbeszédablakok
+    sensitive_content: Szenzitív tartalom
   application_mailer:
     notification_preferences: E-mail beállítások módosítása
-    salutation: "%{name},"
+    salutation: "%{name}!"
     settings: 'E-mail beállítások módosítása: %{link}'
     view: 'Megtekintés:'
     view_profile: Profil megtekintése
@@ -323,7 +521,10 @@ hu:
     warning: Ez érzékeny adat. Soha ne oszd meg másokkal!
     your_token: Hozzáférési kulcsod
   auth:
-    agreement_html: A feliratkozással elfogatod az <a href="%{rules_path}">instancia szabályzatát</a> és a <a href="%{terms_path}">felhasználási feltételeket</a>.
+    apply_for_account: Meghívó kérése
+    change_password: Jelszó
+    checkbox_agreement_html: Egyetértek a <a href="%{rules_path}" target="_blank">szerver szabályaival</a> és a <a href="%{terms_path}" target="_blank">felhasználási feltételekkel</a>
+    confirm_email: E-mail megerősítése
     delete_account: Felhasználói fiók törlése
     delete_account_html: Felhasználói fiókod törléséhez <a href="%{path}">kattints ide</a>. A rendszer újbóli megerősítést fog kérni.
     didnt_get_confirmation: Nem kaptad meg a megerősítési lépéseket?
@@ -333,12 +534,19 @@ hu:
     logout: Kijelentkezés
     migrate_account: Felhasználói fiók költöztetése
     migrate_account_html: Ha szeretnéd átirányítani ezt a fiókodat egy másikra, a beállításokat <a href="%{path}">itt találod meg</a>.
+    or_log_in_with: Vagy jelentkezz be ezzel
+    providers:
+      cas: CAS
+      saml: SAML
     register: Regisztráció
+    registration_closed: "%{instance} nem fogad új tagokat"
     resend_confirmation: Megerősítési lépések újraküldése
     reset_password: Jelszó visszaállítása
     security: Biztonság
     set_new_password: Új jelszó beállítása
+    trouble_logging_in: Problémád van a bejelentkezéssel?
   authorize_follow:
+    already_following: Már követed ezt a felhasználót
     error: Hiba történt a távoli felhasználó keresésekor
     follow: Követés
     follow_request: 'Engedélyt kértél az alábbi felhasználó követésére:'
@@ -367,9 +575,19 @@ hu:
     confirm_password: Személyazonosságod megerősítéséhez írd be a jelenlegi jelszavad
     description_html: Ezzel <strong>véglegesen és visszafordíthatatlanul</strong> törlöd minden tartalmadat és deaktiválod a fiókodat. A felhasználónevedet megtartjuk, hogy megakadályozzuk a neveddel történő jövőbeni visszaélések lehetőségét.
     proceed: Felhasználói fiók törlése
-    success_msg: Felhasználói fiókod sikeresen törölve lett
-    warning_html: Csak azt tudjuk garantálni, hogy az általad létrehozott tartalmat erről az instanciáról töröljük. Ha egyes tartalmaidat sokan megosztották, valószínűleg marad nyomuk a megosztások miatt. Nam fogjuk tudni frissíteni azon instanciák adatbázisát, amelyek nem kapcsolódnak a föderációhoz vagy amelyek leiratkoztak a tülkjeidről.
+    success_msg: Felhasználói fiókod sikeresen töröltük
+    warning_html: Csak azt tudjuk garantálni, hogy az általad létrehozott tartalmat erről a szerverről töröljük. Ha egyes tartalmaidat sokan megosztották, valószínűleg marad nyomuk a megosztások miatt. Nem fogjuk tudni frissíteni azon szerverek adatbázisát, amelyek nem kapcsolódnak a föderációhoz vagy amelyek leiratkoztak a tülkjeidről.
     warning_title: Szórt tartalmak elérése
+  directories:
+    directory: Profilok
+    enabled: Szerepelsz a profil adatbázisban.
+    enabled_but_waiting: Engedélyezted, hogy szerepelj a profil adatbázisban, de még nincs elegendő követőd (%{min_followers}) ehhez.
+    explanation: Találj másokra érdeklődésük alapján
+    explore_mastodon: "%{title} felfedezése"
+    how_to_enable: Nem engedélyezted a profil adatbázisban való megjelenésed. Engedélyezheted alább. Használj hashtageket az életrajzodban, hogy az ezekhez tartozó listákba bekerülj!
+    people:
+      one: "%{count} ember"
+      other: "%{count} ember"
   errors:
     '403': Nincs jogosultságod az oldal megtekintéséhez.
     '404': Az általad keresett oldal nem található.
@@ -377,40 +595,93 @@ hu:
     '422':
       content: Megerősítés sikertelen. Nem tiltottad le esetleg a sütiket?
       title: Megerősítés sikertelen
-    '429': Kampec
+    '429': Korlátozva
     '500':
       content: Sajnáljuk, valami hiba történt a mi oldalunkon.
       title: Az oldal nem megfelelő
-    noscript_html: A Mastodon webalkalmazás használatához engedélyezned kell a JavaScriptet. A másik megoldás, hogy kipróbálod az egyik, a platformodnak megfelelő <a href="%{apps_path}">alkalmazást</a>.
+    noscript_html: A Mastodon webalkalmazás használatához engedélyezned kell a JavaScriptet. A másik megoldás, hogy kipróbálsz egy platformodnak megfelelő <a href="%{apps_path}">alkalmazást</a>.
+  existing_username_validator:
+    not_found: ezzel a névvel nem találtunk helyi felhasználót
+    not_found_multiple: nem találtuk %{usernames} felhasználó(ka)t
   exports:
+    archive_takeout:
+      date: Dátum
+      download: Archív letöltése
+      hint_html: Itt kérhető egy archív az összes <strong>feltöltött tülködről és médiádról</strong>. Az exportált adatok ActivityPub formátumban lesznek, melyet bármilyen szabványos program tud olvasni. 7 naponként kérhetsz ilyen archívot.
+      in_progress: Archív összeállítása...
+      request: Archív kérése
+      size: Méret
     blocks: Tiltólistádon
     csv: CSV
+    domain_blocks: Tiltott domainjeid
     follows: Követettjeid
+    lists: Listáid
     mutes: Némításaid
     storage: Médiatároló
-  followers:
-    domain: Domain
-    explanation_html: Ahhoz, hogy biztosítsd a tülkjeid adatvédelmét, tudnod kell, kik követnek téged. <strong>Még privátnak jelölt tülkjeid is továbbítódnak minden instanciára, ahol követőid vannak</strong>. Az alábbi listában láthatod, melyek ezek az instanciák; eltávolíthatod őket, ha nem vagy biztos benne, hogy az adott instancia üzemeltetői tiszteletben tartják az adatvédelmi beállításaidat.
-    followers_count: Követők száma
-    lock_link: Fiókod priváttá tétele
-    purge: Eltávolítás a követőid közül
-    success:
-      one: Egy domainen található követőid tiltása folyamatban...
-      other: "%{count} domainen található követőid tiltása folyamatban..."
-    true_privacy_html: Tartsd észben, hogy <strong>valódi biztonság csak végponttól-végpontig titkosítással érhető el</strong>.
-    unlocked_warning_html: Bárki követhet és így azonnal láthatja a privát tülkjeid. A %{lock_link} funkció bekapcsolásával lehetőséged van egyenként felülvizsgálni a követési kérelmeket.
-    unlocked_warning_title: A fiókod jelenleg nem privát
+  featured_tags:
+    add_new: Új hozzáadása
+    errors:
+      limit: Már kiemelted a maximálisan engedélyezett számú hashtaget
+  filters:
+    contexts:
+      home: Saját idővonal
+      notifications: Értesítések
+      public: Nyilvános idővonalak
+      thread: Beszélgetések
+    edit:
+      title: Szűrő szerkesztése
+    errors:
+      invalid_context: A megadott kontextus hamis vagy hiányzik
+      invalid_irreversible: Visszafordíthatatlan szűrést csak saját idővonalon vagy értesítéseken lehet végezni
+    index:
+      delete: Törlés
+      title: Szűrők
+    new:
+      title: Új szűrő hozzáadása
+  footer:
+    developers: Fejlesztőknek
+    more: Többet…
+    resources: Segédanyagok
   generic:
-    changes_saved_msg: Változások sikeresen elmentve!
+    all: Mind
+    changes_saved_msg: A változásokat elmentettük!
+    copy: Másolás
+    order_by: Rendezés
     save_changes: Változások mentése
     validation_errors:
       one: Valami nincs rendjén! Kérlek tekintsd meg a hibát alant
       other: Valami nincs rendjén! Kérlek tekintsd meg a %{count} darab hibát alant
+  html_validator:
+    invalid_markup: 'hibás HTML leíró: %{error}'
+  identity_proofs:
+    active: Aktív
+    authorize: Igen, engedélyezés
+    authorize_connection_prompt: Engedélyezed ezt a kriptografikus kapcsolatot?
+    errors:
+      failed: A kriptografikus kapcsolat sikertelen. Próbáld inkább innen %{provider}.
+      keybase:
+        invalid_token: A Keybase tokenek hashelt aláírások és pont 66 hexa karakterből állnak
+        verification_failed: A Keybase ezt a tokent nem ismerte fel a %{kb_username} Keybase felhasználó aláírásaként. Próbáld újra Keybase-ből.
+      wrong_user: Nem tudjuk tanúsítani %{proving} felhasználót amíg %{current} felhasználóként vagy bejelentkezve. Jelentkezz be %{proving} felhasználóként és próbáld újra.
+    explanation_html: Itt más személyazonosságaiddal tudsz kriptografikus kapcsolatot létesíteni, pl. Keybase profillal. Így mások titkosított üzenetet küldhetnek neked, valamint megbízhatnak az általad küldött tartalomban is.
+    i_am_html: "%{username} vagyok %{service} szerveren."
+    identity: Személyazonosság
+    inactive: Inaktív
+    publicize_checkbox: 'És ezt tülköld ki:'
+    publicize_toot: 'Tanúsítva! %{username} vagyok %{service}: %{url} szerveren'
+    status: Ellenőrzés állapota
+    view_proof: Tanúsítás megtekintése
   imports:
-    preface: Itt importálhatod egy másik instanciáról lementett adataidat, például követettjeid és letiltott felhasználóid listáját.
+    modes:
+      merge: Összefésülés
+      merge_long: Megtartjuk a meglévő bejegyzéseket és hozzávesszük az újakat
+      overwrite: Felülírás
+      overwrite_long: Lecseréljük újakkal a jelenlegi bejegyzéseket
+    preface: Itt importálhatod egy másik szerverről lementett adataidat, például követettjeid és letiltott felhasználóid listáját.
     success: Adataidat sikeresen feltöltöttük és feldolgozásukat megkezdtük
     types:
       blocking: Letiltottak listája
+      domain_blocking: Letiltott domainek listája
       following: Követettjeid listája
       muting: Némított felhasználók listája
     upload: Feltöltés
@@ -423,14 +694,16 @@ hu:
       '21600': 6 óra
       '3600': 1 óra
       '43200': 12 óra
+      '604800': 1 hét
       '86400': 1 nap
     expires_in_prompt: Soha
     generate: Generálás
+    invited_by: 'Téged meghívott:'
     max_uses:
       one: 1 felhasználás
       other: "%{count} felhasználás"
     max_uses_prompt: Nincs korlát
-    prompt: Az itt generált linkek megosztásával hívhatod meg ismerőseidet az instanciára
+    prompt: Az itt generált linkek megosztásával hívhatod meg ismerőseidet erre a szerverre
     table:
       expires_at: Lejárat
       uses: Használat
@@ -446,7 +719,7 @@ hu:
     acct: Az új fiók felhasznalonev@domain formátumban
     currently_redirecting: 'A profilod az alábbi fiókra van átirányítva:'
     proceed: Mentés
-    updated_msg: Fiókod átirányítási beállítasait sikeresen mentettük!
+    updated_msg: Fiókod átirányítási beállításait sikeresen mentettük!
   moderation:
     title: Moderáció
   notification_mailer:
@@ -462,52 +735,95 @@ hu:
         other: "%{count} új értesítésed érkezett legutóbbi látogatásod óta \U0001F418"
       title: Amíg távol voltál…
     favourite:
-      body: 'Az állapotodat kedvencnek jelölte %{name}:'
-      subject: "%{name} kedvencnek jelölte az állapotod"
+      body: 'A tülködet kedvencnek jelölte %{name}:'
+      subject: "%{name} kedvencnek jelölte a tülködet"
       title: Új kedvencnek jelölés
     follow:
       body: "%{name} mostantól követ téged!"
       subject: "%{name} mostantól követ téged"
       title: Új követő
     follow_request:
-      action: Követési kérések kezelése
+      action: Követési kérelmek kezelése
       body: "%{name} követni szeretne téged"
       subject: 'Jóváhagyásra vár: %{name}'
-      title: Új követési kérés
+      title: Új követési kérelem
     mention:
       action: Válasz
       body: "%{name} megemlített téged:"
       subject: "%{name} megemlített téged"
       title: Új említés
     reblog:
-      body: 'Az állapotod reblogolta %{name}:'
-      subject: "%{name} reblogolta az állapotod"
-      title: Új reblog
+      body: 'A tülködet %{name} megtolta:'
+      subject: "%{name} megtolta a tülködet"
+      title: Új megtolás
   number:
     human:
       decimal_units:
         format: "%n%u"
         units:
-          billion: B
+          billion: Mrd
           million: M
           quadrillion: Q
           thousand: K
           trillion: T
-          unit: " "
   pagination:
+    newer: Újabb
     next: Következő
+    older: Régebbi
     prev: Előző
     truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: Ezen a szavazáson már voksoltál
+      duplicate_options: duplázott elemeket tartalmaz
+      duration_too_long: túl távoli időpont
+      duration_too_short: túl közeli időpont
+      expired: A szavazásnak már vége
+      over_character_limit: egyik sem lehet %{max} karakternél hosszabb
+      too_few_options: több, mint egy opciónak kell lennie
+      too_many_options: nem lehet több, mint %{max} opció
   preferences:
-    languages: Nyelvek
     other: Egyéb
-    publishing: Közzététel
-    web: Web
+    posting_defaults: Tülkölés alapértelmezései
+    public_timelines: Nyilvános idővonalak
+  relationships:
+    activity: Fiók aktivitás
+    dormant: Elhagyott
+    last_active: Utoljára aktív
+    most_recent: Legutóbbi
+    moved: Átköltöztetve
+    mutual: Kölcsönös
+    primary: Elsődleges
+    relationship: Kapcsolat
+    remove_selected_domains: A választott domainekről minden követő eltávolítása
+    remove_selected_followers: Kiválasztott követők eltávolítása
+    remove_selected_follows: Kiválasztottak követésének abbahagyása
+    status: Fiók állapota
   remote_follow:
     acct: Írd be a felhasználódat, amelyről követni szeretnéd felhasznalonev@domain formátumban
     missing_resource: A fiókodnál nem található a szükséges átirányítási URL
+    no_account_html: Nincs fiókod? <a href='%{sign_up_path}' target='_blank'>Regisztrálj itt</a>
     proceed: Tovább a követéshez
     prompt: 'Őt tervezed követni:'
+    reason_html: "<strong>Miért van erre szükség?</strong> <code>%{instance}</code> nem feltétlenül az a szerver, ahol regisztrálva vagy, ezért először a saját szerveredre irányítunk."
+  remote_interaction:
+    favourite:
+      proceed: Jelöljük kedvencnek
+      prompt: 'Ezt a tülköt szeretnéd kedvencnek jelölni:'
+    reblog:
+      proceed: Megtolás
+      prompt: 'Ezt a tülköt szeretnéd megtolni:'
+    reply:
+      proceed: Válaszadás
+      prompt: 'Erre a tülkre szeretnél válaszolni:'
+  remote_unfollow:
+    error: Hiba
+    title: Cím
+    unfollowed: Nem követett
+  scheduled_statuses:
+    over_daily_limit: Túllépted az időzített tülkökre vonatkozó napi limitet (%{limit})
+    over_total_limit: Túllépted az időzített tülkökre vonatkozó limitet (%{limit})
+    too_soon: Az időzítéshez jövőbeni időpont kell
   sessions:
     activity: Legutóbbi tevékenység
     browser: Böngésző
@@ -550,29 +866,54 @@ hu:
     revoke_success: Munkamenet sikeresen visszavonva
     title: Munkamenetek
   settings:
+    account: Fiók
+    account_settings: Fiók beállítások
+    appearance: Megjelenés
     authorized_apps: Jóváhagyott alkalmazások
     back: Vissza a Mastodonhoz
     delete: Fiók törlése
     development: Fejlesztőknek
     edit_profile: Profil szerkesztése
     export: Adatok exportálása
-    followers: Jóváhagyott követők
+    featured_tags: Kiemelt hashtagek
+    identity_proofs: Személyazonosság tanúsítások
     import: Importálás
+    import_and_export: Import és export
     migrate: Fiók átirányítása
     notifications: Értesítések
-    preferences: Általános beállítások
-    settings: Beállítások
+    preferences: Beállítások
+    profile: Profil
+    relationships: Követések és követők
     two_factor_authentication: Kétlépcsős azonosítás
-    your_apps: Alkalmazásaid
   statuses:
+    attached:
+      description: 'Csatolva: %{attached}'
+      image:
+        one: "%{count} kép"
+        other: "%{count} kép"
+      video:
+        one: "%{count} videó"
+        other: "%{count} videó"
+    boosted_from_html: Megtolva innen %{acct_link}
+    content_warning: 'Tartalom figyelmeztetés: %{warning}'
+    disallowed_hashtags:
+      one: 'tiltott hashtaget tartalmaz: %{tags}'
+      other: 'tiltott hashtageket tartalmaz: %{tags}'
+    language_detection: Nyelv automatikus felismerése
     open_in_web: Megnyitás a weben
     over_character_limit: Túllépted a maximális %{max} karakteres keretet
     pin_errors:
       limit: Elérted a kitűzhető tülkök maximális számát
       ownership: Nem tűzheted ki valaki más tülkjét
-      private: Csak publikus tülköt tűzhetsz ki
-      reblog: Reblogolt tülköt nem tudsz kitűzni
+      private: Csak nyilvános tülköt tűzhetsz ki
+      reblog: Megtolt tülköt nem tudsz kitűzni
+    poll:
+      total_votes:
+        one: "%{count} szavazat"
+        other: "%{count} szavazat"
+      vote: Szavazás
     show_more: Mutass többet
+    sign_in_to_participate: Jelentkezz be, hogy részt vehess a beszélgetésben
     title: '%{name}: "%{quote}"'
     visibilities:
       private: Csak követőknek
@@ -580,53 +921,163 @@ hu:
       public: Nyilvános
       public_long: Bárki láthatja a tülköt
       unlisted: Listázatlan
-      unlisted_long: Mindenki látja, de a nyilvános időfolyamokban nem jelenik meg
+      unlisted_long: Mindenki látja, de a nyilvános idővonalakon nem jelenik meg
   stream_entries:
     pinned: Kitűzött tülk
-    reblogged: reblogolt
+    reblogged: megtolt
     sensitive_content: Szenzitív tartalom
   terms:
+    body_html: |
+      <h2>Adatvédelmi nyilatkozat</h2>
+      <h3 id="collect">Milyen adatokat gyűjtünk?</h3>
+
+      <ul>
+      <li><em>Alapvető fiókadatok</em>: Ha regisztrálsz ezen a szerveren, kérhetünk tőled felhasználói nevet, e-mail címet és jelszót is. Megadhatsz magadról egyéb profil információt, mint megjelenítendő név, bemutatkozás, feltölthetsz profilképet, háttérképet. A felhasználói neved, megjelenítendő neved, bemutatkozásod, profil képed és háttér képed mindig nyilvánosak mindenki számára.</li>
+      <li><em>Tülkök (posztok), követések, más nyilvános adatok</em>: Az általad követett emberek listája nyilvános. Ugyanez igaz a te követőidre is. Ha küldesz egy üzenetet, ennek az idejét eltároljuk azzal az alkalmazással együtt, melyből az üzenetet küldted. Az üzenetek tartalmazhatnak média csatolmányt, képeket, videókat. A nyilvános tülkök (posztok) bárki számára elérhetőek. Ha egy tülköt kiemelsz a profilodon, az is nyilvánossá válik. Amikor a tülkjeidet a követőidnek továbbítjuk, a poszt más szerverekre is kerülhet, melyeken így másolatok képződhetnek. Ha törölsz tülköket, ez is továbbítódik a követőid felé. A megtolás (reblog) és kedvencnek jelölés művelete is mindig nyilvános.</li>
+      <li><em>Közvetlen üzenetek és csak követőknek szánt tülkök</em>: Minden tülk a szerveren tárolódik. A csak követőknek szánt tülköket a követőidnek és az ezekben megemlítetteknek továbbítjuk, míg a közvetlen üzeneteket kizárólag az ebben megemlítettek kapják. Néhány esetben ez azt jelenti, hogy ezek más szerverekre is továbbítódnak, így ott másolatok keletkezhetnek. Jóhiszeműen feltételezzük, hogy más szerverek is hasonlóan járnak el, mikor ezeket az üzeneteket csak az arra jogosultaknak mutatják meg. Ugyanakkor ez nem feltétlenül igaz. Ezért érdemes megnézni azokat a szervereket, melyeken követőid vannak. Be tudod állítani, hogy minden követési kérelmet jóvá kelljen hagynod. <em>Tartsd észben, hogy a szerver üzemeltetői láthatják az üzeneteket</em>, illetve a fogadók képernyőképet, másolatot készíthetnek belőlük, vagy újraoszthatják őket.<em>Ne ossz meg veszélyes információt a Mastodon hálózaton!</em></li>
+      <li><em>IP címek és egyéb metaadatok</em>: Bejelentkezéskor letároljuk a használt böngésződet és IP címedet. Mindent rögzített munkamenet elérhető és visszavonható a beállítások között. A legutolsó IP címet maximum 12 hónapig tárolunk. Egyéb szerver logokat is megtarthatunk, melyek HTTP kérésenként is tárolhatják az IP címedet.</li>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="use">Mire használjuk az adataidat?</h3>
+
+      <p>Bármely tőled begyűjtött adatot a következő célokra használhatjuk:</p>
+
+      <ul>
+      <li>Mastodon alapfunkcióinak biztosítása: Csak akkor léphetsz kapcsolatba másokkal, ha be vagy jelentkezve. Pl. követhetsz másokat a saját, személyre szabott idővonaladon.</li>
+      <li>Közösségi moderáció elősegítése: Pl. IP címek összehasonlítása másokéval, hogy kiszűrjük a kitiltások megkerülését.</li>
+      <li>Kapcsolattartás veled: Az általad megadott e-mail címen infókat, értesítéseket küldünk mások interakcióiról, kérésekről, kérdésekről.</li>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="protect">Hogyan védjük az adataidat?</h3>
+
+      <p>Üzemben tartunk néhány biztonsági rendszert, hogy megvédjük a személyes adataidat, amikor eléred vagy karbantartod ezeket. Többek között a böngésződ munkamenete, a szerver oldal, valamint a böngésző közötti teljes kommunikáció SSL-lel van titkosítva, a jelszavadat pedig erős, egyirányú algoritmussal hash-eljük. Kétlépcsős azonosítást is bekapcsolhatsz, hogy még biztonságosabbá tedd a fiókodhoz való hozzáférést.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="data-retention">Mik az adatmegőrzési szabályaink?</h3>
+
+      <p>Jóhiszeműen járunk el, hogy:</p>
+
+      <ul>
+      <li>A szerver logokat, melyek kérésenként tartalmazzák a felhasználó IP címét maximum 90 napig tartjuk meg.</li>
+      <li>A regisztrált felhasználók IP címeikkel összekötő adatokat maximum 12 hónapig tartjuk meg.</li>
+      </ul>
+
+      <p>Kérhetsz archívot minden tárolt adatodról, tülkjeidről, média fájljaidról, profil- és háttér képedről.</p>
+
+      <p>Bármikor visszaállíthatatlanul le is törölheted a fiókodat.</p>
+
+      <hr class="spacer"/>
+
+      <h3 id="cookies">Használunk sütiket?</h3>
+
+      <p>Igen. A sütik pici állományok, melyeket az oldalunk a böngésződön keresztül a háttértáradra rak, ha engedélyezed ezt. Ezek a sütik teszik lehetővé, hogy az oldalunk felismerje a böngésződet, és ha regisztráltál, hozzá tudjon kötni a fiókodhoz.</p>
+
+      <p>Arra is használjuk a sütiket, hogy elmenthessük a beállításaidat egy következő látogatás céljából.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="disclose">Átadunk bármilyen adatot harmadik személynek?</h3>
+
+      <p>Az azonosításodra alkalmazható adatokat nem adjuk el, nem kereskedünk vele, nem adjuk át külső szereplőnek. Ez nem foglalja magába azon harmadik személyeket, aki az üzemeltetésben, felhasználók kiszolgálásban és a tevékenységünkben segítenek, de csak addig, amíg ők is elfogadják, hogy ezeket az adatokat bizalmasan kezelik. Akkor is átadhatjuk ezeket az adatokat, ha erre hitünk szerint törvény kötelez minket, ha betartatjuk az oldalunk szabályzatát vagy megvédjük a saját vagy mások személyiségi jogait, tulajdonát, biztonságát.</p>
+
+      <p>A nyilvános tartalmaidat más hálózatban lévő szerverek letölthetik. A nyilvános és csak követőknek szánt tülkjeid olyan szerverekre is elküldődnek, melyeken követőid vannak. A közvetlen üzenetek is átkerülnek a címzettek szervereire, ha ők más szerveren regisztráltak.</p>
+
+      <p>Ha felhatalmazol egy alkalmazást, hogy használja a fiókodat, a jóváhagyott hatásköröktől függően ez elérheti a nyilvános profiladataidat, a követettjeid listáját, a követőidet, listáidat, tülkjeidet és kedvenceidet is. Ezek az alkalmazások ugyanakkor sosem érhetik el a jelszavadat és e-mail címedet.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="children">Az oldal gyerekek általi használata</h3>
+
+      <p>Ha ez a szerver az EU-ban vagy EEA-ban van: Az oldalunk, szolgáltatásaink és termékeink mind 16 éven felülieket céloznak. Ha 16 évnél fiatalabb vagy, a GDPR (<a href="https://en.wikipedia.org/wiki/General_Data_Protection_Regulation">General Data Protection Regulation</a>) értelmében kérlek ne használd ezt az oldalt!</p>
+
+      <p>Ha ez a szerver az USA-ban van: Az oldalunk, szolgáltatásaink és termékeink mind 13 éven felülieket céloznak. Ha 13 évnél fiatalabb vagy, a COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) értelmében kérlek ne használd ezt az oldalt!</p>
+
+      <p>A jogi előírások különbözhetnek ettől a világ egyéb tájain.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="changes">Adatvédelmi nyilatkozat változásai</h3>
+
+      <p>Ha úgy döntünk, hogy megváltoztatjuk az adatvédelmi nyilatkozatot, ezt ezen az oldalon közzé fogjuk tenni.</p>
+
+      <p>Ez a dokumentum CC-BY-SA. Utoljára 2018.03.07 frissült.</p>
+
+      <p>Eredetileg innen adaptálva <a href="https://github.com/discourse/discourse">Discourse privacy policy</a>.</p>
     title: "%{instance} Felhasználási feltételek és Adatkezelési nyilatkozat"
   themes:
-    default: Mastodon
+    contrast: Mastodon (Nagy kontrasztú)
+    default: Mastodon (Sötét)
+    mastodon-light: Mastodon (Világos)
   time:
     formats:
       default: "%Y %b %d, %H:%M"
+      month: "%Y %b"
   two_factor_authentication:
     code_hint: Megerősítéshez írd be az alkalmazás által generált kódot
-    description_html: He engedélyezed a <strong>kétlépcsős azonosítást</strong>, a bejelentkezéshez szükséged lesz a teefonodre és egy alkalmazásra, amely hozzáférési kódot generál számodra.
+    description_html: He engedélyezed a <strong>kétlépcsős azonosítást</strong>, a bejelentkezéshez szükséged lesz a telefonodra és egy alkalmazásra, amely hozzáférési kódot generál számodra.
     disable: Kikapcsolás
     enable: Engedélyezés
     enabled: Kétlépcsős azonosítás engedélyezve
     enabled_success: A kétlépcsős azonosítást sikeresen engedélyezted
     generate_recovery_codes: Visszaállítási kódok generálása
-    instructions_html: "<strong>Olvasd be ez a QR-kódot a telefonodon futó Google Authenticator (vagy egyéb TOTP) alkalmazással</strong>. A jövőben ez az alkalmazás fog számodra hozzáférési kódot generálni a belépéshez."
+    instructions_html: "<strong>Olvasd be ezt a QR-kódot a telefonodon futó Google Authenticator vagy egyéb TOTP alkalmazással</strong>. A jövőben ez az alkalmazás fog számodra hozzáférési kódot generálni a belépéshez."
     lost_recovery_codes: A visszaállítási kódok segítségével tudsz belépni, ha elveszítenéd a telefonod. Ha a visszaállítási kódjaidat hagytad el, itt generálhatsz újakat. A régi kódokat ebben az esetben érvénytelenítjük.
     manual_instructions: 'Ha nem sikerült a QR-kód beolvasása, itt a szöveges kulcs, amelyet manuálisan kell begépelned:'
     recovery_codes: Visszaállítási kódok biztonsági mentése
-    recovery_codes_regenerated: Visszaállítási kódok sikeresen újragenerálva
+    recovery_codes_regenerated: A visszaállítási kódokat sikeresen újrageneráltuk
     recovery_instructions_html: A visszaállítási kódok egyikének segítségével tudsz majd belépni, ha elveszítenéd a telefonod. <strong>Tartsd biztos helyen a visszaállítási kódjaid</strong>! Például nyomtasd ki őket és tárold a többi fontos iratoddal együtt.
     setup: Beállítás
     wrong_code: A beírt kód nem érvényes! A szerver órája és az eszközöd órája szinkronban jár?
   user_mailer:
+    backup_ready:
+      explanation: A Mastodon fiókod teljes mentését kérted. A mentés kész ás letölthető!
+      subject: Az adataidról készült archív letöltésre kész
+      title: Archiválás
+    warning:
+      explanation:
+        disable: A fiókod befagyasztott állapotban megtartja minden adatát, de feloldásig nem csinálhatsz vele semmit.
+        silence: A fiókod korlátozott állapotában csak a követőid láthatják a tülkjeidet, valamint nem kerülsz rá nyilvános idővonalakra. Ugyanakkor mások manuálisan még követhetnek.
+        suspend: A fiókodat felfüggesztették, így minden tülköd és feltöltött fájlod menthetetlenül elveszett erről a szerverről és minden olyanról is, ahol voltak követőid.
+      review_server_policies: Szerver szabályzat átnézése
+      subject:
+        disable: A fiókodat %{acct} befagyasztották
+        none: Figyelmeztetés a %{acct} fióknak
+        silence: A fiókodat %{acct} korlátozták
+        suspend: A fiókodat %{acct} felfüggesztették
+      title:
+        disable: Befagyasztott fiók
+        none: Figyelem
+        silence: Lekorlátozott fiók
+        suspend: Felfüggesztett fiók
     welcome:
       edit_profile_action: Készítsd el profilod
       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.'
+      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ővonalon és a hashtageknél. Kezdd például azzal, hogy bemutatkozol: használd a #bemutatkozas vagy az #introductions hashtaget 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.
+      full_handle_hint: Ez az, amit megadhatsz másoknak, hogy üzenhessenek neked vagy követhessenek téged más szerverekrő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.
+      review_preferences_step: Tekintsd át beállításaidat, például hogy milyen értesítéseket kérsz e-mailben vagy hogy alapértelmezettként mi legyen a tülkjeid láthatósága. 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_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!
+      tip_federated_timeline: A nyilvános idővonal a Mastodon ütőere, ahol minden tülkölés összefolyik. Nem teljes ugyan, mert csak azokat az embereket fogod látni, akiket a szervered többi felhasználója közül valaki követ.
+      tip_following: Alapértelmezettként szervered adminisztrátorait követed. Látogasd meg a helyi és a nyilvános idővonalat, hogy más érdekes emberekre is rátalálj.
+      tip_local_timeline: A helyi idővonal a saját szervered (%{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 a kezdőképernyődhöz add a Mastodont, még értesítéseket is fogsz kapni, akárcsak egy igazi alkalmazás esetében!
       tips: Tippek
       title: Üdv a fedélzeten, %{name}!
   users:
+    follow_limit_reached: Nem követhetsz több, mint %{limit} embert
     invalid_email: A megadott e-mail cím helytelen
     invalid_otp_token: Érvénytelen ellenőrző kód
+    otp_lost_help_html: Ha mindkettőt elvesztetted, kérhetsz segítséget itt %{email}
+    seamless_external_login: Külső szolgáltatáson keresztül jelentkeztél be, így a jelszó és e-mail beállítások nem elérhetőek.
     signed_in_as: Bejelentkezve mint
+  verification:
+    explanation_html: 'A profilodon <strong>hitelesítheted magad, mint az itt található linkek tulajdonosa</strong>. Ehhez a linkelt weboldalnak tartalmaznia kell egy linket vissza a Mastodon profilodra. Ennek <strong>tartalmaznia kell</strong> a <code>rel="me"</code> attribútumot. A link szövege bármi lehet. Itt egy példa:'
+    verification: Hitelesítés
diff --git a/config/locales/hy.yml b/config/locales/hy.yml
new file mode 100644
index 0000000000000000000000000000000000000000..86645a57464f0d8490abb7e5e436711065f3733a
--- /dev/null
+++ b/config/locales/hy.yml
@@ -0,0 +1,17 @@
+---
+hy:
+  errors:
+    '403': You don't have permission to view this page.
+    '404': The page you are looking for isn't here.
+    '410': The page you were looking for doesn't exist here anymore.
+    '422': 
+    '429': Throttled
+    '500': 
+  invites:
+    expires_in:
+      '1800': 30 minutes
+      '21600': 6 hours
+      '3600': 1 hour
+      '43200': 12 hours
+      '604800': 1 week
+      '86400': 1 day
diff --git a/config/locales/id.yml b/config/locales/id.yml
index fabf2746e396661134fe2a9abf07092359ea0077..43721b19b9f68255ff9c2a9fc8dab9a7cf111b3f 100644
--- a/config/locales/id.yml
+++ b/config/locales/id.yml
@@ -4,9 +4,8 @@ id:
     about_hashtag_html: Ini adalah toot public yang ditandai dengan <strong>#%{hashtag}</strong>. Anda bisa berinteraksi dengan mereka jika anda memiliki akun dimanapun di fediverse.
     about_mastodon_html: Mastodon adalah sebuah jejaring sosial <em>terbuka, open-source</em. Sebuah alternatif <em>desentralisasi</em> dari platform komersial, menjauhkan anda resiko dari sebuah perusahaan yang memonopoli komunikasi anda. Pilih server yang anda percayai &mdash; apapun yang anda pilih, anda tetap dapat berinteraksi dengan semua orang. Semua orang dapat menjalankan server Mastodon sendiri dan berpartisipasi dalam <em>jejaring sosial</em> dengan mudah.
     about_this: Tentang server ini
-    api: API
+    administered_by: 'Dikelola oleh:'
     apps: Aplikasi hp
-    closed_registrations: Pendaftaran untuk server ini sedang ditutup. Tetapi, anda bisa mencari server lain untuk membuat akun dan mendapatkan akses dari jaringan yang sama di sana.
     contact: Kontak
     contact_missing: Belum diset
     contact_unavailable: Tidak Tersedia
@@ -14,41 +13,27 @@ id:
     extended_description_html: |
       <h3>Tempat yang baik untuk peraturan</h3>
       <p>Deskripsi lainnya belum diset.</p>
-    features:
-      humane_approach_body: Belajar dari kegagalan jaringan lain, Mastodon berupaya untuk membuat pilihan desain yang etis untuk melawan penyalahgunaan media sosial.
-      humane_approach_title: Pendekatan yang lebih manusiawi
-      not_a_product_body: Mastodon bukanlah jaringan komersil. Tidak ada iklan, tidak ada pengumpulan data, tidak ada batasan vendor. Tidak ada otoritas terpusat.
-      not_a_product_title: Anda adalah orang, bukanlah sebuah produk
-      real_conversation_body: Dengan 500 karakter dan dukungan konten granular dan peringatan media, anda dapat mengekspresikan diri anda sendiri sesuai yang anda mau.
-      real_conversation_title: Dibangun untuk percakapan yang sebenarnya
-      within_reach_body: Berbagai aplikasi untuk iOS, Android, dan platform lainnya berkat ekosistem API yang ramah pada pengembang untuk tetap terhubung dengan teman-teman anda dimanapun.
-      within_reach_title: Selalu dalam jangkauan
     generic_description: "%{domain} adalah satu server dalam jaringan"
     hosted_on: Mastodon dihosting di %{domain}
     learn_more: Pelajari selengkapnya
-    other_instances: Daftar Server
     privacy_policy: Kebijakan Privasi
     source_code: Kode sumber
     status_count_after:
-      one: status
       other: status
     status_count_before: Yang telah menulis
     terms: Kebijakan layanan
     user_count_after:
-      one: pengguna
       other: pengguna
     user_count_before: Tempat bernaung bagi
     what_is_mastodon: Apa itu Mastodon?
   accounts:
     follow: Ikuti
     followers:
-      one: Pengikut
       other: Pengikut
     following: Mengikuti
     joined: Bergabung pada %{date}
     last_active: terakhir aktif
     link_verified_on: Kepemilikan tautan ini telah dicek pada %{date}
-    media: Media
     moved_html: "%{name} telah pindah ke %{new_profile_link}:"
     network_hidden: Informasi ini tidak tersedia
     nothing_here: Tidak ada apapun disini!
@@ -57,71 +42,110 @@ id:
     pin_errors:
       following: Anda harus mengikuti orang yang ingin anda endorse
     posts:
-      one: Toot
       other: Toot
     posts_tab_heading: Toot
     posts_with_replies: Toot dan balasan
     reserved_username: Nama pengguna telah dipesan
     roles:
-      admin: Admin
-      bot: Bot
       moderator: Moderator
     unfollow: Berhenti mengikuti
   admin:
     account_actions:
       action: Lakukan aksi
+      title: Lakukan moderasi pada %{acct}
+    account_moderation_notes:
+      create: Beri catatan
+      created_msg: Catatan moderasi berhasil dibuat!
+      delete: Hapus
+      destroyed_msg: Catatan moderasi berhasil dihapus!
     accounts:
       are_you_sure: Anda yakin?
+      change_email:
+        changed_msg: Email akun ini berhasil diubah!
+        current_email: Email saat ini
+        label: Ganti email
+        new_email: Email baru
+        submit: Ganti email
+        title: Ganti email untuk %{username}
       confirm: Konfirmasi
       confirmed: Dikonfirmasi
       confirming: Mengkonfirmasi
+      deleted: Terhapus
+      disable: Nonaktifkan
+      disable_two_factor_authentication: Nonaktifkan 2FA
+      disabled: Dinonaktifkan
       display_name: Nama
-      domain: Domain
       edit: Ubah
       email: E-mail
       email_status: Status Email
+      enable: Aktifkan
+      enabled: Diaktifkan
       feed_url: URL Feed
       followers: Pengikut
+      followers_url: URL pengikut
       follows: Mengikut
+      inbox_url: URL Kotak masuk
+      invited_by: Diundang oleh
+      joined: Bergabung
       location:
         all: Semua
         local: Lokal
-        remote: Remote
         title: Lokasi
+      login_status: Status login
       media_attachments: Lampiran media
+      memorialize: Ubah menjadi memoriam
       moderation:
+        active: Aktif
         all: Semua
         silenced: Didiamkan
         suspended: Disuspen
         title: Moderasi
+      moderation_notes: Catatan moderasi
       most_recent_activity: Aktivitas terbaru
       most_recent_ip: IP terbaru
+      no_limits_imposed: Tidak ada batasan
       not_subscribed: Tidak berlangganan
+      outbox_url: URL Kotak keluar
       perform_full_suspension: Lakukan suspen penuh
       profile_url: URL profil
+      promote: Promosikan
+      protocol: Protokol
       public: Publik
       push_subscription_expires: Langganan PuSH telah kadaluarsa
+      redownload: Muat ulang profil
+      remove_avatar: Hapus avatar
+      remove_header: Hapus header
       resend_confirmation:
         already_confirmed: Pengguna ini sudah dikonfirmasi
         send: Kirim ulang email konfirmasi
         success: Email konfirmasi berhasil dikirim!
       reset_password: Reset kata sandi
+      resubscribe: Langganan ulang
+      role: Hak akses
+      roles:
+        staff: Staf
+        user: Pengguna
       salmon_url: URL Salmon
+      search: Cari
       show:
         created_reports: Laporan yang dibuat oleh akun ini
         targeted_reports: Laporan yang dibuat tentang akun ini
       silence: Diam
+      silenced: Didiamkan
       statuses: Status
+      subscribe: Langganan
+      suspended: Disuspen
       title: Akun
+      unconfirmed_email: Email belum dikonfirmasi
       undo_silenced: Undo mendiamkan
       undo_suspension: Undo suspen
+      unsubscribe: Berhenti langganan
       username: Nama pengguna
-      web: Web
+      warn: Beri Peringatan
     domain_blocks:
       add_new: Tambah
       created_msg: Pemblokiran domain sedang diproses
       destroyed_msg: Pemblokiran domain telah dibatalkan
-      domain: Domain
       new:
         create: Buat pemblokiran
         hint: Pemblokiran domain tidak akan menghentikan pembuatan akun dalam database, tapi kami akan memberikan moderasi otomatis pada akun-akun tersebut.
@@ -134,13 +158,11 @@ id:
       reject_media_hint: Hapus file media yang tersimpan dan menolak semua unduhan nantinya. Tidak terpengaruh dengan suspen
       show:
         affected_accounts:
-          one: Satu akun di dalam database terpengaruh
           other: "%{count} akun dalam database terpengaruh"
         retroactive:
           silence: Hapus pendiaman terhadap akun pada domain ini
           suspend: Hapus suspen terhadap akun pada domain ini
         title: Hapus pemblokiran domain %{domain}
-        undo: Undo
     instances:
       title: Server yang diketahui
     reports:
@@ -151,7 +173,6 @@ id:
       reported_account: Akun yang dilaporkan
       reported_by: Dilaporkan oleh
       resolved: Terseleseikan
-      status: Status
       title: Laporan
       unresolved: Belum Terseleseikan
     settings:
@@ -162,8 +183,6 @@ id:
         closed_message:
           desc_html: Ditampilkan pada halaman depan saat pendaftaran ditutup<br>Anda bisa menggunakan tag HTML
           title: Pesan penutupan pendaftaran
-        open:
-          title: Pendaftaran terbuka
       site_description:
         desc_html: Ditampilkan sebagai sebuah paragraf di halaman depan dan digunakan sebagai tag meta.<br>Anda bisa menggunakan tag HTML, khususnya <code>&lt;a&gt;</code> dan <code>&lt;em&gt;</code>.
         title: Deskripsi situs
@@ -173,11 +192,9 @@ id:
       site_title: Judul Situs
       title: Pengaturan situs
     subscriptions:
-      callback_url: Callback URL
       confirmed: Dikonfirmasi
       expires_in: Kadaluarsa dalam
       last_delivery: Terakhir dikirim
-      title: WebSub
       topic: Topik
     title: Administrasi
   application_mailer:
@@ -220,28 +237,16 @@ id:
     '422':
       content: Verifikasi keamanan gagal. Apa anda memblokir cookie?
       title: Verifikasi keamanan gagal
+    '429': Throttled
+    '500': 
   exports:
     blocks: Anda blokir
-    csv: CSV
     follows: Anda ikuti
     mutes: Anda bisukan
     storage: Penyimpanan media
-  followers:
-    domain: Domain
-    explanation_html: Jika anda ingin memastikan privasi dari status anda, anda harus tahu siapa yang mengikuti anda. <strong>Status pribadi anda dikirim ke semua server dimana pengikut anda berada</strong>. Anda mungkin ingin untuk mengkaji ulang dan menghapus pengikut jika anda tidak mempercayai bahwa privasi anda di tangan staf atau software di server tersebut.
-    followers_count: Jumlah pengikut
-    lock_link: Kunci akun anda
-    purge: Hapus dari pengikut
-    success:
-      one: Dalam proses memblokir pengikut dari satu domain...
-      other: Dalam proses memblokir pengikut dari %{count} domain...
-    true_privacy_html: Mohon diingat bahwa <strong>privasi yang sebenarnya hanya dapat dicapai dengan enkripsi end-to-end</strong>.
-    unlocked_warning_html: Semua orang dapat mengikuti anda untuk langsung dapat melihat status pribadi anda. %{lock_link} untuk dapat meninjau dan menolak calon pengikut.
-    unlocked_warning_title: Akun anda tidak dikunci
   generic:
     changes_saved_msg: Perubahan berhasil disimpan!
     save_changes: Simpan perubahan
-    validation_errors: Ada yang tidak beres! Mohon tinjau error dibawah ini
   imports:
     preface: Anda bisa mengimpor data tertentu seperti orang-orang yang anda ikuti atau anda blokir di server ini, dari file yang dibuat oleh fitur expor di server lain.
     success: Data anda berhasil diupload dan akan diproses sesegera mungkin
@@ -250,6 +255,14 @@ id:
       following: Daftar diikuti
       muting: Daftar didiamkan
     upload: Unggah
+  invites:
+    expires_in:
+      '1800': 30 minutes
+      '21600': 6 hours
+      '3600': 1 hour
+      '43200': 12 hours
+      '604800': 1 week
+      '86400': 1 day
   media_attachments:
     validations:
       images_and_video: Tidak bisa melampirkan video pada status yang telah memiliki gambar
@@ -259,10 +272,8 @@ id:
       body: Ini adalah ringkasan singkat yang anda lewatkan pada sejak kunjungan terakhir anda pada %{since}
       mention: "%{name} menyebut anda di:"
       new_followers_summary:
-        one: Anda mendapatkan satu pengikut baru! Hore!
         other: Anda mendapatkan %{count} pengikut baru! Luar biasa!
       subject:
-        one: "1 notifikasi baru sejak kunjungan terakhir anda pada \U0001F418"
         other: "%{count} notifikasi baru sejak kunjungan terakhir anda pada \U0001F418"
     favourite:
       body: 'Status anda disukai oleh %{name}:'
@@ -279,21 +290,9 @@ id:
     reblog:
       body: 'Status anda di-boost oleh %{name}:'
       subject: "%{name} mem-boost status anda"
-  number:
-    human:
-      decimal_units:
-        format: "%n%u"
-        units:
-          billion: B
-          million: M
-          quadrillion: Q
-          thousand: K
-          trillion: T
-          unit: ''
   pagination:
     next: Selanjutnya
     prev: Sebelumnya
-    truncate: "&hellip;"
   remote_follow:
     acct: Masukkan namapengguna@domain yang akan anda ikuti
     missing_resource: Tidak dapat menemukan URL redirect dari akun anda
@@ -304,10 +303,8 @@ id:
     back: Kembali ke Mastodon
     edit_profile: Ubah profil
     export: Expor data
-    followers: Pengikut yang diizinkan
     import: Impor
     preferences: Pilihan
-    settings: Pengaturan
     two_factor_authentication: Autentikasi Two-factor
   statuses:
     open_in_web: Buka di web
diff --git a/config/locales/io.yml b/config/locales/io.yml
index 73c981a985a9971a392146ec32bdfb2af0a4ba5d..559bf0f534dcb71eb6c69c9418fd0ff29d0d9c6a 100644
--- a/config/locales/io.yml
+++ b/config/locales/io.yml
@@ -3,101 +3,37 @@ io:
   about:
     about_mastodon_html: Mastodon esas <em>gratuita, apertitkodexa</em> sociala reto. Ol esas <em>sencentra</em> altra alternativo a komercala servadi. Ol evitigas, ke sola firmo guvernez tua tota komunikadol. Selektez servero, quan tu fidas. Irge qua esas tua selekto, tu povas komunikar kun omna altra uzeri. Irgu povas krear sua propra instaluro di Mastodon en sua servero, e partoprenar en la <em>sociala reto</em> tote glate.
     about_this: Pri ta instaluro
-    closed_registrations: Membresko ne nun esas posible en ta instaluro.
     contact: Kontaktar
-    other_instances: Altra instaluri
     source_code: Fontkodexo
-    status_count_after: mesaji
     status_count_before: Qua publikigis
-    user_count_after: uzeri
     user_count_before: Hemo di
   accounts:
     follow: Sequar
-    followers: Sequanti
     following: Sequati
     nothing_here: Esas nulo hike!
     people_followed_by: Sequati da %{name}
     people_who_follow: Sequanti di %{name}
-    posts: Mesaji
     unfollow: Dessequar
   admin:
     accounts:
       are_you_sure: Ka tu esas certa?
-      display_name: Display name
-      domain: Domain
-      edit: Edit
       email: E-mail
-      feed_url: Feed URL
-      followers: Followers
-      follows: Follows
-      location:
-        all: All
-        local: Local
-        remote: Remote
-        title: Location
-      media_attachments: Media attachments
-      moderation:
-        all: All
-        silenced: Silenced
-        suspended: Suspended
-        title: Moderation
-      most_recent_activity: Most recent activity
-      most_recent_ip: Most recent IP
-      not_subscribed: Not subscribed
       perform_full_suspension: Perform full suspension
-      profile_url: Profile URL
-      public: Public
-      push_subscription_expires: PuSH subscription expires
-      reset_password: Reset password
-      salmon_url: Salmon URL
       show:
         created_reports: Reports created by this account
         targeted_reports: Reports made about this account
-      silence: Silence
-      statuses: Statuses
-      title: Accounts
-      undo_silenced: Undo silence
-      undo_suspension: Undo suspension
-      username: Username
-      web: Web
     domain_blocks:
       add_new: Add new
-      created_msg: Domain block is now being processed
-      destroyed_msg: Domain block has been undone
-      domain: Domain
       new:
-        create: Create block
-        hint: The domain block will not prevent creation of account entries in the database, but will retroactively and automatically apply specific moderation methods on those accounts.
         severity:
           desc_html: "<strong>Silence</strong> will make the account's posts invisible to anyone who isn't following them. <strong>Suspend</strong> will remove all of the account's content, media, and profile data."
-          silence: Silence
-          suspend: Suspend
-        title: New domain block
-      reject_media: Reject media files
-      reject_media_hint: Removes locally stored media files and refuses to download any in the future. Irrelevant for suspensions
       show:
-        affected_accounts:
-          one: One account in the database affected
-          other: "%{count} accounts in the database affected"
         retroactive:
           silence: Unsilence all existing accounts from this domain
           suspend: Unsuspend all existing accounts from this domain
-        title: Undo domain block for %{domain}
-        undo: Undo
       undo: Undo
     instances:
       title: Known Instances
-    reports:
-      comment:
-        none: None
-      mark_as_resolved: Mark as resolved
-      report: 'Report #%{id}'
-      reported_account: Reported account
-      reported_by: Reported by
-      resolved: Resolved
-      status: Status
-      title: Reports
-      unresolved: Unresolved
     settings:
       contact_information:
         email: Enter a public e-mail address
@@ -105,9 +41,6 @@ io:
       registrations:
         closed_message:
           desc_html: Displayed on frontpage when registrations are closed<br>You can use HTML tags
-          title: Closed registration message
-        open:
-          title: Open registration
       site_description:
         desc_html: Displayed as a paragraph on the frontpage and used as a meta tag.<br>You can use HTML tags, in particular <code>&lt;a&gt;</code> and <code>&lt;em&gt;</code>.
         title: Site description
@@ -116,14 +49,6 @@ io:
         title: Extended site description
       site_title: Site title
       title: Site Settings
-    subscriptions:
-      callback_url: Callback URL
-      confirmed: Confirmed
-      expires_in: Expires in
-      last_delivery: Last delivery
-      title: WebSub
-      topic: Topic
-    title: Administration
   application_mailer:
     settings: 'Chanjar la retpost-mesajala preferi: %{link}'
     view: 'Vidar:'
@@ -145,29 +70,18 @@ io:
     title: Sequar %{acct}
   datetime:
     distance_in_words:
-      about_x_hours: "%{count}h"
-      about_x_months: "%{count}mo"
-      about_x_years: "%{count}y"
-      almost_x_years: "%{count}y"
       half_a_minute: Jus
-      less_than_x_minutes: "%{count}m"
       less_than_x_seconds: Jus
-      over_x_years: "%{count}y"
-      x_days: "%{count}d"
-      x_minutes: "%{count}m"
-      x_months: "%{count}mo"
-      x_seconds: "%{count}s"
   errors:
+    '403': You don't have permission to view this page.
     '404': La pagino quan tu serchas ne existas.
     '410': La pagino quan tu serchas ne plus existas.
-    '422':
-      content: Security verification failed. Are you blocking cookies?
-      title: Security verification failed
+    '422': 
+    '429': Throttled
+    '500': 
   exports:
     blocks: Tu blokusas
-    csv: CSV
     follows: Tu sequas
-    mutes: You mute
     storage: Konservado di kontenajo
   generic:
     changes_saved_msg: Chanji senprobleme konservita!
@@ -181,12 +95,15 @@ io:
     types:
       blocking: Listo de blokusiti
       following: Listo de sequati
-      muting: Muting list
     upload: Kargar
-  media_attachments:
-    validations:
-      images_and_video: Cannot attach a video to a status that already contains images
-      too_many: Cannot attach more than 4 files
+  invites:
+    expires_in:
+      '1800': 30 minutes
+      '21600': 6 hours
+      '3600': 1 hour
+      '43200': 12 hours
+      '604800': 1 week
+      '86400': 1 day
   notification_mailer:
     digest:
       body: Yen mikra rezumo di to, depos ke tu laste vizitis en %{since}
@@ -212,21 +129,9 @@ io:
     reblog:
       body: "%{name} diskonocigis tua mesajo:"
       subject: "%{name} diskonocigis tua mesajo"
-  number:
-    human:
-      decimal_units:
-        format: "%n%u"
-        units:
-          billion: B
-          million: M
-          quadrillion: Q
-          thousand: K
-          trillion: T
-          unit: ''
   pagination:
     next: Sequanta
     prev: Preiranta
-    truncate: "&hellip;"
   remote_follow:
     acct: Enpozez tua uzernomo@instaluro de ube tu volas sequar ta uzero
     missing_resource: La URL di plussendado ne povis esar trovita
@@ -239,7 +144,6 @@ io:
     export: Exportacar datumi
     import: Importacar
     preferences: Preferi
-    settings: Settings
     two_factor_authentication: Dufaktora autentikigo
   statuses:
     open_in_web: Apertar retnavigile
@@ -252,23 +156,13 @@ io:
   stream_entries:
     reblogged: diskonocigita
     sensitive_content: Titiliva kontenajo
-  time:
-    formats:
-      default: "%b %d, %Y, %H:%M"
   two_factor_authentication:
-    code_hint: Enter the code generated by your authenticator app to confirm
     description_html: Se tu posibligas <strong>dufaktora autentikigo</strong>, tu bezonos tua poshtelefonilo por enirar, nam ol kreos nombri, quin tu devos enskribar.
     disable: Extingar
     enable: Acendar
-    enabled_success: Two-factor authentication successfully enabled
     generate_recovery_codes: Generate Recovery Codes
     instructions_html: "<strong>Skanez ta QR-kodexo per Google Authenticator o per simila apliko di tua poshtelefonilo</strong>. De lore, la apliko kreos nombri, quin tu devos enskribar."
-    lost_recovery_codes: Recovery codes allow you to regain access to your account if you lose your phone. If you've lost your recovery codes, you can regenerate them here. Your old recovery codes will be invalidated.
-    manual_instructions: 'If you can''t scan the QR code and need to enter it manually, here is the plain-text secret:'
-    recovery_codes_regenerated: Recovery codes successfully regenerated
     recovery_instructions_html: If you ever lose access to your phone, you can use one of the recovery codes below to regain access to your account. Keep the recovery codes safe, for example by printing them and storing them with other important documents.
-    setup: Set up
-    wrong_code: The entered code was invalid! Are server time and device time correct?
   users:
     invalid_email: La retpost-adreso ne esas valida
     invalid_otp_token: La dufaktora autentikigila kodexo ne esas valida
diff --git a/config/locales/it.yml b/config/locales/it.yml
index 6d45ece8356c1bdff059d0c7c339580c7297f6e5..6dfe212d1496abc4b94d73243d27b1364e764337 100644
--- a/config/locales/it.yml
+++ b/config/locales/it.yml
@@ -4,36 +4,36 @@ it:
     about_hashtag_html: Questi sono i toot pubblici etichettati con <strong>#%{hashtag}</strong>. Puoi interagire con loro se hai un account nel fediverse.
     about_mastodon_html: Mastodon è un social network <em>gratuito e open-source</em>. Un'alternativa <em>decentralizzata</em> alle piattaforme commerciali che evita che una singola compagnia monopolizzi il tuo modo di comunicare. Scegli un server di cui ti fidi &mdash; qualunque sia la tua scelta, potrai interagire con chiunque altro. Chiunque può sviluppare un suo server Mastodon e partecipare alla vita del <em>social network</em>.
     about_this: A proposito di questo server
+    active_count_after: attivo
+    active_footnote: Utenti Attivi Mensili (MAU)
     administered_by: 'Amministrato da:'
     api: API
     apps: Applicazioni Mobile
-    closed_registrations: Al momento le iscrizioni a questo server sono chiuse. Tuttavia! Puoi provare a cercare un istanza diversa su cui creare un account ed avere accesso alla stessa identica rete.
+    apps_platforms: Usa Mastodon da iOS, Android e altre piattaforme
+    browse_directory: Sfoglia la directory dei profili e filtra per interessi
+    browse_public_posts: Sfoglia il flusso in tempo reale di post pubblici su Mastodon
     contact: Contatti
     contact_missing: Non impostato
     contact_unavailable: N/D
+    discover_users: Scopri utenti
     documentation: Documentazione
     extended_description_html: |
       <h3>Un buon posto per le regole</h3>
       <p>La descrizione estesa non è ancora stata preparata.</p>
-    features:
-      humane_approach_body: Imparando dai fallimenti degli altri networks, Mastodon mira a fare scelte etiche di design per combattere l'abuso dei social media.
-      humane_approach_title: Un approccio più umano
-      not_a_product_body: Mastodon non è una rete commerciale. Niente pubblicità, niente data mining, nessun recinto dorato. Non c'è nessuna autorità centrale.
-      not_a_product_title: Tu sei una persona, non un prodotto
-      real_conversation_body: Con 65535 caratteri a disposizione, un supporto per i contenuti granulari ed avvisi sui media potrai esprimerti nel modo desiderato.
-      real_conversation_title: Creato per conversazioni reali
-      within_reach_body: Apps per iOS, Android ed altre piattaforme, realizzate grazie ad un ecosistema di API adatto agli sviluppatori, ti consentono di poter stare in contatto con i tuoi amici ovunque ti trovi.
-      within_reach_title: Sempre a portata di mano
+    federation_hint_html: Con un account su %{instance} sarai in grado di seguire persone su qualsiasi server Mastodon e oltre.
     generic_description: "%{domain} è un server nella rete"
+    get_apps: Prova un'app per smartphone
     hosted_on: Mastodon ospitato su %{domain}
     learn_more: Scopri altro
-    other_instances: Elenco istanze
-    privacy_policy: Policy su la Privacy
+    privacy_policy: Politica della privacy
+    see_whats_happening: Guarda cosa succede
+    server_stats: 'Statistiche del server:'
     source_code: Codice sorgente
     status_count_after:
-      one: status
-      other: status
+      one: stato
+      other: stati
     status_count_before: Che hanno pubblicato
+    tagline: Segui amici e trovane di nuovi
     terms: Termini di Servizio
     user_count_after:
       one: utente
@@ -48,6 +48,7 @@ it:
       other: Seguaci
     following: Segui
     joined: Dal %{date}
+    last_active: ultima attività
     link_verified_on: La proprietà di questo link è stata controllata il %{date}
     media: Media
     moved_html: "%{name} è stato spostato su %{new_profile_link}:"
@@ -67,16 +68,22 @@ it:
       admin: Amministratore
       bot: Bot
       moderator: Moderatore
+    unavailable: Profilo non disponibile
     unfollow: Non seguire più
   admin:
+    account_actions:
+      action: Esegui azione
+      title: Esegui azione di moderazione su %{acct}
     account_moderation_notes:
       create: Lascia nota
       created_msg: Nota di moderazione creata con successo!
       delete: Elimina
       destroyed_msg: Nota di moderazione distrutta con successo!
     accounts:
+      approve: Approva
+      approve_all: Approva tutto
       are_you_sure: Sei sicuro?
-      avatar: Avatar
+      avatar: Immagine di profilo
       by_domain: Dominio
       change_email:
         changed_msg: Account email cambiato con successo!
@@ -88,6 +95,7 @@ it:
       confirm: Conferma
       confirmed: Confermato
       confirming: Confermando
+      deleted: Cancellato
       demote: Declassa
       disable: Disabilita
       disable_two_factor_authentication: Disabilita 2FA
@@ -103,8 +111,11 @@ it:
       followers: Follower
       followers_url: URL follower
       follows: Segue
+      header: Intestazione
       inbox_url: URL inbox
+      invited_by: Invitato da
       ip: IP
+      joined: Unito
       location:
         all: Tutto
         local: Locale
@@ -114,16 +125,20 @@ it:
       media_attachments: Media allegati
       memorialize: Trasforma in memoriam
       moderation:
+        active: Attivo
         all: Tutto
+        pending: In attesa
         silenced: Silenziati
         suspended: Sospesi
         title: Moderazione
       moderation_notes: Note di moderazione
       most_recent_activity: Attività più recenti
       most_recent_ip: IP più recenti
+      no_account_selected: Nessun account è stato modificato visto che non ne è stato selezionato nessuno
       no_limits_imposed: Nessun limite imposto
       not_subscribed: Non sottoscritto
       outbox_url: URL outbox
+      pending: Revisioni in attesa
       perform_full_suspension: Sospendi
       profile_url: URL profilo
       promote: Promuovi
@@ -131,7 +146,10 @@ it:
       public: Pubblico
       push_subscription_expires: Sottoscrizione PuSH scaduta
       redownload: Aggiorna avatar
+      reject: Rifiuta
+      reject_all: Rifiuta tutto
       remove_avatar: Rimuovi avatar
+      remove_header: Rimuovi intestazione
       resend_confirmation:
         already_confirmed: Questo utente è già confermato
         send: Reinvia email di conferma
@@ -156,18 +174,21 @@ it:
       statuses: Stati
       subscribe: Sottoscrivi
       suspended: Sospeso
+      time_in_queue: Attesa in coda %{time}
       title: Account
       unconfirmed_email: Email non confermata
       undo_silenced: Rimuovi silenzia
       undo_suspension: Rimuovi sospensione
       unsubscribe: Annulla l'iscrizione
       username: Nome utente
+      warn: Avverti
       web: Web
     action_logs:
       actions:
         assigned_to_self_report: "%{name} ha assegnato il rapporto %{target} a se stesso"
         change_email_user: "%{name} ha cambiato l'indirizzo email per l'utente %{target}"
         confirm_user: "%{name} ha confermato l'indirizzo email per l'utente %{target}"
+        create_account_warning: "%{name} ha mandato un avvertimento a %{target}"
         create_custom_emoji: "%{name} ha caricato un nuovo emoji %{target}"
         create_domain_block: "%{name} ha bloccato il dominio %{target}"
         create_email_domain_block: "%{name} ha messo il dominio email %{target} nella blacklist"
@@ -195,7 +216,7 @@ it:
         update_custom_emoji: "%{name} ha aggiornato l'emoji %{target}"
         update_status: "%{name} stato aggiornato da %{target}"
       deleted_status: "(stato cancellato)"
-      title: Audit log
+      title: Registro di controllo
     custom_emojis:
       by_domain: Dominio
       copied_msg: Creata con successo una copia locale dell'emoji
@@ -214,7 +235,7 @@ it:
       new:
         title: Aggiungi nuovo emoji personalizzato
       overwrite: Sovrascrivi
-      shortcode: Shortcode
+      shortcode: Scorciatoia
       shortcode_hint: Almeno due caratteri, solo caratteri alfanumerici e trattino basso
       title: Emoji personalizzate
       unlisted: Non elencato
@@ -222,12 +243,14 @@ it:
       updated_msg: Emoji aggiornata con successo!
       upload: Carica
     dashboard:
-      backlog: backlogged jobs
+      backlog: lavori arretrati
       config: Configurazione
       feature_deletions: Cancellazioni di account
       feature_invites: Link di invito
+      feature_profile_directory: Directory dei profili
       feature_registrations: Registrazioni
       feature_relay: Ripetitore di federazione
+      feature_timeline_preview: Anteprima timeline
       features: Funzionalità
       hidden_service: Federazione con servizi nascosti
       open_reports: apri report
@@ -236,7 +259,7 @@ it:
       single_user_mode: Modalita utente singolo
       software: Software
       space: Utilizzo dello spazio
-      title: Dashboard
+      title: Cruscotto
       total_users: utenti totali
       trends: Tendenze
       week_interactions: interazioni per questa settimana
@@ -247,6 +270,7 @@ it:
       created_msg: Il blocco del dominio sta venendo processato
       destroyed_msg: Il blocco del dominio è stato rimosso
       domain: Dominio
+      existing_domain_block_html: Hai già impostato limitazioni più stringenti su %{name}, dovresti <a href="%{unblock_url}">sbloccare</a> prima.
       new:
         create: Crea blocco
         hint: Il blocco dominio non previene la creazione di utenti nel database, ma applicherà automaticamente e retroattivamente metodi di moderazione specifici su quegli account.
@@ -260,6 +284,11 @@ it:
       reject_media_hint: Rimuovi i file media salvati in locale e blocca i download futuri. Irrilevante per le sospensioni
       reject_reports: Respingi rapporti
       reject_reports_hint: Ignora tutti i rapporti provenienti da questo dominio. Irrilevante per sospensioni
+      rejecting_media: rigetta file media
+      rejecting_reports: rigetta segnalazioni
+      severity:
+        silence: silenziato
+        suspend: sospeso
       show:
         affected_accounts:
           one: Interessato un solo account nel database
@@ -280,8 +309,25 @@ it:
         create: Aggiungi dominio
         title: Nuova voce della lista nera delle email
       title: Lista nera email
+    followers:
+      back_to_account: Torna all'account
+      title: Seguaci di %{acct}
     instances:
+      by_domain: Dominio
+      delivery_available: Distribuzione disponibile
+      known_accounts:
+        one: "%{count} account noto"
+        other: "%{count} account noti"
+      moderation:
+        all: Tutto
+        limited: Limitato
+        title: Moderazione
       title: Istanze conosciute
+      total_blocked_by_us: Bloccato da noi
+      total_followed_by_them: Seguito da loro
+      total_followed_by_us: Seguito da noi
+      total_reported: Segnalazioni su di loro
+      total_storage: Media allegati
     invites:
       deactivate_all: Disattiva tutto
       filter:
@@ -290,6 +336,8 @@ it:
         expired: Scaduto
         title: Filtro
       title: Inviti
+    pending_accounts:
+      title: Account in attesa (%{count})
     relays:
       add_new: Aggiungi ripetitore
       delete: Cancella
@@ -303,7 +351,7 @@ it:
       pending: In attesa dell'approvazione del ripetitore
       save_and_enable: Salva e attiva
       setup: Crea una connessione con un ripetitore
-      status: Status
+      status: Stato
       title: Ripetitori
     report_notes:
       created_msg: Nota rapporto creata!
@@ -346,22 +394,26 @@ it:
         desc_html: Separa i nomi utente con virgola. Funziona solo con account locali e non bloccati. Quando vuoto, valido per tutti gli amministratori locali.
         title: Seguiti predefiniti per i nuovi utenti
       contact_information:
+        email: E-mail di lavoro
         username: Nome utente del contatto
       custom_css:
         desc_html: Modifica l'aspetto con il CSS caricato in ogni pagina
         title: CSS personalizzato
       hero:
-        desc_html: Mostrata nella pagina iniziale. Almeno 600x100 px consigliati. Se non impostata, sarà usato il thumbnail dell'istanza
+        desc_html: Mostrata nella pagina iniziale. Almeno 600x100 px consigliati. Se non impostata, sarà usato il thumbnail del server
         title: Immagine dell'eroe
       mascot:
         desc_html: Mostrata su più pagine. Almeno 293×205px consigliati. Se non impostata, sarò usata la mascotte predefinita
         title: Immagine della mascotte
       peers_api_enabled:
-        desc_html: Nomi di dominio che questa istanza ha incontrato nella fediverse
-        title: Pubblica elenco di istanze scoperte
+        desc_html: Nomi di dominio che questo server ha incontrato nel fediverse
+        title: Pubblica elenco dei server scoperti
       preview_sensitive_media:
         desc_html: Le anteprime dei link su altri siti mostreranno un thumbnail anche se il media è segnato come sensibile
         title: Mostra media sensibili nella anteprime OpenGraph
+      profile_directory:
+        desc_html: Permetti agli utenti di essere trovati
+        title: Attiva directory dei profili
       registrations:
         closed_message:
           desc_html: Mostrato nella pagina iniziale quando le registrazioni sono chiuse. Puoi usare tag HTML
@@ -372,30 +424,34 @@ it:
         min_invite_role:
           disabled: Nessuno
           title: Permetti inviti da
-        open:
-          desc_html: Consenti a chiunque di creare un account
-          title: Apri registrazioni
+      registrations_mode:
+        modes:
+          approved: Approvazione richiesta per le iscrizioni
+          none: Nessuno può iscriversi
+          open: Chiunque può iscriversi
+        title: Modalità di registrazione
       show_known_fediverse_at_about_page:
         desc_html: Quando attivato, mostra nell'anteprima i toot da tutte le istanze conosciute. Altrimenti mostra solo i toot locali.
         title: Mostra la fediverse conosciuta nell'anteprima della timeline
       show_staff_badge:
+        desc_html: Mostra un distintivo dello staff sulla pagina dell'utente
         title: Mostra badge staff
       site_description:
         desc_html: Paragrafo introduttivo nella pagina iniziale. Descrive ciò che rende speciale questo server Mastodon e qualunque altra cosa sia importante dire. Potete usare marcatori HTML, in particolare <code>&lt;a&gt;</code> e <code>&lt;em&gt;</code>.
-        title: Descrizione istanza
+        title: Descrizione del server
       site_description_extended:
-        desc_html: Un posto adatto per pubblicare regole di comportamento, linee guida e altre cose specifiche della vostra istanza. Potete usare marcatori HTML
+        desc_html: Un posto adatto per pubblicare regole di comportamento, linee guida e altre cose specifiche del vostro server. Potete usare marcatori HTML
         title: Informazioni estese personalizzate
       site_short_description:
-        desc_html: Mostrato nella barra laterale e nei tag meta. Descrive in un paragrafo che cos'è Mastodon e che cosa rende questo server speciale. Se vuoto, sarà usata la descrizione predefinita dell'istanza.
-        title: Breve descrizione dell'istanza
+        desc_html: Mostrato nella barra laterale e nei tag meta. Descrive in un paragrafo che cos'è Mastodon e che cosa rende questo server speciale. Se vuoto, sarà usata la descrizione predefinita del server.
+        title: Breve descrizione del server
       site_terms:
         desc_html: Potete scrivere la vostra politica sulla privacy, condizioni del servizio o altre informazioni legali. Potete usare tag HTML
         title: Termini di servizio personalizzati
-      site_title: Nome istanza
+      site_title: Nome del server
       thumbnail:
         desc_html: Usato per anteprime tramite OpenGraph e API. 1200x630px consigliati
-        title: Thumbnail dell'istanza
+        title: Thumbnail del server
       timeline_preview:
         desc_html: Mostra la timeline pubblica sulla pagina iniziale
         title: Anteprima timeline
@@ -417,8 +473,40 @@ it:
       callback_url: URL Callback
       confirmed: Confermato
       expires_in: Scade in
+      last_delivery: Ultima distribuzione
+      title: WebSub
       topic: Argomento
+    tags:
+      accounts: Account
+      hidden: Nascosto
+      hide: Nascondi dalla directory
+      name: Etichetta
+      title: Hashtag
+      unhide: Mostra nella directory
+      visible: Visibile
     title: Amministrazione
+    warning_presets:
+      add_new: Aggiungi nuovo
+      delete: Cancella
+      edit: Modifica
+      edit_preset: Modifica avviso predefinito
+      title: Gestisci avvisi predefiniti
+  admin_mailer:
+    new_pending_account:
+      body: I dettagli del nuovo account sono qui sotto. Puoi approvare o rifiutare questa richiesta.
+      subject: Nuovo account pronto per la revisione su %{instance} (%{username})
+    new_report:
+      body: "%{reporter} ha segnalato %{target}"
+      body_remote: Qualcuno da %{domain} ha segnalato %{target}
+      subject: Nuova segnalazione per %{instance} (#%{id})
+  appearance:
+    advanced_web_interface: Interfaccia web avanzata
+    advanced_web_interface_hint: |-
+      Se vuoi utilizzare l'intera larghezza dello schermo, l'interfaccia web avanzata ti consente di configurare varie colonne per mostrare più informazioni allo stesso tempo, secondo le tue preferenze:
+      Home, notifiche, timeline federata, qualsiasi numero di liste e etichette.
+    animations_and_accessibility: Animazioni e accessibiiltà
+    confirmation_dialogs: Dialoghi di conferma
+    sensitive_content: Contenuto sensibile
   application_mailer:
     notification_preferences: Cambia preferenze email
     salutation: "%{name},"
@@ -433,26 +521,32 @@ it:
     regenerate_token: Rigenera il token di accesso
     token_regenerated: Token di accesso rigenerato
     warning: Fa' molta attenzione con questi dati. Non fornirli mai a nessun altro!
+    your_token: Il tuo token di accesso
   auth:
-    agreement_html: Iscrivendoti, accetti di seguire <a href="%{rules_path}">le regole dell'istanza</a> e <a href="%{terms_path}"> le nostre condizioni di servizio</a>.
+    apply_for_account: Richiedi un invito
     change_password: Password
+    checkbox_agreement_html: Sono d'accordo con le <a href="%{rules_path}" target="_blank">regole del server</a> ed i <a href="%{terms_path}" target="_blank">termini di servizio</a>
     confirm_email: Conferma email
     delete_account: Elimina account
     delete_account_html: Se desideri cancellare il tuo account, puoi <a href="%{path}">farlo qui</a>. Ti sarà chiesta conferma.
     didnt_get_confirmation: Non hai ricevuto le istruzioni di conferma?
     forgot_password: Hai dimenticato la tua password?
+    invalid_reset_password_token: Il token di reimpostazione della password non è valido o è scaduto. Per favore richiedine uno nuovo.
     login: Entra
     logout: Esci da Mastodon
     migrate_account: Sposta ad un account differente
     migrate_account_html: Se vuoi che questo account sia reindirizzato a uno diverso, puoi <a href="%{path}">configurarlo qui</a>.
-    or: o
     or_log_in_with: Oppure accedi con
+    providers:
+      cas: CAS
+      saml: SAML
     register: Iscriviti
-    register_elsewhere: Iscriviti su un altro server
+    registration_closed: "%{instance} non accetta nuovi membri"
     resend_confirmation: Invia di nuovo le istruzioni di conferma
     reset_password: Resetta la password
     security: Credenziali
     set_new_password: Imposta una nuova password
+    trouble_logging_in: Problemi di accesso?
   authorize_follow:
     already_following: Stai già seguendo questo account
     error: Sfortunatamente c'è stato un errore nel consultare l'account remoto
@@ -484,18 +578,33 @@ it:
     description_html: Questa azione eliminerà <strong>in modo permanente e irreversibile</strong> tutto il contenuto del tuo account e lo disattiverà. Il tuo nome utente resterà riservato per prevenire che qualcuno in futuro assuma la tua identità.
     proceed: Cancella l'account
     success_msg: Il tuo account è stato cancellato
-    warning_html: È garantita solo la cancellazione del contenuto solo da questa istanza. I contenuti che sono stati ampiamente condivisi probabilmente lasceranno delle tracce. I server offline e quelli che non ricevono più i tuoi aggiornamenti non aggiorneranno i loro database.
+    warning_html: È garantita la cancellazione del contenuto solo da questo server. I contenuti che sono stati ampiamente condivisi probabilmente lasceranno delle tracce. I server offline e quelli che non ricevono più i tuoi aggiornamenti non aggiorneranno i loro database.
+    warning_title: Disponibilità di contenuto diffuso
+  directories:
+    directory: Directory dei profili
+    enabled: Attualmente sei elencato nella directory.
+    enabled_but_waiting: Hai scelto di essere elencato nella directory, ma non hai ancora il numero minimo di seguaci (%{min_followers}) per comparire.
+    explanation: Scopri utenti in base ai loro interessi
+    explore_mastodon: Esplora %{title}
+    how_to_enable: Attualmente non hai scelto di comparire nella directory. Puoi farlo qui sotto. Se vuoi comparire sotto determinati hashtag, usali nel testo della tua biografia.
+    people:
+      one: "%{count} persona"
+      other: "%{count} persone"
   errors:
     '403': Non sei autorizzato a visualizzare questa pagina.
     '404': La pagina che stavi cercando non esiste.
-    '410': La pagina che stavi cercando non esiste più.
+    '410': La pagina che stavi cercando qui non esiste più.
     '422':
       content: Verifica di sicurezza non riuscita. Stai bloccando i cookies?
       title: Verifica di sicurezza non riuscita
+    '429': Limitato
     '500':
       content: Siamo spiacenti, ma qualcosa non ha funzionato dal nostro lato.
       title: Questa pagina non è corretta
     noscript_html: Per usare l'interfaccia web di Mastodon dovi abilitare JavaScript. In alternativa puoi provare una delle <a href="%{apps_path}">app native</a> per Mastodon per la tua piattaforma.
+  existing_username_validator:
+    not_found: impossibile trovare un utente locale con quel nome utente
+    not_found_multiple: impossibile trovare %{usernames}
   exports:
     archive_takeout:
       date: Data
@@ -506,9 +615,15 @@ it:
       size: Dimensioni
     blocks: Stai bloccando
     csv: CSV
+    domain_blocks: Blocchi di dominio
     follows: Stai seguendo
+    lists: Liste
     mutes: Stai silenziando
     storage: Archiviazione media
+  featured_tags:
+    add_new: Aggiungi nuovo
+    errors:
+      limit: Hai già messo in evidenza il numero massimo di hashtag
   filters:
     contexts:
       home: Timeline home
@@ -519,35 +634,56 @@ it:
       title: Modifica filtro
     errors:
       invalid_context: Contesto mancante o non valido
+      invalid_irreversible: Il filtraggio irreversibile funziona solo nei contesti di home o notifiche
     index:
       delete: Cancella
       title: Filtri
     new:
       title: Aggiungi filtro
-  followers:
-    domain: Dominio
-    explanation_html: Se vuoi garantire la privacy dei tuoi status, devi sapere chi ti sta seguendo. <strong>I tuoi status privati vengono inviati a tutte le istanze su cui hai dei seguaci</strong>. Puoi controllare chi sono i tuoi seguaci, ed eliminarli se non hai fiducia che la tua privacy venga rispettata dallo staff o dal software di quelle istanze.
-    followers_count: Numero di seguaci
-    lock_link: Blocca il tuo account
-    purge: Elimina dai seguaci
-    true_privacy_html: Tieni presente che <strong>l'effettiva riservatezza si può ottenere solo con la crittografia end-to-end</strong>.
-    unlocked_warning_html: Chiunque può seguirti per vedere immediatamente i tuoi status privati. %{lock_link} per poter esaminare e respingere gli utenti che vogliono seguirti.
-    unlocked_warning_title: Il tuo account non è bloccato
   footer:
     developers: Sviluppatori
     more: Altro…
+    resources: Risorse
   generic:
+    all: Tutto
     changes_saved_msg: Modifiche effettuate con successo!
     copy: Copia
+    order_by: Ordina per
     save_changes: Salva modifiche
     validation_errors:
       one: Qualcosa ancora non va bene! Per favore, controlla l'errore qui sotto
       other: Qualcosa ancora non va bene! Per favore, controlla i %{count} errori qui sotto
+  html_validator:
+    invalid_markup: 'contiene markup HTML non valido: %{error}'
+  identity_proofs:
+    active: Attive
+    authorize: Si, autorizza
+    authorize_connection_prompt: Autorizzare questa connessione crittografata?
+    errors:
+      failed: La connessione crittografata non è riuscita. Per favore riprova da %{provider}.
+      keybase:
+        invalid_token: I toked di Keybase sono hash di firme e devono essere lunghi 66 caratteri esadecimali
+        verification_failed: Keybase non riconosce questo token come firma dell'utente Keybase %{kb_username}. Per favore riprova da Keybase.
+      wrong_user: Impossibile creare una prova per %{proving} mentre si è effettuato l'accesso come %{current}. Accedi come %{proving} e riprova.
+    explanation_html: Qui puoi connettere crittograficamente le tue altre identità, come il profilo Keybase. Questo consente ad altre persone di inviarti messaggi criptati e fidarsi dei contenuto che tu invii a loro.
+    i_am_html: Io sono %{username} su %{service}.
+    identity: Identità
+    inactive: Inattiva
+    publicize_checkbox: 'E posta questo:'
+    publicize_toot: 'É provato! Io sono %{username} su %{service}: %{url}'
+    status: Stato della verifica
+    view_proof: Vedi prova
   imports:
-    preface: Puoi importare alcune informazioni, come le persone che segui o hai bloccato su questo server, da file creati da un esportazione su un altro server.
+    modes:
+      merge: Fondi
+      merge_long: Mantieni record esistenti e aggiungine di nuovi
+      overwrite: Sovrascrivi
+      overwrite_long: Sostituisci record attuali con quelli nuovi
+    preface: Puoi importare alcune informazioni, come le persone che segui o hai bloccato su questo server, da file creati da un'esportazione su un altro server.
     success: Le tue impostazioni sono state importate correttamente e verranno applicate in breve tempo
     types:
       blocking: Lista dei bloccati
+      domain_blocking: Lista dei domini bloccati
       following: Lista dei seguaci
       muting: Lista dei silenziati
     upload: Carica
@@ -569,7 +705,7 @@ it:
       one: un uso
       other: "%{count} utilizzi"
     max_uses_prompt: Nessun limite
-    prompt: Genera e condividi dei link ad altri per garantire l'accesso a questa istanza
+    prompt: Genera e condividi dei link con altri per concedere l'accesso a questo server
     table:
       expires_at: Scade
       uses: Utilizzi
@@ -627,44 +763,90 @@ it:
       decimal_units:
         format: "%n%u"
         units:
-          billion: B
+          billion: G
           million: M
-          quadrillion: Q
-          thousand: K
+          quadrillion: P
+          thousand: k
           trillion: T
-          unit: ''
   pagination:
     newer: Più recente
     next: Avanti
     older: Più vecchio
     prev: Indietro
     truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: Hai già votato in questo sondaggio
+      duplicate_options: contiene oggetti duplicati
+      duration_too_long: è troppo lontano nel futuro
+      duration_too_short: è troppo presto
+      expired: Il sondaggio si è già concluso
+      over_character_limit: non possono essere più lunghi di %{max} caratteri ciascuno
+      too_few_options: deve avere più di un elemento
+      too_many_options: non può contenere più di %{max} elementi
   preferences:
-    languages: Lingue
     other: Altro
-    publishing: Pubblicazione
-    web: Web
+    posting_defaults: Predefinite di pubblicazione
+    public_timelines: Timeline pubbliche
+  relationships:
+    activity: Attività dell'account
+    dormant: Dormiente
+    last_active: Ultima volta attivo
+    most_recent: Più recente
+    moved: Trasferito
+    mutual: Reciproco
+    primary: Principale
+    relationship: Relazione
+    remove_selected_domains: Rimuovi tutti i seguaci dai domini selezionati
+    remove_selected_followers: Rimuovi i seguaci selezionati
+    remove_selected_follows: Smetti di seguire gli utenti selezionati
+    status: Stato dell'account
   remote_follow:
     acct: Inserisci il tuo username@dominio da cui vuoi seguire questo utente
     missing_resource: Impossibile trovare l'URL di reindirizzamento richiesto per il tuo account
     no_account_html: Non hai un account? Puoi <a href='%{sign_up_path}' target='_blank'>iscriverti qui</a>
     proceed: Conferma
     prompt: 'Stai per seguire:'
+    reason_html: "<strong>Perchè questo passo è necessario?</strong> <code>%{instance}</code> potrebbe non essere il server nel quale tu sei registrato, quindi dobbiamo reindirizzarti prima al tuo server."
+  remote_interaction:
+    favourite:
+      proceed: Continua per segnare come apprezzato
+      prompt: 'Vuoi segnare questo toot come apprezzato:'
+    reblog:
+      proceed: Continua per condividere
+      prompt: 'Vuoi condividere questo toot:'
+    reply:
+      proceed: Continua per rispondere
+      prompt: 'Vuoi rispondere a questo toot:'
   remote_unfollow:
     error: Errore
     title: Titolo
+    unfollowed: Non più seguito
+  scheduled_statuses:
+    over_daily_limit: Hai superato il limite di %{limit} toot programmati per questo giorno
+    over_total_limit: Hai superato il limite di %{limit} toot programmati
+    too_soon: La data di pubblicazione deve essere nel futuro
   sessions:
     activity: Ultima attività
     browser: Browser
     browsers:
+      alipay: Alipay
       blackberry: Blackberry
       chrome: Chrome
       edge: Microsoft Edge
+      electron: Electron
       firefox: Firefox
       generic: Browser sconosciuto
       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: Sessione corrente
     description: "%{browser} su %{platform}"
     explanation: Questi sono i browser da cui attualmente è avvenuto l'accesso al tuo account Mastodon.
@@ -682,22 +864,29 @@ it:
       windows: Windows
       windows_mobile: Windows Mobile
       windows_phone: Windows Phone
+    revoke: Revoca
+    revoke_success: Sessione revocata con successo
     title: Sessioni
   settings:
+    account: Account
+    account_settings: Impostazioni dell'account
+    appearance: Interfaccia
     authorized_apps: Applicazioni autorizzate
     back: Torna a Mastodon
     delete: Cancellazione account
     development: Sviluppo
     edit_profile: Modifica profilo
     export: Esporta impostazioni
-    followers: Seguaci autorizzati
+    featured_tags: Hashtag in evidenza
+    identity_proofs: Prove di identità
     import: Importa
+    import_and_export: Importa ed esporta
     migrate: Migrazione dell'account
     notifications: Notifiche
     preferences: Preferenze
-    settings: Impostazioni
+    profile: Profilo
+    relationships: Follows and followers
     two_factor_authentication: Autenticazione a due fattori
-    your_apps: Le tue applicazioni
   statuses:
     attached:
       description: 'Allegato: %{attached}'
@@ -708,6 +897,7 @@ it:
         one: "%{count} video"
         other: "%{count} video"
     boosted_from_html: Condiviso da %{acct_link}
+    content_warning: 'Avviso di contenuto: %{warning}'
     disallowed_hashtags:
       one: 'contiene un hashtag non permesso: %{tags}'
       other: 'contiene gli hashtags non permessi: %{tags}'
@@ -719,8 +909,14 @@ it:
       ownership: Non puoi fissare in cima un toot di qualcun altro
       private: Un toot non pubblico non può essere fissato in cima
       reblog: Un toot condiviso non può essere fissato in cima
+    poll:
+      total_votes:
+        one: "%{count} voto"
+        other: "%{count} voti"
+      vote: Vota
     show_more: Mostra di più
     sign_in_to_participate: Accedi per partecipare alla conversazione
+    title: '%{name}: "%{quote}"'
     visibilities:
       private: Mostra solo ai tuoi seguaci
       private_long: Mostra solo ai seguaci
@@ -735,12 +931,13 @@ it:
   terms:
     title: "%{instance} Termini di servizio e politica della privacy"
   themes:
-    contrast: Contrasto elevato
-    default: Mastodon
+    contrast: Mastodon (contrasto elevato)
+    default: Mastodon (scuro)
     mastodon-light: Mastodon (chiaro)
   time:
     formats:
       default: "%b %d, %Y, %H:%M"
+      month: "%b %Y"
   two_factor_authentication:
     code_hint: Inserisci il codice generato dalla tua app di autenticazione
     description_html: Se abiliti <strong>l'autorizzazione a due fattori</strong>, entrare nel tuo account ti richiederà di avere vicino il tuo telefono, il quale ti genererà un codice per eseguire l'accesso.
@@ -762,13 +959,30 @@ it:
       explanation: Hai richiesto un backup completo del tuo account Mastodon. È pronto per essere scaricato!
       subject: Il tuo archivio è pronto per essere scaricato
       title: Esportazione archivio
+    warning:
+      explanation:
+        disable: Mentre il tuo account è congelato, i tuoi dati dell'account rimangono intatti, ma non potrai eseguire nessuna azione fintanto che non viene sbloccato.
+        silence: Mentre il tuo account è limitato, solo le persone che già ti seguono possono vedere i tuoi toot su questo server, e potresti essere escluso da vari elenchi pubblici. Comunque, altri possono manualmente seguirti.
+        suspend: Il tuo account è stato sospeso, e tutti i tuoi toot ed i tuoi file media caricati sono stati irreversibilmente rimossi da questo server, e dai server dove avevi dei seguaci.
+      review_server_policies: Rivedi regole del server
+      subject:
+        disable: Il tuo account %{acct} è stato congelato
+        none: Avviso per %{acct}
+        silence: Il tuo account %{acct} è stato limitato
+        suspend: Il tuo account %{acct} è stato sospeso
+      title:
+        disable: Account congelato
+        none: Avviso
+        silence: Account limitato
+        suspend: Account sospeso
     welcome:
+      edit_profile_action: Imposta profilo
       edit_profile_step: Puoi personalizzare il tuo profilo caricando un avatar, un'intestazione, modificando il tuo nome visualizzato e così via. Se vuoi controllare i tuoi nuovi seguaci prima di autorizzarli a seguirti, puoi bloccare il tuo account.
       explanation: Ecco alcuni suggerimenti per iniziare
       final_action: Inizia a postare
       final_step: 'Inizia a postare! Anche se non hai seguaci, i tuoi messaggi pubblici possono essere visti da altri, ad esempio nelle timeline locali e negli hashtag. Se vuoi puoi presentarti con l''hashtag #introductions.'
       full_handle: Il tuo nome utente completo
-      full_handle_hint: Questo è ciò che diresti ai tuoi amici in modo che possano seguirti o contattarti da un'altra istanza.
+      full_handle_hint: Questo è ciò che diresti ai tuoi amici in modo che possano seguirti o contattarti da un altro server.
       review_preferences_action: Cambia preferenze
       review_preferences_step: Dovresti impostare le tue preferenze, ad esempio quali email vuoi ricevere oppure il livello predefinito di privacy per i tuoi post. Se le immagini in movimento non ti danno fastidio, puoi abilitare l'animazione automatica delle GIF.
       subject: Benvenuto/a su Mastodon
@@ -782,6 +996,7 @@ it:
     follow_limit_reached: Non puoi seguire più di %{limit} persone
     invalid_email: L'indirizzo email inserito non è valido
     invalid_otp_token: Codice d'accesso non valido
+    otp_lost_help_html: Se perdessi l'accesso ad entrambi, puoi entrare in contatto con %{email}
     seamless_external_login: Ti sei collegato per mezzo di un servizio esterno, quindi le impostazioni di email e password non sono disponibili.
     signed_in_as: 'Hai effettuato l''accesso come:'
   verification:
diff --git a/config/locales/ja.yml b/config/locales/ja.yml
index 7ccb2f21c52fb5a8d86c153261f14e3485ee346c..ca640d07d1f42546867ac77070a85a1dc56728ae 100644
--- a/config/locales/ja.yml
+++ b/config/locales/ja.yml
@@ -4,39 +4,37 @@ ja:
     about_hashtag_html: ハッシュタグ <strong>#%{hashtag}</strong> の付いた公開トゥートです。どこでもいいので、連合に参加しているSNS上にアカウントを作れば会話に参加することができます。
     about_mastodon_html: Mastodon は、オープンなウェブプロトコルを採用した、自由でオープンソースなソーシャルネットワークです。電子メールのような分散型の仕組みを採っています。
     about_this: 詳細情報
+    active_count_after: 人アクティブ
+    active_footnote: 月間アクティブユーザー数 (MAU)
     administered_by: '管理者:'
     api: API
     apps: アプリ
-    closed_registrations: 現在このインスタンスでの新規登録は受け付けていません。しかし、他のインスタンスにアカウントを作成しても全く同じネットワークに参加することができます。
+    apps_platforms: iOSやAndroidなど、各種環境から利用できます
+    browse_directory: ディレクトリから気になる人を探しましょう
+    browse_public_posts: Mastodonの公開ライブストリームをご覧ください
     contact: 連絡先
     contact_missing: 未設定
     contact_unavailable: N/A
+    discover_users: ユーザーを見つける
     documentation: ドキュメント
     extended_description_html: |
       <h3>ルールを書くのに適した場所</h3>
       <p>詳細説明が設定されていません。</p>
-    features:
-      humane_approach_body: 他の SNS の失敗から学び、Mastodon はソーシャルメディアが誤った使い方をされることの無いように倫理的な設計を目指しています。
-      humane_approach_title: より思いやりのある設計
-      not_a_product_body: Mastodon は営利的な SNS ではありません。広告や、データの収集・解析によるターゲティングは無く、またユーザーの囲い込みもありません。ここには中央権力はありません。
-      not_a_product_title: あなたは人間であり、商品ではありません
-      real_conversation_body: 好きなように書ける500文字までの投稿や、文章やメディアの内容に警告をつけられる機能で、思い通りに自分自身を表現することができます。
-      real_conversation_title: 本当のコミュニケーションのために
-      within_reach_body: デベロッパーフレンドリーな API により実現された、iOS や Android、その他様々なプラットフォームのためのアプリでどこでも友人とやりとりできます。
-      within_reach_title: いつでも身近に
-    generic_description: "%{domain} は、Mastodon インスタンスの一つです"
+    federation_hint_html: "%{instance} のアカウントひとつでどんなMastodon互換サーバーのユーザーでもフォローできるでしょう。"
+    generic_description: "%{domain} は、Mastodon サーバーの一つです"
+    get_apps: モバイルアプリを試す
     hosted_on: Mastodon hosted on %{domain}
     learn_more: もっと詳しく
-    other_instances: 他のインスタンス
     privacy_policy: プライバシーポリシー
+    see_whats_happening: やりとりを見てみる
+    server_stats: 'サーバー統計:'
     source_code: ソースコード
     status_count_after:
-      one: トゥート
       other: トゥート
     status_count_before: トゥート数
+    tagline: Follow friends and discover new ones
     terms: 利用規約
     user_count_after:
-      one: 人
       other: 人
     user_count_before: ユーザー数
     what_is_mastodon: Mastodon とは?
@@ -44,7 +42,6 @@ ja:
     choices_html: "%{name} によるおすすめ:"
     follow: フォロー
     followers:
-      one: フォロワー
       other: フォロワー
     following: フォロー中
     joined: "%{date} に登録"
@@ -59,7 +56,6 @@ ja:
     pin_errors:
       following: おすすめしたい人はあなたが既にフォローしている必要があります
     posts:
-      one: トゥート
       other: トゥート
     posts_tab_heading: トゥート
     posts_with_replies: トゥートと返信
@@ -68,6 +64,7 @@ ja:
       admin: Admin
       bot: Bot
       moderator: Mod
+    unavailable: プロフィールは利用できません
     unfollow: フォロー解除
   admin:
     account_actions:
@@ -79,6 +76,8 @@ ja:
       delete: 削除
       destroyed_msg: モデレーションメモを削除しました!
     accounts:
+      approve: 承認
+      approve_all: すべて承認
       are_you_sure: 本当に実行しますか?
       avatar: アイコン
       by_domain: ドメイン
@@ -124,22 +123,27 @@ ja:
       moderation:
         active: アクティブ
         all: すべて
+        pending: 承認待ち
         silenced: サイレンス済み
         suspended: 停止済み
         title: モデレーション
       moderation_notes: モデレーションメモ
       most_recent_activity: 直近の活動
       most_recent_ip: 直近のIP
+      no_account_selected: 何も選択されていないため、変更されていません
       no_limits_imposed: 制限なし
       not_subscribed: 購読していない
       outbox_url: Outbox URL
+      pending: 承認待ち
       perform_full_suspension: 活動を完全に停止させる
       profile_url: プロフィールURL
       promote: 昇格
       protocol: プロトコル
       public: パブリック
       push_subscription_expires: PuSH購読期限
-      redownload: アバターの更新
+      redownload: プロフィールを更新
+      reject: 却下
+      reject_all: すべて却下
       remove_avatar: アイコンを削除
       remove_header: ヘッダーを削除
       resend_confirmation:
@@ -159,13 +163,14 @@ ja:
       search: 検索
       shared_inbox_url: Shared inbox URL
       show:
-        created_reports: このアカウントで作られたレポート
-        targeted_reports: このアカウントについてのレポート
+        created_reports: このアカウントで作られた通報
+        targeted_reports: このアカウントについての通報
       silence: サイレンス
       silenced: サイレンス済み
       statuses: トゥート数
       subscribe: 購読する
       suspended: 停止済み
+      time_in_queue: "%{time} 待ち"
       title: アカウント
       unconfirmed_email: 確認待ちのメールアドレス
       undo_silenced: サイレンスから戻す
@@ -176,7 +181,7 @@ ja:
       web: Web
     action_logs:
       actions:
-        assigned_to_self_report: "%{name} さんがレポート %{target} を自身の担当に割り当てました"
+        assigned_to_self_report: "%{name} さんが通報 %{target} を自身の担当に割り当てました"
         change_email_user: "%{name} さんが %{target} さんのメールアドレスを変更しました"
         confirm_user: "%{name} さんが %{target} さんのメールアドレスを確認済みにしました"
         create_account_warning: "%{name} さんが %{target} さんに警告メールを送信しました"
@@ -196,12 +201,12 @@ ja:
         memorialize_account: "%{name} さんが %{target} さんを追悼アカウントページに登録しました"
         promote_user: "%{name} さんが %{target} さんを昇格しました"
         remove_avatar_user: "%{name} さんが %{target} さんのアイコンを削除しました"
-        reopen_report: "%{name} さんがレポート %{target} を再び開きました"
+        reopen_report: "%{name} さんが通報 %{target} を再び開きました"
         reset_password_user: "%{name} さんが %{target} さんのパスワードをリセットしました"
-        resolve_report: "%{name} さんがレポート %{target} を解決済みにしました"
+        resolve_report: "%{name} さんが通報 %{target} を解決済みにしました"
         silence_account: "%{name} さんが %{target} さんをサイレンスにしました"
         suspend_account: "%{name} さんが %{target} さんを停止しました"
-        unassigned_report: "%{name} さんがレポート %{target} の担当を外しました"
+        unassigned_report: "%{name} さんが通報 %{target} の担当を外しました"
         unsilence_account: "%{name} さんが %{target} さんのサイレンスを解除しました"
         unsuspend_account: "%{name} さんが %{target} さんの停止を解除しました"
         update_custom_emoji: "%{name} さんがカスタム絵文字 %{target} を更新しました"
@@ -241,9 +246,10 @@ ja:
       feature_profile_directory: ディレクトリ
       feature_registrations: 新規登録
       feature_relay: 連合リレー
+      feature_timeline_preview: タイムラインプレビュー
       features: 機能
       hidden_service: 秘匿サービスとの連合
-      open_reports: 未解決のレポート
+      open_reports: 未解決の通報
       recent_users: 最近登録したユーザー
       search: 全文検索
       single_user_mode: シングルユーザーモード
@@ -260,6 +266,7 @@ ja:
       created_msg: ドメインブロック処理を完了しました
       destroyed_msg: ドメインブロックを外しました
       domain: ドメイン
+      existing_domain_block_html: 既に%{name}に対して、より厳しい制限を課しています。先に<a href="%{unblock_url}">その制限を解除</a>する必要があります。
       new:
         create: ブロックを作成
         hint: ドメインブロックはデータベース中のアカウント項目の作成を妨げませんが、遡って自動的に指定されたモデレーションをそれらのアカウントに適用します。
@@ -271,23 +278,22 @@ ja:
         title: 新規ドメインブロック
       reject_media: メディアファイルを拒否
       reject_media_hint: ローカルに保存されたメディアファイルを削除し、今後のダウンロードを拒否します。停止とは無関係です
-      reject_reports: レポートを拒否
-      reject_reports_hint: このドメインからのレポートをすべて無視します。停止とは無関係です
+      reject_reports: 通報を拒否
+      reject_reports_hint: このドメインからの通報をすべて無視します。停止とは無関係です
       rejecting_media: メディアファイルを拒否中
-      rejecting_reports: レポートを拒否中
+      rejecting_reports: 通報を拒否中
       severity:
         silence: サイレンス中
         suspend: 停止中
       show:
         affected_accounts:
-          one: データベース中の一つのアカウントに影響します
           other: データベース中の%{count}個のアカウントに影響します
         retroactive:
-          silence: このドメインからの存在するすべてのアカウントのサイレンスを戻す
-          suspend: このドメインからの存在するすべてのアカウントの停止を戻す
+          silence: このドメインの既存の影響するアカウントのサイレンスを戻す
+          suspend: このドメインの既存の影響するアカウントの停止を戻す
         title: "%{domain}のドメインブロックを戻す"
         undo: 元に戻す
-      undo: 元に戻す
+      undo: ドメインブロックを戻す
     email_domain_blocks:
       add_new: 新規追加
       created_msg: ブラックリストに追加しました
@@ -302,19 +308,19 @@ ja:
       back_to_account: 戻る
       title: "%{acct}さんのフォロワー"
     instances:
+      by_domain: ドメイン
       delivery_available: 配送可能
       known_accounts:
-        one: 既知のアカウント数 %{count}
         other: 既知のアカウント数 %{count}
       moderation:
         all: すべて
         limited: 制限あり
         title: モデレーション
-      title: 既知のインスタンス
+      title: 既知のサーバー
       total_blocked_by_us: ブロック合計
       total_followed_by_them: 被フォロー合計
       total_followed_by_us: フォロー合計
-      total_reported: レポート合計
+      total_reported: 通報合計
       total_storage: 添付されたメディア
     invites:
       deactivate_all: すべて無効化
@@ -324,6 +330,8 @@ ja:
         expired: 期限切れ
         title: フィルター
       title: 招待
+    pending_accounts:
+      title: 承認待ちアカウント (%{count})
     relays:
       add_new: リレーを追加
       delete: 削除
@@ -340,19 +348,19 @@ ja:
       status: ステータス
       title: リレー
     report_notes:
-      created_msg: レポートメモを書き込みました!
-      destroyed_msg: レポートメモを削除しました!
+      created_msg: 通報メモを書き込みました!
+      destroyed_msg: 通報メモを削除しました!
     reports:
       account:
         note: メモ
-        report: レポート
-      action_taken_by: レポート処理者
+        report: 通報
+      action_taken_by: 通報処理者
       are_you_sure: 本当に実行しますか?
       assign_to_self: 担当になる
       assigned: 担当者
       comment:
         none: なし
-      created_at: レポート日時
+      created_at: 通報日時
       mark_as_resolved: 解決済みとしてマーク
       mark_as_unresolved: 未解決として再び開く
       notes:
@@ -362,13 +370,13 @@ ja:
         delete: 削除
         placeholder: どのような措置が取られたか、または関連する更新を記述してください…
       reopen: 再び開く
-      report: レポート#%{id}
+      report: 通報#%{id}
       reported_account: 報告対象アカウント
       reported_by: 報告者
       resolved: 解決済み
-      resolved_msg: レポートを解決済みにしました!
+      resolved_msg: 通報を解決済みにしました!
       status: ステータス
-      title: レポート
+      title: 通報
       unassign: 担当を外す
       unresolved: 未解決
       updated_at: 更新日時
@@ -381,7 +389,7 @@ ja:
         title: 新規ユーザーが自動フォローするアカウント
       contact_information:
         email: ビジネスメールアドレス
-        username: 連絡先のユーザー名
+        username: 連絡先ユーザー名
       custom_css:
         desc_html: 全ページに適用されるCSSの編集
         title: カスタムCSS
@@ -392,8 +400,8 @@ ja:
         desc_html: 複数のページに表示されます。サイズは293x205px以上推奨です。未設定の場合、標準のマスコットが使用されます
         title: マスコットイメージ
       peers_api_enabled:
-        desc_html: 連合内でこのインスタンスが遭遇したドメインの名前
-        title: 接続しているインスタンスのリストを公開する
+        desc_html: 連合内でこのサーバーが遭遇したドメインの名前
+        title: 接続しているサーバーのリストを公開する
       preview_sensitive_media:
         desc_html: 他のウェブサイトにリンクを貼った際、メディアが閲覧注意としてマークされていてもサムネイルが表示されます
         title: OpenGraphによるプレビューで閲覧注意のメディアも表示する
@@ -410,9 +418,12 @@ ja:
         min_invite_role:
           disabled: 誰も許可しない
           title: 招待の作成を許可
-        open:
-          desc_html: 誰でも自由にアカウントを作成できるようにします
-          title: 新規登録を受け付ける
+      registrations_mode:
+        modes:
+          approved: 登録には承認が必要
+          none: 誰も許可しない
+          open: 誰でも登録可
+        title: 新規登録
       show_known_fediverse_at_about_page:
         desc_html: チェックを入れるとプレビュー欄に既知の連合先全てのトゥートを表示します。外すとローカルのトゥートだけ表示します。
         title: タイムラインプレビューに連合タイムラインを表示する
@@ -420,21 +431,21 @@ ja:
         desc_html: ユーザーページにスタッフのバッジを表示します
         title: スタッフバッジを表示する
       site_description:
-        desc_html: フロントページへの表示に使用される紹介文です。このMastodonインスタンスを特徴付けることやその他重要なことを記述してください。HTMLタグ、特に<code>&lt;a&gt;</code> と <code>&lt;em&gt;</code>が使えます。
-        title: インスタンスの説明
+        desc_html: フロントページへの表示に使用される紹介文です。このMastodonサーバーを特徴付けることやその他重要なことを記述してください。HTMLタグ、特に<code>&lt;a&gt;</code> と <code>&lt;em&gt;</code>が使えます。
+        title: サーバーの説明
       site_description_extended:
-        desc_html: あなたのインスタンスにおける行動規範やルール、ガイドライン、そのほかの記述をする際に最適な場所です。HTMLタグが使えます
+        desc_html: あなたのサーバーにおける行動規範やルール、ガイドライン、そのほかの記述をする際に最適な場所です。HTMLタグが使えます
         title: カスタム詳細説明
       site_short_description:
-        desc_html: サイドバーと meta タグに表示されます。Mastodon とは何か、そしてこのサーバーの特別な何かを1段落で記述してください。空欄の場合、インスタンスの説明が使用されます。
-        title: 短いインスタンスの説明
+        desc_html: サイドバーと meta タグに表示されます。Mastodon とは何か、そしてこのサーバーの特別な何かを1段落で記述してください。空欄の場合、サーバーの説明が使用されます。
+        title: 短いサーバーの説明
       site_terms:
-        desc_html: あなたは独自のプライバシーポリシーや利用規約、そのほかの法的根拠を書くことができます。HTMLタグが使えます
+        desc_html: 独自のプライバシーポリシーや利用規約、その他の法的根拠を記述できます。HTMLタグが使えます
         title: カスタム利用規約
-      site_title: インスタンスの名前
+      site_title: サーバーの名前
       thumbnail:
         desc_html: OpenGraphとAPIによるプレビューに使用されます。サイズは1200×630px推奨です
-        title: インスタンスのサムネイル
+        title: サーバーのサムネイル
       timeline_preview:
         desc_html: ランディングページに公開タイムラインを表示します
         title: タイムラインプレビュー
@@ -475,10 +486,19 @@ ja:
       edit_preset: プリセット警告文を編集
       title: プリセット警告文を管理
   admin_mailer:
+    new_pending_account:
+      body: 新しいアカウントの詳細は以下の通りです。この申請を承認または却下することができます。
+      subject: "%{instance} で新しいアカウント (%{username}) が承認待ちです"
     new_report:
       body: "%{reporter} が %{target} を通報しました"
       body_remote: "%{domain} の誰かが %{target} を通報しました"
       subject: "%{instance} の新しい通報 (#%{id})"
+  appearance:
+    advanced_web_interface: 上級者向け UI
+    advanced_web_interface_hint: ディスプレイを幅いっぱいまで活用したい場合、上級者向け UI をおすすめします。ホーム、通知、連合タイムライン、更にはリストやハッシュタグなど、様々な異なるカラムから望む限りの情報を一度に受け取れるような設定が可能になります。
+    animations_and_accessibility: アニメーションとアクセシビリティー
+    confirmation_dialogs: 確認ダイアログ
+    sensitive_content: 閲覧注意コンテンツ
   application_mailer:
     notification_preferences: メール設定の変更
     salutation: "%{name} さん"
@@ -495,8 +515,9 @@ ja:
     warning: このデータは気をつけて取り扱ってください。他の人と共有しないでください!
     your_token: アクセストークン
   auth:
-    agreement_html: 登録するをクリックすると <a href="%{rules_path}">インスタンスのルール</a> と <a href="%{terms_path}">プライバシーポリシー</a> に従うことに同意したことになります。
+    apply_for_account: 登録を申請する
     change_password: パスワード
+    checkbox_agreement_html: <a href="%{rules_path}" target="_blank">サーバーのルール</a> と <a href="%{terms_path}" target="_blank">プライバシーポリシー</a> に同意します
     confirm_email: メールアドレスの確認
     delete_account: アカウントの削除
     delete_account_html: アカウントを削除したい場合、<a href="%{path}">こちら</a> から手続きが行えます。削除する前に、確認画面があります。
@@ -507,17 +528,17 @@ ja:
     logout: ログアウト
     migrate_account: 別のアカウントに引っ越す
     migrate_account_html: 引っ越し先を明記したい場合は<a href="%{path}">こちら</a>で設定できます。
-    or: または
     or_log_in_with: または次のサービスでログイン
     providers:
       cas: CAS
       saml: SAML
     register: 登録する
-    register_elsewhere: 他のインスタンスで新規登録
+    registration_closed: "%{instance} は現在、新規登録停止中です"
     resend_confirmation: 確認メールを再送する
     reset_password: パスワードを再発行
     security: セキュリティ
     set_new_password: 新しいパスワード
+    trouble_logging_in: ログインできませんか?
   authorize_follow:
     already_following: あなたは既にこのアカウントをフォローしています
     error: 残念ながら、リモートアカウント情報の取得中にエラーが発生しました
@@ -549,7 +570,7 @@ ja:
     description_html: あなたのアカウントに含まれるコンテンツは全て削除され、アカウントは無効化されます。これは恒久的なもので、<strong>取り消すことはできません</strong>。なりすましを防ぐために、同じユーザー名で再度登録することはできなくなります。
     proceed: アカウントを削除する
     success_msg: アカウントは正常に削除されました
-    warning_html: 削除が保証されるのはこのインスタンス上のコンテンツのみです。他のインスタンス等、外部に広く共有されたコンテンツについては痕跡が残ることがあります。また、現在接続できないサーバーや、あなたの更新を受け取らなくなったサーバーに対しては、削除は反映されません。
+    warning_html: 削除が保証されるのはこのサーバー上のコンテンツのみです。他のサーバー等、外部に広く共有されたコンテンツについては痕跡が残ることがあります。また、現在接続できないサーバーや、あなたの更新を受け取らなくなったサーバーに対しては、削除は反映されません。
     warning_title: 共有されたコンテンツについて
   directories:
     directory: ディレクトリ
@@ -559,7 +580,6 @@ ja:
     explore_mastodon: "%{title}を探索"
     how_to_enable: あなたはディレクトリへの掲載を選択していません。下記から選択できます。ハッシュタグカラムに掲載するにはプロフィール文にハッシュタグを使用してください。
     people:
-      one: "%{count} 人"
       other: "%{count} 人"
   errors:
     '403': このページを表示する権限がありません。
@@ -573,6 +593,9 @@ ja:
       content: もうしわけありませんが、なにかが間違っています。
       title: このページは正しくありません
     noscript_html: Mastodonのウェブアプリケーションを利用する場合はJavaScriptを有効にしてください。またはあなたのプラットフォーム向けの<a href="%{apps_path}">Mastodonネイティブアプリ</a>を探すことができます。
+  existing_username_validator:
+    not_found: そのようなユーザー名はローカルに見つかりませんでした
+    not_found_multiple: "%{usernames} は見つかりませんでした"
   exports:
     archive_takeout:
       date: 日時
@@ -588,6 +611,10 @@ ja:
     lists: リスト
     mutes: ミュート
     storage: メディア
+  featured_tags:
+    add_new: 追加
+    errors:
+      limit: 注目のハッシュタグの上限に達しました
   filters:
     contexts:
       home: ホームタイムライン
@@ -604,34 +631,49 @@ ja:
       title: フィルター
     new:
       title: 新規フィルターを追加
-  followers:
-    domain: ドメイン
-    explanation_html: あなたの投稿のプライバシーを確保したい場合、誰があなたをフォローしているのかを把握している必要があります。 <strong>プライベート投稿は、あなたのフォロワーがいる全てのインスタンスに配信されます</strong>。 フォロワーのインスタンスの管理者やソフトウェアがあなたのプライバシーを尊重してくれるかどうか怪しい場合は、そのフォロワーを削除した方がよいかもしれません。
-    followers_count: フォロワー数
-    lock_link: 承認制アカウントにする
-    purge: フォロワーから削除する
-    success:
-      one: 1個のドメインからソフトブロックするフォロワーを処理中...
-      other: "%{count} 個のドメインからソフトブロックするフォロワーを処理中..."
-    true_privacy_html: "<strong>プライバシーの保護はエンドツーエンドの暗号化でのみ実現可能</strong>であることに留意ください。"
-    unlocked_warning_html: 誰でもあなたをフォローすることができ、フォロワー限定の投稿をすぐに見ることができます。フォローする人を限定したい場合は%{lock_link}に設定してください。
-    unlocked_warning_title: このアカウントは承認制アカウントに設定されていません
   footer:
     developers: 開発者向け
     more: さらに…
     resources: リソース
   generic:
+    all: すべて
     changes_saved_msg: 正常に変更されました!
     copy: コピー
+    order_by: 並び順
     save_changes: 変更を保存
     validation_errors:
-      one: エラーが発生しました! 以下のエラーを確認してください
       other: エラーが発生しました! 以下の%{count}個のエラーを確認してください
+  html_validator:
+    invalid_markup: '無効なHTMLマークアップが含まれています: %{error}'
+  identity_proofs:
+    active: アクティブ
+    authorize: 許可する
+    authorize_connection_prompt: この暗号化接続を許可しますか?
+    errors:
+      failed: 暗号化接続に失敗しました。%{provider}からもう一度やり直してください。
+      keybase:
+        invalid_token: Keybaseトークンは16進数で66文字のハッシュである必要があります
+        verification_failed: KeybaseはこのトークンをKeybaseユーザー%{kb_username}の署名として認識しませんでした。Keybaseから再試行してください。
+      wrong_user: "%{current}としてログインしている間%{proving}の証明を作成することはできません。%{proving}としてログインし、もう一度やり直してください。"
+    explanation_html: ここではKeybaseのような他のサービスのアカウントと暗号化し関連づけることができます。これにより他の人が暗号化されたメッセージを送信したり、その内容を信用できるようになります。
+    i_am_html: I am %{username} on %{service}.
+    identity: Identity
+    inactive: 非アクティブ
+    publicize_checkbox: 'そしてこれをトゥートします:'
+    publicize_toot: 'It is proven! I am %{username} on %{service}: %{url}'
+    status: 認証状態
+    view_proof: 証明を表示
   imports:
-    preface: 他のインスタンスでエクスポートされたファイルから、フォロー/ブロックした情報をこのインスタンス上のアカウントにインポートできます。
+    modes:
+      merge: 統合
+      merge_long: 現在のレコードを保持したまま新しいものを追加します
+      overwrite: 上書き
+      overwrite_long: 現在のレコードを新しいもので置き換えます
+    preface: 他のサーバーでエクスポートされたファイルから、フォロー/ブロックした情報をこのサーバー上のアカウントにインポートできます。
     success: ファイルは正常にアップロードされ、現在処理中です。しばらくしてから確認してください
     types:
       blocking: ブロックしたアカウントリスト
+      domain_blocking: 非表示にしたドメインリスト
       following: フォロー中のアカウントリスト
       muting: ミュートしたアカウントリスト
     upload: アップロード
@@ -650,10 +692,9 @@ ja:
     generate: 作成
     invited_by: '次の人に招待されました:'
     max_uses:
-      one: '1'
       other: "%{count}"
     max_uses_prompt: 無制限
-    prompt: リンクを生成・共有してこのインスタンスへの新規登録を受け付けることができます
+    prompt: リンクを生成・共有してこのサーバーへの新規登録を受け付けることができます
     table:
       expires_at: 有効期限
       uses: 使用
@@ -678,10 +719,8 @@ ja:
       body: '最後のログイン(%{since})からの出来事:'
       mention: "%{name} さんがあなたに返信しました:"
       new_followers_summary:
-        one: また、離れている間に新たなフォロワーを獲得しました!
         other: また、離れている間に%{count} 人の新たなフォロワーを獲得しました!
       subject:
-        one: "新しい1件の通知 \U0001F418"
         other: "新しい%{count}件の通知 \U0001F418"
       title: 不在の間に…
     favourite:
@@ -722,11 +761,33 @@ ja:
     older: 以前のトゥート
     prev: 前
     truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: このアンケートには投票済みです
+      duplicate_options: に同じものがあります
+      duration_too_long: が長過ぎます
+      duration_too_short: が短過ぎます
+      expired: アンケートは既に終了しました
+      over_character_limit: は%{max}文字より長くすることはできません
+      too_few_options: は複数必要です
+      too_many_options: は%{max}個までです
   preferences:
-    languages: 言語
     other: その他
-    publishing: 投稿
-    web: ウェブ
+    posting_defaults: デフォルトの投稿設定
+    public_timelines: 公開タイムライン
+  relationships:
+    activity: 活動
+    dormant: 非アクティブ
+    last_active: 最後の活動
+    most_recent: 新着
+    moved: 引っ越し済み
+    mutual: 相互
+    primary: 標準
+    relationship: 関係性
+    remove_selected_domains: 選択したドメインのフォロワーを全て解除
+    remove_selected_followers: 選択したフォロワーを解除
+    remove_selected_follows: 選択したユーザーをフォロー解除
+    status: 状態
   remote_follow:
     acct: あなたの ユーザー名@ドメイン を入力してください
     missing_resource: リダイレクト先が見つかりませんでした
@@ -774,7 +835,7 @@ ja:
       uc_browser: UCBrowser
       weibo: Weibo
     current_session: 現在のセッション
-    description: "%{browser} on %{platform}"
+    description: "%{platform} 上の %{browser}"
     explanation: あなたのMastodonアカウントに現在ログインしているウェブブラウザの一覧です。
     ip: IP
     platforms:
@@ -794,42 +855,48 @@ ja:
     revoke_success: セッションを削除しました
     title: セッション
   settings:
+    account: アカウント
+    account_settings: セキュリティ
+    appearance: 外観
     authorized_apps: 認証済みアプリ
     back: Mastodon に戻る
     delete: アカウントの削除
     development: 開発
     edit_profile: プロフィールを編集
     export: データのエクスポート
-    followers: 信頼済みのインスタンス
+    featured_tags: 注目のハッシュタグ
+    identity_proofs: Identity proofs
     import: データのインポート
+    import_and_export: インポート・エクスポート
     migrate: アカウントの引っ越し
     notifications: 通知
     preferences: ユーザー設定
-    settings: 設定
+    profile: プロフィール
+    relationships: フォロー・フォロワー
     two_factor_authentication: 二段階認証
-    your_apps: アプリ
   statuses:
     attached:
       description: '添付: %{attached}'
       image:
-        one: "%{count} 枚の画像"
         other: "%{count} 枚の画像"
       video:
-        one: "%{count} 本の動画"
         other: "%{count} 本の動画"
     boosted_from_html: "%{acct_link} からブースト"
     content_warning: '閲覧注意: %{warning}'
     disallowed_hashtags:
-      one: '許可されていないハッシュタグが含まれています: %{tags}'
       other: '許可されていないハッシュタグが含まれています: %{tags}'
     language_detection: 自動検出
     open_in_web: Webで開く
     over_character_limit: 上限は %{max}文字までです
     pin_errors:
-      limit: 固定されているトゥートの上限に達しました
+      limit: 固定できるトゥート数の上限に達しました
       ownership: 他人のトゥートを固定することはできません
       private: 非公開のトゥートを固定することはできません
-      reblog: ブーストされたトゥートを固定することはできません
+      reblog: ブーストを固定することはできません
+    poll:
+      total_votes:
+        other: "%{count}票"
+      vote: 投票
     show_more: もっと見る
     sign_in_to_participate: ログインして会話に参加
     title: '%{name}: "%{quote}"'
@@ -850,10 +917,10 @@ ja:
       <h3 id="collect">どのような情報を収集しますか?</h3>
 
       <ul>
-        <li><em>基本的なアカウント情報</em>: 当サイトに登録すると、ユーザー名・メールアドレス・パスワードの入力を求められることがあります。また表示名や自己紹介・プロフィール画像・ヘッダー画像といった追加のプロフィールを登録できます。ユーザー名・表示名・自己紹介・プロフィール画像・ヘッダー画像は常に公開されます。</li>
-        <li><em>投稿・フォロー・その他公開情報</em>: フォローしているユーザーの一覧は一般公開されます。フォロワーも同様です。メッセージを投稿する際、日時だけでなく投稿に使用したアプリケーション名も記録されます。メッセージには写真や動画といった添付メディアを含むことがあります。「公開」や「未収載」の投稿は一般公開されます。プロフィールに投稿を載せるとそれもまた公開情報となります。投稿はフォロワーに配信されます。場合によっては他のサーバーに配信され、そこにコピーが保存されることを意味します。投稿を削除した場合も同様にフォロワーに配信されます。他の投稿をリブログやお気に入り登録する行動は常に公開されます。</li>
-        <li><em>「ダイレクト」と「フォロワー限定」投稿</em>: すべての投稿はサーバーに保存され、処理されます。「フォロワー限定」投稿はフォロワーと投稿に書かれたユーザーに配信されます。「ダイレクト」投稿は投稿に書かれたユーザーにのみ配信されます。場合によっては他のサーバーに配信され、そこにコピーが保存されることを意味します。私たちはこれらの閲覧を一部の許可された者に限定するよう誠意を持って努めます。しかし他のサーバーにおいても同様に扱われるとは限りません。したがって、相手の所属するサーバーを吟味することが重要です。設定で新しいフォロワーの承認または拒否を手動で行うよう切り替えることもできます。<em>サーバー管理者は「ダイレクト」や「フォロワー限定」投稿も閲覧する可能性があることを忘れないでください。</em>また受信者がスクリーンショットやコピー、もしくは共有する可能性があることを忘れないでください。<em>いかなる危険な情報もMastodon上で共有しないでください。</em></li>
-        <li><em>IPアドレスやその他メタデータ</em>: ログインする際IPアドレスだけでなくブラウザーアプリケーション名を記録します。ログインしたセッションはすべてユーザー設定で見直し、取り消すことができます。使用されている最新のIPアドレスは最大12ヵ月間保存されます。またサーバーへのIPアドレスを含むすべてのリクエストのログを保持することがあります。</li>
+      <li><em>基本的なアカウント情報</em>: 当サイトに登録すると、ユーザー名・メールアドレス・パスワードの入力を求められることがあります。また表示名や自己紹介・プロフィール画像・ヘッダー画像といった追加のプロフィールを登録できます。ユーザー名・表示名・自己紹介・プロフィール画像・ヘッダー画像は常に公開されます。</li>
+      <li><em>投稿・フォロー・その他公開情報</em>: フォローしているユーザーの一覧は一般公開されます。フォロワーも同様です。メッセージを投稿する際、日時だけでなく投稿に使用したアプリケーション名も記録されます。メッセージには写真や動画といった添付メディアを含むことがあります。「公開」や「未収載」の投稿は一般公開されます。プロフィールに投稿を載せるとそれもまた公開情報となります。投稿はフォロワーに配信されます。場合によっては他のサーバーに配信され、そこにコピーが保存されることを意味します。投稿を削除した場合も同様にフォロワーに配信されます。他の投稿をリブログやお気に入り登録する行動は常に公開されます。</li>
+      <li><em>「ダイレクト」と「フォロワー限定」投稿</em>: すべての投稿はサーバーに保存され、処理されます。「フォロワー限定」投稿はフォロワーと投稿に書かれたユーザーに配信されます。「ダイレクト」投稿は投稿に書かれたユーザーにのみ配信されます。場合によっては他のサーバーに配信され、そこにコピーが保存されることを意味します。私たちはこれらの閲覧を一部の許可された者に限定するよう誠意を持って努めます。しかし他のサーバーにおいても同様に扱われるとは限りません。したがって、相手の所属するサーバーを吟味することが重要です。設定で新しいフォロワーの承認または拒否を手動で行うよう切り替えることもできます。<em>サーバー管理者は「ダイレクト」や「フォロワー限定」投稿も閲覧する可能性があることを忘れないでください。</em>また受信者がスクリーンショットやコピー、もしくは共有する可能性があることを忘れないでください。<em>いかなる危険な情報もMastodon上で共有しないでください。</em></li>
+      <li><em>IPアドレスやその他メタデータ</em>: ログインする際IPアドレスだけでなくブラウザーアプリケーション名を記録します。ログインしたセッションはすべてユーザー設定で見直し、取り消すことができます。使用されている最新のIPアドレスは最大12ヵ月間保存されます。またサーバーへのIPアドレスを含むすべてのリクエストのログを保持することがあります。</li>
       </ul>
 
       <hr class="spacer" />
@@ -863,9 +930,9 @@ ja:
       <p>収集した情報は次の用途に使用されることがあります:</p>
 
       <ul>
-        <li>Mastodonのコア機能の提供: ログインしている間にかぎり他の人たちと投稿を通じて交流することができます。例えば自分専用のホームタイムラインで投稿をまとめて読むために他の人たちをフォローできます。</li>
-        <li>コミュニティ維持の補助: 例えばIPアドレスを既知のものと比較し、BAN回避目的の複数登録者やその他違反者を判別します。</li>
-        <li>提供されたメールアドレスはお知らせの送信・投稿に対するリアクションやメッセージ送信の通知・お問い合わせやその他要求や質問への返信に使用されることがあります。</li>
+      <li>Mastodonのコア機能の提供: ログインしている間にかぎり他の人たちと投稿を通じて交流することができます。例えば自分専用のホームタイムラインで投稿をまとめて読むために他の人たちをフォローできます。</li>
+      <li>コミュニティ維持の補助: 例えばIPアドレスを既知のものと比較し、BAN回避目的の複数登録者やその他違反者を判別します。</li>
+      <li>提供されたメールアドレスはお知らせの送信・投稿に対するリアクションやメッセージ送信の通知・お問い合わせやその他要求や質問への返信に使用されることがあります。</li>
       </ul>
 
       <hr class="spacer" />
@@ -881,8 +948,8 @@ ja:
       <p>私たちは次のように誠意を持って努めます:</p>
 
       <ul>
-        <li>当サイトへのIPアドレスを含むすべての要求に対するサーバーログを90日以内のできるかぎりの間保持します。</li>
-        <li>登録されたユーザーに関連付けられたIPアドレスを12ヵ月以内の間保持します。</li>
+      <li>当サイトへのIPアドレスを含むすべての要求に対するサーバーログを90日以内のできるかぎりの間保持します。</li>
+      <li>登録されたユーザーに関連付けられたIPアドレスを12ヵ月以内の間保持します。</li>
       </ul>
 
       <p>あなたは投稿・添付メディア・プロフィール画像・ヘッダー画像を含む自身のデータのアーカイブを要求し、ダウンロードすることができます。</p>
@@ -928,8 +995,8 @@ ja:
       <p>オリジナルの出典: <a href="https://github.com/discourse/discourse">Discourse privacy policy</a></p>
     title: "%{instance} 利用規約・プライバシーポリシー"
   themes:
-    contrast: ハイコントラスト
-    default: Mastodon
+    contrast: Mastodon (ハイコントラスト)
+    default: Mastodon (ダーク)
     mastodon-light: Mastodon (ライト)
   time:
     formats:
@@ -974,21 +1041,21 @@ ja:
         suspend: アカウントが停止されました
     welcome:
       edit_profile_action: プロフィールを設定
-      edit_profile_step: アバター画像やヘッダー画像をアップロードしたり、表示名やその他プロフィールを変更しカスタマイズすることができます。新しいフォロワーからのフォローを許可する前に検討したい場合、アカウントを承認制にすることができます。
+      edit_profile_step: アイコンやヘッダーの画像をアップロードしたり、表示名を変更したりして、自分のプロフィールをカスタマイズすることができます。また、誰かからの新規フォローを許可する前にその人の様子を見ておきたい場合、アカウントを承認制にすることもできます。
       explanation: 始めるにあたってのアドバイスです
       final_action: 始めましょう
-      final_step: 'さあ始めましょう! たとえフォロワーがいなくても、あなたの公開した投稿はローカルタイムラインやハッシュタグなどで誰かの目に止まるかもしれません。自己紹介をしたい時は #introductions ハッシュタグを使うといいかもしれません。'
-      full_handle: あなたの正式なユーザー名
-      full_handle_hint: これは別のインスタンスからフォローしてもらったりメッセージのやり取りをする際に、友達に伝えるといいでしょう。
+      final_step: 'さあ、始めましょう! たとえフォロワーがまだいなくても、あなたの公開した投稿はローカルタイムラインやハッシュタグなどを通じて誰かの目にとまるはずです。自己紹介をしたいときには #introductions ハッシュタグが便利かもしれません。'
+      full_handle: あなたの正式なユーザーID
+      full_handle_hint: 別のサーバーの友達とフォローやメッセージをやり取りする際には、これを伝えることになります。
       review_preferences_action: 設定の変更
-      review_preferences_step: 受け取りたいメールや投稿の公開範囲などの設定を必ず行ってください。不快でないならアニメーション GIF の自動再生を有効にすることもできます。
+      review_preferences_step: 受け取りたいメールの種類や投稿のデフォルト公開範囲など、ユーザー設定を必ず済ませておきましょう。目が回らない自信があるなら、アニメーション GIF を自動再生する設定もご検討ください。
       subject: Mastodon へようこそ
-      tip_federated_timeline: 連合タイムラインは Mastodon ネットワークの流れを見られるものです。ただしあなたと同じインスタンスの人がフォローしている人だけが含まれるので、それが全てではありません。
-      tip_following: 標準では自動でインスタンスの管理者をフォローしています。もっと興味のある人たちを見つけるには、ローカルタイムラインと連合タイムラインを確認してください。
-      tip_local_timeline: ローカルタイムラインは %{instance} にいる人々の流れを見られるものです。彼らはあなたと同じインスタンスにいる隣人のようなものです!
-      tip_mobile_webapp: もしモバイル端末のブラウザで Mastodon をホーム画面に追加できる場合、プッシュ通知を受け取ることができます。それはまるでネイティブアプリのように動作します!
+      tip_federated_timeline: 連合タイムラインは Mastodon ネットワークの流れを見られるものです。ただしあなたと同じサーバーの人がフォローしている人だけが含まれるので、それが全てではありません。
+      tip_following: 最初は、サーバーの管理者をフォローした状態になっています。もっと興味のある人たちを見つけるには、ローカルタイムラインと連合タイムラインを確認してみましょう。
+      tip_local_timeline: ローカルタイムラインは %{instance} にいる人々の流れを見られるものです。彼らはあなたと同じサーバーにいる隣人のようなものです!
+      tip_mobile_webapp: お使いのモバイル端末で、ブラウザから Mastodon をホーム画面に追加できますか? もし追加できる場合、プッシュ通知の受け取りなど、まるで「普通の」アプリのような機能が楽しめます!
       tips: 豆知識
-      title: ようこそ、%{name} !
+      title: ようこそ、%{name}!
   users:
     follow_limit_reached: あなたは現在 %{limit} 人以上フォローできません
     invalid_email: メールアドレスが無効です
diff --git a/config/locales/ka.yml b/config/locales/ka.yml
index 056942ecd5503a5cc876e727c930a68f60075995..53057d8603312cd6fa368577bfe041c572c5c482 100644
--- a/config/locales/ka.yml
+++ b/config/locales/ka.yml
@@ -7,7 +7,6 @@ ka:
     administered_by: 'ადმინისტრატორი:'
     api: აპი
     apps: მობილური აპლიკაციები
-    closed_registrations: რეგისტრაციები ამჟამად ინსტანციაზე დახურულია. თუმცა! ანგარიშის შესაქმნელად შეგიძლიათ იპოვოთ სხვა ინსტანცია და იმავე ქსელზე იქონიოთ წვდომა იქიდან.
     contact: კონტაქტი
     contact_missing: არაა დაყენებული
     contact_unavailable: მიუწ.
@@ -15,31 +14,18 @@ ka:
     extended_description_html: |
       <h3>კარგი ადგილი წესებისთვის</h3>
       <p>განვრცობილი აღწერილობა ჯერ არ შექმნილა.</p>
-    features:
-      humane_approach_body: სხვა ქსელების შეცდომების გათვალისწინებით, მასტოდონი მიზნად ისახავს ეტიკური დიზაინის არჩევნების გაკეთებას, დაუპირისპირდეს სოციალური მედიის არასწორ მოხმარებას.
-      humane_approach_title: უფრო ადამიანური მიდგომა
-      not_a_product_body: მასტოდონი არ არის კომერციული ქსელი. არაა რეკლამა, არაა მაინინგი, არაა შემოღობილი ბაღები. არაა ცენტრალური ავტორიტეტი.
-      not_a_product_title: შენ ხარ პერსონა და არა პროდუქტი
-      real_conversation_body: 500 ნიშნის განკარგულებით, მარცვლოვანი კონტენტის და მედია გაფრთხილებების მხარდაჭერით, შეგიძლიათ გამოხატოთ ისე როგორც გსურთ.
-      real_conversation_title: შექმნილია ნამდვილი საუბრისთვის
-      within_reach_body: დეველოპერისთვის-მეგობრული აპი ექოსისტემის წყალობით, მრავალი აპლიკაცია აი-ოსისთვის, ანდროიდისთვის და სხვა პლატფორმებისთვის, საშალებას მოგცემთ ნებისმიერი ადგილიდან იქონიოთ კავშირი თქვენს მეგობრებთან.
-      within_reach_title: მუდამ წვდომის ქვეშ
     generic_description: "%{domain} ერთი სერვერია ქსელში"
     hosted_on: მასტოდონს მასპინძლობს %{domain}
     learn_more: გაიგე მეტი
-    other_instances: ინსტანციების სია
     privacy_policy: კონფიდენციალურობის პოლიტიკა
     source_code: კოდი
-    status_count_after: სტატუსები
     status_count_before: ვინც უავტორა
     terms: მომსახურების პირობები
-    user_count_after: მომხმარებლისთვის
     user_count_before: სახლი
     what_is_mastodon: რა არის მასტოდონი?
   accounts:
     choices_html: "%{name}-ის არჩევნები:"
     follow: გაყევი
-    followers: მიმდევრები
     following: მიჰყვება
     joined: გაწევრიანდა %{date}
     media: მედია
@@ -50,7 +36,6 @@ ka:
     people_who_follow: ხალხი ვინც მიჰყვება %{name}-ს
     pin_errors:
       following: იმ ადამიანს, ვინც მოგწონთ, უკვე უნდა მიჰყვებოდეთ
-    posts: ტუტები
     posts_with_replies: ტუტები და პასუხები
     reserved_username: მომხმარებელი რეზერვირებულია
     roles:
@@ -344,9 +329,6 @@ ka:
         min_invite_role:
           disabled: არავინ
           title: ნება დაერთოს მოწვეევებს
-        open:
-          desc_html: უფლება მიეცით ყველას, გახსნან ანგარიში
-          title: ღია რეგისტრაცია
       show_known_fediverse_at_about_page:
         desc_html: ჩართვისას, ეს გამოაჩენს ტუტებს ყველა ცნობილი ფედივერსისგან პრევიუზე. სხვა შემთხვევაში, გამოაჩენს მხოლოდ ლოკალურ ტუტებს.
         title: გამოჩნდეს ცნობილი ვედივერსი თაიმლაინ პრევიუში
@@ -401,7 +383,6 @@ ka:
       subject: ახალი რეპორტი %{instance} (#%{id})-ზე
   application_mailer:
     notification_preferences: შეცვალეთ ელ-ფოსტის პრეფერნსიები
-    salutation: "%{name},"
     settings: 'შეცვალეთ ელ-ფოსტის პრეფერენსიები: %{link}'
     view: 'ჩვენება:'
     view_profile: პროფილის ჩვენება
@@ -415,7 +396,6 @@ ka:
     warning: იყავით ძალიან ფრთხილად ამ მონაცემთან. არასდროს გააზიაროთ ეს!
     your_token: თქვენი წვდომის ტოკენი
   auth:
-    agreement_html: რეგისტრაციით თქვენ ეთანხმებით <a href="%{rules_path}">ინსტანციის წესებს</a> და <a href="%{terms_path}">ჩვენ მომსახურების პირობებს</a>.
     change_password: პაროლი
     confirm_email: ელ-ფოსტის დამოწმება
     delete_account: ანგარიშის გაუქმება
@@ -427,13 +407,11 @@ ka:
     logout: გასვლა
     migrate_account: სხვა ანგარიშზე გადასვლა
     migrate_account_html: თუ გსურთ ამ ანგარიშის რედირექტის ხვაზე, შეგიძლიათ <a href="%{path}">გაუწიოთ კონფიგურაცია აქ</a>.
-    or: ან
     or_log_in_with: ან გამოიყენეთ
     providers:
       cas: ქეს
       saml: სამლ
     register: რეგისტრაცია
-    register_elsewhere: რეგისტრაცია სხვა სერვერზე
     resend_confirmation: დამოწმების ინსტრუქციების ხელახალი გამოგზავნა
     reset_password: პაროლის გადატვირთვა
     security: უსაფრთხოება
@@ -512,18 +490,6 @@ ka:
       title: ფილტრები
     new:
       title: ახალი ფილტრის დამატება
-  followers:
-    domain: დომენი
-    explanation_html: თუ გსურთ უზრუნველყოთ თქვენი სტატუსების კონფიდენციალურობა, უნდა იცოდეთ თუ ვინ მოგყვებათ. <strong>კერძო სტატუსები მიეწოდება ყველა ინსტანციას, სადაც გყავთ მიმდევრები</strong>. შესაძლოა გსურდეთ განიხილოთ ისინი და ამოშალოთ მიმდევრები თუ არ ენდობით თქვენი კონფიდენციალურობის პატივისცემას სტაფისა თუ პროგრამისგან იმ ინსტანციებში.
-    followers_count: მიმდევრების რაოდენობა
-    lock_link: თქვენი ანგარიშის ჩაკეტვა
-    purge: მიმდევრებიდან ამოშლა
-    success:
-      one: მიმდევრების სოფტ-ბლოკირების პროცესი ერთი დომენზე...
-      other: მიმდევრების სოფტ-ბლოკირების პროცესი %{count} დომენზე...
-    true_privacy_html: გთხოვთ გაითვალისწინეთ, <strong>ჭეშმარიტი კონფიდენციალურობა მიღწევადია მხოლოდ ენდ-თუ-ენდ შიფრაციით</strong>.
-    unlocked_warning_html: ყველას შეუძლია გამოგყვეთ, რომ უცბად იხილოს თქვენი სტატუსები. %{lock_link} რომ შეძლოთ განიხილოთ და უარყოთ მიმდევრები.
-    unlocked_warning_title: თქვენი ანგარიში არაა ჩაკეტილი
   footer:
     developers: დეველოპერები
     more: მეტი…
@@ -616,25 +582,19 @@ ka:
   number:
     human:
       decimal_units:
-        format: "%n%u"
         units:
           billion: ბილ.
           million: მილ.
           quadrillion: კუად.
           thousand: ათას.
           trillion: ტრილ.
-          unit: ''
   pagination:
     newer: უფრო ახალი
     next: შემდეგი
     older: ძველი
     prev: წინა
-    truncate: "&hellip;"
   preferences:
-    languages: ენები
     other: სხვა
-    publishing: გამოქვეყნება
-    web: ვები
   remote_follow:
     acct: შეიყვანეთ თქვენი username@domain საიდანაც გსურთ გაჰყვეთ
     missing_resource: საჭირო გადამისამართების ურლ თქვენი ანგარიშისთვის ვერ მოიძებნა
@@ -693,14 +653,11 @@ ka:
     development: დეველოპმენტი
     edit_profile: პროფილის ცვლილება
     export: მონაცემის ექსპორტი
-    followers: ავტორიზირებული მიმდევრები
     import: იმპორტი
     migrate: ანგარიშის მიგრაცია
     notifications: შეტყობინებები
     preferences: პრეფერენციები
-    settings: პარამეტრები
     two_factor_authentication: მეორე-ფაქტორის აუტენტიფიკაცია
-    your_apps: თქვენი აპლიკაციები
   statuses:
     attached:
       description: 'თან დართული: %{attached}'
@@ -725,7 +682,6 @@ ka:
       reblog: ბუსტი ვერ აიპინება
     show_more: მეტის ჩვენება
     sign_in_to_participate: საუბარში მონაწილეობისთვის გაიარეთ ავტორიზაცია
-    title: '%{name}: "%{quote}"'
     visibilities:
       private: მხოლოდ-მიმდევრები
       private_long: აჩვენე მხოლოდ მიმდევრებს
@@ -743,10 +699,10 @@ ka:
       <h3 id="collect">რა ინფორმაციას ვაგროვებთ?</h3>
 
       <ul>
-        <li><em>ძირითადი ანგარიშის ინფორმაცია</em>: თუ დარეგისტრირდებით ამ სერვერზე, შესაძლოა მოგთხოვოთ მომხმარებლის სახელი, ელ-ფოსტის მისამართი და პაროლი. შესაძლებელია, ასევე შეიყვანოთ დამატებითი პროფილის ინორმაცია, როგორიცაა დისპლეის სახელი და ბიოგრაფია, ასევე ატვირთოთ პროფილის და დასათაურების სურათი. მომხმარებლის სახელი, დისპლეის სახელი, ბიოგრაფია, პროფილის სურათი, დასათაურების სურათი ყოველთვის ღიადაა ჩამოთვლილი.</li>
-        <li><em>პოსტები, დადევნებები და სხვა საჯარო ინფორმაცია</em>: ადამიანების სია, რომლებსაც მიჰყვებით საჯაროდაა ჩამოთვლილი, იგივე ეხება თქვენს მიდევრებსაც. როდესაც აგზავნით წერილს, თარიღი, დრო და აპლიკაცია თუ საიდანაც განათავსეთ წერილი ინახება. წერილები შესაძლოა შეიცავდნენ მედია ფაილებს, როგორებიცაა სურათები და ვიდეოები. ღია და ჩამოუთვლელი პოსტები ხელმისაწვდომია საჯაროდ. როდესაც ათავსებთ პოსტს თქვენს პროფილზე, ის ასევე საჟაროდ წვდომადი ხდება. თქვენი პოსტები ეგზავნებათ თქვენს მიმდევრებს, ზოგიერთ შემთხვევაში ეს ნიშნავს, რომ ისინი იგზავნება სხვა სერვერებზე და მათი ასლები იქვე ინახება. როდესაც აუქმებთ პოსტს, ეს მოქმედება ეგზავნებათ თქვენს მიმდევრებს. რე-ბლოგირების ან ფავორიტად ქცევის ქმედებები ასევე საქვეყნოა.</li>
-        <li><em>პირდაპირი და პოსტები მხოლოდ-მიმდევრებისთვის</em>: ყველა პოსტი ინახება და მათი პროცესირება ხდება სერვერზე. პოსტები რომლებიც განეკუთვნება მხოლოდ მიმდევრებს მიეწოდებათ მათ, მომხმარებლები, რომლებიც დასახელებულია პოსტებში და პირდაპირი პოსტები ეგზავნებათ მხოლოდ ჩამოთვლილ მომხმარებლებს. ზოგიერთ შემთხვევაში, ეს ნიშნავს, რომ გადაგზავნა ხდება გარე სერვერებზე და ასლებიც იქ ინახება. ჩვენ დიდ ძალისხმევას ვუწევთ წვდომის ლიმიტს მხოლოდ აუტორიზირებული ადამიანებისთვის, თუმცა სხვა სერვერებმა შეიძლება ეს არ აწარმოონ. აქედან გამომდინარე, მნიშვნელოვანია განიხილოთ სერვერები, საიდანაც მოდიან თქვენი მიმდევრები. შეგიძლიათ ჩართოთ ან გამორთოთ პარამეტრი, დაადასტუროთ ან უარყოთ ახალი მიმდევარი. <em>გთხოვთ გაითვალისწინოთ, რომ სერვერის ოპერაციები და სხვა მიმღები სერვერები შესაძლოა კითხულობდნენ ამგვარ წერილებს</em>, მიმღებებს შეუძლიათ შექმნან სქრინშოთი, დააკოპირონ ან ხელახლა გააზიარონ ისინი. <em>არ გააზიაროთ საშიში ინფორმაცია მასტოდონით.</em></li>
-        <li><em>აი-პიები და სხვა მეტა-მონაცემები</em>: როდესაც გაივლით აუტენტიფიკაციას, ჩვენ ვინახავთ აი-პი მისამართს საიდანაც შემოხვედით, ასევე ბრაუზერის აპლიკაციას. ყველა ავტორიზირებული სესია თქვენთვის განსახილველად და გასაუქმებლად ხელმისაწვდომია პარამეტრებში. ბოლო შენახული აი-პი მისამართი ინახება მაქსიმუმ 12 თვით. ჩვენ ასევე შეიძლება გაგვაჩნდეს სერვერის ლოგი, რომელიც ინახავს თითოეული მოთხოვნის IP მისამართს.</li>
+      <li><em>ძირითადი ანგარიშის ინფორმაცია</em>: თუ დარეგისტრირდებით ამ სერვერზე, შესაძლოა მოგთხოვოთ მომხმარებლის სახელი, ელ-ფოსტის მისამართი და პაროლი. შესაძლებელია, ასევე შეიყვანოთ დამატებითი პროფილის ინორმაცია, როგორიცაა დისპლეის სახელი და ბიოგრაფია, ასევე ატვირთოთ პროფილის და დასათაურების სურათი. მომხმარებლის სახელი, დისპლეის სახელი, ბიოგრაფია, პროფილის სურათი, დასათაურების სურათი ყოველთვის ღიადაა ჩამოთვლილი.</li>
+      <li><em>პოსტები, დადევნებები და სხვა საჯარო ინფორმაცია</em>: ადამიანების სია, რომლებსაც მიჰყვებით საჯაროდაა ჩამოთვლილი, იგივე ეხება თქვენს მიდევრებსაც. როდესაც აგზავნით წერილს, თარიღი, დრო და აპლიკაცია თუ საიდანაც განათავსეთ წერილი ინახება. წერილები შესაძლოა შეიცავდნენ მედია ფაილებს, როგორებიცაა სურათები და ვიდეოები. ღია და ჩამოუთვლელი პოსტები ხელმისაწვდომია საჯაროდ. როდესაც ათავსებთ პოსტს თქვენს პროფილზე, ის ასევე საჟაროდ წვდომადი ხდება. თქვენი პოსტები ეგზავნებათ თქვენს მიმდევრებს, ზოგიერთ შემთხვევაში ეს ნიშნავს, რომ ისინი იგზავნება სხვა სერვერებზე და მათი ასლები იქვე ინახება. როდესაც აუქმებთ პოსტს, ეს მოქმედება ეგზავნებათ თქვენს მიმდევრებს. რე-ბლოგირების ან ფავორიტად ქცევის ქმედებები ასევე საქვეყნოა.</li>
+      <li><em>პირდაპირი და პოსტები მხოლოდ-მიმდევრებისთვის</em>: ყველა პოსტი ინახება და მათი პროცესირება ხდება სერვერზე. პოსტები რომლებიც განეკუთვნება მხოლოდ მიმდევრებს მიეწოდებათ მათ, მომხმარებლები, რომლებიც დასახელებულია პოსტებში და პირდაპირი პოსტები ეგზავნებათ მხოლოდ ჩამოთვლილ მომხმარებლებს. ზოგიერთ შემთხვევაში, ეს ნიშნავს, რომ გადაგზავნა ხდება გარე სერვერებზე და ასლებიც იქ ინახება. ჩვენ დიდ ძალისხმევას ვუწევთ წვდომის ლიმიტს მხოლოდ აუტორიზირებული ადამიანებისთვის, თუმცა სხვა სერვერებმა შეიძლება ეს არ აწარმოონ. აქედან გამომდინარე, მნიშვნელოვანია განიხილოთ სერვერები, საიდანაც მოდიან თქვენი მიმდევრები. შეგიძლიათ ჩართოთ ან გამორთოთ პარამეტრი, დაადასტუროთ ან უარყოთ ახალი მიმდევარი. <em>გთხოვთ გაითვალისწინოთ, რომ სერვერის ოპერაციები და სხვა მიმღები სერვერები შესაძლოა კითხულობდნენ ამგვარ წერილებს</em>, მიმღებებს შეუძლიათ შექმნან სქრინშოთი, დააკოპირონ ან ხელახლა გააზიარონ ისინი. <em>არ გააზიაროთ საშიში ინფორმაცია მასტოდონით.</em></li>
+      <li><em>აი-პიები და სხვა მეტა-მონაცემები</em>: როდესაც გაივლით აუტენტიფიკაციას, ჩვენ ვინახავთ აი-პი მისამართს საიდანაც შემოხვედით, ასევე ბრაუზერის აპლიკაციას. ყველა ავტორიზირებული სესია თქვენთვის განსახილველად და გასაუქმებლად ხელმისაწვდომია პარამეტრებში. ბოლო შენახული აი-პი მისამართი ინახება მაქსიმუმ 12 თვით. ჩვენ ასევე შეიძლება გაგვაჩნდეს სერვერის ლოგი, რომელიც ინახავს თითოეული მოთხოვნის IP მისამართს.</li>
       </ul>
 
       <hr class="spacer" />
@@ -756,9 +712,9 @@ ka:
       <p>ნებისმიერი სხვა ინფორმაცია, რომელსაც ვაგროვებთ თქვენგან შესაძლოა გამოყენებულ იქნას შემდეგი გზებით:</p>
 
       <ul>
-        <li>რომ უზრუნველვყოთ მასტოდონის მთავარი ფუნქციონალი. შეგიძლიათ ინტერაქცია გაუწიოთ მხოლოდ სხვის კონტენტს და შექმნათ პოსტები მაშინ როდესაც ავტორიზებული ხართ. მაგალითად, შესაძლოა გაჰყვეთ სხვა ადამიანებს, რათა იხილოთ მათი ჯამური პოსტები საკუთარ პერსონალიზებულ სახლის თაიმლაინზე.</li>
-        <li>რომ შევუწყვოთ ხელი საზოგადოების მოდერაციას, მაგალითად შევადაროთ თქვენი აი-პი მისამართი სხვა ცნობილ მისამართებს, რათა ამოვიცნოთ ბანის გადაუხდელობა ან სხვა დარღვევები.</li>
-        <li>ელ-ფოსტის მისამართი რომელსაც გვაწვდით, შესაძლოა გამოვიყენოთ თქვენთვის ინფორმაციის გამოსაგძავნად, შეგატყობინოთ სხვა ადამიანების ინტერაქციაზე თქვენს კონტენტთან ან თქვენთვის გამოგზავნილ წერილებზე, ასევე რომ გიპასუხოთ მოთხოვნებზე და/ან სხვა საკითხებზე.</li>
+      <li>რომ უზრუნველვყოთ მასტოდონის მთავარი ფუნქციონალი. შეგიძლიათ ინტერაქცია გაუწიოთ მხოლოდ სხვის კონტენტს და შექმნათ პოსტები მაშინ როდესაც ავტორიზებული ხართ. მაგალითად, შესაძლოა გაჰყვეთ სხვა ადამიანებს, რათა იხილოთ მათი ჯამური პოსტები საკუთარ პერსონალიზებულ სახლის თაიმლაინზე.</li>
+      <li>რომ შევუწყვოთ ხელი საზოგადოების მოდერაციას, მაგალითად შევადაროთ თქვენი აი-პი მისამართი სხვა ცნობილ მისამართებს, რათა ამოვიცნოთ ბანის გადაუხდელობა ან სხვა დარღვევები.</li>
+      <li>ელ-ფოსტის მისამართი რომელსაც გვაწვდით, შესაძლოა გამოვიყენოთ თქვენთვის ინფორმაციის გამოსაგძავნად, შეგატყობინოთ სხვა ადამიანების ინტერაქციაზე თქვენს კონტენტთან ან თქვენთვის გამოგზავნილ წერილებზე, ასევე რომ გიპასუხოთ მოთხოვნებზე და/ან სხვა საკითხებზე.</li>
       </ul>
 
       <hr class="spacer" />
@@ -774,8 +730,8 @@ ka:
       <p>ჩვენ არ დავიშურებთ ძალისხმევას რომ:</p>
 
       <ul>
-        <li>შევინარჩუნოთ სერვერის ლოგები, რომლებიც მოიცავენ ყველა მოთხოვნის აი-პი მისამართს, თუმცა ესეთი ლოგები არ ინახება 90 დღეზე მეტ ხანს.</li>
-        <li>შევინარჩუნოთ რეგისტრირებული მომხმარებლების აი-პი მისამართები მაქსიმუმ 12 თვით.</li>
+      <li>შევინარჩუნოთ სერვერის ლოგები, რომლებიც მოიცავენ ყველა მოთხოვნის აი-პი მისამართს, თუმცა ესეთი ლოგები არ ინახება 90 დღეზე მეტ ხანს.</li>
+      <li>შევინარჩუნოთ რეგისტრირებული მომხმარებლების აი-პი მისამართები მაქსიმუმ 12 თვით.</li>
       </ul>
 
       <p>შეგიძლიათ მოითხოვოთ და ჩამოტვირთოთ თქვენი კონტენტის არქივი, რომელიც მოიცავს თქვენს პოსტებს, მედია ფაილებს, პროფილის და დასათაურების სურათს.</p>
@@ -824,10 +780,6 @@ ka:
     contrast: მაღალი კონტრასტი
     default: მასტოდონი
     mastodon-light: მასტოდონი (ღია)
-  time:
-    formats:
-      default: "%b %d, %Y, %H:%M"
-      month: "%b %Y"
   two_factor_authentication:
     code_hint: დასამოწმებლად შეიყვანეთ თქვენი აუტენტიფიკატორ აპლიკაციისგან გენერირებული კოდი
     description_html: თუ ჩართავთ <strong>მეორე-ფაქტორის აუტენტიფიკაციას</strong>, შესვლისას აუცილებელი იქნება ფლობდეთ ტელეფონს, რომელიც დააგენერირებს შესვლის ტოკენებს.
diff --git a/config/locales/kk.yml b/config/locales/kk.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c6212c378fd33925b54416da0fb61617cd34d726
--- /dev/null
+++ b/config/locales/kk.yml
@@ -0,0 +1,981 @@
+---
+kk:
+  about:
+    about_hashtag_html: Бұл жерде <strong>#%{hashtag}</strong> хэштегімен жинақталған жазбалар. Желіге тіркеліп, сіз де қосыла аласыз бұл ортаға.
+    about_mastodon_html: Mastodon - әлеуметтік желіге негізделген, тегін және веб протоколды, ашық кодты бағдарлама. Ол email сияқты орталығы жоқ құрылым.
+    about_this: Туралы
+    administered_by: 'Админ:'
+    apps: Мобиль қосымшалар
+    contact: Байланыс
+    contact_missing: Бапталмаған
+    contact_unavailable: Белгісіз
+    documentation: Құжаттама
+    extended_description_html: |
+      <h3>Ережелерге арналған жақсы орын</h3>
+      <p>Әлі ештеңе жазылмапты</p>
+    generic_description: "%{domain} желідегі серверлердің бірі"
+    hosted_on: Mastodon орнатылған %{domain} доменінде
+    learn_more: Көбірек білу
+    privacy_policy: Құпиялылық саясаты
+    source_code: Ашық коды
+    status_count_after:
+      one: жазба
+      other: жазба
+    status_count_before: Барлығы
+    terms: Қолдану шарттары
+    user_count_after:
+      one: қолданушы
+      other: қолданушы
+    user_count_before: Желіде
+    what_is_mastodon: Mastodon деген не?
+  accounts:
+    choices_html: "%{name} таңдаулары:"
+    follow: Жазылу
+    followers:
+      one: Оқырман
+      other: Оқырман
+    following: Жазылғандары
+    joined: Тіркелген күні %{date}
+    last_active: соңғы әрекеті
+    link_verified_on: Сілтеме меншігі расталған күн %{date}
+    media: Медиа
+    moved_html: "%{name} мына жерге көшті %{new_profile_link}:"
+    network_hidden: Бұл ақпарат қолжетімді емес
+    nothing_here: Бұл жерде ештеңе жоқ!
+    people_followed_by: "%{name} жазылған адамдар"
+    people_who_follow: "%{name} атты қолданушының оқырмандары"
+    pin_errors:
+      following: Оқығыңыз келген адамға жазылуыңыз керек
+    posts:
+      one: Жазба
+      other: Жазба
+    posts_tab_heading: Жазба
+    posts_with_replies: Жазбалар және жауаптар
+    reserved_username: Мұндай логин тіркелген
+    roles:
+      admin: Админ
+      bot: Бот
+      moderator: Мод
+    unfollow: Оқымау
+  admin:
+    account_actions:
+      action: Әрекетті орындаңыз
+      title: Модерация жасаңыз %{acct}
+    account_moderation_notes:
+      create: Жазба қалдырыңыз
+      created_msg: Модерация жазбасы қалдырылды!
+      delete: Өшіру
+      destroyed_msg: Модерация жазбасы өшірілді!
+    accounts:
+      are_you_sure: Шынымен бе?
+      avatar: Аватар
+      by_domain: Домен
+      change_email:
+        changed_msg: Аккаунт email-і сәтті өзгертілді!
+        current_email: Қазіргі email
+        label: email өзгерту
+        new_email: Жаңа email
+        submit: email өзгерт
+        title: Қолданушы email-ін өзгерту %{username}
+      confirm: Құптау
+      confirmed: Құпталды
+      confirming: Құпталуды күтеді
+      deleted: Өшірілді
+      demote: Төмендету
+      disable: Ажырату
+      disable_two_factor_authentication: Ажырату 2FA
+      disabled: Ажыратылды
+      display_name: Атын көрсет
+      domain: Домен
+      edit: Түзету
+      email_status: Email статусы
+      enable: Қосу
+      enabled: Қосылды
+      feed_url: Feеd URL
+      followers: Оқырмандар
+      followers_url: Оқырмандар URL
+      follows: Жазылғандары
+      header: Басы
+      inbox_url: Келген хаттар URL
+      invited_by: Шақырған
+      joined: Қосылды
+      location:
+        all: Барлығы
+        local: Жергілікті
+        remote: Алыс
+        title: Мекен
+      login_status: Логин статусы
+      media_attachments: Медиа файлдар
+      memorialize: Естелік қылу
+      moderation:
+        active: Актив
+        all: Барлығы
+        silenced: Үнсіз
+        suspended: Тоқтатылды
+        title: Модерация
+      moderation_notes: Модерация жазбалары
+      most_recent_activity: Соңғы белсенділіктер
+      most_recent_ip: Соңғы ІР
+      no_limits_imposed: Шектеу жоқ
+      not_subscribed: Жазылмаған
+      outbox_url: Кеткен хаттар URL
+      perform_full_suspension: Тоқтат
+      profile_url: Профиль URL
+      promote: Жарнамалау
+      protocol: Хаттама
+      public: Ашық
+      push_subscription_expires: PuSH жазылу мерзімі аяқталады
+      redownload: Профиль жаңарт
+      remove_avatar: Аватар өшіру
+      remove_header: Мұқаба суретін өшір
+      resend_confirmation:
+        already_confirmed: Қолданушы құпталған
+        send: Құптау хатын қайтадан жібер
+        success: Құптау хаты сәтті жіберілді!
+      reset: Қалпына келтіру
+      reset_password: Құпиясөзді қалпына келтіру
+      resubscribe: Resubscribе
+      role: Қайта жазылу
+      roles:
+        admin: Админ
+        moderator: Модератор
+        staff: Қызметкерлер
+        user: Қолданушы
+      salmon_url: Ақсерке URL
+      search: Іздеу
+      shared_inbox_url: Бөлісілген инбокс URL
+      show:
+        created_reports: Шағымдар жинағы
+        targeted_reports: Жіберілген шағымдар
+      silence: Үнсіз
+      silenced: Үнсіз қылғандар
+      statuses: Статустар
+      subscribe: Жазылу
+      suspended: Тоқтатылды
+      title: Аккаунттар
+      unconfirmed_email: Құпталмаған email
+      undo_silenced: Үнсіздікті қайтып алу
+      undo_suspension: Тоқтатуды қайтып алу
+      unsubscribe: Жазылмау
+      username: Логин
+      warn: Ескерту
+      web: Веб
+    action_logs:
+      actions:
+        assigned_to_self_report: "%{name} шағым тастады %{target} өздері үшін"
+        change_email_user: "%{name} e-mail адресін өзгертті - %{target}"
+        confirm_user: "%{name} e-mail адресін құптады - %{target}"
+        create_account_warning: "%{name} ескерту жіберді - %{target}"
+        create_custom_emoji: "%{name} жаңа эмодзи қосты %{target}"
+        create_domain_block: "%{name} домен бұғаттады - %{target}"
+        create_email_domain_block: "%{name} e-mail доменін қара тізімге қосты - %{target}"
+        demote_user: "%{name} төмендетілген қолданушы - %{target}"
+        destroy_custom_emoji: "%{name} эмодзи жойды %{target}"
+        destroy_domain_block: "%{name} бұғатталмаған домен %{target}"
+        destroy_email_domain_block: "%{name} e-mail доменін ақ тізімге кіргізді %{target}"
+        destroy_status: "%{name} жазбасын өшірді %{target}"
+        disable_2fa_user: "%{name} қолданушы үшін екі фактор ажыратылған %{target}"
+        disable_custom_emoji: "%{name} эмодзи алып тастады %{target}"
+        disable_user: "%{name} қосылмаған логин %{target}"
+        enable_custom_emoji: "%{name} қосылған эмодзи %{target}"
+        enable_user: "%{name} қосылған логин %{target}"
+        memorialize_account: "%{name} %{target} аккаунтын естеліктеріне қосты"
+        promote_user: "%{name} жарнамалады %{target}"
+        remove_avatar_user: "%{name} %{target} аватарын өшірді"
+        reopen_report: "%{name} %{target} шағымын қайта қарады"
+        reset_password_user: "%{name} %{target} құпиясөзін қалпына келтірді"
+        resolve_report: "%{name} %{target} шағымын қарастырды"
+        silence_account: "%{name} %{target} аккаунтын үнсіз қылды"
+        suspend_account: "%{name} %{target} аккаунтын тоқтатты"
+        unassigned_report: "%{name} бекітілмеген есеп %{target}"
+        unsilence_account: "%{name} %{target} аккаунтын қайта қосты"
+        unsuspend_account: "%{name} %{target} аккаунтын қайта қосты"
+        update_custom_emoji: "%{name} эмодзи жаңартты %{target}"
+        update_status: "%{name} жазбасын жаңартты %{target}"
+      deleted_status: "(өшірілген жазба)"
+      title: Аудит логы
+    custom_emojis:
+      by_domain: Домен
+      copied_msg: Жергілікті эмодзидің көшірмесі сәтті жасалды
+      copy: Көшіру
+      copy_failed_msg: Жергілікті эмодзидің көшірмесі жасалмады
+      created_msg: Эмодзи сәтті жаңартылды!
+      delete: Өшіру
+      destroyed_msg: Эмодзи сәтті жойылды!
+      disable: Ажырату
+      disabled_msg: Бұл эмодзи сәтті жойылды
+      emoji: Эмодзи
+      enable: Қосу
+      enabled_msg: Эмодзи сәтті қосылды
+      image_hint: PNG 50KB
+      listed: Тізілді
+      new:
+        title: Жаңа эмодзи қос
+      overwrite: Үстіне жаз
+      shortcode: Шорткод
+      shortcode_hint: Кем дегенде 2 символ, тек латын әріптері мен асты сызылған таңбалар
+      title: Таңдаулы эмодзилар
+      unlisted: Тізімде жоқ
+      update_failed_msg: Бұл эмодзи жаңартылмады
+      updated_msg: Эмодзи сәтті жаңартылды!
+      upload: Жүктеу
+    dashboard:
+      backlog: босатылған тапсырмалар
+      config: Конфигурация
+      feature_deletions: Аккаунттарды жою
+      feature_invites: Шақыру сілтемелері
+      feature_profile_directory: Профиль каталогы
+      feature_registrations: Тіркелулер
+      feature_relay: Федерация релесі
+      features: Мүмкіндіктер
+      hidden_service: Жасырын қызметтер федерациясы
+      open_reports: ашық шағымдар
+      recent_users: Соңғы қолданушылар
+      search: Толық мәтінмен іздеу
+      single_user_mode: Жалғыз пайдаланушы режимі
+      software: Бағдарлама
+      space: Пайдаланылған кеңістік
+      title: Басқару тақтасы
+      total_users: барлық қолданушы
+      trends: Трендтер
+      week_interactions: осы аптадағы әрекеттер
+      week_users_active: осы аптадағы белсенділік
+      week_users_new: осы аптадағы қолданушылар
+    domain_blocks:
+      add_new: Жаңа домен блокын қосу
+      created_msg: Домендік блок енді өңделуде
+      destroyed_msg: Домендік блок қалпына келтірілді
+      domain: Домен
+      new:
+        create: Блок құру
+        hint: Домендік блок дерекқорда тіркелгі жазбаларын құруға кедергі жасамайды, бірақ сол есептік жазбаларда ретроактивті және автоматты түрде нақты модерация әдістерін қолданады.
+        severity:
+          desc_html: "<strong>Silence</strong> will make the account's posts invisible to anyone who isn't following them. <strong>Suspend</strong> will remove all of the account's content, media, and profile data. Use <strong>None</strong> if you just want to reject media filеs."
+          noop: Ештеңе
+          silence: Үнсіз
+          suspend: Тоқтатылған
+        title: Жаңа домен блокы
+      reject_media: Медиа файлдарды қабылдамау
+      reject_media_hint: Жергілікті сақталған мультимедиалық файлдарды жояды және болашақта кез келген жүктеуден бас тартады. Суспензияға байланысты емес
+      reject_reports: Шағым қабылдамау
+      reject_reports_hint: Бұл доменнен келген барлық есептерді елемеңіз. Суспензияға байланысты емес
+      rejecting_media: медиа файлдарды қабылдамау
+      rejecting_reports: шағымдарды қабылдамау
+      severity:
+        silence: үнсіз
+        suspend: тоқтатылған
+      show:
+        affected_accounts:
+          one: Дерекқорда бір тіркелгі қозғалды
+          other: дерекқордағы %{count} аккаунт қозғалған
+        retroactive:
+          silence: Осы домендегі бар тіркелгілерді жою
+          suspend: Осы домендегі бар барлық тіркелгілерді тоқтатыңыз
+        title: "%{domain} доменіндегі блокты алып таста"
+        undo: Қайтару
+      undo: Домен блокын қайтып алу
+    email_domain_blocks:
+      add_new: Жаңасын қосу
+      created_msg: Қаратізімге email домені қосылды
+      delete: Өшіру
+      destroyed_msg: Successfully deletеd e-mail domain from blacklist
+      domain: Домен
+      new:
+        create: Add dоmain
+        title: New e-mail blаcklist entry
+      title: E-mail қаратізімі
+    followers:
+      back_to_account: Back To Accоunt
+      title: "%{acct} оқырмандары"
+    instances:
+      by_domain: Domаin
+      delivery_available: Жеткізу қол жетімді
+      known_accounts:
+        one: "%{count} таныс аккаунт"
+        other: "%{count} таныс аккаунт"
+      moderation:
+        all: Барлығы
+        limited: Лимит
+        title: Модерация
+      title: Федерация
+      total_blocked_by_us: Біз бұғаттағандар
+      total_followed_by_them: Олар жазылғандар
+      total_followed_by_us: Біз жазылғандар
+      total_reported: Келген шағымдар
+      total_storage: Медиа файлдар
+    invites:
+      deactivate_all: Барлығын сөндір
+      filter:
+        all: Барлығы
+        available: Қолжетімді
+        expired: Уақыты өткен
+        title: Фильтр
+      title: Шақырулар
+    relays:
+      add_new: Жаңа арна қосу
+      delete: Өшіру
+      description_html: A <strong>fedеration relay</strong> is an intermediary server that exchanges large volumes of public toots between servers that subscribe and publish to it. <strong>It can help small and medium servers discover content from the fediverse</strong>, which would otherwise require local users manually following other people on remote servers.
+      disable: Сөндіру
+      disabled: Сөндірілді
+      enable: Қосу
+      enable_hint: Once enabled, your server will subscribe to all public toots from this rеlay, and will begin sending this server's public toots to it.
+      enabled: Қосылды
+      inbox_url: Арна URL
+      pending: Жаңа арна құпталуын күту
+      save_and_enable: Сақта да қос
+      setup: Арна байланысын баптау
+      status: Статус
+      title: Арналар
+    report_notes:
+      created_msg: Шағым жазбасы сәтті құрылды!
+      destroyed_msg: Шағым жазбасы сәтті өшірілді!
+    reports:
+      account:
+        note: жазба
+        report: шағым
+      action_taken_by: Белсенділік жасаған
+      are_you_sure: Шынымен бе?
+      assign_to_self: Мені тағайындау
+      assigned: Модератор тағайындау
+      comment:
+        none: Ештеңе
+      created_at: Шағым тасталды
+      mark_as_resolved: Шешілді деп белгіле
+      mark_as_unresolved: Шешілмеді деп белгіле
+      notes:
+        create: Жазба қос
+        create_and_resolve: Жазба қосып шеш
+        create_and_unresolve: Жазба қосып қайта аш
+        delete: Өшіру
+        placeholder: Қандай әрекеттер жасалғанын немесе қандай да бір қатысты әрекеттерді сипаттаңыз ...
+      reopen: Шағымды қайта аш
+      report: 'Шағым #%{id}'
+      reported_account: Шағымдалған аккаунт
+      reported_by: Шағым тастаушы
+      resolved: Қайта шешілді
+      resolved_msg: Шағым қайтадан шешілді!
+      status: Статус
+      title: Шағымдар
+      unassign: Қайтып алу
+      unresolved: Шешілмеген
+      updated_at: Жаңартылды
+    settings:
+      activity_api_enabled:
+        desc_html: Соңғы аптада жазылған жазбалар, белсенді қолданушылар, жаңа тіркелімдер
+        title: Пайдаланушы әрекеті туралы жиынтық статистиканы жариялау
+      bootstrap_timeline_accounts:
+        desc_html: Бірнеше пайдаланушы атын үтірмен бөліңіз. Тек жергілікті және бұғатталмаған аккаунттар. Барлық жергілікті админдер бос болғанда.
+        title: Жаңа қолданушыларға жазылғандар
+      contact_information:
+        email: Бизнес e-mail
+        username: Қолданушымен байланыс
+      custom_css:
+        desc_html: Әр беттегі өзгерістерді CSS жаңаруымен қарау
+        title: Жеке CSS
+      hero:
+        desc_html: Бастапқы бетінде көрсетіледі. Кем дегенде 600x100px ұсынылады. Орнатылмаған кезде, сервердің нобайына оралады
+        title: Қаһарман суреті
+      mascot:
+        desc_html: Displayed on multiple pages. Кем дегенде 293×205px рекоменделеді. When not set, falls back to default mascot
+        title: Маскот суреті
+      peers_api_enabled:
+        desc_html: Домен names this server has encountered in the fediverse
+        title: Publish list of discovered серверлер
+      preview_sensitive_media:
+        desc_html: Link previews on other websites will display a thumbnail even if the media is marked as сезімтал
+        title: Show sensitive media in OpenGraph превью
+      profile_directory:
+        desc_html: Рұқсат users to be discoverable
+        title: Enable профиль directory
+      registrations:
+        closed_message:
+          desc_html: Displayed on frontpage when registrations are closed. You can use HTML тег
+          title: Closed registration мессадж
+        deletion:
+          desc_html: Allow anyone to delete their аккаунт
+          title: Open аккаунт deletion
+        min_invite_role:
+          disabled: Ешкім
+          title: Allow шақырулар by
+      show_known_fediverse_at_about_page:
+        desc_html: When toggled, it will show toots from all the known fediverse on preview. Otherwise it will only show жергілікті toots.
+        title: Show known fediverse on timeline превью
+      show_staff_badge:
+        desc_html: Show a staff badge on a user бет
+        title: Көрсет staff badge
+      site_description:
+        desc_html: Introductory paragraph on the басты бет. Describe what makes this Mastodon server special and anything else important. You can use HTML tags, in particular <code>&lt;a&gt;</code> and <code>&lt;em&gt;</code>.
+        title: Сервер туралы
+      site_description_extended:
+        desc_html: A good place for your code of conduct, rules, guidelines and other things that set your server apart. You can use HTML тег
+        title: Custom extended ақпарат
+      site_short_description:
+        desc_html: Displayed in sidebar and meta tags. Describe what Mastodon is and what makes this server special in a single paragraph. If empty, defaults to сервер description.
+        title: Short сервер description
+      site_terms:
+        desc_html: You can write your own privacy policy, terms of service or other legalese. You can use HTML тег
+        title: Қолдану шарттары мен ережелер
+      site_title: Сервер аты
+      thumbnail:
+        desc_html: Used for previews via OpenGraph and API. 1200x630px рекоменделеді
+        title: Сервер суреті
+      timeline_preview:
+        desc_html: Display public timeline on лендинг пейдж
+        title: Таймлайн превьюі
+      title: Сайт баптаулары
+    statuses:
+      back_to_account: Аккаунт бетіне оралы
+      batch:
+        delete: Delеte
+        nsfw_off: Сезімтал емес ретінде белгіле
+        nsfw_on: Сезімтал ретінде белгіле
+      failed_to_execute: Орындалмады
+      media:
+        title: Медиa
+      no_media: Медиасыз
+      no_status_selected: Бірде-бір статус өзгерген жоқ, себебі ештеңе таңдалмады
+      title: Аккаунт статустары
+      with_media: Медиамен
+    subscriptions:
+      callback_url: Callbаck URL
+      confirmed: Confirmеd
+      expires_in: Expirеs in
+      last_delivery: Last dеlivery
+      title: WеbSub
+      topic: Tоpic
+    tags:
+      accounts: Accоunts
+      hidden: Hiddеn
+      hide: Hidе from directory
+      name: Hаshtag
+      title: Hashtаgs
+      unhide: Shоw in directory
+      visible: Visiblе
+    title: Administrаtion
+    warning_presets:
+      add_new: Add nеw
+      delete: Deletе
+      edit: Еdit
+      edit_preset: Edit warning prеset
+      title: Manage warning presеts
+  admin_mailer:
+    new_report:
+      body: "%{reporter} has rеported %{target}"
+      body_remote: Someone from %{domain} has rеported %{target}
+      subject: New rеport for %{instance} (#%{id})
+  application_mailer:
+    notification_preferences: Change e-mail prеferences
+    settings: 'Change e-mail preferеnces: %{link}'
+    view: 'Viеw:'
+    view_profile: Viеw Profile
+    view_status: Viеw status
+  applications:
+    created: Application succеssfully created
+    destroyed: Application succеssfully deleted
+    invalid_url: The providеd URL is invalid
+    regenerate_token: Regenerate accеss token
+    token_regenerated: Access token succеssfully regenerated
+    warning: Be very carеful with this data. Never share it with anyone!
+    your_token: Your access tokеn
+  auth:
+    change_password: Құпиясөз
+    confirm_email: Еmаil құптау
+    delete_account: Аккаунт өшіру
+    delete_account_html: Аккаунтыңызды жойғыңыз келсе, <a href="%{path}">мына жерді</a> басыңыз. Сізден растау сұралатын болады.
+    didnt_get_confirmation: Растау хаты келмеді ме?
+    forgot_password: Құпиясөзіңізді ұмытып қалдыңыз ба?
+    invalid_reset_password_token: Құпиясөз қайтып алу қолжетімді емес немесе мерзімі аяқталған. Қайтадан сұратыңыз.
+    login: Кіру
+    logout: Шығу
+    migrate_account: Басқа аккаунтқа көшіру
+    migrate_account_html: Егер аккаунтыңызды басқасына байлағыңыз келсе, <a href="%{path}">мына жерге келіңіз</a>.
+    or_log_in_with: Немесе былай кіріңіз
+    providers:
+      cas: САS
+      saml: SАML
+    register: Тіркелу
+    resend_confirmation: Растау нұсқаулықтарын жіберу
+    reset_password: Құпиясөзді қалпына келтіру
+    security: Қауіпсіздік
+    set_new_password: Жаңа құпиясөз қою
+  authorize_follow:
+    already_following: Бұл аккаунтқа жазылғансыз
+    error: Өкінішке орай, қашықтағы тіркелгіні іздеуде қате пайда болды
+    follow: Жазылу
+    follow_request: 'Сіз жазылуға өтініш жібердіңіз:'
+    following: 'Керемет! Сіз енді жазылдыңыз:'
+    post_follow:
+      close: Немесе терезені жаба салыңыз.
+      return: Қолданушы профилін көрсет
+      web: Вебте ашу
+    title: Жазылу %{acct}
+  datetime:
+    distance_in_words:
+      about_x_hours: "%{count}сағ"
+      about_x_months: "%{count}ай"
+      about_x_years: "%{count}жыл"
+      almost_x_years: "%{count}жыл"
+      half_a_minute: Осы бойда
+      less_than_x_minutes: "%{count}мин"
+      less_than_x_seconds: Осы бойда
+      over_x_years: "%{count}жыл"
+      x_days: "%{count}күн"
+      x_minutes: "%{count}мин"
+      x_months: "%{count}ай"
+      x_seconds: "%{count}сек"
+  deletes:
+    bad_password_msg: Болмады ма, хакер бала? Құпиясөз қате
+    confirm_password: Қазіргі құпиясөзіңізді жазыңыз
+    description_html: This will <strong>permanently, irreversibly</strong> remove content from your account аnd deactivate it. Your username will remain reserved to prevent future impersonations.
+    proceed: Аккаунт өшіру
+    success_msg: Аккаунтыңыз сәтті өшірілді
+    warning_html: Only deletion of content from this particular server is guaranteed. Content that has been widely sharеd is likely to leave traces. Offline servers and servers that have unsubscribed from your updates will not update their databases.
+    warning_title: Бөлінген мазмұнның қол жетімділігі
+  directories:
+    directory: Профильдер каталогы
+    enabled: Каталогтағы тізімге ендіңіз.
+    enabled_but_waiting: Каталогта көрінгіңіз келетінін түсінеміз, бірақ ол үшін кем дегенде (%{min_followers}) оқырманыңыз болуы қажет.
+    explanation: Қолданушыларды қызығушылықтарына қарай реттеу
+    explore_mastodon: "%{title} шарлау"
+    how_to_enable: Сіз қазіргі уақытта каталогқа қосылмағансыз. Төменде қосылуға болады. Арнайы био мәтініндегі хэштегтерді қолданыңыз!
+    people:
+      one: "%{count} адам"
+      other: "%{count} адам"
+  errors:
+    '403': Бұны көру үшін сізде рұқсат жоқ.
+    '404': Сіз іздеген бет бұл жерде емес екен.
+    '410': Сіз іздеген бет қазір жоқ екен.
+    '422':
+      content: Қауіпсіздік растауы қате. кукилерді блоктағансыз ба?
+      title: Қауіпсіздік растауы жасалмады
+    '429': Қысқартылған
+    '500':
+      content: Кешірерсіз, бірақ қазір бір қате пайда болып тұр.
+      title: Бұл бет дұрыс емес екен
+    noscript_html: Mastodon веб қосымшасын қолдану үшін, JavaScript қосыңыз. Болмай жатса, <a href="%{apps_path}">мына қосымшаларды</a> қосып көріңіз, Mastodon қолдану үшін.
+  exports:
+    archive_takeout:
+      date: Уақыты
+      download: Мұрағатыңызды түсіріп алыңыз
+      hint_html: Өзіңіздің <strong>жазба және медиаларыңыздың</strong> мұрағатын сақтап алуыңызға болады. Экспортталатын деректер ActivityPub форматында болады, сәйкес бағдарламамлармен ашуға болады. Әр 7 күн сайын сұратуыңызға болады.
+      in_progress: Мұрағатыңызды жинақтау...
+      request: Мұрағат сұрату
+      size: Өлшемі
+    blocks: Бұғатталғансыз
+    csv: СSV
+    domain_blocks: Домен блоктары
+    follows: Оқитындарыңыз
+    lists: Тізімдер
+    mutes: Үнсіздер
+    storage: Медиа жинақ
+  featured_tags:
+    add_new: Жаңасын қосу
+    errors:
+      limit: Хэштег лимитинен асып кеттіңіз
+  filters:
+    contexts:
+      home: Ішкі желі
+      notifications: Ескертпелер
+      public: Ашық желі
+      thread: Пікірталас
+    edit:
+      title: Фильтр өңдеу
+    errors:
+      invalid_context: Жоқ немесе жарамсыз контекст берілген
+      invalid_irreversible: Қайтарылмайтын сүзгі тек ішкі немесе ескертпелер контекстімен жұмыс істейді
+    index:
+      delete: Өшіру
+      title: Фильтрлер
+    new:
+      title: Жаңа фильтр қосу
+  footer:
+    developers: Жасаушылар
+    more: Тағы…
+    resources: Ресурстар
+  generic:
+    changes_saved_msg: Өзгерістер сәтті сақталды!
+    copy: Көшіру
+    save_changes: Өзгерістерді сақтау
+    validation_errors:
+      one: Бір нәрсе дұрыс емес! Төмендегі қатені қараңыз
+      other: Бір нәрсе дұрыс емес! Төмендегі %{count} қатені қараңыз
+  imports:
+    modes:
+      merge: Біріктіру
+      merge_long: Бар жазбаларды сақтаңыз және жаңаларын қосыңыз
+      overwrite: Үстіне жазу
+      overwrite_long: Ағымдағы жазбаларды жаңаларына ауыстырыңыз
+    preface: Басқа серверден экспортталған деректерді импорттауға болады, мысалы, сіз бақылайтын немесе блоктайтын адамдардың тізімін.
+    success: Деректеріңіз сәтті жүктелді және дер кезінде өңделеді
+    types:
+      blocking: Бұғат тізімі
+      domain_blocking: Домен бұғаттары тізімі
+      following: Жазылғандар тізімі
+      muting: Үнсіздер тізімі
+    upload: Жүктеу
+  in_memoriam_html: Естеліктерде.
+  invites:
+    delete: Ажырату
+    expired: Мерзімі өткен
+    expires_in:
+      '1800': 30 минут
+      '21600': 6 сағат
+      '3600': 1 сағат
+      '43200': 12 сағат
+      '604800': 1 апта
+      '86400': 1 күн
+    expires_in_prompt: Ешқашан
+    generate: Құру
+    invited_by: 'Сізді шақырған:'
+    max_uses:
+      one: 1 қолданыс
+      other: "%{count} қолданыс"
+    max_uses_prompt: Лимитсіз
+    prompt: Осы серверге кіру рұқсатын беру үшін сілтемелерді жасаңыз және бөлісіңіз
+    table:
+      expires_at: Аяқталу мерзімі
+      uses: Қолданыс
+    title: Адам шақыру
+  lists:
+    errors:
+      limit: Сіз тізімдердің максимум мөлшеріне жеттіңіз
+  media_attachments:
+    validations:
+      images_and_video: Жазбаға видео қоса алмайсыз, тек сурет қосуға болады
+      too_many: 4 файлдан артық қосылмайды
+  migrations:
+    acct: жаңа аккаунт үшін username@domain
+    currently_redirecting: 'Профиліңіз көшіріледі:'
+    proceed: Сақтау
+    updated_msg: Аккаунт көшіруіңіз сәтті аяқталды!
+  moderation:
+    title: Модерация
+  notification_mailer:
+    digest:
+      action: Барлық ескертпелер
+      body: Міне, соңғы кірген уақыттан кейін келген хаттардың қысқаша мазмұны %{since}
+      mention: "%{name} сізді атап өтіпті:"
+      new_followers_summary:
+        one: Сондай-ақ, сіз бір жаңа оқырман таптыңыз! Алақай!
+        other: Сондай-ақ, сіз %{count} жаңа оқырман таптыңыз! Керемет!
+      subject:
+        one: "Соңғы кіруіңізден кейін 1 ескертпе келіпті \U0001F418"
+        other: "Соңғы кіруіңізден кейін %{count} ескертпе келіпті \U0001F418"
+      title: Сіз жоқ кезде...
+    favourite:
+      body: 'Жазбаңызды ұнатып, таңдаулыға қосты %{name}:'
+      subject: "%{name} жазбаңызды таңдаулыға қосты"
+      title: Жаңа таңдаулы
+    follow:
+      body: "%{name} сізге жазылды!"
+      subject: "%{name} сізге жазылды"
+      title: Жаңа оқырман
+    follow_request:
+      action: Жазылуға сұранымдарды реттеу
+      body: "%{name} сізге жазылғысы келеді"
+      subject: 'Жазылғысы келеді: %{name}'
+      title: Жазылуға сұраным
+    mention:
+      action: Жауап
+      body: 'Сізді атап өтіпті %{name} мында:'
+      subject: Сізді %{name} атап өтіпті
+      title: Жаңа аталым
+    reblog:
+      body: 'Жазбаңызды бөліскен %{name}:'
+      subject: "%{name} жазбаңызды бөлісті"
+      title: Жаңа бөлісім
+  number:
+    human:
+      decimal_units:
+        units:
+          billion: Ð’
+          million: М
+          thousand: К
+          trillion: Т
+  pagination:
+    newer: Ешқашан
+    next: Келесі
+    older: Ерте
+    prev: Алдыңғы
+  polls:
+    errors:
+      already_voted: Бұл сауалнамаға қатысқансыз
+      duplicate_options: қайталанатын нәрселер бар
+      duration_too_long: тым ұзақ екен
+      duration_too_short: тым аз екен
+      expired: Сауалнама уақыты аяқталған
+      over_character_limit: "%{max} таңбадан артық болмайды"
+      too_few_options: бір жауаптан көп болуы керек
+      too_many_options: "%{max} жауаптан көп болмайды"
+  preferences:
+    other: Басқа
+  remote_follow:
+    acct: Өзіңіздің username@domain теріңіз
+    missing_resource: Аккаунтыңызға байланған URL табылмады
+    no_account_html: Әлі тіркелмегенсіз бе? Мына жерден <a href='%{sign_up_path}' target='_blank'>тіркеліп алыңыз</a>
+    proceed: Жазылу
+    prompt: 'Жазылғыңыз келеді:'
+    reason_html: "<strong>Неліктен бұл қадам қажет?</strong> <code>%{instance}</code> тіркелгіңіз келген сервер болмауы мүмкін, сондықтан сізді алдымен ішкі серверіңізге қайта бағыттау қажет."
+  remote_interaction:
+    favourite:
+      proceed: Таңдаулыға қосу
+      prompt: 'Мына жазбаны таңдаулыға қосасыз:'
+    reblog:
+      proceed: Жазба бөлісу
+      prompt: 'Сіз мына жазбаны бөлісесіз:'
+    reply:
+      proceed: Жауап жазу
+      prompt: 'Сіз мына жазбаға жауап жазасыз:'
+  remote_unfollow:
+    error: Қате
+    title: Тақырыбы
+    unfollowed: Жазылудан бас тартылды
+  scheduled_statuses:
+    over_daily_limit: Сіз бір күндік %{limit} жазба лимитін тауыстыңыз
+    over_total_limit: Сіз %{limit} жазба лимитін тауыстыңыз
+    too_soon: Жоспарланған күн болашақта болуы керек
+  sessions:
+    activity: Соңғы әрекеттер
+    browser: Браузер
+    browsers:
+      alipay: Аlipay
+      blackberry: Blаckberry
+      chrome: Chrоme
+      edge: Microsоft Edge
+      electron: Electrоn
+      firefox: Firеfox
+      generic: Белгісіз браузер
+      ie: Internet Explоrer
+      micro_messenger: MicroMеssenger
+      nokia: Nokia S40 Ovi Brоwser
+      opera: Opеra
+      otter: Ottеr
+      phantom_js: PhаntomJS
+      qq: QQ Brоwser
+      safari: Safаri
+      uc_browser: UCBrоwser
+      weibo: Weibо
+    current_session: Қазіргі сессия
+    description: "%{browser} - %{platform}"
+    explanation: Сіздің аккаунтыңызбен кірілген браузерлер тізімі.
+    ip: ІР
+    platforms:
+      adobe_air: Adobе Air
+      android: Andrоid
+      blackberry: Blackbеrry
+      chrome_os: ChromеOS
+      firefox_os: Firefоx OS
+      ios: iОS
+      linux: LÑ–nux
+      mac: Mаc
+      other: белгісіз платформа
+      windows: Windоws
+      windows_mobile: Windows Mоbile
+      windows_phone: Windоws Phone
+    revoke: Шығып кету
+    revoke_success: Сессиялар сәтті жабылды
+    title: Сессиялар
+  settings:
+    authorized_apps: Authorizеd apps
+    back: Желіге оралу
+    delete: Аккаунт өшіру
+    development: Жасаушы топ
+    edit_profile: Профиль өңдеу
+    export: Экспорт уақыты
+    featured_tags: Таңдаулы хэштегтер
+    import: Импорт
+    migrate: Аккаунт көшіру
+    notifications: Ескертпелер
+    preferences: Таңдаулар
+    two_factor_authentication: Екі-факторлы авторизация
+  statuses:
+    attached:
+      description: 'Жүктелді: %{attached}'
+      image:
+        one: "%{count} сурет"
+        other: "%{count} сурет"
+      video:
+        one: "%{count} видео"
+        other: "%{count} видео"
+    boosted_from_html: Бөлісілді %{acct_link}
+    content_warning: 'Контент ескертуі: %{warning}'
+    disallowed_hashtags:
+      one: 'рұқсат етілмеген хэштег: %{tags}'
+      other: 'рұқсат етілмеген хэштегтер: %{tags}'
+    language_detection: Тілді өздігінен таңда
+    open_in_web: Вебте ашу
+    over_character_limit: "%{max} максимум таңбадан асып кетті"
+    pin_errors:
+      limit: Жабыстырылатын жазба саны максимумынан асты
+      ownership: Біреудің жазбасы жабыстырылмайды
+      private: Жабық жазба жабыстырылмайды
+      reblog: Бөлісілген жазба жабыстырылмайды
+    poll:
+      total_votes:
+        one: "%{count} дауыс"
+        other: "%{count} дауыс"
+      vote: Дауыс беру
+    show_more: Тағы әкел
+    sign_in_to_participate: Сұхбатқа қатысу үшін кіріңіз
+    visibilities:
+      private: Тек оқырмандарға
+      private_long: Тек оқырмандарға ғана көрінеді
+      public: Ашық
+      public_long: Бәрі көре алады
+      unlisted: Тізімге енбеген
+      unlisted_long: Бәрі көре алады, бірақ ашық тізімдерге ене алмайды
+  stream_entries:
+    pinned: Жабыстырылған жазба
+    reblogged: бөлісті
+    sensitive_content: Нәзік мазмұн
+  terms:
+    body_html: |
+      <h2>Құпиялылық шарттары</h2>
+      <h3 id="collect">What information do we collect?</h3>
+
+      <ul>
+      <li><em>Basic account information</em>: If you register on this server, you may be asked to enter a username, an e-mail address and a password. You may also enter additional profile information such as a display name and biography, and upload a profile picture and header image. The username, display name, biography, profile picture and header image are always listed publicly.</li>
+      <li><em>Posts, following and other public information</em>: The list of people you follow is listed publicly, the same is true for your followers. When you submit a message, the date and time is stored as well as the application you submitted the message from. Messages may contain media attachments, such as pictures and videos. Public and unlisted posts are available publicly. When you feature a post on your profile, that is also publicly available information. Your posts are delivered to your followers, in some cases it means they are delivered to different servers and copies are stored there. When you delete posts, this is likewise delivered to your followers. The action of reblogging or favouriting another post is always public.</li>
+      <li><em>Direct and followers-only posts</em>: All posts are stored and processed on the server. Followers-only posts are delivered to your followers and users who are mentioned in them, and direct posts are delivered only to users mentioned in them. In some cases it means they are delivered to different servers and copies are stored there. We make a good faith effort to limit the access to those posts only to authorized persons, but other servers may fail to do so. Therefore it's important to review servers your followers belong to. You may toggle an option to approve and reject new followers manually in the settings. <em>Please keep in mind that the operators of the server and any receiving server may view such messages</em>, and that recipients may screenshot, copy or otherwise re-share them. <em>Do not share any dangerous information over Mastodon.</em></li>
+      <li><em>IPs and other metadata</em>: When you log in, we record the IP address you log in from, as well as the name of your browser application. All the logged in sessions are available for your review and revocation in the settings. The latest IP address used is stored for up to 12 months. We also may retain server logs which include the IP address of every request to our server.</li>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="use">What do we use your information for?</h3>
+
+      <p>Any of the information we collect from you may be used in the following ways:</p>
+
+      <ul>
+      <li>To provide the core functionality of Mastodon. You can only interact with other people's content and post your own content when you are logged in. For example, you may follow other people to view their combined posts in your own personalized home timeline.</li>
+      <li>To aid moderation of the community, for example comparing your IP address with other known ones to determine ban evasion or other violations.</li>
+      <li>The email address you provide may be used to send you information, notifications about other people interacting with your content or sending you messages, and to respond to inquiries, and/or other requests or questions.</li>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="protect">How do we protect your information?</h3>
+
+      <p>We implement a variety of security measures to maintain the safety of your personal information when you enter, submit, or access your personal information. Among other things, your browser session, as well as the traffic between your applications and the API, are secured with SSL, and your password is hashed using a strong one-way algorithm. You may enable two-factor authentication to further secure access to your account.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="data-retention">What is our data retention policy?</h3>
+
+      <p>We will make a good faith effort to:</p>
+
+      <ul>
+      <li>Retain server logs containing the IP address of all requests to this server, in so far as such logs are kept, no more than 90 days.</li>
+      <li>Retain the IP addresses associated with registered users no more than 12 months.</li>
+      </ul>
+
+      <p>You can request and download an archive of your content, including your posts, media attachments, profile picture, and header image.</p>
+
+      <p>You may irreversibly delete your account at any time.</p>
+
+      <hr class="spacer"/>
+
+      <h3 id="cookies">Do we use cookies?</h3>
+
+      <p>Yes. Cookies are small files that a site or its service provider transfers to your computer's hard drive through your Web browser (if you allow). These cookies enable the site to recognize your browser and, if you have a registered account, associate it with your registered account.</p>
+
+      <p>We use cookies to understand and save your preferences for future visits.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="disclose">Do we disclose any information to outside parties?</h3>
+
+      <p>We do not sell, trade, or otherwise transfer to outside parties your personally identifiable information. This does not include trusted third parties who assist us in operating our site, conducting our business, or servicing you, so long as those parties agree to keep this information confidential. We may also release your information when we believe release is appropriate to comply with the law, enforce our site policies, or protect ours or others rights, property, or safety.</p>
+
+      <p>Your public content may be downloaded by other servers in the network. Your public and followers-only posts are delivered to the servers where your followers reside, and direct messages are delivered to the servers of the recipients, in so far as those followers or recipients reside on a different server than this.</p>
+
+      <p>When you authorize an application to use your account, depending on the scope of permissions you approve, it may access your public profile information, your following list, your followers, your lists, all your posts, and your favourites. Applications can never access your e-mail address or password.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="children">Site usage by children</h3>
+
+      <p>If this server is in the EU or the EEA: Our site, products and services are all directed to people who are at least 16 years old. If you are under the age of 16, per the requirements of the GDPR (<a href="https://en.wikipedia.org/wiki/General_Data_Protection_Regulation">General Data Protection Regulation</a>) do not use this site.</p>
+
+      <p>If this server is in the USA: Our site, products and services are all directed to people who are at least 13 years old. If you are under the age of 13, per the requirements of COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) do not use this site.</p>
+
+      <p>Law requirements can be different if this server is in another jurisdiction.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="changes">Changes to our Privacy Policy</h3>
+
+      <p>If we decide to change our privacy policy, we will post those changes on this page.</p>
+
+      <p>This document is CC-BY-SA. It was last updated March 7, 2018.</p>
+
+      <p>Originally adapted from the <a href="https://github.com/discourse/discourse">Discourse privacy policy</a>.</p>
+    title: "%{instance} Қызмет көрсету шарттары және Құпиялылық саясаты"
+  themes:
+    contrast: Mastodon (Жоғары контраст)
+    default: Mastodon (Қою)
+    mastodon-light: Mastodon (Ашық)
+  two_factor_authentication:
+    code_hint: Растау үшін түпнұсқалықты растау бағдарламасы арқылы жасалған кодты енгізіңіз
+    description_html: "<strong>екі факторлы түпнұсқалықты растауды</strong> қоссаңыз, кіру үшін сізге телефонға кіруіңізді талап етеді, сізге арнайы токен беріледі."
+    disable: Ажырату
+    enable: Қосу
+    enabled: Екі-факторлы авторизация қосылған
+    enabled_success: Екі-факторлы авторизация сәтті қосылды
+    generate_recovery_codes: Қалпына келтіру кодтарын жасаңыз
+    instructions_html: "<strong>Мына QR кодты Google Authenticator арқылы скандаңыз немесе ұқсас TOTP бағдарламалары арқылы</strong>. Одан кейін желіге кіру үшін токендер берілетін болады."
+    lost_recovery_codes: Қалпына келтіру кодтары телефонды жоғалтсаңыз, тіркелгіңізге қайта кіруге мүмкіндік береді. Қалпына келтіру кодтарын жоғалтсаңыз, оларды осында қалпына келтіре аласыз. Ескі қалпына келтіру кодтары жарамсыз болады.
+    manual_instructions: 'Егер сіз QR-кодты сканерлей алмасаңыз және оны қолмен енгізуіңіз қажет болса, мұнда қарапайым нұсқаулық:'
+    recovery_codes: Қалпына келтіру кодтарын резервтік көшіру
+    recovery_codes_regenerated: Қалпына келтіру кодтары қалпына келтірілді
+    recovery_instructions_html: Егер сіз телефонға кіруді жоғалтсаңыз, тіркелгіңізге кіру үшін төмендегі қалпына келтіру кодтарының бірін пайдалануға болады. <strong>Қалпына келтіру кодтарын қауіпсіз ұстаңыз </strong>. Мысалы, оларды басып шығарып, оларды басқа маңызды құжаттармен сақтауға болады.
+    setup: Орнату
+    wrong_code: Енгізілген код жарамсыз! Сервер уақыты мен құрылғының уақыты дұрыс па?
+  user_mailer:
+    backup_ready:
+      explanation: Сіз Mastodon аккаунтыңыздың толық мұрағатын сұрадыңыз. Қазір жүктеуге дайын!
+      subject: Мұрағатыңыз түсіріп алуға дайын
+      title: Мұрағатты алу
+    warning:
+      explanation:
+        disable: Аккаунтыңыз қатып қалса, сіздің деректеріңіз өзгеріссіз қалады, бірақ ол құлыптан босатылғанша ешқандай әрекетті орындай алмайсыз.
+        silence: While your account is limited, only people who are already following you will see your toots on this server, and you may be excluded from various public listings. However, others may still manually follоw you.
+        suspend: Сіздің аккаунтыңыз уақытша тоқтатылды және сіздің барлық файлдарыңыз бен жүктеп салынған медиа файлдарыңыз осы серверлерден және оқырманы болған серверлерден қайтарылмайды.
+      review_server_policies: Сервер саясатын қарап шығыңыз
+      subject:
+        disable: Аккаунтыңыз %{acct} уақытша тоқтатылды
+        none: "%{acct} ескертуі"
+        silence: "%{acct} аккаунтыңыз шектеулі"
+        suspend: "%{acct} аккаунт тоқтатылды"
+      title:
+        disable: Аккаунт қатырылды
+        none: Ескерту
+        silence: Аккаунт шектеулі
+        suspend: Аккаунт тоқтатылды
+    welcome:
+      edit_profile_action: Профиль өңдеу
+      edit_profile_step: Профиліңізге аватар, мұқаба сурет жүктей аласыз, аты-жөніңізді көрсете аласыз. Оқырмандарыңызға сізбен танысуға рұқсат бермес бұрын аккаунтыңызды уақытша құлыптап қоюға болады.
+      explanation: Мына кеңестерді шолып өтіңіз
+      final_action: Жазба жазу
+      final_step: 'Жазуды бастаңыз! Тіпті оқырмандарыңыз болмаса да, сіздің жалпы жазбаларыңызды басқа адамдар көре алады, мысалы, жергілікті желіде және хэштегтерде. Жазбаларыңызға # протоколды хэштег қоссаңыз болады.'
+      full_handle: Желі тұтқасы
+      full_handle_hint: This is what you would tell your friends so they can message or follow you frоm another server.
+      review_preferences_action: Таңдауларды өзгерту
+      review_preferences_step: Қандай хат-хабарларын алуды қалайтыныңызды немесе сіздің хабарламаларыңыздың қандай құпиялылық деңгейін алғыңыз келетінін анықтаңыз. Сондай-ақ, сіз GIF автоматты түрде ойнату мүмкіндігін қосуды таңдай аласыз.
+      subject: Mastodon Желісіне қош келдіңіз
+      tip_federated_timeline: Жаһандық желі - Mastodon желісінің негізгі құндылығы.
+      tip_following: Сіз бірден желі админіне жазылған болып саналасыз. Басқа адамдарға жазылу үшін жергілікті және жаһандық желіні шолып шығыңыз.
+      tip_local_timeline: Жерігілкті желіде маңайыздағы адамдардың белсенділігін көре аласыз %{instance}. Олар - негізгі көршілеріңіз!
+      tip_mobile_webapp: Мобиль браузеріңіз Mastodon желісін бастапқы бетке қосуды ұсынса, қабылдаңыз. Ескертпелер де шығатын болады. Арнайы қосымша сияқты бұл!
+      tips: Кеңестер
+      title: Ортаға қош келдің, %{name}!
+  users:
+    follow_limit_reached: Сіз %{limit} лимитінен көп адамға жазыла алмайсыз
+    invalid_email: Бұл e-mail адрес қате
+    invalid_otp_token: Қате екі-факторлы код
+    otp_lost_help_html: Егер кіру жолдарын жоғалтып алсаңыз, сізге %{email} арқылы жіберіледі
+    seamless_external_login: Сыртқы сервис арқылы кіріпсіз, сондықтан құпиясөз және электрондық пошта параметрлері қол жетімді емес.
+    signed_in_as: 'Былай кірдіңіз:'
+  verification:
+    explanation_html: 'Өзіңіздің профиль метадеректеріңіздегі сілтемелердің иесі ретінде өзіңізді <strong>тексере аласыз</strong>. Ол үшін байланыстырылған веб-сайтта Mastodon профиліне <strong>сілтеме болуы керек. </strong> Сілтемеде <code>rel = «me»</code> атрибуты болуы керек. Сілтеме мәтінінің мазмұны маңызды емес. Міне мысал:'
+    verification: Растау
diff --git a/config/locales/ko.yml b/config/locales/ko.yml
index bf6a8b7705d4597121a7bddd283d1c5499dd60dc..3f14d5df64e70359bde3ca8ff560c9a8ed8aac11 100644
--- a/config/locales/ko.yml
+++ b/config/locales/ko.yml
@@ -4,39 +4,37 @@ ko:
     about_hashtag_html: "<strong>#%{hashtag}</strong> 라는 해시태그가 붙은 공개 툿 입니다. 같은 연합에 속한 임의의 인스턴스에 계정을 생성하면 당신도 대화에 참여할 수 있습니다."
     about_mastodon_html: 마스토돈은 <em>오픈 소스 기반의</em> 소셜 네트워크 서비스 입니다. 상용 플랫폼의 대체로서 <em>분산형 구조</em>를 채택해, 여러분의 대화가 한 회사에 독점되는 것을 방지합니다. 신뢰할 수 있는 인스턴스를 선택하세요 &mdash; 어떤 인스턴스를 고르더라도, 누구와도 대화할 수 있습니다. 누구나 자신만의 마스토돈 인스턴스를 만들 수 있으며, 아주 매끄럽게 <em>소셜 네트워크</em>에 참가할 수 있습니다.
     about_this: 이 인스턴스에 대해서
+    active_count_after: 활성 사용자
+    active_footnote: 월간 활성 사용자
     administered_by: '관리자:'
     api: API
     apps: 모바일 앱
-    closed_registrations: 현재 이 인스턴스에서는 신규 등록을 받고 있지 않습니다.
+    apps_platforms: 마스토돈을 iOS, 안드로이드, 다른 플랫폼들에서도 사용하세요
+    browse_directory: 프로필 디렉터리를 둘러보고 관심사 찾기
+    browse_public_posts: 마스토돈의 공개 라이브 스트림을 둘러보기
     contact: 연락처
     contact_missing: 미설정
-    contact_unavailable: N/A
+    contact_unavailable: 없음
+    discover_users: 유저 발견하기
     documentation: 문서
     extended_description_html: |
       <h3>룰을 작성하는 장소</h3>
       <p>아직 설명이 작성되지 않았습니다.</p>
-    features:
-      humane_approach_body: 다른 SNS의 실패를 교훈삼아, 마스토돈은 소셜미디어가 잘못 사용되는 것을 막기 위하여 윤리적인 설계를 추구합니다.
-      humane_approach_title: 보다 배려를 의식한 설계를 추구
-      not_a_product_body: 마스토돈은 이익을 추구하는 SNS가 아닙니다. 그러므로 광고와 데이터의 수집 및 분석이 존재하지 않고, 유저를 구속하지도 않습니다.
-      not_a_product_title: 여러분은 사람이며, 상품이 아닙니다
-      real_conversation_body: 자유롭게 사용할 수 있는 500문자의 메세지와 미디어 경고 내용을 바탕으로, 자기자신을 자유롭게 표현할 수 있습니다.
-      real_conversation_title: 진정한 커뮤니케이션을 위하여
-      within_reach_body: 개발자 친화적인 API에 의해서 실현된 iOS나 Android, 그 외의 여러 Platform들 덕분에 어디서든 친구들과 자유롭게 메세지를 주고 받을 수 있습니다.
-      within_reach_title: 언제나 유저의 곁에서
+    federation_hint_html: "%{instance}에 계정을 만드는 것으로 모든 마스토돈 서버, 그리고 호환 되는 모든 서버의 사용자를 팔로우 할 수 있습니다."
     generic_description: "%{domain} 은 네트워크에 있는 한 서버입니다"
+    get_apps: 모바일 앱 사용해 보기
     hosted_on: "%{domain}에서 호스팅 되는 마스토돈"
     learn_more: 자세히
-    other_instances: 다른 인스턴스
     privacy_policy: 개인정보 정책
+    see_whats_happening: 무슨 일이 일어나는 지 보기
+    server_stats: '서버 통계:'
     source_code: 소스 코드
     status_count_after:
-      one: 툿
       other: 툿
     status_count_before: 툿 수
+    tagline: 친구들을 팔로우 하고 새로운 사람들도 만나기
     terms: 이용약관
     user_count_after:
-      one: 명
       other: 명
     user_count_before: 사용자 수
     what_is_mastodon: 마스토돈이란?
@@ -44,7 +42,6 @@ ko:
     choices_html: "%{name}의 추천:"
     follow: 팔로우
     followers:
-      one: 팔로워
       other: 팔로워
     following: 팔로잉
     joined: "%{date}에 가입함"
@@ -59,7 +56,6 @@ ko:
     pin_errors:
       following: 추천하려는 사람을 팔로우 하고 있어야 합니다
     posts:
-      one: 툿
       other: 툿
     posts_tab_heading: 툿
     posts_with_replies: 툿과 답장
@@ -68,6 +64,7 @@ ko:
       admin: 관리자
       bot: ë´‡
       moderator: 모더레이터
+    unavailable: 프로필 사용 불가
     unfollow: 팔로우 해제
   admin:
     account_actions:
@@ -79,6 +76,8 @@ ko:
       delete: 삭제
       destroyed_msg: 모더레이션 기록이 성공적으로 삭제되었습니다!
     accounts:
+      approve: 승인
+      approve_all: 모두 승인
       are_you_sure: 정말로 실행하시겠습니까?
       avatar: 아바타
       by_domain: 도메인
@@ -93,7 +92,7 @@ ko:
       confirmed: 확인됨
       confirming: 확인 중
       deleted: 삭제됨
-      demote: 모더레이터 강등
+      demote: 강등
       disable: 비활성화
       disable_two_factor_authentication: 2단계 인증을 비활성화
       disabled: 비활성화된
@@ -124,22 +123,27 @@ ko:
       moderation:
         active: 활동
         all: ì „ì²´
+        pending: 대기중
         silenced: 침묵 중
         suspended: 정지 중
         title: 모더레이션
       moderation_notes: 모더레이션 기록
       most_recent_activity: 최근 활동
       most_recent_ip: 최근 IP
+      no_account_selected: 아무 계정도 선택 되지 않아 아무 것도 변경 되지 않았습니다
       no_limits_imposed: 제한 없음
       not_subscribed: 구독하지 않음
       outbox_url: 발신함 URL
+      pending: 심사 대기
       perform_full_suspension: 정지시키기
       profile_url: 프로필 URL
-      promote: 모더레이터로 승급
+      promote: 승급
       protocol: 프로토콜
       public: 전체 공개
       push_subscription_expires: PuSH 구독 기간 만료
       redownload: 프로필 업데이트
+      reject: ê±°ë¶€
+      reject_all: 모두 거부
       remove_avatar: 아바타 지우기
       remove_header: 헤더 삭제
       resend_confirmation:
@@ -147,7 +151,7 @@ ko:
         send: 다시 확인 이메일
         success: 확인 이메일이 전송되었습니다!
       reset: 초기화
-      reset_password: 비밀번호 초기화
+      reset_password: 암호 초기화
       resubscribe: 다시 구독
       role: 권한
       roles:
@@ -166,6 +170,7 @@ ko:
       statuses: 툿 수
       subscribe: 구독하기
       suspended: 정지 됨
+      time_in_queue: "%{time}동안 기다림"
       title: 계정
       unconfirmed_email: 미확인 된 이메일 주소
       undo_silenced: 침묵 해제
@@ -241,6 +246,7 @@ ko:
       feature_profile_directory: 프로필 디렉토리
       feature_registrations: 가입
       feature_relay: 연합 릴레이
+      feature_timeline_preview: 타임라인 미리보기
       features: 기능
       hidden_service: 히든 서비스와의 연합
       open_reports: 미해결 신고
@@ -260,6 +266,7 @@ ko:
       created_msg: 도메인 차단 처리를 완료했습니다
       destroyed_msg: 도메인 차단이 해제되었습니다
       domain: 도메인
+      existing_domain_block_html: 이미 %{name}에 대한 더 강력한 제한이 걸려 있습니다, <a href="%{unblock_url}">차단 해제</a>를 먼저 해야 합니다.
       new:
         create: 차단 추가
         hint: 도메인 차단은 내부 데이터베이스에 계정이 생성되는 것까지는 막을 수 없지만, 그 도메인에서 생성된 계정에 자동적으로 특정한 모더레이션을 적용하게 할 수 있습니다.
@@ -282,7 +289,6 @@ ko:
         suspend: ì •ì§€
       show:
         affected_accounts:
-          one: 데이터베이스 중 1개의 계정에 영향을 끼칩니다
           other: 데이터베이스 중 %{count}개의 계정에 영향을 끼칩니다
         retroactive:
           silence: 이 도메인에 존재하는 모든 계정의 침묵를 해제
@@ -304,9 +310,9 @@ ko:
       back_to_account: 계정으로 돌아가기
       title: "%{acct}의 팔로워"
     instances:
+      by_domain: 도메인
       delivery_available: 전송 가능
       known_accounts:
-        one: 알려진 계정 %{count}개
         other: 알려진 계정 %{count}개
       moderation:
         all: 모두
@@ -326,6 +332,8 @@ ko:
         expired: 만료됨
         title: í•„í„°
       title: 초대
+    pending_accounts:
+      title: 대기중인 계정 (%{count})
     relays:
       add_new: 릴레이 추가
       delete: 삭제
@@ -350,7 +358,7 @@ ko:
         report: 리포트
       action_taken_by: 신고 처리자
       are_you_sure: 정말로 실행하시겠습니까?
-      assign_to_self: 나에게 할당 됨
+      assign_to_self: 나에게 할당하기
       assigned: 할당 된 모더레이터
       comment:
         none: 없음
@@ -388,14 +396,14 @@ ko:
         desc_html: 모든 페이지에 적용할 CSS
         title: 커스텀 CSS
       hero:
-        desc_html: 프론트페이지에 표시 됩니다. 최소 600x100픽셀을 권장합니다. 만약 설정되지 않았다면, 인스턴스의 썸네일이 사용 됩니다
+        desc_html: 프론트페이지에 표시 됩니다. 최소 600x100픽셀을 권장합니다. 만약 설정되지 않았다면, 서버의 썸네일이 사용 됩니다
         title: 히어로 이미지
       mascot:
         desc_html: 여러 페이지에서 보여집니다. 최소 293x205px을 추천합니다. 설정 되지 않은 경우, 기본 마스코트가 사용 됩니다
         title: 마스코트 이미지
       peers_api_enabled:
-        desc_html: 이 인스턴스가 페디버스에서 만났던 도메인 네임들
-        title: 발견 된 인스턴스들의 리스트 발행
+        desc_html: 이 서버가 페디버스에서 만났던 도메인 네임들
+        title: 발견 된 서버들의 리스트 발행
       preview_sensitive_media:
         desc_html: 민감한 미디어로 설정되었더라도 다른 웹사이트에서 링크 미리보기에 썸네일을 보여줍니다
         title: 민감한 미디어를 오픈그래프 미리보기에 보여주기
@@ -412,9 +420,12 @@ ko:
         min_invite_role:
           disabled: 아무도 못 하게
           title: 초대링크를 만들 수 있는 권한
-        open:
-          desc_html: 계정을 생성할 수 있도록 허용합니다
-          title: 신규 계정 등록을 받음
+      registrations_mode:
+        modes:
+          approved: 가입하려면 승인이 필요함
+          none: 아무도 가입 할 수 없음
+          open: 누구나 가입 할 수 있음
+        title: 가입 모드
       show_known_fediverse_at_about_page:
         desc_html: 활성화 되면 프리뷰 페이지에서 페디버스의 모든 툿을 표시합니다. 비활성화시 로컬에 있는 툿만 표시 됩니다.
         title: 타임라인 프리뷰에 알려진 페디버스 표시하기
@@ -422,21 +433,21 @@ ko:
         desc_html: 유저 페이지에 스태프 배지를 표시합니다
         title: 스태프 배지 표시
       site_description:
-        desc_html: 프론트 페이지의 소개문에 사용 됩니다.이 마스토돈 서버의 특별한 점 등을 설명하세요. HTML 태그, 주로 <code>&lt;a&gt;</code>, <code>&lt;em&gt;</code> 같은 것을 사용 가능합니다.
-        title: 사이트 설명
+        desc_html: API의 소개문에 사용 됩니다.이 마스토돈 서버의 특별한 점 등을 설명하세요. HTML 태그, 주로 <code>&lt;a&gt;</code>, <code>&lt;em&gt;</code> 같은 것을 사용 가능합니다.
+        title: 서버 설명
       site_description_extended:
         desc_html: 규칙, 가이드라인 등을 작성하기 좋은 곳입니다. HTML 태그를 사용할 수 있습니다
         title: 사이트 상세 설명
       site_short_description:
-        desc_html: 사이드바와 메타 태그에 나타납니다. 마스토돈이 무엇이고 이 서버의 특징은 무엇인지 한 문장으로 설명하세요. 비워두면 인스턴스 설명이 대신 사용됩니다.
-        title: 짧은 인스턴스 설명
+        desc_html: 사이드바와 메타 태그에 나타납니다. 마스토돈이 무엇이고 이 서버의 특징은 무엇인지 한 문장으로 설명하세요.
+        title: 짧은 서버 설명
       site_terms:
         desc_html: 당신은 독자적인 개인정보 취급 방침이나 이용약관, 그 외의 법적 근거를 작성할 수 있습니다. HTML태그를 사용할 수 있습니다
         title: 커스텀 서비스 이용 약관
-      site_title: 사이트 이름
+      site_title: 서버 이름
       thumbnail:
         desc_html: OpenGraph와 API의 미리보기로 사용 됩니다. 1200x630px을 권장합니다
-        title: 인스턴스 썸네일
+        title: 서버 썸네일
       timeline_preview:
         desc_html: 랜딩 페이지에 공개 타임라인을 표시합니다
         title: 타임라인 프리뷰
@@ -477,15 +488,24 @@ ko:
       edit_preset: 경고 틀 수정
       title: 경고 틀 관리
   admin_mailer:
+    new_pending_account:
+      body: 아래에 새 계정에 대한 상세정보가 있습니다. 이 가입을 승인하거나 거부할 수 있습니다.
+      subject: "%{instance}의 새 계정(%{username})에 대한 심사가 대기중입니다"
     new_report:
       body: "%{reporter} 가 %{target} 를 신고했습니다"
       body_remote: "%{domain}의 누군가가 %{target}을 신고했습니다"
       subject: "%{instance} 에 새 신고 등록됨 (#%{id})"
+  appearance:
+    advanced_web_interface: 고급 웹 인터페이스
+    advanced_web_interface_hint: '화면의 가로폭을 가득 채우고 싶다면, 고급 웹 인터페이스는 한 번에 여러 정보를 볼 수 있도록 여러 컬럼을 설정할 수 있도록 합니다: 홈, 알림, 연합타임라인, 리스트, 해시태그 등'
+    animations_and_accessibility: 애니메이션과 접근성
+    confirmation_dialogs: 확인 대화상자
+    sensitive_content: 민감한 내용
   application_mailer:
     notification_preferences: 메일 설정 변경
     salutation: "%{name} 님,"
     settings: '메일 설정을 변경: %{link}'
-    view: 'View:'
+    view: '보기:'
     view_profile: 프로필 보기
     view_status: 게시물 보기
   applications:
@@ -497,29 +517,30 @@ ko:
     warning: 이 데이터를 조심히 다뤄 주세요. 다른 사람들과 절대로 공유하지 마세요!
     your_token: 액세스 토큰
   auth:
-    agreement_html: 이 등록으로 <a href="%{rules_path}">이용규약</a> 과 <a href="%{terms_path}">약관</a>에 동의하는 것으로 간주됩니다.
+    apply_for_account: 가입 요청하기
     change_password: 패스워드
+    checkbox_agreement_html: <a href="%{rules_path}" target="_blank">서버 규칙</a>과 <a href="%{terms_path}" target="_blank">이용약관</a>에 동의합니다
     confirm_email: 확인 메일 승인
     delete_account: 계정 삭제
     delete_account_html: 계정을 삭제하고 싶은 경우, <a href="%{path}">여기서</a> 삭제할 수 있습니다. 삭제 전 확인 화면이 표시됩니다.
     didnt_get_confirmation: 확인 메일을 받지 못하셨습니까?
     forgot_password: 비밀번호를 잊어버리셨습니까?
-    invalid_reset_password_token: 비밀번호 리셋 토큰이 올바르지 못하거나 기간이 만료되었습니다. 다시 요청해주세요.
+    invalid_reset_password_token: 암호 리셋 토큰이 올바르지 못하거나 기간이 만료되었습니다. 다시 요청해주세요.
     login: 로그인
     logout: 로그아웃
     migrate_account: 계정 옮기기
     migrate_account_html: 이 계정을 다른 계정으로 리디렉션 하길 원하는 경우 <a href="%{path}">여기</a>에서 설정할 수 있습니다.
-    or: 또는
     or_log_in_with: 다른 방법으로 로그인 하려면
     providers:
       cas: CAS
       saml: SAML
     register: 등록하기
-    register_elsewhere: 다른 인스턴스에서 가입
+    registration_closed: "%{instance}는 새로운 가입을 받지 않고 있습니다"
     resend_confirmation: 확인 메일을 다시 보내기
-    reset_password: 비밀번호 재설정
+    reset_password: 암호 재설정
     security: 보안
-    set_new_password: 새 비밀번호
+    set_new_password: 새 암호
+    trouble_logging_in: 로그인 하는데 문제가 있나요?
   authorize_follow:
     already_following: 이미 이 계정을 팔로우 하고 있습니다
     error: 리모트 계정을 확인하는 도중 오류가 발생했습니다
@@ -551,7 +572,7 @@ ko:
     description_html: 계정에 업로드된 모든 컨텐츠가 삭제되며, 계정은 비활성화 됩니다. 이것은 영구적으로 이루어지는 것이므로 <strong>되돌릴 수 없습니다</strong>. 사칭 행위를 방지하기 위해 같은 아이디로 다시 등록하는 것은 불가능합니다.
     proceed: 계정 삭제
     success_msg: 계정이 성공적으로 삭제되었습니다
-    warning_html: 삭제가 보장되는 것은 이 인스턴스 상에서의 컨텐츠에 한합니다. 타 인스턴스 등, 외부에 멀리 공유된 컨텐츠는 흔적이 남아 삭제되지 않는 경우도 있습니다. 그리고 현재 접속이 불가능한 서버나, 업데이트를 받지 않게 된 서버에 대해서는 삭제가 반영되지 않을 수도 있습니다.
+    warning_html: 삭제가 보장되는 것은 이 서버 상에서의 컨텐츠에 한합니다. 타 서버 등, 외부에 멀리 공유된 컨텐츠는 흔적이 남아 삭제되지 않는 경우도 있습니다. 그리고 현재 접속이 불가능한 서버나, 업데이트를 받지 않게 된 서버에 대해서는 삭제가 반영되지 않을 수도 있습니다.
     warning_title: 공유된 컨텐츠에 대해서
   directories:
     directory: 프로필 디렉토리
@@ -561,12 +582,11 @@ ko:
     explore_mastodon: "%{title} 탐사하기"
     how_to_enable: 아직 디렉터리에 참여하지 않았습니다. 아래에서 참여할 수 있습니다. 바이오 텍스트에 해시태그를 사용해 특정 해시태그 디렉터리에 표시 될 수 있습니다!
     people:
-      one: "%{count}명"
       other: "%{count}명"
   errors:
     '403': 이 페이지를 표시할 권한이 없습니다.
     '404': 당신이 찾으려는 페이지는 존재하지 않습니다.
-    '410': 당신이 보려는 페이지는 더이상 존재하지 않습니다.
+    '410': 당신이 보려는 페이지는 더이상 여기에 존재하지 않습니다.
     '422':
       content: 보안 인증에 실패했습니다. 쿠키를 차단하고 있진 않습니까?
       title: 보안 인증 실패
@@ -575,6 +595,9 @@ ko:
       content: 죄송합니다, 뭔가 잘못 되었습니다.
       title: 이 페이지는 잘못되었습니다
     noscript_html: 마스토돈을 사용하기 위해서는 자바스크립트를 켜 주십시오. 아니면 <a href="%{apps_path}">네이티브 앱</a> 중 하나를 사용할 수 있습니다.
+  existing_username_validator:
+    not_found: 해당 유저네임에 대한 로컬 유저를 찾을 수 없습니다
+    not_found_multiple: "%{usernames}를 찾을 수 없습니다"
   exports:
     archive_takeout:
       date: 날짜
@@ -590,6 +613,10 @@ ko:
     lists: 리스트
     mutes: 뮤트
     storage: 미디어
+  featured_tags:
+    add_new: 추가
+    errors:
+      limit: 이미 추천 해시태그의 개수가 최대입니다
   filters:
     contexts:
       home: 홈 타임라인
@@ -606,34 +633,49 @@ ko:
       title: í•„í„°
     new:
       title: 필터 추가
-  followers:
-    domain: 도메인
-    explanation_html: 프라이버시를 확보하고 싶은 경우, 누가 여러분을 팔로우 하고 있는지 파악해둘 필요가 있습니다. <strong>프라이빗 포스팅은 여러분의 팔로워가 소속하는 모든 인스턴스로 배달됩니다</strong>. 팔로워가 소속된 인스턴스 관리자나 소프트웨어가 여러분의 프라이버시를 존중하고 있는지 잘 모를 경우, 그 팔로워를 삭제하는 것이 좋을 수도 있습니다.
-    followers_count: 팔로워 수
-    lock_link: 비공개 계정
-    purge: 팔로워에서 삭제
-    success:
-      one: 1개 도메인에서 팔로워를 soft-block 처리 중...
-      other: "%{count}개 도메인에서 팔로워를 soft-block 처리 중..."
-    true_privacy_html: "<strong>프라이버시 보호는 End-to-End 암호화로만 이루어 질 수 있다는 것에 유의</strong>해 주십시오."
-    unlocked_warning_html: 누구든 여러분을 팔로우 할 수 있으며, 여러분의 프라이빗 투고를 볼 수 있습니다. 팔로우 할 수 있는 사람을 제한하고 싶은 경우 %{lock_link}에서 설정해 주십시오.
-    unlocked_warning_title: 이 계정은 비공개로 설정되어 있지 않습니다
   footer:
     developers: 개발자
     more: 더 보기…
     resources: 리소스
   generic:
+    all: 모두
     changes_saved_msg: 정상적으로 변경되었습니다!
     copy: 복사
+    order_by: 순서
     save_changes: 변경 사항을 저장
     validation_errors:
-      one: 오류가 발생했습니다. 아래 오류를 확인해 주십시오
       other: 오류가 발생했습니다. 아래 %{count}개 오류를 확인해 주십시오
+  html_validator:
+    invalid_markup: '올바르지 않은 HTML 마크업을 포함하고 있습니다: %{error}'
+  identity_proofs:
+    active: 활성
+    authorize: 네, 인증합니다
+    authorize_connection_prompt: 이 암호화 연결을 인증합니까?
+    errors:
+      failed: 암호화 연결에 실패했습니다. %{provider}에서 다시 시도해 주세요.
+      keybase:
+        invalid_token: 키베이스 토큰은 서명의 해시이며 66자의 16진수 문자여야 합니다
+        verification_failed: 키베이스가 이 토큰을 키베이스 유저 %{kb_username}의 서명으로 인식하지 못했습니다. 키베이스에서 다시 시도하세요.
+      wrong_user: "%{current}로 로그인 한 상태에서는 %{proving}에 대한 증명을 할 수 없습니다. %{proving}으로 로그인 한 후 다시 시도하세요."
+    explanation_html: 키베이스와 같은 다른 명의에 대한 암호화 연결을 할 수 있습니다. 이것으로 다른 사람들이 당신에게 암호화 된 메시지를 보낼 수 있고 당신의 메시지를 믿을 수 있습니다.
+    i_am_html: 나는 %{service}의 %{username} 입니다.
+    identity: 신원
+    inactive: 비활성
+    publicize_checkbox: '그리고 이것을 툿 하세요:'
+    publicize_toot: '증명되었습니다! 저는 %{service}에 있는 %{username}입니다: %{url}'
+    status: 인증 상태
+    view_proof: 증명 보기
   imports:
-    preface: 다른 인스턴스에서 내보내기 한 파일에서 팔로우 / 차단 정보를 이 인스턴스 계정으로 불러올 수 있습니다.
+    modes:
+      merge: 병합
+      merge_long: 기존 것을 그대로 둔 채 새로 추가
+      overwrite: 덮어쓰기
+      overwrite_long: 기존 것을 모두 지우고 새로 추가
+    preface: 다른 서버에서 내보내기 한 파일에서 팔로우 / 차단 정보를 이 계정으로 불러올 수 있습니다.
     success: 파일이 정상적으로 업로드 되었으며, 현재 처리 중입니다
     types:
       blocking: 차단한 계정 목록
+      domain_blocking: 도메인 차단 목록
       following: 팔로우 중인 계정 목록
       muting: 뮤트 중인 계정 목록
     upload: 업로드
@@ -652,10 +694,9 @@ ko:
     generate: 생성
     invited_by: '당신을 초대한 사람:'
     max_uses:
-      one: 일회용
       other: "%{count} 회"
     max_uses_prompt: 제한 없음
-    prompt: 이 인스턴스에 대한 초대 링크를 만들고 공유합니다
+    prompt: 이 서버에 대한 초대 링크를 만들고 공유합니다
     table:
       expires_at: 만료
       uses: 사용됨
@@ -680,10 +721,8 @@ ko:
       body: 마지막 로그인(%{since}) 이후로 일어난 일들에 관한 요약
       mention: "%{name} 님이 답장했습니다:"
       new_followers_summary:
-        one: 그리고, 접속 하지 않으신 동안 새 팔로워가 생겼습니다!
         other: 게다가, 접속하지 않은 동안 %{count} 명의 팔로워가 생겼습니다!
       subject:
-        one: "1건의 새로운 알림 \U0001F418"
         other: "%{count}건의 새로운 알림 \U0001F418"
       title: 당신이 없는 동안에...
     favourite:
@@ -718,18 +757,39 @@ ko:
           quadrillion: Q
           thousand: K
           trillion: T
-          unit: "."
   pagination:
     newer: 새로운 툿
     next: 다음
     older: 오래된 툿
     prev: 이전
     truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: 이미 투표에 참여하셨습니다
+      duplicate_options: 중복된 항목이 있습니다
+      duration_too_long: 너무 먼 미래입니다
+      duration_too_short: 너무 가깝습니다
+      expired: 투표가 이미 끝났습니다
+      over_character_limit: 각각 %{max} 글자를 넘을 수 없습니다
+      too_few_options: 한가지 이상의 항목을 포함해야 합니다
+      too_many_options: 항목은 %{max}개를 넘을 수 없습니다
   preferences:
-    languages: 언어
     other: 기타
-    publishing: 퍼블리싱
-    web: 웹
+    posting_defaults: 게시물 기본설정
+    public_timelines: 공개 타임라인
+  relationships:
+    activity: 계정 활동
+    dormant: 휴면
+    last_active: 마지막 활동
+    most_recent: 가장 최근
+    moved: 이동함
+    mutual: 상호 팔로우
+    primary: 주 계정
+    relationship: 관계
+    remove_selected_domains: 선택한 도메인의 모든 팔로워 삭제
+    remove_selected_followers: 선택한 팔로워 삭제
+    remove_selected_follows: 선택한 유저들을 팔로우 해제
+    status: 계정 상태
   remote_follow:
     acct: 당신이 사용하는 아이디@도메인을 입력해 주십시오
     missing_resource: 리디렉션 대상을 찾을 수 없습니다
@@ -774,7 +834,7 @@ ko:
       phantom_js: PhantomJS
       qq: QQ 브라우저
       safari: 사파리
-      uc_browser: UCBrowser
+      uc_browser: UC브라우저
       weibo: 웨이보
     current_session: 현재 세션
     description: "%{platform}의 %{browser}"
@@ -797,33 +857,35 @@ ko:
     revoke_success: 세션이 성공적으로 삭제되었습니다
     title: 세션
   settings:
+    account: 계정
+    account_settings: 계정 설정
+    appearance: 외관
     authorized_apps: 인증된 애플리케이션
     back: 돌아가기
     delete: 계정 삭제
     development: 개발
     edit_profile: 프로필 편집
     export: 데이터 내보내기
-    followers: 신뢰 중인 인스턴스
+    featured_tags: 추천 해시태그
+    identity_proofs: 신원 증명
     import: 데이터 가져오기
+    import_and_export: 가져오기 / 내보내기
     migrate: 계정 이동
     notifications: 알림
     preferences: 사용자 설정
-    settings: 설정
+    profile: 프로필
+    relationships: 팔로잉과 팔로워
     two_factor_authentication: 2단계 인증
-    your_apps: 애플리케이션
   statuses:
     attached:
       description: '첨부: %{attached}'
       image:
-        one: "%{count} 이미지"
         other: "%{count} 이미지"
       video:
-        one: "%{count} 영상"
         other: "%{count} 영상"
-    boosted_from_html: "%{acct_link} 님이 부스트"
+    boosted_from_html: "%{acct_link} 님으로부터 부스트"
     content_warning: '열람 주의: %{warning}'
     disallowed_hashtags:
-      one: '허용 되지 않은 해시태그를 포함하고 있습니다: %{tags}'
       other: '허용되지 않은 해시태그를 포함하고 있습니다: %{tags}'
     language_detection: 자동으로 언어 감지
     open_in_web: Web으로 열기
@@ -833,6 +895,10 @@ ko:
       ownership: 다른 사람의 툿은 고정될 수 없습니다
       private: 비공개 툿은 고정될 수 없습니다
       reblog: 부스트는 고정될 수 없습니다
+    poll:
+      total_votes:
+        other: "%{count}명 투표함"
+      vote: 투표
     show_more: 더 보기
     sign_in_to_participate: 로그인 하여 이 대화에 참여하기
     title: '%{name}: "%{quote}"'
@@ -853,10 +919,10 @@ ko:
       <h3 id="collect">우리가 어떤 정보를 수집하나요?</h3>
 
       <ul>
-        <li><em>기본 계정 정보</em>: 이 서버에 가입하실 때 유저네임, 이메일 주소, 패스워드 등을 입력 받게 됩니다. 추가적으로 디스플레이네임이나 자기소개, 프로필 이미지, 헤더 이미지 등의 프로필 정보를 입력하게 됩니다. 유저네임, 디스플레이네임, 자기소개, 프로필 이미지와 헤더 이미지는 언제나 공개적으로 게시됩니다.</li>
-        <li><em>게시물, 팔로잉, 기타 공개된 정보</em>: 당신이 팔로우 하는 사람들의 리스트는 공개됩니다. 당신을 팔로우 하는 사람들도 마찬가지입니다. 당신이 게시물을 작성하는 경우, 응용프로그램이 메시지를 받았을 때의 날짜와 시간이 기록 됩니다. 게시물은 그림이나 영상 등의 미디어를 포함할 수 있습니다. 퍼블릭과 미표시(unlisted) 게시물은 공개적으로 접근이 가능합니다. 프로필에 게시물을 고정하는 경우 마찬가지로 공개적으로 접근 가능한 정보가 됩니다. 당신의 게시물들은 당신의 팔로워들에게 전송 됩니다. 몇몇 경우 이것은 다른 서버에 전송되고 그곳에 사본이 저장 됩니다. 당신이 게시물을 삭제하는 경우 이 또한 당신의 팔로워들에게 전송 됩니다. 다른 게시물을 리블로깅 하거나 즐겨찾기 하는 경우 이는 언제나 공개적으로 제공 됩니다.</li>
-        <li><em>DM, 팔로워 공개 게시물</em>: 모든 게시물들은 서버에서 처리되고 저장됩니다. 팔로워 공개 게시물은 당신의 팔로워와 멘션 된 사람들에게 전달이 됩니다. 다이렉트 메시지는 멘션 된 사람들에게만 전송 됩니다. 몇몇 경우 이것은 다른 서버에 전송 되고 그곳에 사본이 저장됨을 의미합니다. 우리는 이 게시물들이 권한을 가진 사람들만 열람이 가능하도록 노력을 할 것이지만 다른 서버에서는 이것이 실패할 수도 있습니다. 그러므로 당신의 팔로워들이 속한 서버를 재확인하는 것이 중요합니다. 당신은 새 팔로워를 수동으로 승인하거나 거절하도록 설정을 변경할 수 있습니다. <em>해당 서버의 운영자는 서버가 받는 메시지를 열람할 수 있다는 것을 항상 염두해 두세요</em>, 그리고 수신자들은 스크린샷을 찍거나 복사하는 등의 방법으로 다시 공유할 수 있습니다. <em>위험한 정보를 마스토돈을 통해 공유하지 마세요.</em></li>
-        <li><em>IP와 기타 메타데이터</em>: 당신이 로그인 하는 경우 IP 주소와 브라우저의 이름을 저장합니다. 모든 세션은 당신이 검토하고 취소할 수 있도록 설정에서 제공 됩니다. 마지막으로 사용 된 IP 주소는 최대 12개월 간 저장됩니다. 또한, 모든 요청에 대해 IP주소를 포함한 정보를 로그에 저장할 수 있습니다.</li>
+      <li><em>기본 계정 정보</em>: 이 서버에 가입하실 때 유저네임, 이메일 주소, 패스워드 등을 입력 받게 됩니다. 추가적으로 디스플레이네임이나 자기소개, 프로필 이미지, 헤더 이미지 등의 프로필 정보를 입력하게 됩니다. 유저네임, 디스플레이네임, 자기소개, 프로필 이미지와 헤더 이미지는 언제나 공개적으로 게시됩니다.</li>
+      <li><em>게시물, 팔로잉, 기타 공개된 정보</em>: 당신이 팔로우 하는 사람들의 리스트는 공개됩니다. 당신을 팔로우 하는 사람들도 마찬가지입니다. 당신이 게시물을 작성하는 경우, 응용프로그램이 메시지를 받았을 때의 날짜와 시간이 기록 됩니다. 게시물은 그림이나 영상 등의 미디어를 포함할 수 있습니다. 퍼블릭과 미표시(unlisted) 게시물은 공개적으로 접근이 가능합니다. 프로필에 게시물을 고정하는 경우 마찬가지로 공개적으로 접근 가능한 정보가 됩니다. 당신의 게시물들은 당신의 팔로워들에게 전송 됩니다. 몇몇 경우 이것은 다른 서버에 전송되고 그곳에 사본이 저장 됩니다. 당신이 게시물을 삭제하는 경우 이 또한 당신의 팔로워들에게 전송 됩니다. 다른 게시물을 리블로깅 하거나 즐겨찾기 하는 경우 이는 언제나 공개적으로 제공 됩니다.</li>
+      <li><em>DM, 팔로워 공개 게시물</em>: 모든 게시물들은 서버에서 처리되고 저장됩니다. 팔로워 공개 게시물은 당신의 팔로워와 멘션 된 사람들에게 전달이 됩니다. 다이렉트 메시지는 멘션 된 사람들에게만 전송 됩니다. 몇몇 경우 이것은 다른 서버에 전송 되고 그곳에 사본이 저장됨을 의미합니다. 우리는 이 게시물들이 권한을 가진 사람들만 열람이 가능하도록 노력을 할 것이지만 다른 서버에서는 이것이 실패할 수도 있습니다. 그러므로 당신의 팔로워들이 속한 서버를 재확인하는 것이 중요합니다. 당신은 새 팔로워를 수동으로 승인하거나 거절하도록 설정을 변경할 수 있습니다. <em>해당 서버의 운영자는 서버가 받는 메시지를 열람할 수 있다는 것을 항상 염두해 두세요</em>, 그리고 수신자들은 스크린샷을 찍거나 복사하는 등의 방법으로 다시 공유할 수 있습니다. <em>위험한 정보를 마스토돈을 통해 공유하지 마세요.</em></li>
+      <li><em>IP와 기타 메타데이터</em>: 당신이 로그인 하는 경우 IP 주소와 브라우저의 이름을 저장합니다. 모든 세션은 당신이 검토하고 취소할 수 있도록 설정에서 제공 됩니다. 마지막으로 사용 된 IP 주소는 최대 12개월 간 저장됩니다. 또한, 모든 요청에 대해 IP주소를 포함한 정보를 로그에 저장할 수 있습니다.</li>
       </ul>
 
       <hr class="spacer" />
@@ -866,9 +932,9 @@ ko:
       <p>당신에게서 수집한 정보는 다음과 같은 곳에 사용 됩니다:</p>
 
       <ul>
-        <li>마스토돈의 주요 기능 제공. 다른 사람의 게시물에 상호작용 하거나 자신의 게시물을 작성하기 위해서는 로그인을 해야 합니다. 예를 들어, 다른 사람의 게시물을 자신만의 홈 타임라인에서 모아 보기 위해 팔로우를 할 수 있습니다.</li>
-        <li>커뮤니티의 모더레이션을 위해, 예를 들어 당신의 IP 주소와 기타 사항을 비교하여 금지를 우회하거나 다른 규칙을 위반하는지 판단하는 데에 사용할 수 있습니다.</li>
-        <li>당신이 제공한 이메일 주소를 통해 정보, 다른 사람들의 반응이나 받은 메시지에 대한 알림, 기타 요청 등에 관한 응답 요청 등을 보내는 데에 활용됩니다.</li>
+      <li>마스토돈의 주요 기능 제공. 다른 사람의 게시물에 상호작용 하거나 자신의 게시물을 작성하기 위해서는 로그인을 해야 합니다. 예를 들어, 다른 사람의 게시물을 자신만의 홈 타임라인에서 모아 보기 위해 팔로우를 할 수 있습니다.</li>
+      <li>커뮤니티의 모더레이션을 위해, 예를 들어 당신의 IP 주소와 기타 사항을 비교하여 금지를 우회하거나 다른 규칙을 위반하는지 판단하는 데에 사용할 수 있습니다.</li>
+      <li>당신이 제공한 이메일 주소를 통해 정보, 다른 사람들의 반응이나 받은 메시지에 대한 알림, 기타 요청 등에 관한 응답 요청 등을 보내는 데에 활용됩니다.</li>
       </ul>
 
       <hr class="spacer" />
@@ -884,8 +950,8 @@ ko:
       <p>우리는 다음을 위해 노력을 할 것입니다:</p>
 
       <ul>
-        <li>IP를 포함해 이 서버에 전송 되는 모든 요청에 대한 로그는 90일을 초과하여 저장되지 않습니다.</li>
-        <li>가입 된 유저의 IP 정보는 12개월을 초과하여 저장 되지 않습니다.</li>
+      <li>IP를 포함해 이 서버에 전송 되는 모든 요청에 대한 로그는 90일을 초과하여 저장되지 않습니다.</li>
+      <li>가입 된 유저의 IP 정보는 12개월을 초과하여 저장 되지 않습니다.</li>
       </ul>
 
       <p>당신은 언제든지 게시물, 미디어 첨부, 프로필 이미지, 헤더 이미지를 포함한 당신의 컨텐트에 대한 아카이브를 요청하고 다운로드 할 수 있습니다.</p>
@@ -931,8 +997,8 @@ ko:
       <p>Originally adapted from the <a href="https://github.com/discourse/discourse">Discourse privacy policy</a>.</p>
     title: "%{instance} 이용약관과 개인정보 취급 방침"
   themes:
-    contrast: 고대비
-    default: 마스토돈
+    contrast: 마스토돈 (고대비)
+    default: 마스토돈 (어두움)
     mastodon-light: 마스토돈 (밝음)
   time:
     formats:
@@ -982,7 +1048,7 @@ ko:
       final_action: 포스팅 시작하기
       final_step: '포스팅을 시작하세요! 팔로워가 없더라도 퍼블릭 메시지는 다른 사람들이 볼 수 있습니다, 예를 들면 로컬 타임라인이나 해시태그에서요. 사람들에게 자신을 소개하고 싶다면 #introductions 해시태그를 이용해보세요.'
       full_handle: 당신의 풀 핸들
-      full_handle_hint: 이것을 당신의 친구들에게 알려주면 다른 인스턴스에서 팔로우 하거나 메시지를 보낼 수 있습니다.
+      full_handle_hint: 이것을 당신의 친구들에게 알려주면 다른 서버에서 팔로우 하거나 메시지를 보낼 수 있습니다.
       review_preferences_action: 설정 바꾸기
       review_preferences_step: 당신의 설정을 확인하세요. 어떤 이메일로 알림을 받을 것인지, 기본적으로 어떤 프라이버시 설정을 사용할 것인지, 멀미가 없다면 GIF를 자동 재생하도록 설정할 수도 있습니다.
       subject: 마스토돈에 오신 것을 환영합니다
diff --git a/config/locales/lt.yml b/config/locales/lt.yml
new file mode 100644
index 0000000000000000000000000000000000000000..2cf0b7c42bfd9b1acc055b856cc5fa760701c771
--- /dev/null
+++ b/config/locales/lt.yml
@@ -0,0 +1,883 @@
+---
+lt:
+  about:
+    about_hashtag_html: Čia visiems prieinamas įrankis <strong>#%{hashtag}</strong>. Jūs galite juo naudotis bet kur, jeigu turite paskyra fedi-visatoje.
+    about_mastodon_html: Mastodon, tai socialinis tinklas pagrįstas atviro kodo programavimu, ir atvirais web protokolais. Visiškai nemokamas. Ši sistema decantrilizuota kaip jūsų elektroninis paštas.
+    about_this: Apie
+    administered_by: 'Administruoja:'
+    apps: Mobilioji Aplikacija
+    contact: Kontaktai
+    contact_missing: Nenustatyta
+    documentation: Dokumentacija
+    extended_description_html: |
+      <h3>TaisyklÄ—s</h3>
+      <p>Ilgas aprašymas dar nėra sudartyas</p>
+    generic_description: "%{domain} yra vienas serveris tinkle"
+    hosted_on: Mastodon palaikomas naudojantis %{domain} talpinimu
+    learn_more: Daugiau
+    privacy_policy: Privatumo Politika
+    source_code: Å altinio kodas
+    status_count_before: Autorius
+    terms: Naudojimo sÄ…lygos
+    user_count_before: Namai
+    what_is_mastodon: Kas tai, Mastodon?
+  accounts:
+    choices_html: "%{name} pasirinkimai:"
+    follow: Sekti
+    following: Sekami
+    joined: Prisijungiai %{date}
+    last_active: paskutinį kartą aktyvus
+    link_verified_on: Nuorodos nuosavybė paskutinį kartą tikrinta %{date}
+    media: Medija
+    moved_html: "%{name} persikėlė į %{new_profile_link}:"
+    network_hidden: Å i informacija neprieinama
+    nothing_here: ÄŒia nieko nÄ—ra!
+    people_followed_by: Žmonės, kuriuos %{name} seka
+    people_who_follow: Žmonės kurie seka %{name}
+    pin_errors:
+      following: Privalai sekti žmogų kurį nori pagerbti
+    posts_tab_heading: Tootai
+    posts_with_replies: Tootai ir atsakymai
+    reserved_username: Vartotojo vardas rezervuotas
+    roles:
+      admin: Administratorius
+      bot: Bot'as
+      moderator: Moderatorius
+    unfollow: Nesekti
+  admin:
+    account_actions:
+      action: Veiksmas
+      title: Moderuoti %{acct}
+    account_moderation_notes:
+      create: Palikti žinutę
+      created_msg: Moderavimo žinutė sėkimngai sukurta!
+      delete: Ištrinti
+      destroyed_msg: Moderacijos žinutė sėkmingai ištrinta!
+    accounts:
+      are_you_sure: Ar esate įsitikinęs?
+      avatar: Profilio nuotrauka
+      by_domain: Domenas
+      change_email:
+        changed_msg: Paskyros el paštas sėkmingai pakeistas!
+        current_email: Dabartinis el paštas
+        label: Pakeisti el pašto adresą
+        new_email: Naujas el pašto adresas
+        submit: Pakeisti el pašto adresą
+        title: Pakeisti el pašto adresą vartotojui %{username}
+      confirm: Patvirtinti
+      confirmed: Patvirtinta
+      confirming: Tvirtinama
+      deleted: Ištrinti
+      demote: Pažeminti
+      disable: Išjungti
+      disable_two_factor_authentication: Išjungti 2 faktorių autentifikaciją
+      disabled: Išjungta
+      display_name: Matomas vardas
+      domain: Domenas
+      edit: Keisti
+      email: El paštas
+      email_status: El pašto statusas
+      enable: Įjungti
+      enabled: Įjungta
+      feed_url: Srauto URL
+      followers: SekÄ—jai
+      followers_url: Sekėjų URL
+      follows: Seka
+      header: Antraštė
+      inbox_url: Gautųjų URL
+      invited_by: PakvietÄ—
+      joined: PrisijungÄ—
+      location:
+        all: Visi
+        local: Lokali
+        remote: Nuotolinis
+        title: Lokacija
+      login_status: Prisijungimo statusas
+      media_attachments: Prisegti medijos failai
+      memorialize: Paversti į memorija
+      moderation:
+        active: Aktyvus
+        all: Visi
+        silenced: Užtildytas
+        suspended: Užrakintas
+        title: Moderacija
+      moderation_notes: Medaracijos žinutės
+      most_recent_activity: Paskutinioji veikla
+      most_recent_ip: Paskutinis IP
+      no_limits_imposed: Be limitu
+      not_subscribed: Ne prenumeruota
+      outbox_url: Išsiustųjų URL
+      perform_full_suspension: Užrakinti
+      profile_url: Profilio URL
+      promote: Paaukštinti
+      protocol: Protokolas
+      public: Viešas
+      push_subscription_expires: PuSH prenumeramivas pasibaigÄ—
+      redownload: Perkrauti profilį
+      remove_avatar: Panaikinti profilio nuotraukÄ…
+      remove_header: Panaikinti antraštę
+      resend_confirmation:
+        already_confirmed: Å is vartotojas jau patvirtintas
+        send: Dar kartą išsiųsti patvirtinimo žinutę
+        success: Patvirtinimo laiškas sėkmingai išsiųstas!
+      reset: IÅ¡ naujo
+      reset_password: Atkurti slaptažodį
+      resubscribe: Per prenumeruoti
+      role: Leidimai
+      roles:
+        admin: Administratorius
+        moderator: Moderatorius
+        staff: Personalas
+        user: Vartotojas
+      salmon_url: Lašišos URL
+      search: Ieškoti
+      shared_inbox_url: Bendroji gautųjų URL
+      show:
+        created_reports: Parašyti raportai
+        targeted_reports: Reportuotas kitų
+      silence: Tyla
+      silenced: Užtildytas
+      statuses: Statusai
+      subscribe: Prenumeruoti
+      suspended: Užrakintas
+      title: Vartotojai
+      unconfirmed_email: Nepatvirtintas el pašto adresas
+      undo_silenced: Atšaukti užtildymą
+      undo_suspension: Atšaukti užrakinimą
+      unsubscribe: Nebeprenumeruoti
+      username: Slapyvardis
+      warn: Įspėti
+    action_logs:
+      actions:
+        assigned_to_self_report: "%{name} paskyrÄ— reportÄ… %{target} saviems"
+        change_email_user: "%{name} pakeitė el pašto adresą vartotojui %{target}"
+        confirm_user: "%{name} patvirtino el pašto adresą vartotojui %{target}"
+        create_account_warning: "%{name} išsiuntė įspėjimą %{target}"
+        create_custom_emoji: "%{name} įkėlė naują jaustuką %{target}"
+        create_domain_block: "%{name} užblokavo domena %{target}"
+        create_email_domain_block: "%{name} įkėlė į juodajį sąrašą el pašto domena %{target}"
+        demote_user: "%{name} pažemino %{target}"
+        destroy_custom_emoji: "%{name} sunaikino jaustukÄ… %{target}"
+        destroy_domain_block: "%{name} atrakino domenÄ… %{target}"
+        destroy_email_domain_block: "%{name} pašalino iš juodojo sąrašo el pašto domeną %{target}"
+        destroy_status: "%{name} pašalino statusą %{target}"
+        disable_2fa_user: "%{name} išjungė 2 faktorių autentikavimo sistemos reikalavimus vartotojui  %{target}"
+        disable_custom_emoji: "%{name} išjungė jaustuką %{target}"
+        disable_user: "%{name} išjungė prisijungimą vartotojui %{target}"
+        enable_custom_emoji: "%{name} įjungė jaustuką %{target}"
+        enable_user: "%{name} įjungė prisijungimą vartotojui %{target}"
+        memorialize_account: "%{name} pavertė vartotojo %{target} paskyrą į prisiminimų puslapį"
+        promote_user: "%{name} paaukštino vartotoją %{target}"
+        remove_avatar_user: "%{name} panaikino vartotojo %{target} profilio nuotraukÄ…"
+        reopen_report: "%{name} atidarÄ— skundÄ… %{target}"
+        reset_password_user: "%{name} atstatyti slaptažodį vartotojui %{target}"
+        resolve_report: "%{name} išsprendė skundą %{target}"
+        silence_account: "%{name} pritildÄ— vartotojo %{target} paskyrÄ…"
+        suspend_account: "%{name} laikinai užblokavo vartotojo %{target} paskyrą"
+        unassigned_report: "%{name} nepaskirtas skundas %{target}"
+        unsilence_account: "%{name} atitildÄ— vartotojo %{target} paskyrÄ…"
+        unsuspend_account: "%{name} atblokavo vartotojo %{target} paskyrÄ…"
+        update_custom_emoji: "%{name} atnaujino jaustukÄ… %{target}"
+        update_status: "%{name} pakeitÄ— statusÄ… %{target}"
+      deleted_status: "(panaikintas statusas)"
+      title: Audito žurnalas
+    custom_emojis:
+      by_domain: Domenas
+      copied_msg: SÄ—kmingai sukurta lokali jaustuko kopija
+      copy: Kopijuoti
+      copy_failed_msg: Lokali jaustuko kopija negalėjo būti sukurta
+      created_msg: Jaustukas sukurtas sÄ—kmingai!
+      delete: Ištrinti
+      destroyed_msg: Jaustukas sÄ—kmingai sunaikintas!
+      disable: Išjungti
+      disabled_msg: Šis jaustukas sėkmingai išjungtas
+      emoji: Jaustukas
+      enable: Įjungti
+      enabled_msg: Šis jaustukas sėkmingai įjungtas
+      image_hint: PNG failo dydis iki 50KB
+      listed: Įtrauktas į sąrašą
+      new:
+        title: PridÄ—ti naujÄ… jaustukÄ…
+      overwrite: Perrašyti
+      shortcode: Trumpas-kodas
+      shortcode_hint: Bent du ženklai, tik raidiniai skaitmeniniai ženklai bei akcentai(_)
+      title: Asmeniniai jaustukai
+      unlisted: Neįtrauktas į sąrašą
+      update_failed_msg: Jaustukas negalėjo būti pakeistas
+      updated_msg: Jaustukas sÄ—kmingai pakeistas!
+      upload: Įkelti
+    dashboard:
+      backlog: Neatlikti darbai
+      config: Konfiguracija
+      feature_deletions: Paskyrų šalinimas
+      feature_invites: Pakivetimo nuorodos
+      feature_profile_directory: Profilio direktorija
+      feature_registrations: Registracijos
+      feature_relay: Federacijos perjungÄ—jas
+      features: Išskirtinumai
+      hidden_service: Federacija su paslÄ—ptomis paslaugomis
+      open_reports: atidaryti skundai
+      recent_users: Neseni vartotojai
+      search: Pilno teksto paieška
+      single_user_mode: Vieno vartotojo būsena
+      software: Programinė įranga
+      space: Naudojama atmintis
+      title: Pagrindinis puslapis
+      total_users: viso vartotoju
+      trends: Tendencijos
+      week_interactions: naudojimai šią savaitę
+      week_users_active: aktyvūs šią savaitę
+      week_users_new: vartotojai šią savaitę
+    domain_blocks:
+      add_new: PridÄ—ti naujÄ… domeno blokÄ…
+      created_msg: Domeno užblokavimas nagrinėjamas
+      destroyed_msg: Domeno blokas pašalintas
+      domain: Domenas
+      new:
+        create: Sukurti blokÄ…
+        hint: Domeno blokavimas nesustabdys vartotojų paskyrų sukūrimo duomenų sistemoje, tačiau automatiškai pritaikys atitinkamus moderavimo metodus šioms paskyroms.
+        severity:
+          desc_html: |-
+            <strong>1Tyla</strong>2 padarys paskyros įkelimus nematomus visiems, kurie jų neseka.
+            <strong>3Draudimas</strong>4 panaikins visus paskyros įkėlimus ir profilio informaciją.Naudok<strong>5Nieko</strong>6 jeigu tiesiog norite atmesti medijos failus.
+          noop: Nieko
+          silence: Tyla
+          suspend: Draudimas
+        title: Naujos domeno blokas
+      reject_media: Atmesti medijos failai
+      reject_media_hint: Panaikina lokaliai saugomus medijos failus bei atsisako jų parsisiuntimo ateityje. Neliečia užblokavimu
+      reject_reports: Atmesti skundai
+      reject_reports_hint: Ignoruoti visus skundus, kurie siunčiami iš šio domeno. Neliečia užblokavimu
+      rejecting_media: atmetami medijos failai
+      rejecting_reports: atmetami skundai
+      severity:
+        silence: užtildytas
+        suspend: uždraustas
+      show:
+        retroactive:
+          silence: Atitildyti visus egzistuojančius vartotojus šiame domene
+          suspend: Atblokuotis visus egzistuojančius vartotojus šiame domene
+        title: Atkurti domeno blokavimÄ… domenui %{domain}
+        undo: Atkurti
+      undo: Atkurti domeno blokÄ…
+    email_domain_blocks:
+      add_new: PridÄ—ti naujÄ…
+      created_msg: El pašto domenas sėkmingai pridėtas į juodąjį sąrašą
+      delete: Ištrinti
+      destroyed_msg: El pašto adresas sėkmingai pašalintas iš juodojo sąrašo
+      domain: Domenas
+      new:
+        create: PridÄ—to domenÄ…
+        title: Naujas el pašto juodojo sąrašo įtraukimas
+      title: El pašto juodasis sąrašas
+    followers:
+      back_to_account: Atgal Ä® PaskyrÄ…
+      title: "%{acct} SekÄ—jai"
+    instances:
+      by_domain: Domenas
+      delivery_available: Pristatymas galimas
+      moderation:
+        all: Visi
+        limited: Limituotas
+        title: Moderacija
+      title: Federacija
+      total_blocked_by_us: Mes užblokavome
+      total_followed_by_them: Jų sekami
+      total_followed_by_us: Mūsų sekami
+      total_reported: Skundai apie juos
+      total_storage: Medijos prisegti failai
+    invites:
+      deactivate_all: Deaktyvuoti visus
+      filter:
+        all: Visi
+        available: Prieinamas
+        expired: Pasibaigęs
+        title: Filtras
+      title: Pakvietimai
+    relays:
+      add_new: PridÄ—ti naujÄ… pamainÄ…
+      delete: Ištrinti
+      description_html: "<strong>Federacijos perjungėjas</strong> tai tarpinis serveris, kuris apsikeičia didelios apimties informacija tarp kitų serverių. <strong> Tai gali padėti mažesniems serveriams atrasti turinį iš fedi-visatos</strong>, kuris kitaip reikalautų vartotojų lokaliai sekti kitus žmones naudojantis kitus tolimus serverius."
+      disable: Išjungti
+      disabled: Išjungtas
+      enable: Įjungti
+      enable_hint: Kai įjungta, Jūsų serveris prenumeruos visas viešas žinutes iš šio tinklo, ir pradės siųsti šio serverio viešas žinutes į tinklą.
+      enabled: Įjungtas
+      inbox_url: Perdavimo URL
+      pending: Laukiama perdavimo patvirtinimo
+      save_and_enable: Išsaugoti ir įjungti
+      setup: Sukurti perdavimo ryšį
+      status: Statusas
+      title: Perdavimai
+    report_notes:
+      created_msg: Skundo žinutė sekmingai sukurta!
+      destroyed_msg: Skundo žinutė sekmingai ištrinta!
+    reports:
+      account:
+        note: raštelis
+        report: skundas
+      action_taken_by: Veiksmo Ä—mÄ—si
+      are_you_sure: Ar tu įsitikinęs?
+      assign_to_self: Paskirti man
+      assigned: Paskirtas moderatorius
+      comment:
+        none: NÄ—ra
+      created_at: Reportuotas
+      mark_as_resolved: Pažymėti kaip išsprestą
+      mark_as_unresolved: Pažymėti kaip neišsprestą
+      notes:
+        create: Pridėti raštelį
+        create_and_resolve: Išspręsti su rašteliu
+        create_and_unresolve: Atidaryti su rašteliu
+        delete: Ištrinti
+        placeholder: Apibūdink, kokių veiksmų imtasi arba kitokie atnaujinimai..
+      reopen: Atidaryti skundÄ…
+      report: 'Skundas #%{id}'
+      reported_account: Reportuota paskyra
+      reported_by: Skundas sukurtas
+      resolved: Išspręsta
+      resolved_msg: Skundas sėkmingai įšspręstas!
+      status: Statusas
+      title: Skundai
+      unassign: Nepriskirti
+      unresolved: Neišspręsti
+      updated_at: Atnaujinti
+    settings:
+      activity_api_enabled:
+        desc_html: Skaičiai lokaliai įkeltų statusų, aktyvių vartotojų ir naujų registracijų, kas savaitiniuose atnaujinimuose
+        title: Paskelbti agreguotÄ… statistikÄ… apie vartotojo veiklÄ…
+      bootstrap_timeline_accounts:
+        desc_html: Atskirti vartotojų vardus naudojant kablelį (,). Tik lokalios ir neužblokuotos paskyros veiks. Pradinis kai tuščia, visi lokalūs administratoriai.
+        title: Numatyti sekimai naujiems vartotojams
+      contact_information:
+        email: Verslo el paštas
+        username: Kontaktinis slapyvardis
+      custom_css:
+        desc_html: Pakeisk išvaizdą su CSS užkraunamu kiekviename puslapyje
+        title: Asmeninis CSS
+      hero:
+        desc_html: Rodomas pagrindiniame puslapyje. Bent 600x100px rekomenduojama. Kai nenustatyta, renkamasi numatytÄ… serverio nuotraukÄ…
+        title: Herojaus nuotrauka
+      mascot:
+        desc_html: Rodoma keleta puslapių. Bent 293×205px rekomenduoja. Kai nenustatyą, renkamasi numatytą varianta
+        title: Talismano nuotrauka
+      peers_api_enabled:
+        desc_html: Domeno vardai, kuriuos šis serveris sutiko fedi-visatoje
+        title: Paskelbti sąrašą atrastų serveriu
+      preview_sensitive_media:
+        desc_html: Nuorodų peržiūros kituose tinklalapiuose bus rodomos su maža nuotrauka, net jeigu failas parinktas kaip "jautraus turinio"
+        title: Rodyti jautrią informaciją OpenGraph peržiūrose
+      profile_directory:
+        desc_html: Leisti vartotojams būti atrastiems
+        title: Įjungti profilio direktorija
+      registrations:
+        closed_message:
+          desc_html: Rodoma pagrindiniame puslapyje, kuomet registracijos uždarytos. Jūs galite naudoti HTML
+          title: Uždarytos registracijos žinutė
+        deletion:
+          desc_html: Leisti visiems ištrinti savo paskyrą
+          title: Atidaryti paskyros trynimÄ…
+        min_invite_role:
+          disabled: Nei vienas
+          title: Leisti pakvietimus
+      show_known_fediverse_at_about_page:
+        desc_html: Kai įjungta, rodys įrašus iš visos žinomos fedi-visatos. Kitokiu atvėju, rodys tik lokalius įrašus.
+        title: Rodyti žinoma fedi-visatos laiko juosta peržiūroje
+      show_staff_badge:
+        desc_html: Rodyti personalo ženklelį vartotojo puslapyje
+        title: Rodyti personalo ženklelį
+      site_description:
+        desc_html: Introdukcinis paragrafas pagrindiniame puslapyje. Apibūdink, kas padaro šį Mastodon serverį išskirtiniu ir visa kita, kas svarbu. Nebijok naudoti HTML žymes, pavyzdžiui <code> &lt; a &gt;</code> bei <code>&lt;em&gt;</code>.
+        title: Serverio apibūdinimas
+      site_description_extended:
+        desc_html: Gera vieta Jūsų elgesio kodeksui, taisyklėms, nuorodms ir kitokiai informacijai, kuri yra išskirtinė Jūsų serveriui. Galite naudoti HTML žymes
+        title: Išsamesnė išskirtine informacija
+      site_short_description:
+        desc_html: Rodoma šoniniame meniu ir meta žymėse. Apibūdink kas yra Mastodon, ir kas daro šį serverį išskirtiniu, vienu paragrafu. Jeigu tuščias, naudojamas numatytasis tekstas.
+        title: Trumpas serverio apibūdinimas
+      site_terms:
+        desc_html: Jūs galite parašyti savo pačio privatumo politika, naudojimo sąlygas ar kita informacija. Galite naudoti HTML žymes
+        title: Išskirtinės naudojimosi taisyklės
+      site_title: Serverio pavadinimas
+      thumbnail:
+        desc_html: Naudojama OpenGraph peržiūroms ir API. Rekomenduojama 1200x630px
+        title: Serverio miniatūra
+      timeline_preview:
+        desc_html: Rodyti viešą laiko juostą apsilankymo puslapyje
+        title: Laiko juostos peržiūra
+      title: Tinklalapio nustatymai
+    statuses:
+      back_to_account: Atgal į paskyros puslapį
+      batch:
+        delete: Ištrinti
+        nsfw_off: Pažymėti kaip ne jautrią informaciją
+        nsfw_on: Pažymėti kaip jautrią informaciją
+      failed_to_execute: NesÄ—kmingas veiksmas
+      media:
+        title: Medija
+      no_media: NÄ—ra medijos
+      no_status_selected: Jokie statusai nebuvo pakeisti, nes niekas nepasirinkta
+      title: Paskyros statusai
+      with_media: Su medija
+    subscriptions:
+      callback_url: AtgalinÄ— URL
+      confirmed: Patvirtinta
+      expires_in: Pasibaigia
+      last_delivery: Paskutinis pristatymas
+      title: WebSub protokolas
+      topic: Tema
+    tags:
+      accounts: Paskyros
+      hidden: PaslÄ—pti
+      hide: Paslėpti iš direktorijos
+      name: Saitažodis(#)
+      title: Saitažodžiai(#)
+      unhide: Rodyti direktorijoje
+      visible: Matomas
+    title: Administracija
+    warning_presets:
+      add_new: PridÄ—ti naujÄ…
+      delete: Ištrinti
+      edit: Keisti
+      edit_preset: Keisti įspėjimo nustatymus
+      title: Valdyti įspėjimo nustatymus
+  admin_mailer:
+    new_report:
+      body: "%{reporter} parašė skundą apie %{target}"
+      body_remote: Kažkas iš %{domain} parašė skundą apie %{target}
+      subject: Naujas skundas %{instance} (#%{id})
+  application_mailer:
+    notification_preferences: Keisti el pašto parinktis
+    settings: 'Keisti el pašto parinktis: %{link}'
+    view: 'Peržiūra:'
+    view_profile: Peržiurėti profilį
+    view_status: Peržiūrėti statusą
+  applications:
+    created: Aplikacija sÄ—kmingai sukurta
+    destroyed: Aplikacija sėkmingai ištrinta
+    invalid_url: Gauta URL nuoroda netinkama
+    regenerate_token: Regeneruoti prieigos žetoną
+    token_regenerated: Prieigos žetonas sėkmingai sugeneruotas
+    warning: Būkite atsargūs su šia informacija. Niekada jos nesidalinkite!
+    your_token: Jūsų prieigos žetonas
+  auth:
+    change_password: Slaptažodis
+    confirm_email: Patvirtinti el paštą
+    delete_account: Ištrinti paskyrą
+    delete_account_html: Jeigu norite ištrinti savo paskyrą, galite eiti <a href="%{path}">čia</a>. Jūsų prašys patvirtinti pasirinkimą.
+    didnt_get_confirmation: Negavote patvirtinimo instrukcijų?
+    forgot_password: Pamiršote slaptažodį?
+    invalid_reset_password_token: Slaptažodžio atkūrimo žetonas netinkamas arba jo galiojimo laikas pasibaigęs. Prašykite naujo žetono.
+    login: Prisijungti
+    logout: Atsijungti
+    migrate_account: Prisijungti prie kitos paskyros
+    migrate_account_html: Jeigu norite nukreipti šią paskyrą į kita, galite tai <a href="%{path}">konfiguruoti čia</a>.
+    or_log_in_with: Arba prisijungti su
+    register: Užsiregistruoti
+    resend_confirmation: Išsiųsti dar kartą patvirtinimo instrukcijas
+    reset_password: Atstatyti slaptažodį
+    security: Apsauga
+    set_new_password: Nustatyti naują slaptažodį
+  authorize_follow:
+    already_following: Jūs jau sekate šią paskyrą
+    error: Dėja, aptikta klaida ieškant tolimosios paskyros
+    follow: Sekti
+    follow_request: 'Jūs išsiuntėte sekimo prašymą:'
+    following: 'Puiku! Jūs pradėjote sekti:'
+    post_follow:
+      close: Arba, Jūs galite uždaryti šį langą.
+      return: Rodyti vartotojo paskyrÄ…
+      web: Eiti į
+    title: Sekti %{acct}
+  datetime:
+    distance_in_words:
+      about_x_hours: "%{count} val"
+      about_x_months: "%{count}mÄ—n"
+      about_x_years: "%{count}met"
+      almost_x_years: "%{count}met"
+      half_a_minute: KÄ… tik
+      less_than_x_minutes: "%{count}min"
+      less_than_x_seconds: KÄ… tik
+      over_x_years: "%{count}met"
+      x_days: "%{count}dien"
+      x_minutes: "%{count}min"
+      x_months: "%{count}mÄ—n"
+      x_seconds: "%{count}sek"
+  deletes:
+    bad_password_msg: Geras bandymas, programišiau! Neteisingas slaptažodis
+    confirm_password: Kad patvirtintumėte savo tapatybę, įveskite dabartini slaptažodį
+    description_html: Tai <strong>be sugrąžinimo, visam laikui</strong> panaikins visa turini iš Jūsų paskyros ir deaktyvuos ją. Jūsų vartotojo vardas paliks rezervuotas, kad išvengtumėme tapatybės pavagimo ateityje.
+    proceed: Ištrinti paskyrą
+    success_msg: Jūsų paskyra sėkmingai ištrinta
+    warning_html: Tiktai panaikinimas turinio iš šio serverio garantuotas. Turinys, kuris buvo viešai prieinamas ir dalinamas kituose serveriuose paliks pėdsakus. Serveriai, kurie neseka jūsų, kurie nėra tinkle, nepakeis savo duomenų sistemos.
+    warning_title: Platinamo turinio prieinamumas
+  directories:
+    directory: Profilio direktorija
+    enabled: Jūs esate rodomas šioje direktorijoje.
+    enabled_but_waiting: Jūs pasirinkote būti įtrauktas į direktorija, bet jūs neturite minimalaus sekėjų skaičiaus (%{min_followers}), kad būtumėte rodomas.
+    explanation: Raskite vartotojus, remiantis tuo, kuo jie domisi
+    explore_mastodon: Naršyti %{title}
+    how_to_enable: Jūs nesate prisijungęs prie šios direktorijos. Galite prisijungti žemiau. Naudokite saitažodžius savo biografiniame tekste, kad būtumėte rastas naudojantis specifinius saitažodžius!
+  errors:
+    '403': Jūs neturie prieigos matyti šiam puslapiui.
+    '404': Puslapis nerastas.
+    '410': Puslapis neegzistuoja.
+    '422':
+      content: Apsaugos patvirtinmas klaidingas. Ar jūs blokuojate sausainius?
+      title: Apsaugos patvirtinimas nepavyko
+    '429': Stabdomas
+    '500':
+      content: Atsiprašome, tačiau mūsų pusėje įvyko klaida.
+      title: Netinkamas puslapis
+    noscript_html: Kad naudotumėtės Mastodon web aplikacija, prašome įsijungti JavaScript. Alternatyviai, pabandykite viena iš <a href="%{apps_path}">vietinių aplikacijų</a> Mastodon savo platformai.
+  exports:
+    archive_takeout:
+      date: Data
+      download: Parsisiųsti archyvą
+      hint_html: Jūs galite prašyti savo <strong>įrašų bei medijos</strong> archyvo. Eksportuota informacija bus ActivityPub formatu, skaitoma suderintų programų. Galite prašyti archyvo, kas 7 dienas.
+      in_progress: Sudaromas archyvas...
+      request: Prašyti savo archyvo
+      size: Dydis
+    blocks: Jūs blokuojate
+    domain_blocks: Domeno blokai
+    follows: Jūs sekate
+    lists: Sąrašai
+    mutes: Jūs tildote
+    storage: Medijos sandÄ—lis
+  featured_tags:
+    add_new: PridÄ—ti naujÄ…
+    errors:
+      limit: Jūs jau naudojate maksimalų galimą saitažodžių(#) kiekį
+  filters:
+    contexts:
+      home: Namų laiko juosta
+      notifications: Priminimai
+      public: Viešos laiko juostos
+      thread: Pokalbiai
+    edit:
+      title: Keisti filtrÄ…
+    errors:
+      invalid_context: Jokio arba netinkamas pateiktas kontekstas
+      invalid_irreversible: Negrąžinamas filtras veikia tik namų ir priminimų kontekste
+    index:
+      delete: Ištrinti
+      title: Filtrai
+    new:
+      title: PridÄ—ti naujÄ… filtrÄ…
+  footer:
+    developers: Programuotojai
+    more: Daugiau…
+    resources: Resursai
+  generic:
+    changes_saved_msg: Pakeitimai sėkmingai išsaugoti!
+    copy: Kopijuoti
+    save_changes: Išsaugoti pakeitimus
+  imports:
+    modes:
+      merge: Sulieti
+      merge_long: Išsaugoti esančius įrašus ir pridėti naujus
+      overwrite: Perrašyti
+      overwrite_long: Pakeisti senus įrašus naujais
+    preface: Jūs galite importuoti informaciją iš kito serverio, tokią kaip sąrašą žmonių kuriuos sekate.
+    success: Jūsų informacija sėkmingai įkelta ir bus apdorota kaip įmanoma greičiau
+    types:
+      blocking: Blokuojamų sąrašas
+      domain_blocking: Domeno blokavimo sąrašas
+      following: Sekėju sąrašas
+      muting: Tildomų sąrašas
+    upload: Įkelti
+  in_memoriam_html: Atminimui.
+  invites:
+    delete: Deaktyvuoti
+    expired: Pasibaigęs
+    expires_in:
+      '1800': 30 minučių
+      '21600': 6 valandų
+      '3600': 1 valandos
+      '43200': 12 valandų
+      '604800': 1 savaitÄ—s
+      '86400': 1 dienos
+    expires_in_prompt: Niekada
+    generate: Generuoti
+    invited_by: 'Jus pakvietÄ—:'
+    max_uses_prompt: Be limito
+    prompt: Generuoti ir dalintis įrašais su kitais, kad sukurti prieigą prie serverio
+    table:
+      expires_at: Pasibaigia
+      uses: Naudojimai
+    title: Pakviesti žmones
+  lists:
+    errors:
+      limit: Jūs pasieketė maksimalų sąrašų skaičių
+  media_attachments:
+    validations:
+      images_and_video: Negalima pridÄ—ti video prie statuso, kuris jau turi nuotraukÄ…
+      too_many: Negalima pridėti daugiau nei 4 failų
+  migrations:
+    acct: slapyvardis@domenas naujam vartotojui
+    currently_redirecting: 'Jūsų profilis nustatytas nukreipimui į:'
+    proceed: Išsaugoti
+    updated_msg: Jūsų paskyros migracijos nustatymai sėkmingai pakeisti!
+  moderation:
+    title: Moderacija
+  notification_mailer:
+    digest:
+      action: Peržiurėti visus pranešimus
+      body: Čia yra trumpa santrauka žinutės, kurią jūs praleidote nuo jūsų paskutinio apsilankymo %{since}
+      mention: "%{name} paminÄ—jo jus:"
+      title: Kol jūsų nebuvo...
+    favourite:
+      body: 'Jūsų statusą pamėgo %{name}:'
+      subject: "%{name} pamėgo Jūsų statusą"
+      title: Naujas mÄ—gstamas
+    follow:
+      body: "%{name} pradÄ—jo jus sekti!"
+      subject: "%{name} pradÄ—jo jus sekti"
+      title: Naujas sekÄ—jas
+    follow_request:
+      action: Tvarkyti prašymus sekti
+      body: "%{name} nori tapti Jūsų sekėju"
+      subject: 'Laukiantis sprendimo sekÄ—jas:  %{name}'
+      title: Naujas prašymas sekti
+    mention:
+      action: Atsakyti
+      body: 'Jus paminėjo %{name} pranešime:'
+      subject: Jus paminÄ—jo %{name}
+      title: Naujas paminÄ—jimas
+    reblog:
+      body: 'Jūsų statusą pakėlė %{name}:'
+      subject: "%{name} pakėlė Jūsų statusą"
+      title: Naujas pakÄ—limas
+  pagination:
+    newer: Naujesnis
+    next: Kitas
+    older: Senesnis
+    prev: Ankstesnis
+  preferences:
+    other: Kita
+  remote_follow:
+    acct: Įveskite Jūsų slapyvardį@domenas kurį norite naudoti
+    missing_resource: Jūsų paskyros nukreipimo URL nerasta
+    no_account_html: Neturite paskyros? Jūs galite<a href='%{sign_up_path}' target='_blank'> užsiregistruoti čia </a>
+    proceed: Sekti
+    prompt: 'Jūs seksite:'
+    reason_html: "<strong>Kodėl šis žingsnis svarbus?</strong><code>%{instance}</code> gali būti serveris, kuriame jūs nesate užsiregistravęs, todėl mes turime jus nukreipti į Jūsų namų serveri."
+  remote_interaction:
+    favourite:
+      proceed: PamÄ—gti
+      prompt: 'Jūs norite pamėgti šį toot''ą:'
+    reblog:
+      proceed: Pakelti
+      prompt: 'Jūs norite pakelti šį toot''ą:'
+    reply:
+      proceed: Atsakyti
+      prompt: 'Jūs norite atsakyti šiam toot''ui:'
+  remote_unfollow:
+    error: Klaida
+    title: Pavadinimas
+    unfollowed: Nebesekama
+  scheduled_statuses:
+    over_daily_limit: Jūs pasieketė limitą (%{limit}) galimų toot'ų per dieną
+    over_total_limit: Jūs pasieketė %{limit} limitą galimų toot'ų
+    too_soon: Planuota data privalo būti ateityje
+  sessions:
+    activity: PaskutinÄ— veikla
+    browser: Naršyklė
+    browsers:
+      generic: Nežinoma naršyklė
+    current_session: DabartinÄ— sesija
+    description: "%{browser} ant %{platform}"
+    explanation: Čia rodomos web naršyklės prijungtos prie Jūsų Mastodon paskyros.
+    platforms:
+      other: nežinoma platforma
+    revoke: Atšaukti
+    revoke_success: Sesija sėkmingai atšaukta
+    title: Sesijos
+  settings:
+    authorized_apps: Autorizuotos aplikacijos
+    back: Atgal į Mastodon
+    delete: Paskyros trynimas
+    development: PlÄ—tojimas
+    edit_profile: Keisti profilį
+    export: Informacijos eksportas
+    featured_tags: Rodomi saitažodžiai(#)
+    import: Importuoti
+    migrate: Paskyros migracija
+    notifications: Pranešimai
+    preferences: Preferencijos
+    two_factor_authentication: Dviejų veiksnių autentikacija
+  statuses:
+    attached:
+      description: 'PridÄ—ta: %{attached}'
+    boosted_from_html: Pakelta iš %{acct_link}
+    content_warning: 'Turinio įspėjimas: %{warning}'
+    language_detection: Automatiškai nustatyti kalbą
+    open_in_web: Atidaryti naudojan Web
+    over_character_limit: pasiektas %{max} simbolių limitas
+    pin_errors:
+      limit: Jūs jau prisegėte maksimalų toot'ų skaičų
+      ownership: Kitų vartotojų toot'ai negali būti prisegti
+      private: Ne vieši toot'ai negali būti prisegti
+      reblog: Pakeltos žinutės negali būti prisegtos
+    show_more: Daugiau
+    sign_in_to_participate: Prisijunkite jeigu norite dalyvauti pokalbyje
+    visibilities:
+      private: Tik sekÄ—jams
+      private_long: Rodyti tik sekÄ—jams
+      public: Viešas
+      public_long: Matyti gali visi
+      unlisted: Neįtrauktas į sąrašus
+      unlisted_long: Matyti gali visi, tačiau nėra įtraukta į viešas laiko juostas
+  stream_entries:
+    pinned: Prisegtas toot'as
+    reblogged: pakeltas
+    sensitive_content: Jautrus turinys
+  terms:
+    body_html: |
+      <h2>Privatumo politika</h2>
+      <h3 id="collect">Kokia informacija yra renkama?</h3>
+      <ul>
+      <li><em>Paprasa paskyros informacija</em>: Jeigu Jūs užsiregistruojate šiame serveryje, Jūsų gali paklausti, kad įrašytumėte slapyvardį, el pašto adresą ir paskyros slaptąžodį. Jūs irgi galite įrašyti papildomą profilio informaciją, tokią kaip rodomas vardas ir biografiją bei įkelti profilio nuotrauką ir antraštės nuotrauką. Slapyvardis , rodomas vardas, biografija, profilio nuotrauka ir antraštės nuotrauka visada viešai prieinama informacija.</li>
+      <li><em>Įrašai, sekami ir kita vieša informacija</em>: Sąrašas žmonių, kuriuos Jūs sekate yra matomas viešai, taip pat kaip ir Jūsų sekėjams. Kai Jūs išsiunčiate žinutę, data ir laikas yra išsaugomi bei aplikacija iš kurios jūs išsiuntėte žinutę. Žinutėse gali būti prisegtų medijos failų kaip vaizdo įrašai bei nuotraukos. Viešos ir neįtrauktos į sąrašus žinutės yra viešai prieinamos. Kai nusprendžiate rodyti pranešimą ant savo profilio, tai irgi yra viešai prieinama informacija. Jūsų pranešimai yra pristatomi Jūsų sekėjams, kai kuriais atvėjais tai gali reikšti, kad šie pranešimai yra pristatomi į kitus serverius ir saugomi ten. Kai Jūs ištrinate įrašus, šie įrašai ištrinami ir Jūsų sekėjams. Veiksmas pamėgti kitus įrašus irgi yra viešas.
+      </li><li><em>Tiesioginiai ir tik sekėjams įrašai</em>: Visi įrašai yra saugomi ir apdorojami serveryje. Tik sekėjams įrašai yra pristatomi Jūsų sekėjams ir vartotojams, kurie yra paminėti įrašuose, ir tiesioginiai įrašai pristatomi tik vartotojams, kurie yra paminėti įraše. Kai kuriais atvėjais tai gali reikšti, kad šie įrašai yra pristatomi į kitą serverį ir įrašų kopijos saugomos ten. Mes stengiames riboti prieigą prie šių pranešimų tiktai autorizuotiems gavėjams, tačiau kiti serveriai to gali nedaryti. Todėl yra svarbu peržiurėti serverius, kuriems Jūsų sekėjai priklauso. Jūs galite įjungti būseną nustatymuose, kad galėtumetė priimti arba atmesti naujas sekimo užklausas.<em> Prašome nepamiršti, kad serverio operatoriai ir kiti serveriai, kurie gauna šias žinutes, gali jas peržiurėti </em> bei, kad gavėjai gali padaryti foto kopija, tektso kopija ar kitaip pasidalinti Jūsų žinutėmis.<em> Nesidalinkite jokia jautria ar pavojinga informacija naudojantis Mastodon.</em></li>
+      <li><em>IP adresai ir kiti metaduomenys</em>: Kai prisijungiate, mes įrašome IP adresą iš kurio jūs prisijungėte, ir naudojamos naršyklės pavadinimą. Visos prisijungimo sesijos yra prieinamos Jūsų apžvalgai ir atšaukimams nustatymuose. Paskutiniai IP adresai yra saugomi iki 12-kos mėnesių. Mes taipogi galime pasilikti serverio registrą, kuriuose yra saugoma IP adresai iš visų bandymu prisijungti prie serverio prašant informacijos.
+      </li></ul>
+
+      <hr class="spacer" />
+
+      <h3 id="use">Kam mes naudojame Jūsų informaciją?</h3>
+      <p>Visa surinkta informacija apie jus, gali būti panaudota šiems tikslams: </p>
+      <ul>
+      <li>Suteikti pagrindį Mastodon funkcialumą. Jūs galite sąveikauti su kitų vartotojų turiniu ir kelti sąvajį, kuomet esate prisijungęs. Pavyzdžiui, galite sekti kitus žmones, peržiūrėti jų sujungtus įrašus savo pačio personalizuotoje laiko juostoje. </li>
+      <li>Padėti bendruomenės moderavimui, pavyzdžiui, lyginant Jūsų IP adresą, su kitu žinomu IP adresu, kad nustatyti bandymus vengti užblokavimo.</li>
+      <li>Jūsų el pašto adresas gali būti naudojamas išsiųsti informacija jums, priminimus apie kitų vartotojų interakciją su jūsų paskyra, pavyzdžiui, kai jie jums siunčia žinutes, ir atsakyti į užklausas ir/arba kitais klausimais. </li>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="protect">Kaip mes saugome Jūsų informacija? </h3>
+
+      <p>Mes implementavome saugumo priemones, tam, kad apsaugotume Jūsų privačią informaciją. Tarp šių dalykų, Jūsų naršyklės sesija, taip pat ir eismas tarp Jūsų aplikacijos ir API yra apsaugoti SSL, ir Jūsų slaptažodis yra užsifruotas sudėtingu algoritmu. Jūs galite įjungti dviejų veiksnių autentikaciją savo paskyrai, taip apsaugodami ją dar daugiau.
+      </p>
+
+      <hr class="spacer" />
+      <h3 id="data-retention"> Kokia yra mūsų duomenų laikymo politika? </h3>
+
+      <p>Mes stengiamÄ—s:</p>
+
+      <ul>
+      <li> Išsaugoti serverio registrą, kuriame yra visi IP adresai, kurie kreipėsi į serverį, šie duomenys laikomi neilgiau nei 90 dienų.</li>
+      <li> Išsaugoti IP adresus asocijuotus su registruotais vartotojais, ne ilgiau nei 12 mėnesių.</li>
+      </ul>
+
+      <p> Jūs galite pateikti prašymą ir parsisiųsti savo turinio archyvą, kuriame bus Jūsų įrašai, medijos failai, profilio nuotrauka ir antraštės nuotrauka.</p>
+
+      <p> Jūs galite VISIŠKAI ištrinti savo paskyrą bet kuriuo metu.</p>
+
+      <hr class="spacer"/>
+
+      <h3 id="cookies">Ar mes naudojame sausainiukus?</h3>
+
+      <p> Taip. Sausainiukai yra mažos apimties failai, kuriuos svetainė arba svetainės tiekėjas perkelia į Jūsų kompiuterio kietąjį diską naudojantis interneto naršykle (jeigu jūs leidžiate). Šie sausainiai leidžia svetainiai prisiminti Jūsų naršyklę ir jeigu turite registruotą vartotoją, ji asocijuoti su Jūsu vartotoju.</p>
+      <p>Mes naudojame sausainius, kad suprastumėme ir išsaugotumėme Jūsų poreikius kitam apsilankymui.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="disclose">Ar mes atskleidžiame Jūsų informacija kitoms šalims?</h3>
+
+      <p>Mes neparduodame, nesikeičiame, ar kitaip mainomės Jūsų privačiais duomenimis su trečiosiomis šalimis. Į šį sąrašą neįeina patikimos trečiosios šalys, kurios padeda mums naudotis tinklalapiu, daryti verslą, ar padėti jums, tol, kol šios šalys sutinka laikyti šią informaciją konfidencialiai. Mes taippat galime paviešinti Jūsų informaciją, jeigu manome, kad Jūs pažeidėte įstatymus, naudojimosi politiką, ar apsaugoti, ginti Jūsų, mūsų ar kitų teises. </p>
+
+      <p>Jūsų vieši duomenys gali būti atsisiųsti kitų serverių esančių tinkle. Jūsų vieši bei tik sekėjams skirti įrašai pristatomi serveriams, kuriuose Jūsų sekėjai egzistuoja, o tiesioginės žinutės pristatomos tiesiai į gavėjo serverį, tol, kol šie sekėjai ar gavėjai yra naudotojai iš kitų serverių. </p>
+
+      <p>Kai jūs patvirtinate Jūsų paskyros naudojimą aplikacijai, atitinkamai priklausant nuo leidimų, kuriuos jūs suteikėte, aplikacija turi prieiga prie Jūsų viešojo profilio informacijos, Jūsų sekėjų sąrašo, sekamų sąrašo, visų Jūsų įrašų, ir pamėgtų įrašų.
+      Aplikacijos niekada negali turėti prieigos prie Jūsų el pašto adreso arba slaptažodžio.</p>
+
+      <hr class="spacer" />
+
+
+      <h3 id="children">Tinklalapio naudojimas nepilnamečiams</h3>
+
+      <p> Jeigu serveris yra EU arba EEA: Mūsų tinklalapis, produktai ir visi teikiami aptarnavimai yra teikiami tik žmonėms, kuriems yra bent 16 metų. Jeigu jums yra mažiau nei 16 metų, sekant GDPR reikalavimais (<a href="https://en.wikipedia.org/wiki/General_Data_Protection_Regulation">General Data Protection Regulation</a>) prašome nenaudoti šios svetainės. </p>
+
+      <p> Jeigu šis serveris yra USA: Mūsų tinklalapis, produktai ir visi teikiami aptarnavimai yra teikiami žmonėms, kuriems yra bent 13 metų. Jeigu jums mažiau nei 13 metų, sekant COPPA reikalavimais (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) prašome nenaudotis šios svetainės.</p>
+
+      <p>Legalūs reikalavimai gali būti kitokie, jeigu serveris yra kitoje jurisdikcijoje.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="changes">Pasikeitimai mūsų privatumo politikoje</h3>
+
+      <p>Jeigu mes nusprendžiame pakeisti savo privatumo politiką, mes įrašysime šiuos pakeitimus šiame tinklalapyje.</p>
+
+      <p>Šis dokumentas yra CC-BY-SA. Paskutinį kartą keistas Kovo 7, 2018.</p>
+
+      <p>Originaliai adaptuotas iš <a href="https://github.com/discourse/discourse">Discourse privatumo politika</a>.</p>
+    title: "%{instance} Naudojimosi SÄ…lygos ir Privatumo Politika"
+  themes:
+    contrast: Mastodon (Didelio Kontrasto)
+    default: Mastodon (Tamsus)
+    mastodon-light: Mastodon (Å viesus)
+  two_factor_authentication:
+    code_hint: Įveskite autentikacijos aplikacijos sugeneruotą kodą kad galėtumete tęsti
+    description_html: Jeigu įjungiate <strong>dviejų veiksnių autentikaciją</strong>, prisijungiant jums reikės turėti su savimi savo telefoną, kuris jums generuos prisijungimo žetonus.
+    disable: Išjungti
+    enable: Įjungti
+    enabled: Dviejų veiksnių autentikacija įjungta
+    enabled_success: Dviejų veiksnių autentikacija sėkmingai įjungta
+    generate_recovery_codes: Sugeneruoti atkūrimo kodus
+    instructions_html: "<strong>Nuskenuokite šį QR kodą į Google Autentikatorių arba panašią TOTP aplikaciją jūsų telefone</strong>. Nuo šiol, ši aplikacija jums generuos žetonus, kurių reikės norint prisijungti."
+    lost_recovery_codes: Atkūrimo kodai jums leidžia atgauti prisijungimą prie Jūsų paskyros, jeigu prarandate telefoną. Jeigu praradote atkūrimo kodus, juos galite sugeneruoti čia. Jūsų senieji atkūrimo kodai nebeveiks.
+    manual_instructions: 'Jeigu jūs negalite nuskenuoti QR kodo ir turite jį įvesti savarankiškai, štai čia yra tekstas šiam kodui:'
+    recovery_codes: Atsarginio atkūrimo kodai
+    recovery_codes_regenerated: Atkūrimo kodai sėkmingai sugeneruoti
+    recovery_instructions_html: Jeigu prarandate prieiga prie telefono, jūs galite naudoti atkūrimo kodus esančius žemiau, kad atgautumėte priega prie savo paskyros.<strong>Laikykite atkūrimo kodus saugiai</strong> Pavyzdžiui, galite norėti juos išspausdinti, ir laikyti kartu su kitais svarbiais dokumentais.
+    setup: Nustatyti
+    wrong_code: Koda netinkamas! Ar serverio laikas ir prietaiso laikas vienodi?
+  user_mailer:
+    backup_ready:
+      explanation: Jūs prašėte pilnos Mastodon paskyros atsarginės kopijos. Ji paruošta parsisiuntimui!
+      subject: Jūsų archyvas paruoštas parsisiuntimui
+      title: Archyvas išimtas
+    warning:
+      explanation:
+        disable: Kol Jūsų paskyra užšaldyta, Jūsų duomenys tebėra matomi, tačiau jūs negalite atlikti jokių veiksmu, tol, kol užšaldymas panaikintas.
+        silence: Kol Jūsų paskyra limituota, tik žmonės, kurie jus jau sekė matus Jūsų toot'us serveryje, Jūs taip pat būsite išimtas iš viešųjų sąrašų. Tačiau, kiti gali jus rasti, savo rankomis.
+        suspend: Jūsų paskyra buvo užrakinta, ir visi Jūsų toot'ai, medijos failai, buvo panaikinti iš šio serverio, ir visų kitų serverių, kur turėjote sekėjų.
+      review_server_policies: Apžvelgti serverio politiką
+      subject:
+        disable: Jūsų paskyra %{acct} buvo užšaldyta
+        none: Įspėjmas vartotojui %{acct}
+        silence: Jūsų paskyra %{acct} buvo limituota
+        suspend: Jūsų paskyra %{acct} buvo užrakinta
+      title:
+        disable: Paskyra užšaldyta
+        none: Įspėjimas
+        silence: Paskyra limituota
+        suspend: Paskyra užrakinta
+    welcome:
+      edit_profile_action: Nustatyti profilį
+      edit_profile_step: Jūs galite keisti savo profilį įkeldami profilio nuotrauką, antraštę, pakeičiant savo rodomą vardą ir dar daugiau. Jeigu norėtumete peržiurėti naujus sekėjus prieš leidžiant jiems jus sekti, galite užrakinti savo paskyrą.
+      explanation: Štai keletas patarimų Jums
+      final_action: Pradėti kelti įrašus
+      final_step: 'Pradėk kelti įrašus! Net jeigu neturi sekėjų, Jūsų viešos žinutės gali būti matomos kitų, pavyzdžiui, lokalioje laiko juostoje ir saitažodžiuose. Galite norėti prisistatyti naudojan saitąžodį #introductions.'
+      full_handle: Jūsų pilnas slapyvardis
+      full_handle_hint: Štai ką jūs sakytumėte savo draugams, kad jie galėtų jums siųsti žinutes arba just sekti iš kitų serverių.
+      review_preferences_action: Pakeisti pasirinkimus
+      review_preferences_step: Nustatykite savo pasirinkimus, tokius kaip el pašto laiškai, kuriuos norėtumėte gauti, arba kokiu privatumo lygiu norėtumėte, kad jūsų įrašai būtų talpinami, taip pat galite įjungti automatinį GIF paleidimą.
+      subject: Sveiki atvykę į Mastodon
+      tip_federated_timeline: Federuota laiko juosta yra lyg gaisrininkų žarną rodanti Mastodon tinklą. Tačiau, joje rodomi tik žmonės kurie yra sekami Jūsų kaimynų.
+      tip_following: Jūs sekate savo serverio administratorius numatyta tvarka. Norint rasti įdomesnių žmonių, patikrinkite lokalią bei federuotą laiko juostas.
+      tip_local_timeline: Lokali laiko juosta, joje rodomi žmonės iš %{instance}. Jie yra Jūsų artimiausi kaimynai!
+      tip_mobile_webapp: Jeigu Jūsų mobilioji naršyklė leidžia jums pridėti Mastodon prie namų ekrano, jūs galite gauti priminimus. Tai gali veikti kaip vietinė aplikacija!
+      tips: Patarimai
+      title: Sveiki atvykÄ™, %{name}!
+  users:
+    follow_limit_reached: Negalite sekti daugiau nei %{limit} žmonių
+    invalid_email: Netinkamas el pašto adresas
+    invalid_otp_token: Netinkamas dviejų veiksnių kodas
+    otp_lost_help_html: Jeigu praradote prieiga prie abiejų, susisiekite su mumis per %{email}
+    seamless_external_login: Jūs esate prisijungę per išorini įrenginį, todėl slaptąžodis ir el pašto nustatymai neprieinami.
+    signed_in_as: 'Prisijungta kaip:'
+  verification:
+    explanation_html: 'Jūs galite <strong>patvirtinti savę kaip savininką nuorodų savo profilio meta duomenyse</strong>. Kad tai padarytumėte, susieta svetainė privalo turėti nuorodą atgal į Jūsų Mastodon profilį. Nuoroda atgal <strong> privalo </strong> turėti <code>rel="me"</code> savybę. Teksto turinys nuorodoje nesvarbus. Štai pavyzdys:'
+    verification: Patvirtinimas
diff --git a/config/locales/lv.yml b/config/locales/lv.yml
index 0967ef424bce6791893e9a57bb952f80fd536e93..971450a89bae8bd48cf8ae69fec86bb9e5f4dc33 100644
--- a/config/locales/lv.yml
+++ b/config/locales/lv.yml
@@ -1 +1,17 @@
-{}
+---
+lv:
+  errors:
+    '403': You don't have permission to view this page.
+    '404': The page you are looking for isn't here.
+    '410': The page you were looking for doesn't exist here anymore.
+    '422': 
+    '429': Throttled
+    '500': 
+  invites:
+    expires_in:
+      '1800': 30 minutes
+      '21600': 6 hours
+      '3600': 1 hour
+      '43200': 12 hours
+      '604800': 1 week
+      '86400': 1 day
diff --git a/config/locales/ms.yml b/config/locales/ms.yml
index e3c901eff84856a8af490c4a9d7974da12a5853e..3597ccd15fd46d85a60d4aac6099b0950f18a784 100644
--- a/config/locales/ms.yml
+++ b/config/locales/ms.yml
@@ -5,9 +5,7 @@ ms:
     about_mastodon_html: Mastodon ialah rangkaian sosial berasaskan protokol web terbuka dan perisian percuma bersumber terbuka. Ianya tak terpusat seperti emel.
     about_this: Mengenai Kami
     administered_by: 'Ditadbir oleh:'
-    api: API
     apps: Aplikasi mudah alih
-    closed_registrations: Pendaftaran ditutup di tika ini. Tetapi! Anda boleh mencari tika lain untuk mencipta akaun dan capai ke rangkaian yang sama daripada sana.
     contact: Hubungi kami
     contact_missing: Tidak ditetapkan
     contact_unavailable: Tidak tersedia
@@ -15,28 +13,16 @@ ms:
     extended_description_html: |
       <h3>Tempat sesuai untuk peraturan</h3>
       <p>Kenyataan penuh masih belum ditetapkan.</p>
-    features:
-      humane_approach_body: Belajar daripada kegagalan rangkaian lain, Mastodon berazam untuk membuat pilihan reka cipta beretika untuk mengatasi penyalahgunaan media sosial.
-      humane_approach_title: Pendekatan yang lebih berperikemanusiaan
-      not_a_product_body: Mastodon bukannya rangkaian komersial. Tiada iklan, tiada perlombongan data, tiada kurungan atau tapisan. Tiada pihak berkuasa pusat.
-      not_a_product_title: Anda seorang manusia, bukannya sebuah produk
-      real_conversation_body: Dengan had 500 aksara dan sokongan kandungan berbutir serta pemberi amaran media, anda boleh meluahkan diri anda dengan cara yang anda inginkan.
-      real_conversation_title: Dibina untuk perbualan sebenar
-      within_reach_body: Pelbagai aplikasi untuk iOS, Android, dan platform lain telah dibangunkan dengan ekosistem API mesra-pembangun membolehkan anda terus berhubung dengan rakan anda di mana-mana sahaja.
-      within_reach_title: Sentiasa dalam jangkauan
     generic_description: "%{domain} ialah salah sebuah pelayan dalam rangkaian Mastodon"
     hosted_on: Mastodon dihoskan di %{domain}
     learn_more: Ketahui lebih lanjut
-    other_instances: Senarai tika
     privacy_policy: Polisi privasi
     source_code: Kod sumber
     status_count_after:
-      one: status
       other: status
     status_count_before: Telah menulis
     terms: Terma perkhidmatan
     user_count_after:
-      one: pengguna
       other: pengguna
     user_count_before: Rumah kepada
     what_is_mastodon: Apakah itu Mastodon?
@@ -44,12 +30,10 @@ ms:
     choices_html: 'Pilihan %{name}:'
     follow: Ikut
     followers:
-      one: Pengikut
       other: Pengikut
     following: Mengikuti
     joined: Sertai pada %{date}
     link_verified_on: Pemilikan pautan ini diperiksa pada %{date}
-    media: Media
     moved_html: "%{name} telah berpindah ke %{new_profile_link}:"
     network_hidden: Maklumat ini tidak tersedia
     nothing_here: Tiada apa-apa di sini!
@@ -58,14 +42,11 @@ ms:
     pin_errors:
       following: Anda mestilah sudah mengikuti orang yang anda ingin syorkan
     posts:
-      one: Toot
       other: Toot
     posts_tab_heading: Toot
     posts_with_replies: Toot dan maklum balas
     reserved_username: Nama pengguna ini terpelihara
     roles:
-      admin: Admin
-      bot: Bot
       moderator: Pengawal
     unfollow: Nyahikut
   admin:
@@ -76,8 +57,6 @@ ms:
       destroyed_msg: Nota kawalan telah berjaya dipadam!
     accounts:
       are_you_sure: Anda pasti?
-      avatar: Avatar
-      by_domain: Domain
       change_email:
         changed_msg: Emel akaun telah berjaya ditukar!
         current_email: Emel Semasa
@@ -93,7 +72,6 @@ ms:
       disable_two_factor_authentication: Lumpuhkan 2FA
       disabled: Dilumpuhkan
       display_name: Nama paparan
-      domain: Domain
       edit: Tukar
       email: Emel
       email_status: Status Emel
@@ -162,7 +140,6 @@ ms:
       undo_suspension: Buang penggantungan
       unsubscribe: Buang langganan
       username: Nama pengguna
-      web: Web
     action_logs:
       actions:
         assigned_to_self_report: "%{name} memberikan laporan %{target} kepada diri mereka sendiri"
@@ -197,7 +174,6 @@ ms:
       deleted_status: "(status telah dipadam)"
       title: Log audit
     custom_emojis:
-      by_domain: Domain
       copied_msg: Telah berjaya mencipta salinan tempatan emoji
       copy: Salin
       copy_failed_msg: Tidak dapat membuat salinan tempatan emoji tersebut
@@ -206,7 +182,6 @@ ms:
       destroyed_msg: Emoji berjaya dipadam!
       disable: Lumpuhkan
       disabled_msg: Emoji tersebut berjaya dilumpuhkan
-      emoji: Emoji
       enable: Bolehkan
       enabled_msg: Emoji tersebut berjaya dibolehkan
       image_hint: PNG, maksimum 50KB
@@ -246,7 +221,6 @@ ms:
       add_new: Tambah
       created_msg: Sekatan domain sedang diproses
       destroyed_msg: Sekatan domain telah dibatalkan
-      domain: Domain
       new:
         create: Cipta sekatan
         hint: Sekatan domain tidak akan menghindarkan penciptaan entri akaun dalam pangkalan data, tetapi akan diberikan kaedah kawalan khusus tertentu pada akaun-akaun tersebut secara retroaktif dan automatik.
@@ -262,7 +236,6 @@ ms:
       reject_reports_hint: Abaikan semua laporan daripada domain ini. Tidak dikira untuk penggantungan
       show:
         affected_accounts:
-          one: Satu akaun dalam pangkalan data menerima kesan
           other: "%{count} akaun dalam pangkalan data menerima kesan"
         retroactive:
           silence: Buang penyenyapan semua akaun sedia ada daripada domain ini
@@ -275,7 +248,6 @@ ms:
       created_msg: Berjaya menambah domain emel ke dalam senarai hitam
       delete: Padam
       destroyed_msg: Berjaya memadam domain emel daripada senarai hitam
-      domain: Domain
       new:
         create: Tambah domain
         title: Entri senarai hitam emel baru
@@ -303,7 +275,6 @@ ms:
       pending: Menunggu persetujuan geganti
       save_and_enable: Simpan dan bolehkan
       setup: Tetapkan sambungan geganti
-      status: Status
       title: Geganti
     report_notes:
       created_msg: Nota laporan berjaya dicipta!
@@ -325,13 +296,24 @@ ms:
         create: Tambah nota
         create_and_resolve: Selesaikan dengan nota
         placeholder: Terangkan tindakan apa yang telah diambil, atau sebarang kemas kini lain yang berkaitan...
+  errors:
+    '403': You don't have permission to view this page.
+    '404': The page you are looking for isn't here.
+    '410': The page you were looking for doesn't exist here anymore.
+    '422': 
+    '429': Throttled
+    '500': 
   exports:
     archive_takeout:
       in_progress: Mengkompil arkib anda...
-  followers:
-    success:
-      one: Dalam proses menyekat-lembut pengikut daripada satu domain...
-      other: Dalam proses menyekat-lembut pengikut daripada %{count} domain...
+  invites:
+    expires_in:
+      '1800': 30 minutes
+      '21600': 6 hours
+      '3600': 1 hour
+      '43200': 12 hours
+      '604800': 1 week
+      '86400': 1 day
   notification_mailer:
     digest:
       title: Ketika anda tiada di sini...
diff --git a/config/locales/nl.yml b/config/locales/nl.yml
index dd23304fe0ae8fa69749548c4d140f0e56d0e4c9..78be7872d8fb028be74bf90f56efc4eab0199269 100644
--- a/config/locales/nl.yml
+++ b/config/locales/nl.yml
@@ -4,36 +4,36 @@ nl:
     about_hashtag_html: Dit zijn openbare toots die getagged zijn met <strong>#%{hashtag}</strong>. Je kunt er op reageren of iets anders mee doen als je op Mastodon (of ergens anders in de fediverse) een account hebt.
     about_mastodon_html: Mastodon is een sociaal netwerk dat gebruikt maakt van open webprotocollen en vrije software. Het is net zoals e-mail gedecentraliseerd.
     about_this: Over deze server
+    active_count_after: actief
+    active_footnote: Actieve gebruikers per maand (MAU)
     administered_by: 'Beheerd door:'
     api: API
     apps: Mobiele apps
-    closed_registrations: Registreren op deze server is momenteel niet mogelijk. Je kunt echter een andere server vinden om zo toegang te krijgen tot het netwerk.
+    apps_platforms: Gebruik Mastodon op iOS, Android en op andere platformen
+    browse_directory: Gebruikersgids doorbladeren en op interesses filteren
+    browse_public_posts: Livestream van openbare Mastodonberichten bekijken
     contact: Contact
     contact_missing: Niet ingesteld
     contact_unavailable: n.v.t
+    discover_users: Gebruikers ontdekken
     documentation: Documentatie
     extended_description_html: |
       <h3>Een goede plek voor richtlijnen</h3>
       <p>De uitgebreide omschrijving is nog niet ingevuld.</p>
-    features:
-      humane_approach_body: Mastodon heeft van de fouten van andere sociale netwerken geleerd en probeert aan de hand van ethische ontwerpkeuzes misbruik van sociale media te voorkomen.
-      humane_approach_title: Een meer menselijke aanpak
-      not_a_product_body: Mastodon is geen commercieel netwerk. Dus geen advertenties, geen datamining en geen besloten systemen. Er is geen centrale organisatie die alles bepaalt.
-      not_a_product_title: Jij bent een persoon, geen product
-      real_conversation_body: Met 65535 tekens tot jouw beschikking en ondersteuning voor tekst- en media-waarschuwingen, kan je jezelf uiten zoals jij dat wil.
-      real_conversation_title: Voor echte gesprekken gemaakt
-      within_reach_body: Meerdere apps voor iOS, Android en andere platformen, met dank aan het ontwikkelaarsvriendelijke API-systeem, zorgen ervoor dat je overal op de hoogte blijft.
-      within_reach_title: Altijd binnen bereik
+    federation_hint_html: Met een account op %{instance} ben je in staat om mensen die zich op andere Mastodonservers (en op andere plekken) bevinden te volgen.
     generic_description: "%{domain} is een server in het Mastodonnetwerk"
+    get_apps: Mobiele apps
     hosted_on: Mastodon op %{domain}
     learn_more: Meer leren
-    other_instances: Andere servers
     privacy_policy: Privacybeleid
+    see_whats_happening: Kijk wat er aan de hand is
+    server_stats: 'Serverstatistieken:'
     source_code: Broncode
     status_count_after:
       one: toot
       other: toots
     status_count_before: Zij schreven
+    tagline: Vrienden volgen en nieuwe ontdekken
     terms: Gebruiksvoorwaarden
     user_count_after:
       one: gebruiker
@@ -68,6 +68,7 @@ nl:
       admin: Beheerder
       bot: Bot
       moderator: Moderator
+    unavailable: Profiel niet beschikbaar
     unfollow: Ontvolgen
   admin:
     account_actions:
@@ -79,6 +80,8 @@ nl:
       delete: Verwijderen
       destroyed_msg: Verwijderen van opmerking voor moderatoren geslaagd!
     accounts:
+      approve: Goedkeuren
+      approve_all: Alles goedkeuren
       are_you_sure: Weet je het zeker?
       avatar: Avatar
       by_domain: Domein
@@ -118,21 +121,24 @@ nl:
         local: Lokaal
         remote: Extern
         title: Locatie
-      login_status: Login status
+      login_status: Loginstatus
       media_attachments: Mediabijlagen
       memorialize: In gedenkpagina veranderen
       moderation:
         active: Actief
         all: Alles
+        pending: In afwachting
         silenced: Genegeerd
         suspended: Opgeschort
         title: Moderatie
       moderation_notes: Opmerkingen voor moderatoren
       most_recent_activity: Laatst actief
       most_recent_ip: Laatst gebruikt IP-adres
+      no_account_selected: Er zijn geen accounts veranderd, omdat er geen een was geselecteerd
       no_limits_imposed: Geen limieten ingesteld
       not_subscribed: Niet geabonneerd
       outbox_url: Outbox-URL
+      pending: Moet nog beoordeeld worden
       perform_full_suspension: Opschorten
       profile_url: Profiel-URL
       promote: Promoveren
@@ -140,6 +146,8 @@ nl:
       public: Openbaar
       push_subscription_expires: PuSH-abonnement verloopt op
       redownload: Profiel vernieuwen
+      reject: Afkeuren
+      reject_all: Alles afkeuren
       remove_avatar: Avatar verwijderen
       remove_header: Omslagfoto verwijderen
       resend_confirmation:
@@ -166,6 +174,7 @@ nl:
       statuses: Toots
       subscribe: Abonneren
       suspended: Opgeschort
+      time_in_queue: "%{time} in de wachtrij"
       title: Accounts
       unconfirmed_email: Onbevestigd e-mailadres
       undo_silenced: Niet langer negeren
@@ -226,7 +235,7 @@ nl:
       new:
         title: Lokale emoji toevoegen
       overwrite: Overschrijven
-      shortcode: Shortcode
+      shortcode: Verkorte code
       shortcode_hint: Tenminste 2 tekens (alleen alfanumeriek en underscores)
       title: Lokale emoji’s
       unlisted: Niet weergegeven
@@ -241,6 +250,7 @@ nl:
       feature_profile_directory: Gebruikersgids
       feature_registrations: Registraties
       feature_relay: Federatierelay
+      feature_timeline_preview: Voorvertoning van tijdlijn
       features: Functies
       hidden_service: Federatie met verborgen diensten
       open_reports: onopgeloste rapportages
@@ -260,6 +270,7 @@ nl:
       created_msg: Domeinblokkade wordt nu verwerkt
       destroyed_msg: Domeinblokkade is ongedaan gemaakt
       domain: Domein
+      existing_domain_block_html: Jij hebt al strengere beperkingen opgelegd aan %{name}, je moet het domein eerst <a href="%{unblock_url}">deblokkeren</a>.
       new:
         create: Blokkade aanmaken
         hint: Een domeinblokkade voorkomt niet dat accountgegevens van dit domein aan de database worden toegevoegd, maar dat er met terugwerkende kracht en automatisch bepaalde moderatiemethoden op deze accounts worden toegepast.
@@ -302,6 +313,7 @@ nl:
       back_to_account: Terug naar account
       title: Volgers van %{acct}
     instances:
+      by_domain: Domein
       delivery_available: Bezorging is mogelijk
       known_accounts:
         one: "%{count} bekend account"
@@ -324,6 +336,8 @@ nl:
         expired: Verlopen
         title: Filter
       title: Uitnodigingen
+    pending_accounts:
+      title: Accounts in afwachting (%{count})
     relays:
       add_new: Nieuwe relayserver toevoegen
       delete: Verwijderen
@@ -410,9 +424,12 @@ nl:
         min_invite_role:
           disabled: Niemand
           title: Uitnodigingen toestaan door
-        open:
-          desc_html: Toestaan dat iedereen een account kan registereren
-          title: Open registratie
+      registrations_mode:
+        modes:
+          approved: Goedkeuring vereist om te kunnen registreren
+          none: Niemand kan zich registreren
+          open: Iedereen kan zich registreren
+        title: Registratiemodus
       show_known_fediverse_at_about_page:
         desc_html: Wanneer ingeschakeld wordt de globale tijdlijn op de voorpagina getoond en wanneer uitgeschakeld de lokale tijdljn.
         title: De globale tijdlijn op de voorpagina tonen
@@ -420,14 +437,14 @@ nl:
         desc_html: Medewerkersbadge op profielpagina tonen
         title: Medewerkersbadge tonen
       site_description:
-        desc_html: Dit wordt als een alinea op de voorpagina getoond. Beschrijf wat er speciaal is aan deze server en andere zaken die van belang zijn. Je kan HTML gebruiken, zoals <code>&lt;a&gt;</code> en <code>&lt;em&gt;</code>.
-        title: Omschrijving Mastodonserver
+        desc_html: Introductie-alinea voor de API. Beschrijf wat er speciaal is aan deze server en andere zaken die van belang zijn. Je kan HTML gebruiken, zoals <code>&lt;a&gt;</code> en <code>&lt;em&gt;</code>.
+        title: Omschrijving Mastodonserver (API)
       site_description_extended:
-        desc_html: Wordt op de uitgebreide informatiepagina weergegeven<br>Je kan ook hier HTML gebruiken
+        desc_html: Een goede plek voor je gedragscode, regels, richtlijnen en andere zaken die jouw server uniek maken. Je kan ook hier HTML gebruiken
         title: Uitgebreide omschrijving Mastodonserver
       site_short_description:
-        desc_html: Dit wordt in de zijbalk getoond als en als metatag in de paginabron.  Beschrijf in één alinea wat Mastodon is en wat deze server speciaal maakt. De (langere) omschrijving van de Mastodonserver wordt gebruikt wanneer dit veld wordt leeg gelaten.
-        title: Korte omschrijving Mastodonserver
+        desc_html: Dit wordt gebruikt op de voorpagina, in de zijbalk op profielpagina's en als metatag in de paginabron. Beschrijf in één alinea wat Mastodon is en wat deze server speciaal maakt.
+        title: Omschrijving Mastodonserver (website)
       site_terms:
         desc_html: Je kan hier jouw eigen privacybeleid, gebruiksvoorwaarden en ander juridisch jargon kwijt. Je kan HTML gebruiken
         title: Aangepaste gebruiksvoorwaarden
@@ -475,10 +492,19 @@ nl:
       edit_preset: Voorinstelling van waarschuwing bewerken
       title: Voorinstellingen van waarschuwingen beheren
   admin_mailer:
+    new_pending_account:
+      body: Zie hieronder de details van het nieuwe account. Je kunt de aanvraag goedkeuren of afkeuren.
+      subject: Er dient een nieuw account op %{instance} te worden beoordeeld (%{username})
     new_report:
       body: "%{reporter} heeft %{target} gerapporteerd"
       body_remote: Iemand van %{domain} heeft %{target} gerapporteerd
       subject: Nieuwe rapportage op %{instance} (#%{id})
+  appearance:
+    advanced_web_interface: Geavanceerde webomgeving
+    advanced_web_interface_hint: 'Wanneer je van de hele schermbreedte gebruik wilt maken, stelt de geavanceerde webomgeving je in staat om meerdere verschillende kolommen te configureren. Hiermee kun je zoveel mogelijk informatie op hetzelfde moment bekijken, zoals: Start, meldingen, de globale tijdlijn, meerdere lijsten en hashtags.'
+    animations_and_accessibility: Animaties en toegankelijkheid
+    confirmation_dialogs: Bevestigingen
+    sensitive_content: Gevoelige inhoud
   application_mailer:
     notification_preferences: E-mailvoorkeuren wijzigen
     salutation: "%{name},"
@@ -495,11 +521,12 @@ nl:
     warning: Wees voorzichtig met deze gegevens. Deel het nooit met iemand anders!
     your_token: Jouw toegangscode
   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 gebruiksvoorwaarden</a>.
+    apply_for_account: Een uitnodiging aanvragen
     change_password: Wachtwoord
+    checkbox_agreement_html: Ik ga akkoord met de <a href="%{rules_path}" target="_blank">regels van deze server</a> en de <a href="%{terms_path}" target="_blank">gebruiksvoorwaarden</a>
     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.
+    delete_account_html: Wanneer je jouw account graag wilt verwijderen, kun je dat <a href="%{path}">hier doen</a>. We vragen jou daar om een bevestiging.
     didnt_get_confirmation: Geen bevestigingsinstructies ontvangen?
     forgot_password: Wachtwoord vergeten?
     invalid_reset_password_token: De code om jouw wachtwoord opnieuw in te stellen is verlopen. Vraag een nieuwe aan.
@@ -507,17 +534,17 @@ nl:
     logout: Uitloggen
     migrate_account: Naar een ander 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: of
     or_log_in_with: Of inloggen met
     providers:
       cas: CAS
       saml: SAML
     register: Registreren
-    register_elsewhere: Op een andere server registreren
+    registration_closed: "%{instance} laat geen nieuwe gebruikers toe"
     resend_confirmation: Verstuur de bevestigingsinstructies nogmaals
     reset_password: Wachtwoord opnieuw instellen
     security: Beveiliging
     set_new_password: Nieuw wachtwoord instellen
+    trouble_logging_in: Problemen met inloggen?
   authorize_follow:
     already_following: Je volgt dit account al
     error: Helaas, er is een fout opgetreden bij het opzoeken van de externe account
@@ -573,11 +600,14 @@ nl:
       content: Het spijt ons, er is aan onze kant iets fout gegaan.
       title: Er is iets mis
     noscript_html: Schakel JavaScript in om de webapp van Mastodon te kunnen gebruiken. Als alternatief kan je een <a href="%{apps_path}">Mastodon-app</a> zoeken voor jouw platform.
+  existing_username_validator:
+    not_found: Kon geen lokale gebruiker met die gebruikersnaam vinden
+    not_found_multiple: Kon %{usernames} niet vinden
   exports:
     archive_takeout:
       date: Datum
       download: Jouw archief downloaden
-      hint_html: Je kunt een archief opvragen van jouw <strong>toots en geüploade media</strong>. De geëxporteerde gegevens zijn in ActivityPub-formaat, dat door hiervoor geschikte software valt uit te lezen. Je kunt elke 7 dagen een kopie van je archief aanvragen.
+      hint_html: Je kunt een archief opvragen van jouw <strong>toots en geüploade media</strong>. De geëxporteerde gegevens zijn in het ActivityPub-formaat, dat door hiervoor geschikte software valt uit te lezen. Je kunt elke 7 dagen een kopie van je archief aanvragen.
       in_progress: Jouw archief wordt samengesteld...
       request: Jouw archief opvragen
       size: Omvang
@@ -588,6 +618,10 @@ nl:
     lists: Lijsten
     mutes: Jij negeert
     storage: Mediaopslag
+  featured_tags:
+    add_new: Nieuwe toevoegen
+    errors:
+      limit: Je hebt al het maximaal aantal hashtags uitgelicht
   filters:
     contexts:
       home: Starttijdlijn
@@ -604,34 +638,50 @@ nl:
       title: Filters
     new:
       title: Nieuw filter toevoegen
-  followers:
-    domain: Domein
-    explanation_html: Wanneer je de privacy van jouw toots wilt garanderen, moet je goed weten wie jouw volgers zijn. <strong>Toots die alleen aan jouw volgers zijn gericht, worden aan de Mastodonservers van jouw volgers afgeleverd.</strong> Daarom wil je ze misschien controleren en desnoods volgers verwijderen die zich op een Mastodonserver bevinden die jij niet vertrouwd. Bijvoorbeeld omdat de beheerder(s) of de software van zo'n server jouw privacy niet respecteert.
-    followers_count: Aantal volgers
-    lock_link: Maak jouw account besloten
-    purge: Volgers verwijderen
-    success:
-      one: Bezig om volgers van één domein te verwijderen...
-      other: Bezig om volgers van %{count} domeinen te verwijderen...
-    true_privacy_html: Hou er wel rekening mee dat <strong>echte privacy alleen gegarandeerd kan worden met behulp van end-to-end-encryptie</strong>.
-    unlocked_warning_html: Iedereen kan jou volgen en daarmee meteen toots zien die je alleen aan jouw volgers hebt gericht. %{lock_link} om volgers te kunnen beoordelen en desnoods te weigeren.
-    unlocked_warning_title: Jouw account is niet besloten
   footer:
     developers: Ontwikkelaars
     more: Meer…
     resources: Hulpmiddelen
   generic:
+    all: Alles
     changes_saved_msg: Wijzigingen succesvol opgeslagen!
     copy: Kopiëren
+    order_by: Sorteer op
     save_changes: Wijzigingen opslaan
     validation_errors:
       one: Er is iets niet helemaal goed! Bekijk onderstaande fout
       other: Er is iets niet helemaal goed! Bekijk onderstaande %{count} fouten
+  html_validator:
+    invalid_markup: 'bevat ongeldige HTML-opmaak: %{error}'
+  identity_proofs:
+    active: Actief
+    authorize: Ja, autoriseren
+    authorize_connection_prompt: Deze cryptografische verbinding autoriseren?
+    errors:
+      failed: De cryptografische verbinding is mislukt. Probeer het opnieuw vanaf %{provider}.
+      keybase:
+        invalid_token: Keybasetokens zijn hashes van handtekeningen en moeten een lengte hebben van 66 hexadecimale tekens
+        verification_failed: Keybase herkent deze token niet als een handtekening van Keybasegebruiker %{kb_username}. Probeer het opnieuw vanuit Keybase.
+      wrong_user: Er kan geen bewijs worden aangemaakt voor %{proving}   terwijl je bent ingelogd als %{current}. Log in als %{proving} en probeer het opnieuw.
+    explanation_html: Hier kun je met behulp van cryptografie jouw andere identiteiten verbinden, zoals een Keybaseprofiel. Hiermee kunnen andere mensen jou versleutelde berichten sturen en inhoud die jij verstuurt vertrouwen.
+    i_am_html: Ik ben %{username} op %{service}.
+    identity: Identiteit
+    inactive: Inactief
+    publicize_checkbox: 'En toot dit:'
+    publicize_toot: 'Het is bewezen! Ik ben %{username} op %{service}: %{url}'
+    status: Verificatiestatus
+    view_proof: Bekijk bewijs
   imports:
+    modes:
+      merge: Samenvoegen
+      merge_long: Bestaande gegevens behouden en nieuwe toevoegen
+      overwrite: Overschrijven
+      overwrite_long: Huidige gegevens met de nieuwe gegevens vervangen
     preface: Je kunt bepaalde gegevens, zoals de mensen die jij volgt of hebt geblokkeerd, naar jouw account op deze server importeren. Je moet deze gegevens wel eerst op de oorspronkelijke server exporteren.
     success: Jouw gegevens zijn succesvol geüpload en worden binnenkort verwerkt
     types:
       blocking: Blokkeerlijst
+      domain_blocking: Lijst met genegeerde servers
       following: Volglijst
       muting: Negeerlijst
     upload: Uploaden
@@ -711,23 +761,44 @@ nl:
       decimal_units:
         format: "%n%u"
         units:
-          billion: B
-          million: M
-          quadrillion: Q
+          billion: mld.
+          million: mln.
+          quadrillion: qdn.
           thousand: K
-          trillion: T
-          unit: " "
+          trillion: bln.
   pagination:
     newer: Nieuwer
     next: Volgende
     older: Ouder
     prev: Vorige
     truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: Je hebt al op deze poll gestemd
+      duplicate_options: bevat dubbele items
+      duration_too_long: ligt te ver in de toekomst
+      duration_too_short: is te kort van duur
+      expired: De poll is al beëindigd
+      over_character_limit: kan stuk voor stuk niet langer zijn dan %{max} tekens
+      too_few_options: moet meer dan één item bevatten
+      too_many_options: kan niet meer dan %{max} items bevatten
   preferences:
-    languages: Talen
     other: Overig
-    publishing: Publiceren
-    web: Webapp
+    posting_defaults: Standaardinstellingen voor posten
+    public_timelines: Openbare tijdlijnen
+  relationships:
+    activity: Accountactiviteit
+    dormant: Sluimerend
+    last_active: Laatst actief
+    most_recent: Recentelijk gevolgd
+    moved: Verhuisd
+    mutual: Wederzijds
+    primary: Primair
+    relationship: Relatie
+    remove_selected_domains: Alle volgers van de geselecteerde domeinen verwijderen
+    remove_selected_followers: Geselecteerde volgers verwijderen
+    remove_selected_follows: Geselecteerde gebruikers ontvolgen
+    status: Accountstatus
   remote_follow:
     acct: Geef jouw account@domein op die je wilt gebruiken
     missing_resource: Kon vereiste doorverwijzings-URL voor jouw account niet vinden
@@ -795,20 +866,25 @@ nl:
     revoke_success: Sessie succesvol ingetrokken
     title: Sessies
   settings:
+    account: Account
+    account_settings: Accountinstellingen
+    appearance: Uiterlijk
     authorized_apps: Geautoriseerde apps
     back: Terug naar Mastodon
     delete: Account verwijderen
     development: Ontwikkelaars
     edit_profile: Profiel bewerken
     export: Exporteren
-    followers: Geautoriseerde volgers
+    featured_tags: Uitgelichte hashtags
+    identity_proofs: Identiteitsbewijzen
     import: Importeren
+    import_and_export: Importeren en exporteren
     migrate: Accountmigratie
     notifications: Meldingen
     preferences: Voorkeuren
-    settings: Instellingen
+    profile: Profiel
+    relationships: Volgers en gevolgden
     two_factor_authentication: Tweestapsverificatie
-    your_apps: Jouw toepassingen
   statuses:
     attached:
       description: 'Bijlagen: %{attached}'
@@ -831,6 +907,11 @@ nl:
       ownership: Een toot van iemand anders kan niet worden vastgezet
       private: Alleen openbare toots kunnen worden vastgezet
       reblog: Een boost kan niet worden vastgezet
+    poll:
+      total_votes:
+        one: "%{count} stem"
+        other: "%{count} stemmen"
+      vote: Stemmen
     show_more: Meer tonen
     sign_in_to_participate: Meld je aan om aan dit gesprek mee te doen
     title: '%{name}: "%{quote}"'
@@ -851,10 +932,10 @@ nl:
       <h3 id="collect">What information do we collect?</h3>
 
       <ul>
-        <li><em>Basic account information</em>: If you register on this server, you may be asked to enter a username, an e-mail address and a password. You may also enter additional profile information such as a display name and biography, and upload a profile picture and header image. The username, display name, biography, profile picture and header image are always listed publicly.</li>
-        <li><em>Posts, following and other public information</em>: The list of people you follow is listed publicly, the same is true for your followers. When you submit a message, the date and time is stored as well as the application you submitted the message from. Messages may contain media attachments, such as pictures and videos. Public and unlisted posts are available publicly. When you feature a post on your profile, that is also publicly available information. Your posts are delivered to your followers, in some cases it means they are delivered to different servers and copies are stored there. When you delete posts, this is likewise delivered to your followers. The action of reblogging or favouriting another post is always public.</li>
-        <li><em>Direct and followers-only posts</em>: All posts are stored and processed on the server. Followers-only posts are delivered to your followers and users who are mentioned in them, and direct posts are delivered only to users mentioned in them. In some cases it means they are delivered to different servers and copies are stored there. We make a good faith effort to limit the access to those posts only to authorized persons, but other servers may fail to do so. Therefore it's important to review servers your followers belong to. You may toggle an option to approve and reject new followers manually in the settings. <em>Please keep in mind that the operators of the server and any receiving server may view such messages</em>, and that recipients may screenshot, copy or otherwise re-share them. <em>Do not share any dangerous information over Mastodon.</em></li>
-        <li><em>IPs and other metadata</em>: When you log in, we record the IP address you log in from, as well as the name of your browser application. All the logged in sessions are available for your review and revocation in the settings. The latest IP address used is stored for up to 12 months. We also may retain server logs which include the IP address of every request to our server.</li>
+      <li><em>Basic account information</em>: If you register on this server, you may be asked to enter a username, an e-mail address and a password. You may also enter additional profile information such as a display name and biography, and upload a profile picture and header image. The username, display name, biography, profile picture and header image are always listed publicly.</li>
+      <li><em>Posts, following and other public information</em>: The list of people you follow is listed publicly, the same is true for your followers. When you submit a message, the date and time is stored as well as the application you submitted the message from. Messages may contain media attachments, such as pictures and videos. Public and unlisted posts are available publicly. When you feature a post on your profile, that is also publicly available information. Your posts are delivered to your followers, in some cases it means they are delivered to different servers and copies are stored there. When you delete posts, this is likewise delivered to your followers. The action of reblogging or favouriting another post is always public.</li>
+      <li><em>Direct and followers-only posts</em>: All posts are stored and processed on the server. Followers-only posts are delivered to your followers and users who are mentioned in them, and direct posts are delivered only to users mentioned in them. In some cases it means they are delivered to different servers and copies are stored there. We make a good faith effort to limit the access to those posts only to authorized persons, but other servers may fail to do so. Therefore it's important to review servers your followers belong to. You may toggle an option to approve and reject new followers manually in the settings. <em>Please keep in mind that the operators of the server and any receiving server may view such messages</em>, and that recipients may screenshot, copy or otherwise re-share them. <em>Do not share any dangerous information over Mastodon.</em></li>
+      <li><em>IPs and other metadata</em>: When you log in, we record the IP address you log in from, as well as the name of your browser application. All the logged in sessions are available for your review and revocation in the settings. The latest IP address used is stored for up to 12 months. We also may retain server logs which include the IP address of every request to our server.</li>
       </ul>
 
       <hr class="spacer" />
@@ -864,9 +945,9 @@ nl:
       <p>Any of the information we collect from you may be used in the following ways:</p>
 
       <ul>
-        <li>To provide the core functionality of Mastodon. You can only interact with other people's content and post your own content when you are logged in. For example, you may follow other people to view their combined posts in your own personalized home timeline.</li>
-        <li>To aid moderation of the community, for example comparing your IP address with other known ones to determine ban evasion or other violations.</li>
-        <li>The email address you provide may be used to send you information, notifications about other people interacting with your content or sending you messages, and to respond to inquiries, and/or other requests or questions.</li>
+      <li>To provide the core functionality of Mastodon. You can only interact with other people's content and post your own content when you are logged in. For example, you may follow other people to view their combined posts in your own personalized home timeline.</li>
+      <li>To aid moderation of the community, for example comparing your IP address with other known ones to determine ban evasion or other violations.</li>
+      <li>The email address you provide may be used to send you information, notifications about other people interacting with your content or sending you messages, and to respond to inquiries, and/or other requests or questions.</li>
       </ul>
 
       <hr class="spacer" />
@@ -882,8 +963,8 @@ nl:
       <p>We will make a good faith effort to:</p>
 
       <ul>
-        <li>Retain server logs containing the IP address of all requests to this server, in so far as such logs are kept, no more than 90 days.</li>
-        <li>Retain the IP addresses associated with registered users no more than 12 months.</li>
+      <li>Retain server logs containing the IP address of all requests to this server, in so far as such logs are kept, no more than 90 days.</li>
+      <li>Retain the IP addresses associated with registered users no more than 12 months.</li>
       </ul>
 
       <p>You can request and download an archive of your content, including your posts, media attachments, profile picture, and header image.</p>
@@ -929,8 +1010,8 @@ nl:
       <p>Originally adapted from the <a href="https://github.com/discourse/discourse">Discourse privacy policy</a>.</p>
     title: Gebruiksvoorwaarden en privacybeleid van %{instance}
   themes:
-    contrast: Hoog contrast
-    default: Mastodon
+    contrast: Mastodon (hoog contrast)
+    default: Mastodon (donker)
     mastodon-light: Mastodon (licht)
   time:
     formats:
@@ -946,7 +1027,7 @@ nl:
     generate_recovery_codes: Herstelcodes genereren
     instructions_html: "<strong>Scan deze QR-code in Google Authenticator of een soortgelijke app op jouw mobiele telefoon</strong>. Van nu af aan genereert deze app aanmeldcodes die je bij het inloggen moet invoeren."
     lost_recovery_codes: Met herstelcodes kun je toegang tot jouw account krijgen wanneer je jouw telefoon bent kwijtgeraakt. Wanneer je jouw herstelcodes bent kwijtgeraakt, kan je ze hier opnieuw genereren. Jouw oude herstelcodes zijn daarna ongeldig.
-    manual_instructions: Voor het geval je de QR-code niet kunt scannen en het handmatig moet invoeren, vind je hieronder geheime code in gewone tekst.
+    manual_instructions: Voor het geval je de QR-code niet kunt scannen en het handmatig moet invoeren, vind je hieronder de geheime code in platte tekst.
     recovery_codes: Herstelcodes back-uppen
     recovery_codes_regenerated: Opnieuw genereren herstelcodes geslaagd
     recovery_instructions_html: Wanneer je ooit de toegang verliest tot jouw telefoon, kan je met behulp van een van de herstelcodes hieronder opnieuw toegang krijgen tot jouw account. <strong>Zorg ervoor dat je de herstelcodes op een veilige plek bewaard</strong>. Je kunt ze bijvoorbeeld printen en ze samen met andere belangrijke documenten bewaren.
diff --git a/config/locales/no.yml b/config/locales/no.yml
index 5a85a7561198100a71c54f6b1669d53cdf1d53cd..d21dda6fba0f4b4d39131d49fa6054d67606ba22 100644
--- a/config/locales/no.yml
+++ b/config/locales/no.yml
@@ -4,46 +4,29 @@
     about_hashtag_html: Dette er offentlige toots merket med <strong>#%{hashtag}</strong>. Du kan interagere med dem om du har en konto et sted i fediverset.
     about_mastodon_html: Mastodon er et sosialt nettverk laget med <em>fri programvare</em>. Et <em>desentralisert</em> alternativ til kommersielle plattformer. Slik kan det unngå risikoene ved å ha et enkelt selskap som monopoliserer din kommunikasjon. Velg en tjener du stoler på &mdash; uansett hvilken du velger så kan du kommunisere med alle andre. Alle kan kjøre sin egen Mastodon og delta sømløst i det sosiale nettverket.
     about_this: Om denne instansen
-    closed_registrations: Registreringer er for øyeblikket lukket på denne instansen.
     contact: Kontakt
     contact_missing: Ikke innstilt
     contact_unavailable: Ikke tilgjengelig
     extended_description_html: |
       <h3>En god plassering for regler</h3>
       <p>En utvidet beskrivelse er ikke satt opp ennå.</p>
-    features:
-      humane_approach_body: Mastodon har tatt lærdom fra andre nettverk og har til mål å gjøre etiske designvalg for å bekjempe misbruk av sosiale medier.
-      humane_approach_title: En mer menneskelig tilnærming
-      not_a_product_body: Mastodon er ikke et kommerst nettverk. Ingen reklame, ingen datainnsamling, ingen innhegnede hager. Det finnes ingen sentral myndighet.
-      not_a_product_title: Du er en person, ikke et produkt
-      real_conversation_body: Med 65535 tegn til din disposisjon og støtte for granulært innhold og media-advarsler kan du uttrykke deg på den måten du selv vil.
-      real_conversation_title: Laget for ekte samtaler
-      within_reach_body: Takket være et utviklingsvennlig API-økosystem vil flere apper for iOS, Android og andre plattformer la deg holde kontakten med dine venner hvor som helst.
-      within_reach_title: Alltid innen rekkevidde
     generic_description: "%{domain} er en tjener i nettverket"
     hosted_on: Mastodon driftet på %{domain}
     learn_more: Lær mer
-    other_instances: Andre instanser
     source_code: Kildekode
-    status_count_after: statuser
     status_count_before: Som skrev
-    user_count_after: brukere
     user_count_before: Her bor
     what_is_mastodon: Hva er Mastodon?
   accounts:
     follow: Følg
-    followers: Følgere
     following: Følger
-    media: Media
     moved_html: "%{name} har flyttet til %{new_profile_link}:"
     nothing_here: Det er ingenting her!
     people_followed_by: Folk som %{name} følger
     people_who_follow: Folk som følger %{name}
-    posts: Poster
     posts_with_replies: Tuter med svar
     reserved_username: Brukernavnet er reservert
     roles:
-      admin: Admin
       moderator: Moderere
     unfollow: Slutte følge
   admin:
@@ -109,8 +92,6 @@
       resubscribe: Abonner på nytt
       role: Rettigheter
       roles:
-        admin: Administrator
-        moderator: Moderator
         staff: Personale
         user: Bruker
       salmon_url: Salmon-URL
@@ -127,7 +108,6 @@
       undo_suspension: Angre utvisning
       unsubscribe: Avslutte abonnementet
       username: Brukernavn
-      web: Web
     action_logs:
       actions:
         confirm_user: "%{name} bekreftet e-postadresse for bruker %{target}"
@@ -164,7 +144,6 @@
       destroyed_msg: Emojo slettet uten problem!
       disable: Deaktivere
       disabled_msg: Deaktiverte emoji uten problem
-      emoji: Emoji
       enable: Aktivere
       enabled_msg: Aktiverte emojien uten problem
       image_hint: PNG opp til 50KB
@@ -222,7 +201,6 @@
         all: Alle
         available: Tilgjengelig
         expired: Utløpt
-        title: Filter
       title: Invitasjoner
     reports:
       action_taken_by: Handling utført av
@@ -234,7 +212,6 @@
       reported_account: Rapportert konto
       reported_by: Rapportert av
       resolved: Løst
-      status: Status
       title: Rapporter
       unresolved: Uløst
     settings:
@@ -260,9 +237,6 @@
         min_invite_role:
           disabled: Ingen
           title: Tillat invitasjoner fra
-        open:
-          desc_html: Tillatt alle å lage seg en konto
-          title: Ã…pen registrering
       show_staff_badge:
         desc_html: Vis personalemerke på brukersiden
         title: Vis personalemerke
@@ -290,8 +264,6 @@
         nsfw_off: NSFW AV
         nsfw_on: NSFW PÃ…
       failed_to_execute: Utføring mislyktes
-      media:
-        title: Media
       no_media: Ingen media
       title: Kontostatuser
       with_media: Med media
@@ -300,7 +272,6 @@
       confirmed: Bekreftet
       expires_in: Utløper om
       last_delivery: Siste levering
-      title: WebSub
       topic: Emne
     title: Administrasjon
   admin_mailer:
@@ -309,7 +280,6 @@
       subject: Ny rapport for %{instance} (#%{id})
   application_mailer:
     notification_preferences: Endre e-post innstillingene
-    salutation: "%{name},"
     settings: 'Endre foretrukne e-postinnstillinger: %{link}'
     view: 'Se:'
     view_profile: Vis Profil
@@ -323,7 +293,6 @@
     warning: Vær veldig forsiktig med denne data. Aldri del den med noen!
     your_token: Din tilgangsnøkkel
   auth:
-    agreement_html: Ved å registrere deg godtar du å følge <a href="%{rules_path}">instansens regler</a> og <a href="%{terms_path}">våre brukervilkår</a>.
     delete_account: Slett konto
     delete_account_html: Hvis du ønsker å slette din konto kan du <a href="%{path}">fortsette her</a>. Du vil bli spurt om bekreftelse.
     didnt_get_confirmation: Mottok du ikke instruksjoner om bekreftelse?
@@ -384,22 +353,9 @@
     noscript_html: For å bruke Mastodon webapplikasjon må du aktivere JavaScript. Alternativt kan du forsøke en av de mange <a href="%{apps_path}">integrerte appene</a> for Mastodon til din plattform.
   exports:
     blocks: Du blokkerer
-    csv: CSV
     follows: Du følger
     mutes: Du demper
     storage: Medialagring
-  followers:
-    domain: Domene
-    explanation_html: Hvis du vil styre hvem som ser statusene dine, må du være klar over hvem som følger deg. <strong>Dine private statuser leveres til alle instanser der du har følgere</strong>. Du bør kanskje se over dem, og fjerne følgere hvis du ikke stoler på at ditt privatliv vil bli respektert av staben eller programvaren på de instansene.
-    followers_count: Antall følgere
-    lock_link: LÃ¥s kontoen din
-    purge: Fjern fra følgere
-    success:
-      one: I ferd med å mykblokkere følgere fra ett domene...
-      other: I ferd med å mykblokkere følgere fra %{count} domener...
-    true_privacy_html: Merk deg at <strong>virkelig privatliv kun kan oppnås med ende-til-ende-kryptering</strong>.
-    unlocked_warning_html: Alle kan følge deg for å umiddelbart se dine private statuser. %{lock_link} for å kunne se over og avvise følgere.
-    unlocked_warning_title: Din konto er ikke låst
   generic:
     changes_saved_msg: Vellykket lagring av endringer!
     save_changes: Lagre endringer
@@ -423,6 +379,7 @@
       '21600': 6 timer
       '3600': 1 time
       '43200': 12 timer
+      '604800': 1 week
       '86400': 1 dag
     expires_in_prompt: Aldri
     generate: Generer
@@ -483,26 +440,11 @@
       body: 'Din status ble fremhevd av %{name}:'
       subject: "%{name} fremhevde din status"
       title: Ny fremheving
-  number:
-    human:
-      decimal_units:
-        format: "%n%u"
-        units:
-          billion: B
-          million: M
-          quadrillion: Q
-          thousand: K
-          trillion: T
-          unit: " "
   pagination:
     next: Neste
     prev: Forrige
-    truncate: "&hellip;"
   preferences:
-    languages: Språk
     other: Annet
-    publishing: Publisering
-    web: Web
   remote_follow:
     acct: Tast inn brukernavn@domene som du vil følge fra
     missing_resource: Kunne ikke finne URLen for din konto
@@ -512,40 +454,13 @@
     activity: Siste aktivitet
     browser: Nettleser
     browsers:
-      alipay: Alipay
-      blackberry: Blackberry
-      chrome: Chrome
-      edge: Microsoft Edge
-      electron: Electron
-      firefox: Firefox
       generic: Ukjent nettleser
-      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: Nåværende økt
     description: "%{browser} på %{platform}"
     explanation: Dette er nettlesere innlogget på din Mastodon-konto akkurat nå.
     ip: IP-adresse
     platforms:
-      adobe_air: Adobe Air
-      android: Android
-      blackberry: Blackberry
-      chrome_os: ChromeOS
-      firefox_os: Firefox OS
-      ios: iOS
-      linux: Linux
-      mac: Mac
       other: ukjent plattform
-      windows: Windows
-      windows_mobile: Windows Mobile
-      windows_phone: Windows Phone
     revoke: Tilbakekall
     revoke_success: Økt tilbakekalt
     title: Økter
@@ -556,14 +471,11 @@
     development: Utvikling
     edit_profile: Endre profil
     export: Dataeksport
-    followers: Godkjente følgere
     import: Importér
     migrate: Kontomigrering
     notifications: Varslinger
     preferences: Preferanser
-    settings: Innstillinger
     two_factor_authentication: Tofaktorautentisering
-    your_apps: Dine applikasjoner
   statuses:
     open_in_web: Ã…pne i nettleser
     over_character_limit: grense på %{max} tegn overskredet
@@ -573,7 +485,6 @@
       private: Kun offentlige tuter kan festes
       reblog: En fremheving kan ikke festes
     show_more: Vis mer
-    title: '%{name}: "%{quote}"'
     visibilities:
       private: Privat
       private_long: Synlig kun for følgere
@@ -624,7 +535,6 @@
       tip_following: Du følger din tjeners administrator(er) som standard. For å finne mer interessante personer, sjekk den lokale og forente tidslinjen.
       tip_local_timeline: Den lokale tidslinjen blir kontant matet med meldinger fra personer på %{instance}. Dette er dine nærmeste naboer!
       tip_mobile_webapp: Hvis din mobile nettleser tilbyr deg å legge Mastadon til din hjemmeskjerm kan du motta push-varslinger. Det er nesten som en integrert app på mange måter!
-      tips: Tips
       title: Velkommen ombord, %{name}!
   users:
     invalid_email: E-postaddressen er ugyldig
diff --git a/config/locales/oc.yml b/config/locales/oc.yml
index ef158074af9a92dae6102b52a8ae7354a197fa31..785caa4eccab9eccd276cc66d7aefa34fedeee7a 100644
--- a/config/locales/oc.yml
+++ b/config/locales/oc.yml
@@ -4,31 +4,28 @@ oc:
     about_hashtag_html: Vaquí los estatuts publics ligats a <strong>#%{hashtag}</strong>. Podètz interagir amb eles s’avètz un compte ont que siasque sul fediverse.
     about_mastodon_html: Mastodon es un malhum social bastit amb de protocòls liures e gratuits. Es descentralizat coma los corrièls.
     about_this: A prepaus d’aquesta instància
-    administered_by: 'Gerida per :'
-    api: API
+    active_count_after: actius
+    active_footnote: Utilizaire actius per mes (UAM)
+    administered_by: 'Administrat per :'
     apps: Aplicacions per mobil
-    closed_registrations: Las inscripcions son clavadas pel moment sus aquesta instància.
+    apps_platforms: Utilizatz Mastodon d‘iOS, Android o d’autras plataforma estant
+    browse_directory: Navigatz per l’annuari de perfil e filtratz segon çò qu’aimatz
+    browse_public_posts: Navigatz pel flux public a Mastodon
     contact: Contacte
     contact_missing: Pas parametrat
     contact_unavailable: Pas disponible
+    discover_users: Descobrissètz de nòvas personas
     documentation: Documentacion
     extended_description_html: |
       <h3>Una bona plaça per las règlas</h3>
       <p>La descripcion longa es pas estada causida pel moment.</p>
-    features:
-      humane_approach_body: Amb l’experiéncia dels fracasses d’autres malhums, Mastodon ten per objectiu de lutar contra los abuses dels malhums socials en far de causidas eticas.
-      humane_approach_title: Un biais mai uman
-      not_a_product_body: Mastodon es pas un malhum comercial. Pas cap de reclama, d’utilizacion de vòstras donadas o d’òrt daurat clavat. I a pas cap d’autoritat centrala.
-      not_a_product_title: Sètz una persona, non pas un produit
-      real_conversation_body: Amb 65535 caractèrs a vòstra disposicion e un nivèl de confidencialitat per cada publicacion, podètz vos exprimir coma volètz.
-      real_conversation_title: Fach per de conversacions vertadièras
-      within_reach_body: Multiplas aplicacion per iOS, Android, e autras plataformas mercés a un entorn API de bon utilizar, vos permet de gardar lo contacte pertot.
-      within_reach_title: Totjorn al costat
     generic_description: "%{domain} es un dels servidors del malhum"
+    get_apps: Ensajatz una aplicacion mobil
     hosted_on: Mastodon albergat sus %{domain}
     learn_more: Ne saber mai
-    other_instances: Lista d’instàncias
     privacy_policy: Politica de confidencialitat
+    see_whats_happening: Agachatz çò qu’arriba
+    server_stats: 'Estatisticas del servidor :'
     source_code: Còdi font
     status_count_after:
       one: estatut
@@ -65,7 +62,6 @@ oc:
     posts_with_replies: Tuts e responsas
     reserved_username: Aqueste nom d’utilizaire es reservat
     roles:
-      admin: Admin
       bot: Robòt
       moderator: Moderador
     unfollow: Quitar de sègre
@@ -79,8 +75,8 @@ oc:
       delete: Suprimir
       destroyed_msg: Nòta de moderacion ben suprimida !
     accounts:
+      approve: Aprovar
       are_you_sure: Sètz segur ?
-      avatar: Avatar
       by_domain: Domeni
       change_email:
         changed_msg: Adreça corrèctament cambiada !
@@ -111,7 +107,6 @@ oc:
       header: Bandièra
       inbox_url: URL de recepcion
       invited_by: Convidat per
-      ip: IP
       joined: Venguèt
       location:
         all: Totes
@@ -124,6 +119,7 @@ oc:
       moderation:
         active: Actius
         all: Totes
+        pending: En espèra
         silenced: Resconduts
         suspended: Suspenduts
         title: Moderacion
@@ -133,11 +129,11 @@ oc:
       no_limits_imposed: Cap de limit impausat
       not_subscribed: Pas seguidor
       outbox_url: URL Outbox
+      pending: Revision en espèra
       perform_full_suspension: Suspendre
       profile_url: URL del perfil
       promote: Promòure
       protocol: Protocòl
-      public: Public
       push_subscription_expires: Fin de l’abonament PuSH
       redownload: Actualizar lo perfil
       remove_avatar: Supriir l’avatar
@@ -149,9 +145,7 @@ oc:
       reset: Reïnicializar
       reset_password: Reïnicializar lo senhal
       resubscribe: Se tornar abonar
-      role: Permissions
       roles:
-        admin: Administrator
         moderator: Moderador
         staff: Personnal
         user: Uitlizaire
@@ -173,7 +167,6 @@ oc:
       unsubscribe: Se desabonar
       username: Nom d’utilizaire
       warn: Avisar
-      web: Web
     action_logs:
       actions:
         assigned_to_self_report: "%{name} s’assignèt lo rapòrt %{target}"
@@ -218,7 +211,6 @@ oc:
       destroyed_msg: Emoji ben suprimit !
       disable: Desactivar
       disabled_msg: Aqueste emoji es ben desactivat
-      emoji: Emoji
       enable: Activar
       enabled_msg: Aqueste emoji es ben activat
       image_hint: PNG cap a 50Ko
@@ -302,6 +294,7 @@ oc:
       back_to_account: Tornar al compte
       title: Seguidors de %{acct}
     instances:
+      by_domain: Domeni
       delivery_available: Liurason disponibla
       known_accounts:
         one: "%{count} compte conegut"
@@ -386,14 +379,14 @@ oc:
         desc_html: Modificar l’estil amb una fuèlha CSS cargada sus cada pagina
         title: CSS personalizada
       hero:
-        desc_html: Mostrat en primièra pagina. Almens 600x100px recomandat. S’es pas configurat l’imatge de l’instància serà mostrat
+        desc_html: Mostrat en primièra pagina. Almens 600x100px recomandat. S’es pas configurat l’imatge del servidor serà mostrat
         title: Imatge de l’eròi
       mascot:
         desc_html: Mostrat sus mantun paginas. Almens 293×205px recomandat. S’es pas configurat, mostrarem la mascòta per defaut
         title: Imatge de la mascòta
       peers_api_enabled:
-        desc_html: Noms de domeni qu’aquesta instància a trobats pel fediverse
-        title: Publicar la lista de las instàncias conegudas
+        desc_html: Noms de domeni qu’aqueste servidor a trobats pel fediverse
+        title: Publicar la lista dels servidors coneguts
       preview_sensitive_media:
         desc_html: Los apercebuts dels ligams sus los autres sites mostraràn una vinheta encara que lo mèdia siá marcat coma sensible
         title: Mostrar los mèdias sensibles dins los apercebuts OpenGraph
@@ -410,9 +403,10 @@ oc:
         min_invite_role:
           disabled: Degun
           title: Autorizat amb invitacions
-        open:
-          desc_html: Autorizar lo monde a se marcar
-          title: Inscripcions
+      registrations_mode:
+        modes:
+          none: Degun pòt pas se marcar
+        title: Mòdes d’inscripcion
       show_known_fediverse_at_about_page:
         desc_html: Un còp activat mostrarà los tuts de totes los fediverse dins l’apercebut. Autrament mostrarà pas que los tuts locals.
         title: Mostrar los fediverse coneguts dins l’apercebut del flux
@@ -421,20 +415,20 @@ oc:
         title: Mostrar lo badge personal
       site_description:
         desc_html: Paragraf d’introduccion sus la pagina d’acuèlh. Explicatz çò que fa diferent aqueste servidor Mastodon e tot çò qu’es important de dire. Podètz utilizare de balises HTML, en particular <code>&lt;a&gt;</code> e<code>&lt;em&gt;</code>.
-        title: Descripcion de l’instància
+        title: Descripcion del servidor
       site_description_extended:
-        desc_html: Afichada sus la pagina d’informacion complementària del site<br>Podètz utilizar de balisas HTML
+        desc_html: Un bon lòc per las règles de compòrtament e d’autras causas que fan venir vòstre servidor diferent. Podètz utilizar de balisas HTML
         title: Descripcion espandida del site
       site_short_description:
-        desc_html: Mostrat dins la barra laterala e dins las meta balisas. Explica çò qu’es Mastodon e perque aqueste servidor es especial en un solet paragraf. S’es void, serà garnit amb la descripcion de l’instància.
-        title: Descripcion corta de l’instància
+        desc_html: Mostrat dins la barra laterala e dins las meta balisas. Explica çò qu’es Mastodon e perque aqueste servidor es especial en un solet paragraf. S’es void, serà garnit amb la descripcion del servidor.
+        title: Descripcion corta del servidor
       site_terms:
         desc_html: Afichada sus la pagina de las condicions d’utilizacion<br>Podètz utilizar de balisas HTML
         title: Politica de confidencialitat del site
-      site_title: Títol del site
+      site_title: Títol del servidor
       thumbnail:
         desc_html: Servís pels apercebuts via OpenGraph e las API. Talha de 1200x630px recomandada
-        title: Miniatura de l’instància
+        title: Miniatura del servidor
       timeline_preview:
         desc_html: Mostrar lo flux public sus la pagina d’acuèlh
         title: Apercebut flux public
@@ -457,7 +451,6 @@ oc:
       confirmed: Confirmat
       expires_in: S’acaba dins
       last_delivery: Darrièra distribucion
-      title: WebSub
       topic: Subjècte
     tags:
       accounts: Comptes
@@ -466,7 +459,6 @@ oc:
       name: Etiqueta
       title: Etiquetas
       unhide: Aparéisser dins l’annuari
-      visible: Visible
     title: Administracion
     warning_presets:
       add_new: N’ajustar un nòu
@@ -481,7 +473,6 @@ oc:
       subject: Novèl senhalament per %{instance} (#%{id})
   application_mailer:
     notification_preferences: Cambiar las preferéncias de corrièl
-    salutation: "%{name},"
     settings: 'Cambiar las preferéncias de corrièl : %{link}'
     view: 'Veire :'
     view_profile: Veire lo perfil
@@ -495,8 +486,9 @@ oc:
     warning: Mèfi ! Agachatz de partejar aquela donada amb degun !
     your_token: Vòstre geton d’accès
   auth:
-    agreement_html: En vos marcar acceptatz <a href="%{rules_path}">las règlas de l’instància</a> e <a href="%{terms_path}">politica de confidencialitat</a>.
+    apply_for_account: Demandar una invitacion
     change_password: Senhal
+    checkbox_agreement_html: Accepti las <a href="%{rules_path}" target="_blank">règlas del servidor</a> e <a href="%{terms_path}" target="_blank">los tèrmes del servici</a>
     confirm_email: Confirmar lo corrièl
     delete_account: Suprimir lo compte
     delete_account_html: Se volètz suprimir vòstre compte, podètz <a href="%{path}">o far aquí</a>. Vos demandarem que confirmetz.
@@ -507,17 +499,14 @@ 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>.
-    or: o
     or_log_in_with: O autentificatz-vos amb
-    providers:
-      cas: CAS
-      saml: SAML
     register: Se marcar
-    register_elsewhere: Se marcar endacòm mai
+    registration_closed: "%{instance} accepta pas de nòus membres"
     resend_confirmation: Tornar mandar las instruccions de confirmacion
     reset_password: Reïnicializar lo senhal
     security: Seguretat
     set_new_password: Picar un nòu senhal
+    trouble_logging_in: Problèmas de connexion ?
   authorize_follow:
     already_following: Seguètz ja aqueste compte
     error: O planhèm, i a agut una error al moment de cercar lo compte
@@ -529,59 +518,6 @@ oc:
       return: Veire lo perfil a la persona
       web: Tornar a l’interfàcia Web
     title: Sègre %{acct}
-  date:
-    abbr_day_names:
-    - dg
-    - dl
-    - dm
-    - dc
-    - dj
-    - dv
-    - ds
-    abbr_month_names:
-    - None
-    - gen
-    - feb
-    - mar
-    - abr
-    - mai
-    - jun
-    - jul
-    - ago
-    - set
-    - oct
-    - nov
-    - dec
-    day_names:
-    - dimenge
-    - diluns
-    - dimars
-    - dimècres
-    - dijòus
-    - divendres
-    - dissabte
-    formats:
-      default: "%e/%m/%Y"
-      long: Lo %e %B de %Y
-      short: "%e %B de %Y"
-    month_names:
-    - None
-    - de genièr
-    - de febrièr
-    - de març
-    - d’abrial
-    - de mai
-    - de junh
-    - de julhet
-    - d’agost
-    - de setembre
-    - d’octòbre
-    - de novembre
-    - de decembre
-    order:
-    - :day
-    - :month
-    - :year
   datetime:
     distance_in_words:
       about_x_hours: "%{count} h"
@@ -595,17 +531,13 @@ oc:
       x_days: "%{count} jorns"
       x_minutes: "%{count} min"
       x_months: "%{count} meses"
-      x_seconds: "%{count}s"
-      x_years:
-        one: Fa un an
-        other: Fa %{count} ans
   deletes:
     bad_password_msg: Ben ensajat pirata ! Senhal incorrècte
     confirm_password: Picatz vòstre senhal actual per verificar vòstra identitat
     description_html: Aquò suprimirà <strong>definitivament e sens possibilitat de retorn</strong> lo contengut de vòstre compte e lo desactivarà. Lo nom d’utilizaire serà gardat per evitar una futura impostura.
     proceed: Suprimir lo compte
     success_msg: Compte ben suprimit
-    warning_html: La supression del contengut d’aquesta instància es sola assegurada. Lo contengut fòrça partejat daissarà probablament de traças. Los servidors fòra-linha e los que vos sègon pas mai auràn pas la mesa a jorn de lor basa de donada.
+    warning_html: La supression del contengut d’aqueste servidor es sola assegurada. Lo contengut fòrça partejat daissarà probablament de traças. Los servidors fòra-linha e los que vos sègon pas mai auràn pas la mesa a jorn de lor basa de donada.
     warning_title: Disponibilitat del contengut difusat
   directories:
     directory: Annuari de perfils
@@ -619,8 +551,8 @@ oc:
       other: "%{count} personas"
   errors:
     '403': Avètz pas l’autorizacion de veire aquesta pagina.
-    '404': La pagina que recercatz existís pas.
-    '410': La pagina que cercatz existís pas mai.
+    '404': La pagina que cercatz existís pas aquí.
+    '410': La pagina que cercatz existís pas mai aquí.
     '422':
       content: Verificacion de seguretat fracassada. Blocatz los cookies ?
       title: Verificacion de seguretat fracassada
@@ -638,12 +570,15 @@ oc:
       request: Demandar vòstre archiu
       size: Talha
     blocks: Personas que blocatz
-    csv: CSV
     domain_blocks: Blocatge de domenis
     follows: Personas que seguètz
     lists: Listas
     mutes: Personas rescondudas
     storage: Mèdias gardats
+  featured_tags:
+    add_new: Ajustar una etiqueta nòva
+    errors:
+      limit: Avètz ja utilizat lo maximum d’etiquetas
   filters:
     contexts:
       home: Flux d’acuèlh
@@ -660,34 +595,35 @@ oc:
       title: Filtres
     new:
       title: Ajustar un nòu filtre
-  followers:
-    domain: Domeni
-    explanation_html: Se volètz vos assegurar de la confidencialitat de vòstres estatuts, vos cal saber qual sèc vòstre compte. <strong>Vòstres estatuts privats son enviats a totas las instàncias qu’an de monde que vos sègon.</strong>. Benlèu que volètz repassar vòstra lista e tirar los seguidors s’avètz de dobtes tocant las politicas de confidencialitat dels gestionaris de lor instància o sul logicial qu’utilizan.
-    followers_count: Nombre de seguidors
-    lock_link: Clavar vòstre compte
-    purge: Tirar dels seguidors
-    success:
-      one: Soi a blocar los seguidors d’un domeni…
-      other: Soi a blocar los seguidors de %{count} domenis…
-    true_privacy_html: Mèfi que la <strong>vertadièra confidencialitat pòt solament èsser amb un chiframent del cap a la fin (end-to-end)</strong>.
-    unlocked_warning_html: Tot lo monde pòt vos sègre e veire sulpic vòstres estatuts privats. %{lock_link} per poder repassar e regetar los seguidors.
-    unlocked_warning_title: Vòstre compte es pas clavat
   footer:
     developers: Desvolopaires
     more: Mai…
     resources: Ressorsas
   generic:
+    all: Tot
     changes_saved_msg: Cambiaments ben realizats !
     copy: Copiar
     save_changes: Salvar los cambiaments
     validation_errors:
       one: I a quicòm que truca ! Mercés de corregir l’error çai-jos
       other: I a quicòm que truca ! Mercés de corregir las %{count} errors çai-jos
+  identity_proofs:
+    authorize: Ã’c, autorizar
+    authorize_connection_prompt: Autorizar aquesta connexion criptografica ?
+    i_am_html: Soi %{username} a %{service}.
+    identity: Identitat
+    status: Estatut de verificacion
   imports:
-    preface: Podètz importar qualques donadas coma lo monde que seguètz o blocatz a-n aquesta instància d’un fichièr creat d’una autra instància.
+    modes:
+      merge: Fondre
+      merge_long: Gardar los enregistraments existents e ajustar los nòus
+      overwrite: Remplaçar
+      overwrite_long: Remplaçar los enregistraments actuals pels nòus
+    preface: Podètz importar qualques donadas d’un autre servidor, coma lo monde que seguètz o blocatz.
     success: Vòstras donadas son ben estadas mandadas e seràn tractadas tre que possible
     types:
       blocking: Lista de blocatge
+      domain_blocking: Lista dels domenis blocats
       following: Lista de monde que seguètz
       muting: Lista de monde que volètz pas legir
     upload: Importar
@@ -709,11 +645,11 @@ oc:
       one: 1 persona
       other: "%{count} personas"
     max_uses_prompt: Cap de limit
-    prompt: Generar e partejar los ligams per donar accès a aquesta instància
+    prompt: Generar e partejar los ligams per donar accès a aqueste servidor
     table:
       expires_at: Expirats
       uses: Usatges
-    title: Convidar de mond
+    title: Convidar de monde
   lists:
     errors:
       limit: Avètz atengut lo maximum de listas
@@ -762,30 +698,33 @@ oc:
       body: "%{name} a tornat partejar vòstre estatut :"
       subject: "%{name} a tornat partejar vòstre estatut"
       title: Novèl partatge
-  number:
-    human:
-      decimal_units:
-        format: "%n%u"
-        units:
-          billion: B
-          million: M
-          quadrillion: Q
-          thousand: K
-          trillion: T
-          unit: ''
   pagination:
     newer: Mai recents
     next: Seguent
     older: Mai ancians
     prev: Precedent
-    truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: Avètz ja votat per aqueste sondatge
+      duplicate_options: conten d’opcions en doble
+      duration_too_long: es tròp alonhat dins lo futur
+      duration_too_short: es tròp d’ora
+      expired: Lo sondatge es ja acabat
+      over_character_limit: pòt pas èsser superior a %{max} caractèrs cadun
+      too_few_options: deu contenir mai d’una opcion
+      too_many_options: pòt pas contenir mai de %{max} opcions
   preferences:
-    languages: Lengas
     other: Autre
-    publishing: Publicar
-    web: Interfàcia Web
+  relationships:
+    activity: Activitat del compte
+    dormant: Inactiu
+    moved: Mudat
+    mutual: Mutuala
+    primary: Pirmària
+    relationship: Relacion
+    status: Estat del compte
   remote_follow:
-    acct: Picatz vòstre utilizaire@instància que cal utilizar per sègre aqueste utilizaire
+    acct: Picatz vòstre utilizaire@domeni que que volètz utilizar per sègre aqueste utilizaire
     missing_resource: URL de redireccion pas trobada
     no_account_html: Avètz pas cap de compte ? Podètz <a href='%{sign_up_path}' target='_blank'>vos marcar aquí</a>
     proceed: Clicatz per sègre
@@ -802,7 +741,6 @@ oc:
       proceed: Contunhar per respondre
       prompt: 'Volètz respondre a aqueste tut :'
   remote_unfollow:
-    error: Error
     title: Títol
     unfollowed: Pas mai seguit
   scheduled_statuses:
@@ -813,58 +751,28 @@ oc:
     activity: Darrièra activitat
     browser: Navigator
     browsers:
-      alipay: Alipay
-      blackberry: Blackberry
-      chrome: Chrome
-      edge: Microsoft Edge
-      electron: Electron
-      firefox: Firefox
       generic: Navigator desconegut
-      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: Session en cors
     description: "%{browser} sus %{platform}"
     explanation: Aquí los navigators connectats a vòstre compte Mastodon.
-    ip: IP
     platforms:
-      adobe_air: Adobe Air
-      android: Android
-      blackberry: Blackberry
-      chrome_os: ChromeOS
-      firefox_os: Firefox OS
-      ios: iOS
-      linux: Linux
-      mac: Mac
       other: plataforma desconeguda
-      windows: Windows
-      windows_mobile: Windows Mobile
-      windows_phone: Windows Phone
     revoke: Revocar
     revoke_success: Session ben revocada
-    title: Sessions
   settings:
     authorized_apps: Aplicacions autorizadas
     back: Tornar a Mastodon
     delete: Supression de compte
     development: Desvolopament
     edit_profile: Modificar lo perfil
-    export: Export donadas
-    followers: Seguidors autorizats
-    import: Importar
+    export: Exportar de donadas
+    featured_tags: Etiquetas en avant
+    import: Importar de donadas
     migrate: Migracion de compte
     notifications: Notificacions
     preferences: Preferéncias
-    settings: Paramètres
+    relationships: Abonaments e seguidors
     two_factor_authentication: Autentificacion en dos temps
-    your_apps: Vòstras aplicacions
   statuses:
     attached:
       description: 'Ajustat : %{attached}'
@@ -887,13 +795,17 @@ oc:
       ownership: Se pòt pas penjar lo tut de qualqu’un mai
       private: Se pòt pas penjar los tuts pas publics
       reblog: Se pòt pas penjar un tut partejat
+    poll:
+      total_votes:
+        one: "%{count} vòte"
+        other: "%{count} vòtes"
+      vote: Votar
     show_more: Ne veire mai
     sign_in_to_participate: Inscrivètz-vos per participar a la conversacion
     title: '%{name} : "%{quote}"'
     visibilities:
       private: Seguidors solament
       private_long: Mostrar pas qu’als seguidors
-      public: Public
       public_long: Tot lo monde pòt veire
       unlisted: Pas listat
       unlisted_long: Tot lo monde pòt veire mai serà pas visible sul flux public
@@ -907,10 +819,10 @@ oc:
       <h3 id="collect">Quinas informacions reculhèm ?</h3>
 
       <ul>
-        <li><em>Inforacions de basa del compte</em> :  se vos marcatz sus aqueste servidor, vos podèm demandar de picar un escais-nom, una adreça de corrièl e un senhal. Podètz tanben ajustar d’informacions de perfil addicionalas coma un nom de far veire, una biografia, un imatge de perfil e una banièra. L’escais-nom, lo nom d’afichatge, la biografia, l’imatge de perfil e la banièra son totjorn indicats per èsser vistes publicament.</li>
-        <li><em>Publicacions, abonaments e autras informacions publicas</em> : La lista del monde que seguètz es visibla publicament, tot parièr per vòstres seguidors. Quand enviatz un messatge, la data e l’ora son gardats, l’aplicacion qu’avètz utilizada tanben. Los messatges pòdon conténer de mèdias juntats coma d’imatge e vidèos. Las publicacions publicas e pas listadas son disponiblas publicament. Quand penjatz una publicacion per vòstre perfil, aquò tanben es visible per tot lo monde. Vòstras publicacions son mandadas a vòstre seguidors, dins qualques cases aquò significa que passaràn per diferents servidors e seràn copiadas e gardadas sus aqueles servidors. Quand escafatz de publicacions, aquò es tanben mandat a vòstre seguidors. L’accion de partejar o d’ajustar als favorits una publicacion es totjorn quicòm de public.</li>
-       <li><em>Publicacions dirèctas e solament pels seguidors</em> :</li> totas las publicacions son gardadas e tractadas pel servidor. Las publicacions pas que per vòstres seguidors son enviadas a vòstres seguidors e las personas mencionadas dedins, las publicacions dirèctas son pas qu’enviadas a las personas mencionadas. Dins qualques cases aquò significa que passaràn per diferents servidors, copiadas e gardadas sus eles. Ensagem de limitar l’accès a aquelas publicacions a monde autorizat, mas los demai servidors pòdon fracar a far parièr. A causa d’aquò es fòrça important de repassar los servidors d’apertenéncia de vòstres seguidors. Podètz activar una opcion per autorizar o regetar una demanda de seguiment dins los paramètres. <em>Vos cal pas oblidar que’ls administrators dels servidors e dels servidors de recepcion pòdon veire aqueles messatges</em>, e que’ls destinataris pòdon realizar de captura d’ecran, copiar e tornar partejar los messatges.<em>Partegetz pas cap informacion perilhosa sus Mastodon</em><li>.
-        <li><em>Adreças IP e autras metadonadas</em> : quand vos connectatz, enregistrem l’adreça IP qu’utilizatz per establir la connexion, e tanben lo nom de vòstre navigador. Totas las sessions de connexion son disponiblas per que las repassetz e tiretz dins los paramètres. Las darrièras adreças IP son salvagardas fins a 12 meses. Podèm tanben gardar de jornals d’audit del servidor que pòdon conténer las adreças IP de cada requèstas mandadas a nòstre servidor.</li>
+      <li><em>Inforacions de basa del compte</em> :  se vos marcatz sus aqueste servidor, vos podèm demandar de picar un escais-nom, una adreça de corrièl e un senhal. Podètz tanben ajustar d’informacions de perfil addicionalas coma un nom de far veire, una biografia, un imatge de perfil e una banièra. L’escais-nom, lo nom d’afichatge, la biografia, l’imatge de perfil e la banièra son totjorn indicats per èsser vistes publicament.</li>
+      <li><em>Publicacions, abonaments e autras informacions publicas</em> : La lista del monde que seguètz es visibla publicament, tot parièr per vòstres seguidors. Quand enviatz un messatge, la data e l’ora son gardats, l’aplicacion qu’avètz utilizada tanben. Los messatges pòdon conténer de mèdias juntats coma d’imatge e vidèos. Las publicacions publicas e pas listadas son disponiblas publicament. Quand penjatz una publicacion per vòstre perfil, aquò tanben es visible per tot lo monde. Vòstras publicacions son mandadas a vòstre seguidors, dins qualques cases aquò significa que passaràn per diferents servidors e seràn copiadas e gardadas sus aqueles servidors. Quand escafatz de publicacions, aquò es tanben mandat a vòstre seguidors. L’accion de partejar o d’ajustar als favorits una publicacion es totjorn quicòm de public.</li>
+      <li><em>Publicacions dirèctas e solament pels seguidors</em> :</li> totas las publicacions son gardadas e tractadas pel servidor. Las publicacions pas que per vòstres seguidors son enviadas a vòstres seguidors e las personas mencionadas dedins, las publicacions dirèctas son pas qu’enviadas a las personas mencionadas. Dins qualques cases aquò significa que passaràn per diferents servidors, copiadas e gardadas sus eles. Ensagem de limitar l’accès a aquelas publicacions a monde autorizat, mas los demai servidors pòdon fracar a far parièr. A causa d’aquò es fòrça important de repassar los servidors d’apertenéncia de vòstres seguidors. Podètz activar una opcion per autorizar o regetar una demanda de seguiment dins los paramètres. <em>Vos cal pas oblidar que’ls administrators dels servidors e dels servidors de recepcion pòdon veire aqueles messatges</em>, e que’ls destinataris pòdon realizar de captura d’ecran, copiar e tornar partejar los messatges.<em>Partegetz pas cap informacion perilhosa sus Mastodon</em><li>.
+      <li><em>Adreças IP e autras metadonadas</em> : quand vos connectatz, enregistrem l’adreça IP qu’utilizatz per establir la connexion, e tanben lo nom de vòstre navigador. Totas las sessions de connexion son disponiblas per que las repassetz e tiretz dins los paramètres. Las darrièras adreças IP son salvagardas fins a 12 meses. Podèm tanben gardar de jornals d’audit del servidor que pòdon conténer las adreças IP de cada requèstas mandadas a nòstre servidor.</li>
 
       </ul>
 
@@ -921,9 +833,9 @@ oc:
       <p>Totas las informacions que collectem de vos pòdon servir dins los cases seguents :</p>
 
       <ul>
-        <li>Per provesir la foncionament màger de Mastodon. Podètz pas qu’interagir amb lo contengut del monde e de vòstras publicacions quand sètz connectat. Per exemple, avètz la possibilitat de sègre de monde per veire lors publicacions amassadas dins vòstre flux d’actualitat personalizat.</li>
-        <li>Per ajudar la moderacion de la comunitat, per exemple en comparant vòstra adreça IP amb d’autras per determinar d’ensages de contornament de bandiment e d’autras violéncias.</li>
-        <li>Podèm utilizar l’adreça qu’avètz donada per vos enviar d’informacions e de notificacions que demandatz tocant de cambiaments dins los subjèctes del forum o en responsa a vòstre nom d’utilizaire, en responsa a una demanda, e/o tota autra question.</li>
+      <li>Per provesir la foncionament màger de Mastodon. Podètz pas qu’interagir amb lo contengut del monde e de vòstras publicacions quand sètz connectat. Per exemple, avètz la possibilitat de sègre de monde per veire lors publicacions amassadas dins vòstre flux d’actualitat personalizat.</li>
+      <li>Per ajudar la moderacion de la comunitat, per exemple en comparant vòstra adreça IP amb d’autras per determinar d’ensages de contornament de bandiment e d’autras violéncias.</li>
+      <li>Podèm utilizar l’adreça qu’avètz donada per vos enviar d’informacions e de notificacions que demandatz tocant de cambiaments dins los subjèctes del forum o en responsa a vòstre nom d’utilizaire, en responsa a una demanda, e/o tota autra question.</li>
       </ul>
 
       <hr class="spacer" />
@@ -938,8 +850,8 @@ oc:
       <p>Farem esfòrces per :</p>
 
       <ul>
-       <li>Gardar los jornals del servidor que contenon las adreças IP de totas las demandas al servidor pas mai de 90 jorns.</li>
-       <li>Gardar las adreças IP ligadas als utilizaires e lors publicacions pas mai de 12 messes.</li>
+      <li>Gardar los jornals del servidor que contenon las adreças IP de totas las demandas al servidor pas mai de 90 jorns.</li>
+      <li>Gardar las adreças IP ligadas als utilizaires e lors publicacions pas mai de 12 messes.</li>
       </ul>
 
       <p>Podètz demandar e telecargar vòstre archiu de contengut, amb vòstras publicacions, los mèdias enviats, l’imatge de perfil e l’imatge de bandièra.</p>
@@ -987,13 +899,12 @@ oc:
       <p>Prima adaptacion de la <a href="https://github.com/discourse/discourse">politica de confidencialitat de Discourse</a>.</p>
     title: Condicions d’utilizacion e politica de confidencialitat de %{instance}
   themes:
-    contrast: Fòrt contrast
-    default: Mastodon
-    mastodon-light: Mastodon (clar)
+    contrast: Mastodon (Fòrt contrast)
+    default: Mastodon (Escur)
+    mastodon-light: Mastodon (Clar)
   time:
     formats:
       default: Lo %d %b de %Y a %Ho%M
-      month: "%b %Y"
   two_factor_authentication:
     code_hint: Picatz lo còdi generat per vòstra aplicacion d’autentificacion per confirmar
     description_html: S’activatz <strong> l’autentificacion two-factor</strong>, vos caldrà vòstre mobil per vos connectar perque generarà un geton per vos daissar dintrar.
@@ -1038,7 +949,7 @@ oc:
       final_action: Començar de publicar
       final_step: 'Començatz de publicar ! Quitament s’avètz pas de seguidors los autres pòdon veire vòstres messatges publics, per exemple pel flux d’actualitat local e per las etiquetas. Benlèu que volètz vos presentar amb l’etiquetas #introductions.'
       full_handle: Vòstre escais-nom complèt
-      full_handle_hint: Es aquò que vos cal donar a vòstres amics per que pòscan vos escriure o sègre a partir d’una autra instància.
+      full_handle_hint: Es aquò que vos cal donar a vòstres amics per que pòscan vos escriure o sègre a partir d’un autre servidor.
       review_preferences_action: Cambiar las preferéncias
       review_preferences_step: Pensatz de configurar vòstras preferéncias, tal coma los corrièls que volètz recebrer o lo nivèl de confidencialitat de vòstres tuts per defaut. O se l’animacion vos dòna pas enveja de rendre, podètz activar la lectura automatica dels GIF.
       subject: Benvengut a Mastodon
diff --git a/config/locales/pl.yml b/config/locales/pl.yml
index 5ce007ba9f88961de88f4f571f055393f532f40e..78db4c6723440066a59675099917c0318409a41c 100644
--- a/config/locales/pl.yml
+++ b/config/locales/pl.yml
@@ -4,31 +4,30 @@ pl:
     about_hashtag_html: Znajdują się tu publiczne wpisy oznaczone hashtagiem <strong>#%{hashtag}</strong>. Możesz dołączyć do dyskusji, jeżeli posiadasz konto gdziekolwiek w Fediwersum.
     about_mastodon_html: Mastodon jest wolną i otwartą siecią społecznościową, zdecentralizowaną alternatywą dla zamkniętych, komercyjnych platform.
     about_this: O tej instancji
+    active_count_after: aktywni
+    active_footnote: Aktywni użytkownicy miesięcznie (MAU)
     administered_by: 'Administrowana przez:'
     api: API
     apps: Aplikacje
-    closed_registrations: Rejestracja na tej instancji jest obecnie zamknięta. Możesz jednak zarejestrować się na innej instancji, uzyskując dostęp do tej samej sieci.
+    apps_platforms: Korzystaj z Mastodona z poziomu iOS-a, Androida i innych
+    browse_directory: Przeglądaj katalog profilów i filtruj z uwzględnieniem zainteresowań
+    browse_public_posts: Przeglądaj strumień publicznych wpisów na Mastodonie na żywo
     contact: Kontakt
     contact_missing: Nie ustawiono
     contact_unavailable: Nie dotyczy
+    discover_users: Odkrywaj użytkowników
     documentation: Dokumentacja
     extended_description_html: |
       <h3>Dobre miejsce na zasady użytkowania</h3>
       <p>Nie ustawiono jeszcze szczegółowego opisu</p>
-    features:
-      humane_approach_body: Nauczeni na błędach innych sieci społecznościowych, zaprojektowaliśmy Mastodona tak, aby uniknąć częstych nadużyć.
-      humane_approach_title: Bardziej ludzkie podejście
-      not_a_product_body: Mastodon nie jest komercyjną siecią. Nie doświadczysz tu reklam, zbierania danych, ani centralnego ośrodka, tak jak w przypadku wielu rozwiązań.
-      not_a_product_title: Jesteś człowiekiem, nie produktem
-      real_conversation_body: Mając do dyspozycji 65535 znaków na wpis, rozdrobnienie zawartości i ostrzeżenia o multimediach, możesz wyrażać siebie na wszystkie możliwe sposoby.
-      real_conversation_title: Zaprojektowany do prawdziwych rozmów
-      within_reach_body: Wiele aplikacji dla Androida, iOS i innych platform dzięki przyjaznemu programistom API sprawia, że możesz utrzymywać kontakt ze znajomymi praktycznie wszędzie.
-      within_reach_title: Zawsze w Twoim zasięgu
+    federation_hint_html: Z kontem na %{instance}, możesz śledzić użytkowników każdego serwera Mastodona i nie tylko.
     generic_description: "%{domain} jest jednym z serwerów sieci"
+    get_apps: Spróbuj aplikacji mobilnej
     hosted_on: Mastodon uruchomiony na %{domain}
     learn_more: Dowiedz się więcej
-    other_instances: Lista instancji
     privacy_policy: Polityka prywatności
+    see_whats_happening: Zobacz co siÄ™ dzieje
+    server_stats: 'Statystyki serwera:'
     source_code: Kod źródłowy
     status_count_after:
       few: wpisów
@@ -36,6 +35,7 @@ pl:
       one: wpisu
       other: wpisów
     status_count_before: SÄ… autorami
+    tagline: Śledź znajomych i poznawaj nowych
     terms: Zasady użytkowania
     user_count_after:
       few: użytkowników
@@ -76,6 +76,7 @@ pl:
       admin: Administrator
       bot: Bot
       moderator: Moderator
+    unavailable: Profil niedostępny
     unfollow: Przestań śledzić
   admin:
     account_actions:
@@ -87,6 +88,8 @@ pl:
       delete: Usuń
       destroyed_msg: Pomyślnie usunięto notatkę moderacyjną!
     accounts:
+      approve: Przyjmij
+      approve_all: Zatwierdź wszystkie
       are_you_sure: JesteÅ› tego pewien?
       avatar: Awatar
       by_domain: Domena
@@ -132,15 +135,18 @@ pl:
       moderation:
         active: Aktywne
         all: Wszystkie
+        pending: OczekujÄ…ce
         silenced: Wyciszone
         suspended: Zawieszone
         title: Moderacja
       moderation_notes: Notatki moderacyjne
       most_recent_activity: Najnowsza aktywność
       most_recent_ip: Ostatnie IP
+      no_account_selected: Żadne konto nie zostało zmienione, bo żadne nie zostało wybrane
       no_limits_imposed: Nie nałożono ograniczeń
       not_subscribed: Nie zasubskrybowano
       outbox_url: Adres skrzynki nadawczej
+      pending: Oczekuje na przeglÄ…d
       perform_full_suspension: ZawieÅ›
       profile_url: Adres profilu
       promote: PodnieÅ› uprawnienia
@@ -148,6 +154,8 @@ pl:
       public: Publiczne
       push_subscription_expires: Subskrypcja PuSH wygasa
       redownload: Odśwież profil
+      reject: Odrzuć
+      reject_all: Odrzuć wszystkie
       remove_avatar: Usun awatar
       remove_header: Usuń nagłówek
       resend_confirmation:
@@ -174,6 +182,7 @@ pl:
       statuses: Wpisy
       subscribe: Subskrybuj
       suspended: Zawieszono
+      time_in_queue: Czekanie w kolejce %{time}
       title: Konta
       unconfirmed_email: Niepotwierdzony adres e-mail
       undo_silenced: Cofnij wyciszenie
@@ -226,7 +235,7 @@ pl:
       destroyed_msg: Pomyślnie usunięto emoji!
       disable: Wyłącz
       disabled_msg: Pomyślnie wyłączono emoji
-      emoji: Emoji
+      emoji: Emotikona
       enable: Włącz
       enabled_msg: Pomyślnie przywrócono emoji
       image_hint: Plik PNG ważący do 50KB
@@ -234,7 +243,7 @@ pl:
       new:
         title: Dodaj nowe niestandardowe emoji
       overwrite: ZastÄ…p
-      shortcode: Shortcode
+      shortcode: Krótki kod
       shortcode_hint: Co najmniej 2 znaki, tylko znaki alfanumeryczne i podkreślniki
       title: Niestandardowe emoji
       unlisted: Niewidoczne
@@ -249,6 +258,7 @@ pl:
       feature_profile_directory: Katalog profilów
       feature_registrations: Rejestracja
       feature_relay: Przekazywanie federacji
+      feature_timeline_preview: PodglÄ…d osi czasu
       features: Możliwości
       hidden_service: Federowanie z ukrytymi usługami
       open_reports: otwarte zgłoszenia
@@ -268,6 +278,7 @@ pl:
       created_msg: Blokada domen jest przetwarzana
       destroyed_msg: Blokada domeny nie może zostać odwrócona
       domain: Domena
+      existing_domain_block_html: Już narzuciłeś bardziej rygorystyczne limity na %{name}, musisz najpierw <a href="%{unblock_url}">je odblokować</a>.
       new:
         create: Utwórz blokadę
         hint: Blokada domen nie zabroni tworzenia wpisów kont w bazie danych, ale pozwoli na automatyczną moderację kont do nich należących.
@@ -312,6 +323,7 @@ pl:
       back_to_account: Wróć do konta
       title: ÅšledzÄ…cy %{acct}
     instances:
+      by_domain: Domena
       delivery_available: Doręczanie jest dostępne
       known_accounts:
         few: "%{count} znane konta"
@@ -336,6 +348,8 @@ pl:
         expired: Wygasłe
         title: Filtruj
       title: Zaproszenia
+    pending_accounts:
+      title: OczekujÄ…ce konta (%{count})
     relays:
       add_new: Dodaj nowy
       delete: Usuń
@@ -398,14 +412,14 @@ pl:
         desc_html: Modyfikuj wygląd pliku CSS ładowanego na każdej stronie
         title: Niestandardowy CSS
       hero:
-        desc_html: Wyświetlany na stronie głównej. Zalecany jest rozmiar przynajmniej 600x100 pikseli. Jeżeli nie ustawiony, zostanie użyta miniatura instancji
+        desc_html: Wyświetlany na stronie głównej. Zalecany jest rozmiar przynajmniej 600x100 pikseli. Jeżeli nie ustawiony, zostanie użyta miniatura serwera
         title: Obraz bohatera
       mascot:
         desc_html: Wyświetlany na wielu stronach. Zalecany jest rozmiar przynajmniej 293px × 205px. Jeżeli nie ustawiono, zostanie użyta domyślna
         title: Obraz maskotki
       peers_api_enabled:
-        desc_html: Nazwy domen, z którymi ta instancja wchodziła w interakcje
-        title: Publikuj listÄ™ znanych instancji
+        desc_html: Nazwy domen, z którymi ten serwer wchodził w interakcje
+        title: Publikuj listę znanych serwerów
       preview_sensitive_media:
         desc_html: Podgląd odnośników na innych instancjach będzie wyświetlał miniaturę nawet jeśli zawartość multimedialna zostanie oznaczona jako wrażliwa
         title: Wyświetlaj zawartość wrażliwą w podglądzie OpenGraph
@@ -422,9 +436,12 @@ pl:
         min_invite_role:
           disabled: Nikt
           title: Kto może zapraszać użytkowników
-        open:
-          desc_html: Pozwól każdemu na założenie konta
-          title: Otwarta rejestracja
+      registrations_mode:
+        modes:
+          approved: Przyjęcie jest wymagane do rejestracji
+          none: Nikt nie może się zarejestrować
+          open: Każdy może się zarejestrować
+        title: Tryb rejestracji
       show_known_fediverse_at_about_page:
         desc_html: Jeśli włączone, podgląd instancji będzie wyświetlał wpisy z całego Fediwersum. W innym przypadku, będą wyświetlane tylko lokalne wpisy.
         title: Pokazuj wszystkie znane wpisy na podglÄ…dzie instancji
@@ -433,20 +450,20 @@ pl:
         title: Pokazuj odznakÄ™ administracji
       site_description:
         desc_html: Akapit wprowadzający, widoczny na stronie głównej. Opisz, co czyni tę instancję wyjątkową. Możesz korzystać ze znaczników HTML, w szczególności <code>&lt;a&gt;</code> i <code>&lt;em&gt;</code>.
-        title: Opis instancji
+        title: Opis serwera
       site_description_extended:
-        desc_html: Dobre miejsce na zasady użytkowania, wprowadzenie i inne rzeczy, które wyróżniają tę instancję. Możesz korzystać ze znaczników HTML
+        desc_html: Dobre miejsce na zasady użytkowania, wprowadzenie i inne rzeczy, które wyróżniają ten serwer. Możesz korzystać ze znaczników HTML
         title: Niestandardowy opis strony
       site_short_description:
-        desc_html: Wyświetlany na pasku bocznym i w znacznikach meta. Opisz, czym jest Mastodon i czym wyróżnia się ta instancja w jednym akapicie. Jeżeli pusty, zostanie użyty opis instancji.
-        title: Krótki opis instancji
+        desc_html: Wyświetlany na pasku bocznym i w znacznikach meta. Opisz w jednym akapicie, czym jest Mastodon i czym wyróżnia się ten serwer. Jeżeli pusty, zostanie użyty opis serwera.
+        title: Krótki opis serwera
       site_terms:
         desc_html: Miejsce na własną politykę prywatności, zasady użytkowania i inne unormowania prawne. Możesz korzystać ze znaczników HTML
         title: Niestandardowe zasady użytkowania
-      site_title: Nazwa instancji
+      site_title: Nazwa serwera
       thumbnail:
         desc_html: 'Używana w podglądzie przez OpenGraph i API. Zalecany rozmiar: 1200x630 pikseli'
-        title: Miniatura instancji
+        title: Miniatura serwera
       timeline_preview:
         desc_html: Wyświetlaj publiczną oś czasu na stronie widocznej dla niezalogowanych
         title: PodglÄ…d osi czasu
@@ -459,7 +476,7 @@ pl:
         nsfw_on: Oznacz jako NSFW
       failed_to_execute: Nie udało się wykonać
       media:
-        title: Media
+        title: Multimedia
       no_media: Bez zawartości multimedialnej
       no_status_selected: Żaden wpis nie został zmieniony, bo żaden nie został wybrany
       title: Wpisy konta
@@ -475,7 +492,7 @@ pl:
       accounts: Konta
       hidden: Ukryte
       hide: Ukryj w katalogu
-      name: Hashtag
+      name: Hasztag
       title: Hashtagi
       unhide: Pokazuj w katalogu
       visible: Widoczne
@@ -487,10 +504,19 @@ pl:
       edit_preset: Edytuj szablon ostrzeżenia
       title: Zarządzaj szablonami ostrzeżeń
   admin_mailer:
+    new_pending_account:
+      body: Poniżej znajdują się szczegóły dotycząće nowego konta. Możesz przyjąć lub odrzucić to podanie.
+      subject: Nowe konto czeka na przeglÄ…d na %{instance} (%{username})
     new_report:
       body: Użytkownik %{reporter} zgłosił(a) %{target}
       body_remote: Użytkownik instancji %{domain} zgłosił(a) %{target}
       subject: Nowe zgłoszenie na %{instance} (#%{id})
+  appearance:
+    advanced_web_interface: Zaawansowany interfejs użytkownika
+    advanced_web_interface_hint: Jeśli chcesz użyć pełną szerokość swojego ekranu, zaawansowany interfejs użytkownika pozwala Ci skonfigurować wiele różnych kolumn, by zobaczyć jak najwięcej informacji kiedy tylko chcesz. Strona główna, Powiadomienia, Globalna oś czasu, dowolna ilość list i hasztagów.
+    animations_and_accessibility: Animacje i dostępność
+    confirmation_dialogs: Dialogi potwierdzenia
+    sensitive_content: Wrażliwa zawartość
   application_mailer:
     notification_preferences: Zmień ustawienia e-maili
     salutation: "%{name},"
@@ -507,8 +533,9 @@ pl:
     warning: Przechowuj te dane ostrożnie. Nie udostępniaj ich nikomu!
     your_token: Twój token dostępu
   auth:
-    agreement_html: Rejestrując się, oświadczasz, że zapoznałeś(-aś) się z <a href="%{rules_path}">informacjami o instancji</a> i <a href="%{terms_path}">zasadami korzystania z usługi</a>.
+    apply_for_account: PoproÅ› o zaproszenie
     change_password: Hasło
+    checkbox_agreement_html: Zgadzam się z <a href="%{rules_path}" target="_blank">regułami serwera</a> i <a href="%{terms_path}" target="_blank">zasadami korzystania z usługi</a>
     confirm_email: Potwierdź adres e-mail
     delete_account: Usunięcie konta
     delete_account_html: Jeżeli chcesz usunąć konto, <a href="%{path}">przejdź tutaj</a>. Otrzymasz prośbę o potwierdzenie.
@@ -519,17 +546,17 @@ 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}">zrobić to tutaj</a>.
-    or: lub
     or_log_in_with: Lub zaloguj się z użyciem
     providers:
       cas: CAS
       saml: SAML
     register: Rejestracja
-    register_elsewhere: Zarejestruj siÄ™ na innym serwerze
+    registration_closed: "%{instance} nie przyjmuje nowych członków"
     resend_confirmation: Ponownie prześlij instrukcje weryfikacji
     reset_password: Zresetuj hasło
     security: Bezpieczeństwo
     set_new_password: Ustaw nowe hasło
+    trouble_logging_in: Masz problem z zalogowaniem siÄ™?
   authorize_follow:
     already_following: Już śledzisz to konto
     error: Niestety, podczas sprawdzania zdalnego konta wystąpił błąd
@@ -543,7 +570,7 @@ pl:
     title: Śledź %{acct}
   datetime:
     distance_in_words:
-      about_x_hours: "%{count}h"
+      about_x_hours: "%{count}g"
       about_x_months: "%{count} miesięcy"
       about_x_years: "%{count} lat"
       almost_x_years: "%{count} lat"
@@ -561,12 +588,15 @@ pl:
     description_html: Ta opcja usunie <strong>bezpowrotnie i nieodwracalnie</strong> całą zawartość konta i zdezaktywuje je. Twoja nazwa użytkownika pozostanie zarezerwowana, aby zapobiec nadużyciom.
     proceed: Usuń konto
     success_msg: Twoje konto zostało pomyślnie usunięte
-    warning_html: Możemy usunąć zawartość jedynie w obrębie tej instancji. Zawartość udostępniona publicznie pozostawia trwałe ślady. Serwery niepodłączone do sieci bądź nieśledzące Twoich aktualizacji mogą zachować Twoje dane.
+    warning_html: Możemy usunąć zawartość jedynie w obrębie tego serwera. Zawartość udostępniona publicznie pozostawia trwałe ślady. Serwery niepodłączone do sieci bądź nieśledzące Twoich aktualizacji mogą zachować Twoje dane.
     warning_title: Dostępność usuniętej zawartości
   directories:
     directory: Katalog profilów
+    enabled: JesteÅ› obecnie zapisany(-a) do katalogu
+    enabled_but_waiting: Jesteś zapisany(-a) do katalogu, ale jeszcze nie śledzi Cię wystarczająca liczba osób (%{min_followers}), aby się tam pojawić.
     explanation: Poznaj profile na podstawie zainteresowań
     explore_mastodon: Odkrywaj %{title}
+    how_to_enable: Nie jesteś obecnie zapisany(-a) do katalogu. Poniżej możesz zapisać się. Użyj hashtagów w swoim opisie, aby zostać wyświetlonym pod określonymi hashtagami!
     people:
       few: "%{count} osoby"
       many: "%{count} osób"
@@ -584,6 +614,9 @@ pl:
       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="%{apps_path}">natywnych aplikacji</a> obsługującej Twoje urządzenie.
+  existing_username_validator:
+    not_found: nie znaleziono lokalnego użytkownika o tej nazwie
+    not_found_multiple: nie znaleziono %{usernames}
   exports:
     archive_takeout:
       date: Data
@@ -599,6 +632,10 @@ pl:
     lists: Listy
     mutes: Wyciszeni
     storage: UrzÄ…dzenie przechowujÄ…ce dane
+  featured_tags:
+    add_new: Dodaj nowy
+    errors:
+      limit: Już przekroczyłeś(-aś) maksymalną liczbę wyróżnionych hashtagów
   filters:
     contexts:
       home: Strona główna
@@ -615,33 +652,52 @@ pl:
       title: Filtry
     new:
       title: Dodaj nowy filtr
-  followers:
-    domain: Domena
-    explanation_html: Jeżeli chcesz mieć pewność, kto może przeczytać Twoje wpisy, musisz kontrolować, kto śledzi Twój profil. <strong>Twoje prywatne wpisy są dostarczane na te instancje, na których jesteś śledzony</strong>. Możesz sprawdzać, kto Cię śledzi i blokować ich, jeśli nie ufasz właścicielom lub oprogramowaniu danej instancji.
-    followers_count: Liczba śledzących
-    lock_link: Zablokuj swoje konto
-    purge: Przestań śledzić
-    success: W trakcie usuwania śledzących z %{count} domen…
-    true_privacy_html: Pamiętaj, że <strong>rzeczywista prywatność może zostać uzyskana wyłącznie dzięki szyfrowaniu end-to-end</strong>.
-    unlocked_warning_html: Każdy może Cię śledzić, dzięki czemu może zobaczyć Twoje niepubliczne wpisy. %{lock_link} aby móc kontrolować, kto Cię śledzi.
-    unlocked_warning_title: Twoje konto nie jest zablokowane
   footer:
     developers: Dla programistów
     more: Więcej…
     resources: Zasoby
   generic:
+    all: Wszystkie
     changes_saved_msg: Ustawienia zapisane!
+    copy: Kopiuj
+    order_by: Uporządkuj według
     save_changes: Zapisz zmiany
     validation_errors:
       few: Coś jest wciąż nie tak! Przejrzyj %{count} poniższe błędy
       many: Coś jest wciąż nie tak! Przejrzyj %{count} poniższych błędów
       one: Coś jest wciąż nie tak! Przyjrzyj się poniższemu błędowi
       other: Coś jest wciąż nie tak! Przejrzyj poniższe błędy (%{count})
+  html_validator:
+    invalid_markup: 'zawiera nieprawidłową składnię HTML: %{error}'
+  identity_proofs:
+    active: Aktywny
+    authorize: Tak, autoryzuj
+    authorize_connection_prompt: Czy chcesz autoryzować to połączenie kryptograficzne?
+    errors:
+      failed: Połączenioe kryptograficzne nie powiodło się. Spróbuj ponownie z poziomu %{provider}.
+      keybase:
+        invalid_token: Tokeny Keybase są hashami podpisów i musza składać się z 66 znaków heksadecymalnych
+        verification_failed: Keybase nie rozpoznaje tego tokenu jako podpisu użytkownika Keybase %{kb_username}. Spróbuj ponownie z poziomu Keybase.
+      wrong_user: Nie można utworzyć dowodu dla %{proving}, gdy jesteś zalogowany(-a) jako %{current}. Zaloguj się jako %{proving} i spróbuj ponownie.
+    explanation_html: Tutaj możesz połączyć kryptograficznie swoje inne tożsamości, takie jak profil Keybase. To pozwoli innym wysłać Ci szyfrowane wiadomości i zaufać zawartości którą im wysyłasz.
+    i_am_html: Jestem %{username} na %{service}.
+    identity: Tożsamość
+    inactive: Niekatywny
+    publicize_checkbox: 'I opublikuj to:'
+    publicize_toot: 'Udowodnione! Jestem %{username} na %{service}: %{url}'
+    status: Stan weryfikacji
+    view_proof: Wyświetl dowód
   imports:
+    modes:
+      merge: Połącz
+      merge_long: Zachowaj obecne wpisy i dodaj nowe
+      overwrite: Nadpisz
+      overwrite_long: ZastÄ…p obecne wpisy nowymi
     preface: Możesz zaimportować pewne dane (np. lista kont, które śledzisz lub blokujesz) do swojego konta na tym serwerze, korzystając z danych wyeksportowanych z innego serwera.
     success: Twoje dane zostały załadowane i zostaną niebawem przetworzone
     types:
       blocking: Lista blokowanych
+      domain_blocking: Lista zablokowanych domen
       following: Lista śledzonych
       muting: Lista wyciszonych
     upload: Załaduj
@@ -665,7 +721,7 @@ pl:
       one: jedno użycie
       other: "%{count} użyć"
     max_uses_prompt: Bez ograniczenia
-    prompt: Wygeneruj odnośniki i udostępnij je innym, aby pozwolić na rejestrację na instancji
+    prompt: Wygeneruj odnośniki i udostępnij je innym, aby pozwolić na rejestrację na tym serwerze
     table:
       expires_at: Wygaśnie po
       uses: Użycia
@@ -727,33 +783,69 @@ pl:
       decimal_units:
         format: "%n%u"
         units:
-          billion: B
-          million: M
-          quadrillion: Q
-          thousand: K
-          trillion: T
-          unit: ''
+          billion: mld
+          million: mil
+          quadrillion: bld
+          thousand: tys
+          trillion: bln
   pagination:
     newer: Nowsze
     next: Następna
     older: Starsze
     prev: Poprzednia
     truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: Już oddałeś(-aś) głos w tym głosowaniu
+      duplicate_options: zawiera powtarzajÄ…ce siÄ™ opcje
+      duration_too_long: jest zbyt odległa
+      duration_too_short: jest zbyt bliska
+      expired: To głosowanie już zakończyło się
+      over_character_limit: nie może zawierać więcej niż %{max} znaków
+      too_few_options: musi zawierać przynajmniej dwie opcje
+      too_many_options: nie może zawierać więcej niż %{max} opcji
   preferences:
-    languages: Języki
     other: Pozostałe
-    publishing: Publikowanie
-    web: Sieć
+    posting_defaults: Domyślne ustawienia wpisów
+    public_timelines: Publiczne osie czasu
+  relationships:
+    activity: Aktywność konta
+    dormant: Uśpione
+    last_active: Ostatnia aktywność
+    most_recent: Ostatnie
+    moved: Przeniesione
+    mutual: Wspólna
+    primary: Jednostronna
+    relationship: Relacja
+    remove_selected_domains: Usuń wszystkich śledzących z zaznaczonych domen
+    remove_selected_followers: Usuń zaznaczonych śledzących
+    remove_selected_follows: Przestań śledzić zaznaczonych użytkowników
+    status: Stan konta
   remote_follow:
     acct: Podaj swój adres (nazwa@domena), z którego chcesz wykonać działanie
     missing_resource: Nie udało się znaleźć adresu przekierowania z Twojej domeny
     no_account_html: Nie masz konta? Możesz <a href='%{sign_up_path}' target='_blank'>zarejestrować się tutaj</a>
     proceed: Śledź
     prompt: 'Zamierzasz śledzić:'
+    reason_html: "<strong>Dlaczego ten krok jest konieczny?</strong> <code>%{instance}</code> może nie być serwerem na którym jesteś zarejestrowany(-a), więc musisz zostać przekierowany(-a) na swój serwer."
+  remote_interaction:
+    favourite:
+      proceed: Przejdź do dodania do ulubionych
+      prompt: 'Chcesz dodać ten wpis do ulubionych:'
+    reblog:
+      proceed: Przejdź do podbicia
+      prompt: 'Chcesz podbić ten wpis:'
+    reply:
+      proceed: Przejdź do dodawania odpowiedzi
+      prompt: 'Chcesz odpowiedzieć na ten wpis:'
   remote_unfollow:
     error: Błąd
     title: Tytuł
-    unfollowed: Przestałeś śledzić
+    unfollowed: Przestałeś(-aś) śledzić
+  scheduled_statuses:
+    over_daily_limit: Przekroczyłeś(-aś) limit %{limit} zaplanowanych wpisów na ten dzień
+    over_total_limit: Przekroczyłeś(-aś) limit %{limit} zaplanowanych wpisów
+    too_soon: Zaplanowana data musi wypadać w przyszłości
   sessions:
     activity: Ostatnia aktywność
     browser: PrzeglÄ…darka
@@ -796,20 +888,25 @@ pl:
     revoke_success: Pomyślnie unieważniono sesję
     title: Sesje
   settings:
+    account: Konto
+    account_settings: Ustawienia konta
+    appearance: WyglÄ…d
     authorized_apps: Uwierzytelnione aplikacje
     back: Powrót do Mastodona
     delete: Usuń konto
     development: Tworzenie aplikacji
     edit_profile: Edytuj profil
     export: Eksportowanie danych
-    followers: Autoryzowani śledzący
+    featured_tags: Wyróżnione hashtagi
+    identity_proofs: Dowody tożsamości
     import: Importowanie danych
+    import_and_export: Import i eksport
     migrate: Migracja konta
     notifications: Powiadomienia
     preferences: Preferencje
-    settings: Ustawienia
+    profile: Profil
+    relationships: Śledzeni i śledzący
     two_factor_authentication: Uwierzytelnianie dwuetapowe
-    your_apps: Twoje aplikacje
   statuses:
     attached:
       description: 'Załączono: %{attached}'
@@ -825,7 +922,11 @@ pl:
         other: "%{count} filmów"
     boosted_from_html: Podbito przez %{acct_link}
     content_warning: 'Ostrzeżenie o zawartości: %{warning}'
-    disallowed_hashtags: 'zawiera niedozwolone hashtagi: %{tags}'
+    disallowed_hashtags:
+      few: 'zawiera niedozwolone hashtagi: %{tags}'
+      many: 'zawiera niedozwolone hashtagi: %{tags}'
+      one: 'zawiera niedozwolony hashtag: %{tags}'
+      other: 'zawiera niedozwolone hashtagi: %{tags}'
     language_detection: Automatycznie wykrywaj język
     open_in_web: Otwórz w przeglądarce
     over_character_limit: limit %{max} znaków przekroczony
@@ -834,6 +935,13 @@ pl:
       ownership: Nie możesz przypiąć cudzego wpisu
       private: Nie możesz przypiąć niepublicznego wpisu
       reblog: Nie możesz przypiąć podbicia wpisu
+    poll:
+      total_votes:
+        few: "%{count} głosy"
+        many: "%{count} głosy"
+        one: "%{count} głos"
+        other: "%{count} głosy"
+      vote: Głosuj
     show_more: Pokaż więcej
     sign_in_to_participate: Zaloguj się, aby udzielić się w tej konwersacji
     title: '%{name}: "%{quote}"'
@@ -854,10 +962,10 @@ pl:
       <h3 id="collect">Jakie informacje zbieramy?</h3>
 
       <ul>
-        <li><em>Podstawowe informacje o koncie</em>: Podczas rejestracji na tym serwerze, możesz zostać poproszony(-a) o wprowadzenie nazwy użytkownika, adresu e-mail i hasła. Możesz także wprowadzić dodatkowe informacje o profilu, takie jak nazwa wyświetlana i biografia oraz wysłać awatar i obraz nagłówka. Nazwa użytkownika, nazwa wyświetlana, biografia, awatar i obraz nagłówka są zawsze widoczne dla wszystkich.</li>
-        <li><em>Wpisy, śledzenie i inne publiczne informacje</em>: Lista osób które śledzisz jest widoczna publicznie, tak jak lista osób, które Cię śledzą. Jeżeli dodasz wpis, data i czas jego utworzenia i aplikacja, z której go wysłano są przechowywane. Wiadomości mogą zawierać załączniki multimedialne, takie jak zdjęcia i filmy. Publiczne i niewidoczne wpisy są dostępne publicznie. Udostępniony wpis również jest widoczny publicznie. Twoje wpisy są dostarczane obserwującym, co oznacza że jego kopie mogą zostać dostarczone i być przechowywane na innych serwerach. Kiedy usuniesz wpis, przestaje być widoczny również dla osób śledzących Cię. „Podbijanie” i dodanie do ulubionych jest zawsze publiczne.</li>
-        <li><em>Wpisy bezpośrednie i tylko dla śledzących</em>: Wszystkie wpisy są przechowywane i przetwarzane na serwerze. Wpisy przeznaczone tylko dla śledzących są widoczne tylko dla nich i osób wspomnianych we wpisie, a wpisy bezpośrednie tylko dla wspomnianych. W wielu przypadkach oznacza to, że ich kopie są dostarczane i przechowywane na innych serwerach. Staramy się ograniczać zasięg tych wpisów wyłącznie do właściwych odbiorców, ale inne serwery mogą tego nie robić. Ważne jest, aby sprawdzać jakich serwerów używają osoby, które Cię śledzą. Możesz aktywować opcję pozwalającą na ręczne akceptowanie i odrzucanie nowych śledzących. <em>Pamiętaj, że właściciele serwerów mogą zobaczyć te wiadomości</em>, a odbiorcy mogą wykonać zrzut ekranu, skopiować lub udostępniać ten wpis. <em>Nie udostępniaj wrażliwych danych z użyciem Mastodona.</em></li>
-        <li><em>Adresy IP i inne metadane</em>: Kiedy zalogujesz się, przechowujemy adres IP użyty w trakcie logowania wraz z nazwą używanej przeglądarki. Wszystkie aktywne sesje możesz zobaczyć (i wygasić) w ustawieniach. Ostatnio używany adres IP jest przechowywany przez nas do 12 miesięcy. Możemy również przechowywać adresy IP wykorzystywane przy każdym działaniu na serwerze.</li>
+      <li><em>Podstawowe informacje o koncie</em>: Podczas rejestracji na tym serwerze, możesz zostać poproszony(-a) o wprowadzenie nazwy użytkownika, adresu e-mail i hasła. Możesz także wprowadzić dodatkowe informacje o profilu, takie jak nazwa wyświetlana i biografia oraz wysłać awatar i obraz nagłówka. Nazwa użytkownika, nazwa wyświetlana, biografia, awatar i obraz nagłówka są zawsze widoczne dla wszystkich.</li>
+      <li><em>Wpisy, śledzenie i inne publiczne informacje</em>: Lista osób które śledzisz jest widoczna publicznie, tak jak lista osób, które Cię śledzą. Jeżeli dodasz wpis, data i czas jego utworzenia i aplikacja, z której go wysłano są przechowywane. Wiadomości mogą zawierać załączniki multimedialne, takie jak zdjęcia i filmy. Publiczne i niewidoczne wpisy są dostępne publicznie. Udostępniony wpis również jest widoczny publicznie. Twoje wpisy są dostarczane obserwującym, co oznacza że jego kopie mogą zostać dostarczone i być przechowywane na innych serwerach. Kiedy usuniesz wpis, przestaje być widoczny również dla osób śledzących Cię. „Podbijanie” i dodanie do ulubionych jest zawsze publiczne.</li>
+      <li><em>Wpisy bezpośrednie i tylko dla śledzących</em>: Wszystkie wpisy są przechowywane i przetwarzane na serwerze. Wpisy przeznaczone tylko dla śledzących są widoczne tylko dla nich i osób wspomnianych we wpisie, a wpisy bezpośrednie tylko dla wspomnianych. W wielu przypadkach oznacza to, że ich kopie są dostarczane i przechowywane na innych serwerach. Staramy się ograniczać zasięg tych wpisów wyłącznie do właściwych odbiorców, ale inne serwery mogą tego nie robić. Ważne jest, aby sprawdzać jakich serwerów używają osoby, które Cię śledzą. Możesz aktywować opcję pozwalającą na ręczne akceptowanie i odrzucanie nowych śledzących. <em>Pamiętaj, że właściciele serwerów mogą zobaczyć te wiadomości</em>, a odbiorcy mogą wykonać zrzut ekranu, skopiować lub udostępniać ten wpis. <em>Nie udostępniaj wrażliwych danych z użyciem Mastodona.</em></li>
+      <li><em>Adresy IP i inne metadane</em>: Kiedy zalogujesz się, przechowujemy adres IP użyty w trakcie logowania wraz z nazwą używanej przeglądarki. Wszystkie aktywne sesje możesz zobaczyć (i wygasić) w ustawieniach. Ostatnio używany adres IP jest przechowywany przez nas do 12 miesięcy. Możemy również przechowywać adresy IP wykorzystywane przy każdym działaniu na serwerze.</li>
       </ul>
 
       <hr class="spacer" />
@@ -867,9 +975,9 @@ pl:
       <p>Zebrane informacje mogą zostać użyte w następujące sposoby:</p>
 
       <ul>
-        <li>Aby dostarczyć podstawową funkcjonalność Mastodona. Możesz wchodzić w interakcje z zawartością tworzoną przez innych tylko gdy jesteś zalogowany. Na przykład, możesz śledzić innych, aby widzieć ich wpisy w dostosowanej osi czasu.</li>
-        <li>Aby wspomóc moderację społeczności, na przykład porównując Twój adres IP ze znanymi, aby rozpoznać próbę obejścia blokady i inne naruszenia.</li>
-        <li>Adres e-mail może zostać wykorzystany, aby wysyłać Ci informacje, powiadomienia o osobach wchodzących w interakcje z tworzoną przez Ciebie zawartością, wysyłających Ci wiadomości, odpowiadać na zgłoszenia i inne żądania lub zapytania.</li>
+      <li>Aby dostarczyć podstawową funkcjonalność Mastodona. Możesz wchodzić w interakcje z zawartością tworzoną przez innych tylko gdy jesteś zalogowany. Na przykład, możesz śledzić innych, aby widzieć ich wpisy w dostosowanej osi czasu.</li>
+      <li>Aby wspomóc moderację społeczności, na przykład porównując Twój adres IP ze znanymi, aby rozpoznać próbę obejścia blokady i inne naruszenia.</li>
+      <li>Adres e-mail może zostać wykorzystany, aby wysyłać Ci informacje, powiadomienia o osobach wchodzących w interakcje z tworzoną przez Ciebie zawartością, wysyłających Ci wiadomości, odpowiadać na zgłoszenia i inne żądania lub zapytania.</li>
       </ul>
 
       <hr class="spacer" />
@@ -885,8 +993,8 @@ pl:
       <p>Staramy siÄ™:</p>
 
       <ul>
-        <li>Przechowywać logi zawierające adresy IP używane przy każdym żądaniu do serwera przez nie dłużej niż 90 dni.</li>
-        <li>Przechowywać adresy IP przypisane do użytkowników przez nie dłużej niż 12 miesięcy.</li>
+      <li>Przechowywać logi zawierające adresy IP używane przy każdym żądaniu do serwera przez nie dłużej niż 90 dni.</li>
+      <li>Przechowywać adresy IP przypisane do użytkowników przez nie dłużej niż 12 miesięcy.</li>
       </ul>
 
       <p>Możesz zażądać i pobrać archiwum tworzonej zawartości, wliczając Twoje wpisy, załączniki multimedialne, awatar i zdjęcie nagłówka.</p>
@@ -932,12 +1040,12 @@ pl:
       <p>Bazowano na <a href="https://github.com/discourse/discourse">polityce prywatności Discourse</a>.</p>
     title: Zasady korzystania i polityka prywatności %{instance}
   themes:
-    contrast: Wysoki kontrast
-    default: Mastodon
-    mastodon-light: Mastodon (jasny)
+    contrast: Mastodon (Wysoki kontrast)
+    default: Mastodon (Ciemny)
+    mastodon-light: Mastodon (Jasny)
   time:
     formats:
-      default: "%b %d, %Y, %H:%M"
+      default: "%d. %b %Y, %H:%M"
       month: "%b %Y"
   two_factor_authentication:
     code_hint: Aby kontynuować, wprowadź kod wyświetlany przez aplikację uwierzytelniającą
@@ -983,7 +1091,7 @@ pl:
       final_action: Zacznij pisać
       final_step: 'Zacznij tworzyć! Nawet jeżeli nikt Cię nie śledzi, Twoje publiczne wiadomości będą widziane przez innych, na przykład na lokalnej osi czasu i w hashtagach. Możesz też utworzyć wpis wprowadzający używając hashtagu #introductions.'
       full_handle: Twój pełny adres
-      full_handle_hint: Ten adres możesz podać znajomym, aby mogli skontaktować się z Tobą lub zacząć śledzić z innej instancji.
+      full_handle_hint: Ten adres możesz podać znajomym, aby mogli skontaktować się z Tobą lub zacząć śledzić z innego serwera.
       review_preferences_action: Zmień ustawienia
       review_preferences_step: Upewnij się, że zmieniłeś(-aś) ustawienia, takie jak maile, które chciałbyś otrzymywać lub domyślne opcje prywatności. Jeżeli nie masz choroby lokomocyjnej, możesz włączyć automatyczne odtwarzanie animacji GIF.
       subject: Witaj w Mastodonie
diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml
index 785860ed4911205390b3793b9c71f85e9cf71f1b..d75e91b8bcf03bc1f3f4825352f3f8408bb18687 100644
--- a/config/locales/pt-BR.yml
+++ b/config/locales/pt-BR.yml
@@ -4,36 +4,32 @@ pt-BR:
     about_hashtag_html: Estes são toots públicos com a hashtag <strong>#%{hashtag}</strong>. Você pode interagir com eles se tiver uma conta em qualquer lugar no fediverso.
     about_mastodon_html: Mastodon é uma rede social baseada em protocolos abertos e software gratuito e de código aberto. É descentralizada como e-mail.
     about_this: Sobre
+    active_count_after: Ativo
+    active_footnote: Usuários ativos mensais (UAM)
     administered_by: 'Administrado por:'
-    api: API
     apps: Apps
-    closed_registrations: Os cadastros estão atualmente fechados nesta instância. No entanto, você pode procurar uma instância diferente na qual possa criar uma conta e acessar a mesma rede por lá.
+    apps_platforms: Use o Mastodon a partir de iOS, Android e outras plataformas
+    browse_directory: Navegue pelo diretório de perfis e filtre por interesses
+    browse_public_posts: Navegue pelos posts públicos sendo postados ao vivo no Mastodon
     contact: Contato
     contact_missing: Não definido
     contact_unavailable: Não disponível
+    discover_users: Descubra usuários
     documentation: Documentação
     extended_description_html: |
       <h3>Um bom lugar para regras</h3>
       <p>A descrição da instância ainda não foi feita.</p>
-    features:
-      humane_approach_body: Aprendendo com erros de outras redes, Mastodon tem como objetivo fazer decisões éticas de design para combater o desuso de redes sociais.
-      humane_approach_title: Uma abordagem mais humana
-      not_a_product_body: Mastodon não é uma rede comercial. Sem propagandas, coleta de dados, jardins fechados. Não há uma autoridade central.
-      not_a_product_title: Você é uma pessoa e não um produto
-      real_conversation_body: Com 65535 caracteres à sua disposição e suporte para conteúdo granular e avisos de conteúdo, você pode se expressar da maneira que desejar.
-      real_conversation_title: Feito para conversas reais
-      within_reach_body: Vários apps para iOS, Android e outras plataformas graças a um ecossistema de API amigável para desenvolvedores permitem que você possa se manter atualizado sobre seus amigos de qualquer lugar.
-      within_reach_title: Sempre ao seu alcance
+    federation_hint_html: Com uma conta em %{instance} você vai poder seguir pessoas em qualquer servidor Mastodon ou outros do fediverso.
     generic_description: "%{domain} é um servidor na rede"
+    get_apps: Experimente um aplicativo
     hosted_on: Mastodon hospedado em %{domain}
     learn_more: Saiba mais
-    other_instances: Lista de instâncias
     privacy_policy: Política de Privacidade
+    see_whats_happening: Veja o que está acontecendo
+    server_stats: 'Estatísticas do servidor:'
     source_code: Código-fonte
-    status_count_after:
-      one: status
-      other: status
     status_count_before: Autores de
+    tagline: Siga amigos e encontre novos
     terms: Termos de serviço
     user_count_after:
       one: usuário
@@ -58,16 +54,13 @@ pt-BR:
     people_who_follow: Pessoas que seguem %{name}
     pin_errors:
       following: Você tem que estar seguindo a pessoa que você quer sugerir
-    posts:
-      one: Toot
-      other: Toots
-    posts_tab_heading: Toots
     posts_with_replies: Toots e respostas
     reserved_username: Este usuário está reservado
     roles:
       admin: Administrador
       bot: Robô
       moderator: Moderador
+    unavailable: Perfil indisponível
     unfollow: Deixar de seguir
   admin:
     account_actions:
@@ -79,8 +72,9 @@ pt-BR:
       delete: Excluir
       destroyed_msg: Nota de moderação excluída com sucesso!
     accounts:
+      approve: Aprovar
+      approve_all: Aprovar tudo
       are_you_sure: Você tem certeza?
-      avatar: Avatar
       by_domain: Domínio
       change_email:
         changed_msg: E-mail da conta modificado com sucesso!
@@ -111,11 +105,9 @@ pt-BR:
       header: Cabeçalho
       inbox_url: URL da caixa de entrada
       invited_by: Convidado por
-      ip: IP
       joined: Se cadastrou
       location:
         all: Todos
-        local: Local
         remote: Remoto
         title: Localização
       login_status: Situação de login
@@ -124,15 +116,18 @@ pt-BR:
       moderation:
         active: Ativo
         all: Todos
+        pending: Pendente
         silenced: Silenciados
         suspended: Suspensos
         title: Moderação
       moderation_notes: Notas de moderação
       most_recent_activity: Atividade mais recente
       most_recent_ip: IP mais recente
+      no_account_selected: Nenhuma conta foi modificada, pois nenhuma conta foi selecionada
       no_limits_imposed: Nenhum limite imposto
       not_subscribed: Não está inscrito
       outbox_url: URL da caixa de saída
+      pending: Esperando revisão
       perform_full_suspension: Suspender
       profile_url: URL do perfil
       promote: Promover
@@ -140,6 +135,8 @@ pt-BR:
       public: Público
       push_subscription_expires: Inscrição PuSH expira
       redownload: Atualizar perfil
+      reject: Rejeitar
+      reject_all: Rejeitar tudo
       remove_avatar: Remover avatar
       remove_header: Remover cabeçalho
       resend_confirmation:
@@ -173,7 +170,6 @@ pt-BR:
       unsubscribe: Desinscrever-se
       username: Nome de usuário
       warn: Notificar
-      web: Web
     action_logs:
       actions:
         assigned_to_self_report: "%{name} designou a denúncia %{target} para si"
@@ -218,7 +214,6 @@ pt-BR:
       destroyed_msg: Emoji deletado com sucesso!
       disable: Desabilitar
       disabled_msg: Emoji desabilitado com sucesso
-      emoji: Emoji
       enable: Habilitar
       enabled_msg: Emoji habilitado com sucesso
       image_hint: PNG de até 50KB
@@ -241,13 +236,13 @@ pt-BR:
       feature_profile_directory: Diretório de perfis
       feature_registrations: Cadastros
       feature_relay: Repetidor da federação
+      feature_timeline_preview: pré-visualização da timeline
       features: Funcionalidades
       hidden_service: Federação com serviços onion
       open_reports: Denúncias em aberto
       recent_users: Usuários recentes
       search: Pesquisa em texto
       single_user_mode: Modo de usuário único
-      software: Software
       space: Uso de espaço em disco
       title: Painel de controle
       total_users: usuários no total
@@ -302,6 +297,7 @@ pt-BR:
       back_to_account: Voltar para a conta
       title: Pessoas que seguem %{acct}
     instances:
+      by_domain: Domínio
       delivery_available: Entrega está disponível
       known_accounts:
         one: "%{count} conta conhecida"
@@ -324,6 +320,8 @@ pt-BR:
         expired: Expirados
         title: Filtro
       title: Convites
+    pending_accounts:
+      title: Contas pendentes (%{count})
     relays:
       add_new: Adicionar novo repetidor
       delete: Excluir
@@ -337,7 +335,6 @@ pt-BR:
       pending: Esperando pela aprovação do repetidor
       save_and_enable: Salvar e habilitar
       setup: Configurar uma conexão de repetidor
-      status: Status
       title: Repetidores
     report_notes:
       created_msg: Nota de denúncia criada com sucesso!
@@ -367,7 +364,6 @@ pt-BR:
       reported_by: Denunciada por
       resolved: Resolvido
       resolved_msg: Denúncia resolvida com sucesso!
-      status: Status
       title: Denúncias
       unassign: Desatribuir
       unresolved: Não resolvido
@@ -381,7 +377,7 @@ pt-BR:
         title: Usuários a serem seguidos por padrão por novas contas
       contact_information:
         email: E-mail
-        username: Contate usuário
+        username: Usuário de contato
       custom_css:
         desc_html: Modificar o visual com CSS que é carregado em todas as páginas
         title: CSS customizado
@@ -410,9 +406,12 @@ pt-BR:
         min_invite_role:
           disabled: Ninguém
           title: Permitir convites de
-        open:
-          desc_html: Permitir que qualquer um crie uma conta
-          title: Cadastro aberto
+      registrations_mode:
+        modes:
+          approved: Aprovação necessária para cadastro
+          none: Ninguém pode se cadastrar
+          open: Qualquer um pode se cadastrar
+        title: Modo de cadastro
       show_known_fediverse_at_about_page:
         desc_html: Quando ligado, vai mostrar toots de todo o fediverso conhecido na prévia da timeline. Senão, mostra somente toots locais.
         title: Mostrar fediverso conhecido na prévia da timeline
@@ -457,14 +456,11 @@ pt-BR:
       confirmed: Confirmado
       expires_in: Expira em
       last_delivery: Última entrega
-      title: WebSub
       topic: Tópico
     tags:
       accounts: Contas
       hidden: Escondido
       hide: Esconder do diretório
-      name: Hashtag
-      title: Hashtags
       unhide: Mostrar no diretório
       visible: Visível
     title: Administração
@@ -475,13 +471,15 @@ pt-BR:
       edit_preset: Editar o aviso pré-definido
       title: Gerenciar os avisos pré-definidos
   admin_mailer:
+    new_pending_account:
+      body: Os detalhes da nova conta estão abaixo. Você pode aprovar ou rejeitar essa aplicação.
+      subject: Nova conta para revisão em %{instance} (%{username})
     new_report:
       body: "%{reporter} denunciou %{target}"
       body_remote: Alguém da instância %{domain} reportou %{target}
       subject: Nova denúncia sobre %{instance} (#%{id})
   application_mailer:
     notification_preferences: Mudar preferências de e-mail
-    salutation: "%{name},"
     settings: 'Mudar e-mail de preferência: %{link}'
     view: 'Visualizar:'
     view_profile: Ver perfil
@@ -495,8 +493,9 @@ pt-BR:
     warning: Tenha cuidado com estes dados. Nunca compartilhe com alguém!
     your_token: Seu token de acesso
   auth:
-    agreement_html: Ao se cadastrar você concorda em seguir <a href="%{rules_path}">as regras da instância</a> e <a href="%{terms_path}">os nossos termos de serviço</a>.
+    apply_for_account: Pedir um convite
     change_password: Senha
+    checkbox_agreement_html: Eu concordo com <a href="%{rules_path}" target="_blank">as regras do servidor</a> e com <a href="%{terms_path}" target="_blank">os termos de serviço</a>
     confirm_email: Confirmar e-mail
     delete_account: Excluir conta
     delete_account_html: Se você deseja excluir a sua conta, você pode <a href="%{path}">prosseguir para cá</a>. Uma confirmação será requisitada.
@@ -507,17 +506,14 @@ pt-BR:
     logout: Sair
     migrate_account: Mudar para uma conta diferente
     migrate_account_html: Se você quer redirecionar essa conta para uma outra você pode <a href="%{path}">configurar isso aqui</a>.
-    or: ou
     or_log_in_with: Ou faça login com
-    providers:
-      cas: CAS
-      saml: SAML
     register: Cadastrar-se
-    register_elsewhere: Cadastrar-se em um outro servidor
+    registration_closed: "%{instance} não está aceitando novos membros"
     resend_confirmation: Reenviar instruções de confirmação
     reset_password: Redefinir senha
     security: Segurança
     set_new_password: Definir uma nova senha
+    trouble_logging_in: Problemas para se conectar?
   authorize_follow:
     already_following: Você já está seguindo esta conta
     error: Infelizmente, ocorreu um erro ao buscar a conta remota
@@ -531,7 +527,6 @@ pt-BR:
     title: Seguir %{acct}
   datetime:
     distance_in_words:
-      about_x_hours: "%{count}h"
       about_x_months: "%{count} meses"
       about_x_years: "%{count} anos"
       almost_x_years: "%{count} anos"
@@ -553,8 +548,11 @@ pt-BR:
     warning_title: Disponibilidade de conteúdo disseminado
   directories:
     directory: Diretório de perfis
+    enabled: Você está na lista do diretório.
+    enabled_but_waiting: Você escolheu ser listado no diretório, mas você ainda não tem o mínimo de seguidores (%{min_followers}) para ser listado.
     explanation: Descobrir usuários baseado em seus interesses
     explore_mastodon: Explorar %{title}
+    how_to_enable: Você não se inscreveu no diretório. Você pode se inscrever abaixo. Use hashtags no texto da sua bio para ser listado em hashtags específicas!
     people:
       one: "%{count} pessoa"
       other: "%{count} pessoas"
@@ -570,6 +568,9 @@ pt-BR:
       content: Desculpe, algo deu errado.
       title: Esta página não está certa
     noscript_html: Para usar o aplicativo web do Mastodon, por favor ative o JavaScript. Ou, se quiser, experimente um dos <a href="%{apps_path}">apps nativos</a> para o Mastodon em sua plataforma.
+  existing_username_validator:
+    not_found: não foi possível encontrar um usuário local com esse nome de usuário
+    not_found_multiple: não foi possível encontrar %{usernames}
   exports:
     archive_takeout:
       date: Data
@@ -579,12 +580,15 @@ pt-BR:
       request: Solicitar o seu arquivo
       size: Tamanho
     blocks: Você bloqueou
-    csv: CSV
     domain_blocks: Bloqueios de domínio
     follows: Você segue
     lists: Listas
     mutes: Você silenciou
     storage: Armazenamento de mídia
+  featured_tags:
+    add_new: Adicionar uma nova hashtag
+    errors:
+      limit: Você atingiu o limite de hashtags em destaque
   filters:
     contexts:
       home: Página inicial
@@ -601,34 +605,50 @@ pt-BR:
       title: Filtros
     new:
       title: Adicionar novo filtro
-  followers:
-    domain: Domínio
-    explanation_html: Se você quer garantir a privacidade de suas postagens, você deve ficar atento a quem está te seguindo.<strong>Suas postagens privadas são enviadas para todas as instâncias em que você tem seguidores</strong>. Convém revisá-las e remover seguidores se você acredita que a sua privacidade não será respeitada pela equipe ou software destas instâncias.
-    followers_count: Número de seguidores
-    lock_link: Tranque a sua conta
-    purge: Remover de seus seguidores
-    success:
-      one: No processo de bloqueio suave de seguidores de outro domínio...
-      other: No processo de bloqueio suave de seguidores de outros %{count} domínios...
-    true_privacy_html: Lembre-se de que <strong>a verdadeira privacidade só pode ser alcançada através de encriptação ponto-a-ponto</strong>.
-    unlocked_warning_html: Qualquer pessoa pode te seguir e ver as suas postagens privadas. %{lock_link} para ser capaz de revisar e rejeitar seguidores.
-    unlocked_warning_title: A sua conta não está trancada
   footer:
     developers: Desenvolvedores
     more: Mais…
     resources: Recursos
   generic:
+    all: Tudo
     changes_saved_msg: Mudanças salvas com sucesso!
     copy: Copiar
+    order_by: Ordenar por
     save_changes: Salvar mudanças
     validation_errors:
       one: Algo não está certo! Por favor, reveja o erro abaixo
       other: Algo não está certo! Por favor, reveja os %{count} erros abaixo
+  html_validator:
+    invalid_markup: 'contém HTML inválido: %{error}'
+  identity_proofs:
+    active: Ativo
+    authorize: Sim, autorizar
+    authorize_connection_prompt: Autorizar essa conexão criptográfica?
+    errors:
+      failed: A conexão criptográfica falhou. Por favor tente novamente a partir de %{provider}.
+      keybase:
+        invalid_token: Tokens keybase são hashs de assinatura e devem conter 66 caracteres hexa
+        verification_failed: Keybase não reconhece esse token como uma assinatura do usuário keybase %{kb_username}. Por favor tente novamente a partir de Keybase.
+      wrong_user: Não é possível criar uma prova para %{proving} estando logado como %{current}. Faça login como %{proving} e tente novamente.
+    explanation_html: Você pode conectar criptograficamente suas outras identidades, tais quais seu perfil Keybase. Isso permite outras pessoas de lhe enviarem mensagens encriptadas e confiar no conteúdo que você as envia.
+    i_am_html: Eu sou %{username} em %{service}.
+    identity: Identidade
+    inactive: Inativo
+    publicize_checkbox: 'E publique isso:'
+    publicize_toot: 'Está provado! Eu sou %{username} no %{service}: %{url}'
+    status: Status da verificação
+    view_proof: Ver prova
   imports:
+    modes:
+      merge: Juntar
+      merge_long: Manter os registros existentes e adicionar os novos
+      overwrite: Sobreescrever
+      overwrite_long: Substituir os registros atuais com os novos
     preface: Você pode importar dados que você exportou de outra instância, como a lista de pessoas que você segue ou bloqueou.
     success: Os seus dados foram enviados com sucesso e serão processados em instantes
     types:
       blocking: Lista de bloqueio
+      domain_blocking: Lista de domínios bloqueados
       following: Pessoas que você segue
       muting: Lista de silêncio
     upload: Enviar
@@ -703,28 +723,36 @@ pt-BR:
       body: 'Sua postagem foi compartilhada por %{name}:'
       subject: "%{name} compartilhou a sua postagem"
       title: Novo compartilhamento
-  number:
-    human:
-      decimal_units:
-        format: "%n%u"
-        units:
-          billion: B
-          million: M
-          quadrillion: Q
-          thousand: K
-          trillion: T
-          unit: ''
   pagination:
     newer: Mais novo
     next: Próximo
     older: Mais antigo
     prev: Anterior
-    truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: Você já votou nessa enquete
+      duplicate_options: contém itens duplicados
+      duration_too_long: está muito longe no futuro
+      duration_too_short: é curto demais
+      expired: A enquete já terminou
+      over_character_limit: não pode ter mais que %{max} caracteres em cada
+      too_few_options: deve ter mais que um item
+      too_many_options: não pode ter mais que %{max} itens
   preferences:
-    languages: Idiomas
     other: Outro
-    publishing: Publicação
-    web: Web
+  relationships:
+    activity: Atividade da conta
+    dormant: Inativo
+    last_active: Ativo por último em
+    most_recent: Mais recente
+    moved: Mudou-se
+    mutual: Mútuo
+    primary: Primário
+    relationship: Relação
+    remove_selected_domains: Remover todos os seguidores dos domínios selecionados
+    remove_selected_followers: Remover os seguidores selecionados
+    remove_selected_follows: Deixar de seguir usuários selecionados
+    status: Status da conta
   remote_follow:
     acct: Insira o seu usuário@domínio a partir do qual você deseja agir
     missing_resource: Não foi possível encontrar a URL de direcionamento para a sua conta
@@ -754,58 +782,36 @@ pt-BR:
     activity: Última atividade
     browser: Navegador
     browsers:
-      alipay: Alipay
-      blackberry: Blackberry
-      chrome: Chrome
-      edge: Microsoft Edge
-      electron: Electron
-      firefox: Firefox
       generic: Navegador desconhecido
-      ie: Internet Explorer
-      micro_messenger: MicroMessenger
       nokia: Navegador Nokia S40 Ovi
-      opera: Opera
-      otter: Otter
-      phantom_js: PhantomJS
-      qq: QQ Browser
-      safari: Safari
-      uc_browser: UCBrowser
-      weibo: Weibo
     current_session: Sessão atual
     description: "%{browser} em %{platform}"
     explanation: Estes são os navegadores que estão conectados com a sua conta do Mastodon.
-    ip: IP
     platforms:
-      adobe_air: Adobe Air
-      android: Android
-      blackberry: Blackberry
-      chrome_os: ChromeOS
-      firefox_os: Firefox OS
-      ios: iOS
-      linux: Linux
-      mac: Mac
       other: Plataforma desconhecida
-      windows: Windows
-      windows_mobile: Windows Mobile
-      windows_phone: Windows Phone
     revoke: Revogar
     revoke_success: Sessão revogada com sucesso
     title: Sessões
   settings:
+    account: Conta
+    account_settings: Configurações da conta
+    appearance: Aparência
     authorized_apps: Apps autorizados
     back: Voltar para o Mastodon
     delete: Exclusão de conta
     development: Desenvolvimento
     edit_profile: Editar perfil
     export: Exportar dados
-    followers: Seguidores autorizados
+    featured_tags: Hashtags em destaque
+    identity_proofs: Provas de identidade
     import: Importar
+    import_and_export: Importar e exportar
     migrate: Migração de conta
     notifications: Notificações
     preferences: Preferências
-    settings: Configurações
+    profile: Perfil
+    relationships: Seguindo e seguidores
     two_factor_authentication: Autenticação em dois passos
-    your_apps: Seus aplicativos
   statuses:
     attached:
       description: 'Anexado: %{attached}'
@@ -828,9 +834,13 @@ pt-BR:
       ownership: Toots de outras pessoas não podem ser fixados
       private: Toot não-público não pode ser fixado
       reblog: Um compartilhamento não pode ser fixado
+    poll:
+      total_votes:
+        one: "%{count} voto"
+        other: "%{count} votos"
+      vote: Votar
     show_more: Mostrar mais
     sign_in_to_participate: Entre para participar dessa conversa
-    title: '%{name}: "%{quote}"'
     visibilities:
       private: Apenas seguidores
       private_long: Mostrar apenas para seguidores
@@ -848,10 +858,10 @@ pt-BR:
       <h3 id="collect">Que informação nós coletamos?</h3>
 
       <ul>
-        <li><em>Informação básica de conta</em>: Se você se registrar nesse servidor, podemos pedir que você utilize um nome de usuário, um e-mail e uma senha. Você também pode adicionar informações extras como um nome de exibição e biografia; enviar uma imagem de perfil e imagem de cabeçalho. O nome de usuário, nome de exibição, biografia, imagem de perfil e imagem de cabeçalho são sempre listadas publicamente.</li>
-        <li><em>Posts, informação de seguidores e outras informações públicas</em>: A lista de pessoas que você segue é listada publicamente, o mesmo é verdade para quem te segue. Quando você envia uma mensagem, a data e o horário são armazenados, assim como a aplicação que você usou para enviar a mensagem. Mensagens podem conter mídias anexadas, como imagens e vídeos. Posts públicos e não-listados estão disponíveis publicamente. Quando você destaca um post no seu perfil, isso também é uma informação pública. Seus posts são entregues aos seus seguidores e em alguns casos isso significa que eles são enviados para servidores diferentes e cópias são armazenadas nesses servidores. Quando você remove posts, essa informação também é entregue aos seus seguidores. O ato de compartilhar ou favoritar um outro post é sempre público.</li>
-        <li><em>Mensagens diretas e posts somente para seguidores</em>: Todos os posts são armazenados e processados no servidor. Posts somente para seguidores são entregues aos seus seguidores e usuários que são mencionados neles; mensagens diretas são entregues somente aos usuários mencionados nelas. Em alguns casos isso significa que as mensagens são entregues para servidores diferentes e cópias são armazenadas nesses servidores. Nós fazemos esforços substanciais para limitar o acesso dessas mensagens somente para as pessoas autorizadas, mas outros servidores podem não fazer o mesmo. É importante portanto revisar os servidores à qual seus seguidores pertencem. Você pode usar uma opção para aprovar ou rejeitar novos seguidores manualmente nas configurações. <em>Por favor tenha em mente que os operadores do servidor e de qualquer servidores do destinatário podem ver tais mensagens</em>, e que os destinatários podem fazer capturas de tela, copiar ou de outra maneira compartilhar as mensagens. <em>Não compartilhe informação confidencial pelo Mastodon.</em></li>
-        <li><em>IPs e outros metadados</em>: Quando você faz se autentica, nos guardamos o endereço de IP que você usou ao se autenticar e o nome do seu navegador da internet. Todas as sessões autenticadas são disponíveis para serem analisadas e revogadas nas configurações. O último endereço de IP usado é guardado por até 12 meses. Nós também podemos reter históricos do servidor que incluem o endereço de IP de todas as requisições ao nosso servidor.</li>
+      <li><em>Informação básica de conta</em>: Se você se registrar nesse servidor, podemos pedir que você utilize um nome de usuário, um e-mail e uma senha. Você também pode adicionar informações extras como um nome de exibição e biografia; enviar uma imagem de perfil e imagem de cabeçalho. O nome de usuário, nome de exibição, biografia, imagem de perfil e imagem de cabeçalho são sempre listadas publicamente.</li>
+      <li><em>Posts, informação de seguidores e outras informações públicas</em>: A lista de pessoas que você segue é listada publicamente, o mesmo é verdade para quem te segue. Quando você envia uma mensagem, a data e o horário são armazenados, assim como a aplicação que você usou para enviar a mensagem. Mensagens podem conter mídias anexadas, como imagens e vídeos. Posts públicos e não-listados estão disponíveis publicamente. Quando você destaca um post no seu perfil, isso também é uma informação pública. Seus posts são entregues aos seus seguidores e em alguns casos isso significa que eles são enviados para servidores diferentes e cópias são armazenadas nesses servidores. Quando você remove posts, essa informação também é entregue aos seus seguidores. O ato de compartilhar ou favoritar um outro post é sempre público.</li>
+      <li><em>Mensagens diretas e posts somente para seguidores</em>: Todos os posts são armazenados e processados no servidor. Posts somente para seguidores são entregues aos seus seguidores e usuários que são mencionados neles; mensagens diretas são entregues somente aos usuários mencionados nelas. Em alguns casos isso significa que as mensagens são entregues para servidores diferentes e cópias são armazenadas nesses servidores. Nós fazemos esforços substanciais para limitar o acesso dessas mensagens somente para as pessoas autorizadas, mas outros servidores podem não fazer o mesmo. É importante portanto revisar os servidores à qual seus seguidores pertencem. Você pode usar uma opção para aprovar ou rejeitar novos seguidores manualmente nas configurações. <em>Por favor tenha em mente que os operadores do servidor e de qualquer servidores do destinatário podem ver tais mensagens</em>, e que os destinatários podem fazer capturas de tela, copiar ou de outra maneira compartilhar as mensagens. <em>Não compartilhe informação confidencial pelo Mastodon.</em></li>
+      <li><em>IPs e outros metadados</em>: Quando você faz se autentica, nos guardamos o endereço de IP que você usou ao se autenticar e o nome do seu navegador da internet. Todas as sessões autenticadas são disponíveis para serem analisadas e revogadas nas configurações. O último endereço de IP usado é guardado por até 12 meses. Nós também podemos reter históricos do servidor que incluem o endereço de IP de todas as requisições ao nosso servidor.</li>
       </ul>
 
       <hr class="spacer" />
@@ -861,9 +871,9 @@ pt-BR:
       <p>Toda informação que coletamos de você pode ser usada das seguintes maneiras:</p>
 
       <ul>
-        <li>Para prover a funcionalidade básica do Mastodon. Você só pode interagir com o conteúdo de outras pessoas e postar seu próprio conteúdo estando autenticado. Por exemplo, você pode seguir outras pessoas para ver seus posts combinados na sua linha do tempo personalizada.</li>
-        <li>Para auxiliar na moderação da comunidade, por exemplo ao comparar o seu endereço de IP com outros endereços de IP conhecidos para determinar evasão de banimento e outras violações.</li>
-        <li>O endereço de email que você prover pode ser usado para lhe enviar informação, notificação sobre outras pessoas interagindo com o seu conteúdo ou lhe enviando mensagens e para responder a questões ou outros pedidos.</li>
+      <li>Para prover a funcionalidade básica do Mastodon. Você só pode interagir com o conteúdo de outras pessoas e postar seu próprio conteúdo estando autenticado. Por exemplo, você pode seguir outras pessoas para ver seus posts combinados na sua linha do tempo personalizada.</li>
+      <li>Para auxiliar na moderação da comunidade, por exemplo ao comparar o seu endereço de IP com outros endereços de IP conhecidos para determinar evasão de banimento e outras violações.</li>
+      <li>O endereço de email que você prover pode ser usado para lhe enviar informação, notificação sobre outras pessoas interagindo com o seu conteúdo ou lhe enviando mensagens e para responder a questões ou outros pedidos.</li>
       </ul>
 
       <hr class="spacer" />
@@ -879,8 +889,8 @@ pt-BR:
       <p>Nós fazemos esforços substanciais para:</p>
 
       <ul>
-        <li>Reter o histórico do servidor contendo os endereços de IP de todas as requisições feitas à esse servidor, e com respeito a quanto tempo esses logs são retidos, não mais que 90 dias.</li>
-        <li>Reter o endereço de IP associado com usuários registrados não mais que 12 meses.</li>
+      <li>Reter o histórico do servidor contendo os endereços de IP de todas as requisições feitas à esse servidor, e com respeito a quanto tempo esses logs são retidos, não mais que 90 dias.</li>
+      <li>Reter o endereço de IP associado com usuários registrados não mais que 12 meses.</li>
       </ul>
 
       <p>Você pode pedir e fazer o download de um arquivo de todo o conteúdo da sua conta, incluindo as suas mensagens, suas mídias anexadas, imagem de perfil e imagem de topo.</p>
@@ -926,12 +936,11 @@ pt-BR:
       <p>Adaptado originalmente a partir da <a href="https://github.com/discourse/discourse">política de privacidade Discourse</a>.</p>
     title: "%{instance} Termos de Serviço e Política de Privacidade"
   themes:
-    contrast: Alto contraste
-    default: Mastodon
+    contrast: Mastodon  (Alto contraste)
+    default: Mastodon (Escuro)
     mastodon-light: Mastodon (claro)
   time:
     formats:
-      default: "%b %d, %Y, %H:%M"
       month: "%B de %Y"
   two_factor_authentication:
     code_hint: Insira o código gerado pelo seu aplicativo auteticador para confirmar
diff --git a/config/locales/pt.yml b/config/locales/pt.yml
index 00f45588b67ab35ebf9a755235f1f601060ea564..9cd92f6bd8fc72f69540fc99e3e928c97142cd76 100644
--- a/config/locales/pt.yml
+++ b/config/locales/pt.yml
@@ -4,49 +4,62 @@ pt:
     about_hashtag_html: Estes são toots públicos marcados com <strong>#%{hashtag}</strong>. Podes interagir com eles se tiveres uma conta Mastodon.
     about_mastodon_html: Mastodon é uma rede social baseada em protocolos abertos da web e software livre e gratuito. É descentralizado como e-mail.
     about_this: Sobre esta instância
-    closed_registrations: Novos registos estão fechados nesta instância. No entanto! Podes procurar uma instância diferente na qual criar uma conta e obter acesso à mesma rede desde lá.
+    administered_by: 'Administrado por:'
+    apps: Aplicações móveis
     contact: Contacto
     contact_missing: Não configurado
     contact_unavailable: n.d.
+    documentation: Documentação
     extended_description_html: |
       <h3>Um bom lugar para regras</h3>
       <p>A descrição estendida ainda não foi configurada.</p>
-    features:
-      humane_approach_body: Aprendendo com erros de outras redes sociais, Mastodon tem como objetivo fazer decisões éticas de design para combater o utilização errada de redes sociais.
-      humane_approach_title: Uma abordagem mais humana
-      not_a_product_body: Mastodon não é uma rede comercial. Sem publicidade, sem recolha de dados ou portas fechadas. Não existe uma autoridade central.
-      not_a_product_title: Tu és uma pessoa, não um produto
-      real_conversation_body: Com 65535 caracteres à sua disposição e suporte para conteúdo granular e avisos de conteúdo, podes te expressar da forma que desejares.
-      real_conversation_title: Feito para conversas reais
-      within_reach_body: Várias aplicações para iOS, Android e outras plataformas graças a um ecossistema de API amigável para desenvolvedores, permitem-te que te mantenhas em contacto com os teus amigos em qualquer lugar.
-      within_reach_title: Sempre ao teu alcance
     generic_description: "%{domain} é um servidor na rede"
     hosted_on: Mastodon em %{domain}
     learn_more: Saber mais
-    other_instances: Outras instâncias
+    privacy_policy: Política de privacidade
     source_code: Código fonte
-    status_count_after: publicações
+    status_count_after:
+      one: publicação
+      other: publicações
     status_count_before: Que fizeram
-    user_count_after: utilizadores
+    terms: termos de serviço
+    user_count_after:
+      one: utilizador
+      other: utilizadores
     user_count_before: Casa para
     what_is_mastodon: O que é o Mastodon?
   accounts:
+    choices_html: 'escolhas de %{name}:'
     follow: Seguir
-    followers: Seguidores
+    followers:
+      one: Seguidor
+      other: Seguidores
     following: A seguir
-    media: Media
+    joined: Aderiu %{date}
+    last_active: última vez activo
+    link_verified_on: A posse deste link foi verificada em %{date}
     moved_html: "%{name} mudou-se para %{new_profile_link}:"
+    network_hidden: Esta informação não está disponível
     nothing_here: Não há nada aqui!
     people_followed_by: Pessoas seguidas por %{name}
     people_who_follow: Pessoas que seguem %{name}
-    posts: Posts
+    pin_errors:
+      following: Tu tens de estar a seguir a pessoa que pretendes apoiar
+    posts:
+      one: Publicação
+      other: Publicações
+    posts_tab_heading: Publicações
     posts_with_replies: Posts e Respostas
     reserved_username: Este nome de utilizadores é reservado
     roles:
       admin: Administrador
+      bot: Robô
       moderator: Moderador
     unfollow: Deixar de seguir
   admin:
+    account_actions:
+      action: Executar acção
+      title: Executar acção de moderação em %{acct}
     account_moderation_notes:
       create: Criar
       created_msg: Nota de moderação criada com sucesso!
@@ -55,9 +68,17 @@ pt:
     accounts:
       are_you_sure: Tens a certeza?
       by_domain: Domínio
+      change_email:
+        changed_msg: E-mail da conta alterado com sucesso!
+        current_email: E-mail actual
+        label: Alterar e-mail
+        new_email: Novo e-mail
+        submit: Alterar e-mail
+        title: Alterar e-mail para %{username}
       confirm: Confirme
       confirmed: Confirmado
       confirming: Confirmer
+      deleted: Apagada
       demote: Rebaixar
       disable: Desativar
       disable_two_factor_authentication: Desativar 2FA
@@ -73,17 +94,19 @@ pt:
       followers: Seguidores
       followers_url: URL dos seguidores
       follows: A seguir
+      header: Cabeçalho
       inbox_url: URL da caixa de entrada
-      ip: IP
+      invited_by: Convidado por
+      joined: Aderiu
       location:
         all: Todos
-        local: Local
         remote: Remoto
         title: Local
       login_status: Estado de início de sessão
       media_attachments: Media anexa
       memorialize: Converter em memorial
       moderation:
+        active: Activo
         all: Todos
         silenced: Silenciados
         suspended: Supensos
@@ -91,6 +114,7 @@ pt:
       moderation_notes: Notas de moderação
       most_recent_activity: Actividade mais recente
       most_recent_ip: IP mais recente
+      no_limits_imposed: Sem limites impostos
       not_subscribed: Não inscrito
       outbox_url: URL da caixa de saída
       perform_full_suspension: Fazer suspensão completa
@@ -100,6 +124,8 @@ pt:
       public: Público
       push_subscription_expires: A Inscrição PuSH expira
       redownload: Atualizar avatar
+      remove_avatar: Remover o avatar
+      remove_header: Remover o cabeçalho
       resend_confirmation:
         already_confirmed: Este usuário já está confirmado
         send: Reenviar um email de confirmação
@@ -120,21 +146,28 @@ pt:
         created_reports: Relatórios gerados por esta conta
         targeted_reports: Relatórios feitos sobre esta conta
       silence: Silêncio
+      silenced: Silenciada
       statuses: Status
       subscribe: Inscrever-se
+      suspended: Suspensa
       title: Contas
+      unconfirmed_email: E-mail não confirmado
       undo_silenced: Desfazer silenciar
       undo_suspension: Desfazer supensão
       unsubscribe: Cancelar inscrição
       username: Usuário
-      web: Web
+      warn: Aviso
     action_logs:
       actions:
+        assigned_to_self_report: "%{name} atribuiu o relatório %{target} a si próprios"
+        change_email_user: "%{name} alterou o endereço de e-mail do utilizador %{target}"
         confirm_user: "%{name} confirmou o endereço de e-mail do utilizador %{target}"
+        create_account_warning: "%{name} enviou um aviso para %{target}"
         create_custom_emoji: "%{name} enviado emoji novo %{target}"
         create_domain_block: "%{name} bloqueou o domínio %{target}"
         create_email_domain_block: "%{name} adicionou na lista negra o domínio de correio electrónico %{target}"
         demote_user: "%{name} rebaixou o utilizador %{target}"
+        destroy_custom_emoji: "%{name} destruiu o emoji %{target}"
         destroy_domain_block: "%{name} desbloqueou o domínio %{target}"
         destroy_email_domain_block: "%{name} adicionou na lista branca o domínio de correio electrónico %{target}"
         destroy_status: "%{name} removeu o publicação feita por %{target}"
@@ -145,14 +178,18 @@ pt:
         enable_user: "%{name} ativou o acesso para o utilizador %{target}"
         memorialize_account: "%{name} transformou a conta de %{target} em um memorial"
         promote_user: "%{name} promoveu o utilizador %{target}"
+        remove_avatar_user: "%{name} removeu o avatar de %{target}"
+        reopen_report: "%{name} reabriu o relatório %{target}"
         reset_password_user: "%{name} restabeleceu a palavra-passe do utilizador %{target}"
         resolve_report: "%{name} recusou o relatório %{target}"
         silence_account: "%{name} silenciou a conta de %{target}"
         suspend_account: "%{name} suspendeu a conta de %{target}"
+        unassigned_report: "%{name} não atribuiu o relatório %{target}"
         unsilence_account: "%{name} desativou o silêncio de %{target}"
         unsuspend_account: "%{name} desativou a suspensão de  %{target}"
         update_custom_emoji: "%{name} atualizou o emoji %{target}"
         update_status: "%{name} atualizou o estado de %{target}"
+      deleted_status: "(apagou a publicação)"
       title: Registo de auditoria
     custom_emojis:
       by_domain: Domínio
@@ -164,7 +201,6 @@ pt:
       destroyed_msg: Emoji destruído com sucesso!
       disable: Desativar
       disabled_msg: Desativado com sucesso este emoji
-      emoji: Emoji
       enable: Ativar
       enabled_msg: Ativado com sucesso este emoji
       image_hint: PNG de até 50KB
@@ -179,6 +215,27 @@ pt:
       update_failed_msg: Não foi possível atualizar esse emoji
       updated_msg: Emoji atualizado com sucesso!
       upload: Enviar
+    dashboard:
+      backlog: trabalhos atrasados
+      config: Configuração
+      feature_deletions: Eliminações da conta
+      feature_invites: Links de convites
+      feature_profile_directory: Directório de perfil
+      feature_registrations: Registos
+      feature_relay: Repetidor da federação
+      features: Componentes
+      hidden_service: Federação com serviços escondidos
+      open_reports: relatórios abertos
+      recent_users: Utilizadores recentes
+      search: Pesquisa com texto completo
+      single_user_mode: Modo de utilizador único
+      space: Utilização do espaço
+      title: Painel de controlo
+      total_users: total de utilizadores
+      trends: Tendências
+      week_interactions: interacções desta semana
+      week_users_active: activo esta semana
+      week_users_new: utilizadores nesta semana
     domain_blocks:
       add_new: Adicionar novo
       created_msg: Bloqueio do domínio está a ser processado
@@ -195,6 +252,13 @@ pt:
         title: Novo bloqueio de domínio
       reject_media: Rejeitar ficheiros de media
       reject_media_hint: Remove localmente arquivos armazenados e rejeita fazer guardar novos no futuro. Irrelevante na suspensão
+      reject_reports: Rejeitar relatórios
+      reject_reports_hint: Ignorar todos os relatórios vindos deste domínio. Irrelevantes para efectuar suspensões
+      rejecting_media: a rejeitar ficheiros de media
+      rejecting_reports: a rejeitar relatórios
+      severity:
+        silence: silenciado
+        suspend: suspenso
       show:
         affected_accounts:
           one: Uma conta na base de dados afectada
@@ -215,28 +279,81 @@ pt:
         create: Adicionar domínio
         title: Novo bloqueio de domínio de email
       title: Bloqueio de Domínio de Email
+    followers:
+      back_to_account: Voltar à conta
+      title: Seguidores de %{acct}
     instances:
+      by_domain: Domínio
+      delivery_available: Entrega disponível
+      known_accounts:
+        one: "%{count} conta conhecida"
+        other: "%{count} contas conhecidas"
+      moderation:
+        all: Todas
+        limited: Limitadas
+        title: Moderação
       title: Instâncias conhecidas
+      total_blocked_by_us: Bloqueadas por nós
+      total_followed_by_them: Seguidas por eles
+      total_followed_by_us: Seguidas por nós
+      total_reported: Relatórios sobre eles
+      total_storage: Anexos de media
     invites:
+      deactivate_all: Desactivar todos
       filter:
         all: Todos
         available: Disponíveis
         expired: Expirados
         title: Filtro
       title: Convites
+    relays:
+      add_new: Adicionar novo repetidor
+      delete: Apagar
+      description_html: Um <strong>repetidor da federação</strong> é um servidor intermediário que troca grandes volumes de publicações públicas entre servidores que o subscrevem e publicam. <strong>Ele pode ajudar pequenos e médios servidores a descobrir conteúdo do "fediverse"</strong>que, de outro modo, exigiria que os utilizadores locais seguissem manualmente outras pessoas em servidores remotos.
+      disable: Desactivar
+      disabled: Desactivado
+      enable: Activar
+      enable_hint: Uma vez activado, o teu servidor irá subscrever a todas as publicações deste repetidor e irá começar a enviar as suas publicações públicas para ele.
+      enabled: Ativado
+      inbox_url: URL do repetidor
+      pending: À espera da aprovação do repetidor
+      save_and_enable: Guardar e ativar
+      setup: Configurar uma ligação ao repetidor
+      status: Estado
+      title: Retransmissores
+    report_notes:
+      created_msg: Relatório criado com sucesso!
+      destroyed_msg: Relatório apagado com sucesso!
     reports:
+      account:
+        note: nota
+        report: relatório
       action_taken_by: Ação tomada por
       are_you_sure: Tens a certeza?
+      assign_to_self: Atribuí-me a mim
+      assigned: Atribuído ao moderador
       comment:
         none: Nenhum
+      created_at: Relatado
       mark_as_resolved: Marcar como resolvido
+      mark_as_unresolved: Marcar como não resolvido
+      notes:
+        create: Adicionar nota
+        create_and_resolve: Resolver com nota
+        create_and_unresolve: Reabrir com nota
+        delete: Apagar
+        placeholder: Descreve as ações que foram tomadas ou quaisquer outras atualizações relacionadas...
+      reopen: Reabrir relatório
       report: 'Denúncia #%{id}'
       reported_account: Conta denunciada
       reported_by: Denúnciada por
       resolved: Resolvido
+      resolved_msg: Relatório resolvido com sucesso!
       status: Estado
       title: Denúncias
+      unassign: Não atribuir
       unresolved: Por resolver
+      updated_at: Atualizado
     settings:
       activity_api_enabled:
         desc_html: Contagem semanais de publicações locais, utilizadores activos e novos registos
@@ -247,9 +364,24 @@ pt:
       contact_information:
         email: Inserir um endereço de email para tornar público
         username: Insira um nome de utilizador
+      custom_css:
+        desc_html: Modificar a aparência com CSS carregado em cada página
+        title: CSS personalizado
+      hero:
+        desc_html: Apresentado na primeira página. Pelo menos 600x100px recomendados. Quando não é definido, é apresentado o thumbnail do servidor
+        title: Imagem Hero
+      mascot:
+        desc_html: Apresentada em múltiplas páginas. Pelo menos 293x205px recomendados. Quando não é definida, é apresentada a mascote predefinida
+        title: Imagem da mascote
       peers_api_enabled:
         desc_html: Nomes de domínio que esta instância encontrou no fediverso
         title: Publicar lista de instâncias descobertas
+      preview_sensitive_media:
+        desc_html: Previsualização de links noutros websites irá apresentar uma miniatura, mesmo que a media seja marcada como sensível
+        title: Mostrar media sensível em previsualizações OpenGraph
+      profile_directory:
+        desc_html: Permite aos utilizadores serem descobertos
+        title: Ativar directório do perfil
       registrations:
         closed_message:
           desc_html: Mostrar na página inicial quando registos estão encerrados<br/>Podes usar tags HTML
@@ -260,9 +392,9 @@ pt:
         min_invite_role:
           disabled: Ninguém
           title: Permitir convites de
-        open:
-          desc_html: Permitir que qualquer um crie uma conta
-          title: Aceitar novos registos
+      show_known_fediverse_at_about_page:
+        desc_html: Quando comutado, irá mostrar a previsualização de publicações de todo o fediverse conhecido. De outro modo só mostrará publicações locais.
+        title: Mostrar o fediverse conhecido na previsualização da cronologia
       show_staff_badge:
         desc_html: Mostrar um crachá da equipa na página de utilizador
         title: Mostrar crachá da equipa
@@ -272,6 +404,9 @@ pt:
       site_description_extended:
         desc_html: Mostrar na página de mais informações<br/>Podes usar tags HTML
         title: Página de mais informações
+      site_short_description:
+        desc_html: Mostrada na barra lateral e em etiquetas de metadados. Descreve o que o Mastodon é e o que torna este servidor especial num único parágrafo. Se deixada em branco, remete para a descrição do servidor.
+        title: Breve descrição do servidor
       site_terms:
         desc_html: Podes escrever a tua própria política de privacidade, termos de serviço, entre outras coisas. Podes usar tags HTML
         title: Termos de serviço customizados
@@ -293,23 +428,35 @@ pt:
       media:
         title: Média
       no_media: Não há média
+      no_status_selected: Nenhum estado foi alterado porque nenhum foi selecionado
       title: Estado das contas
-      with_media: Com média
+      with_media: Com media
     subscriptions:
       callback_url: URL de Callback
       confirmed: Confirmado
       expires_in: Expira em
       last_delivery: Última entrega
-      title: WebSub
       topic: Tópico
+    tags:
+      accounts: Contas
+      hidden: Escondidas
+      hide: Esconder no diretório
+      unhide: Mostrar no diretório
+      visible: Visível
     title: Administração
+    warning_presets:
+      add_new: Adicionar novo
+      delete: Apagar
+      edit: Editar
+      edit_preset: Editar o aviso predefinido
+      title: Gerir os avisos predefinidos
   admin_mailer:
     new_report:
       body: "%{reporter} relatou %{target}"
+      body_remote: Alguém de %{domain} relatou %{target}
       subject: Novo relatório sobre %{instance} (#%{id})
   application_mailer:
     notification_preferences: Alterar preferências de e-mail
-    salutation: "%{name},"
     settings: 'Alterar preferências de email: %{link}'
     view: 'Ver:'
     view_profile: Ver perfil
@@ -323,7 +470,7 @@ pt:
     warning: Cuidado com estes dados. Não partilhar com ninguém!
     your_token: O teu token de acesso
   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: 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.
@@ -334,12 +481,14 @@ pt:
     logout: Sair
     migrate_account: Mudar para uma conta diferente
     migrate_account_html: Se desejas redirecionar esta conta para uma outra podes<a href="%{path}">configurar isso aqui</a>.
+    or_log_in_with: Ou iniciar sessão com
     register: Registar
     resend_confirmation: Reenviar instruções de confirmação
     reset_password: Criar nova palavra-passe
     security: Alterar palavra-passe
     set_new_password: Editar palavra-passe
   authorize_follow:
+    already_following: Tu já estás a seguir esta conta
     error: Infelizmente, ocorreu um erro ao buscar a conta remota
     follow: Seguir
     follow_request: 'Enviaste uma solicitação de seguidor para:'
@@ -351,7 +500,6 @@ pt:
     title: Seguir %{acct}
   datetime:
     distance_in_words:
-      about_x_hours: "%{count}h"
       about_x_months: "%{count} meses"
       about_x_years: "%{count} anos"
       almost_x_years: "%{count} anos"
@@ -373,6 +521,16 @@ pt:
       Apenas a eliminação de conteúdo desta instância é garantido.
       Conteúdo que tenha sido partilhado com outras instâncias muito provavelmente deixará pegadas. Servidores offline e servidores que se desinscreveram das tuas atualizações não  atualizarão as suas bases de dados.
     warning_title: Disponibilidade de conteúdo disseminado
+  directories:
+    directory: Dirétorio de perfil
+    enabled: Neste momento tu estás listado no dirétorio.
+    enabled_but_waiting: Tu escolheste ser listado no diretório, mas ainda não tens o número mínimo de seguidores (%{min_followers}) para integrares esta lista.
+    explanation: Descobre utilizadores com base nos seus interesses
+    explore_mastodon: Explorar %{title}
+    how_to_enable: Tu ainda não integras este directório. Podes fazer isso abaixo. Usa hashtags na tua biografia para seres listado em hashtags específicas!
+    people:
+      one: "%{count} pessoa"
+      other: "%{count} pessoas"
   errors:
     '403': Não tens a permissão necessária para ver esta página.
     '404': A página que estás a procurar não existe.
@@ -386,34 +544,61 @@ pt:
       title: Esta página não está correta
     noscript_html: Para usar o aplicativo web do Mastodon, por favor ativa o JavaScript. Alternativamente, experimenta um dos <a href="%{apps_path}">apps nativos</a> para o Mastodon na sua plataforma.
   exports:
+    archive_takeout:
+      date: Data
+      download: Descarregar o teu arquivo
+      hint_html: Podes pedir um arquivo das tuas <strong> publicações e ficheiros de media carregados</strong>. Os dados do ficheiro exportado estarão no formato ActivityPub, que pode ser lido com qualquer software compatível. Tu podes pedir um arquivo destes a cada 7 dias.
+      in_progress: A compilar o seu arquivo...
+      request: Pede o teu arquivo
+      size: Tamanho
     blocks: Bloqueaste
-    csv: CSV
+    domain_blocks: Bloqueios de domínio
     follows: Segues
+    lists: Listas
     mutes: Tens em silêncio
     storage: Armazenamento de média
-  followers:
-    domain: Domínio
-    explanation_html: Se  queres garantir a privacidade das tuas publicações, deves ficar atento a quem te está a seguir.<strong>As tuas publicações privadas são enviadas para todas as instâncias nas que tens seguidores</strong>. Convém revisá-las e remover seguidores se achares que a tua privacidade não será respeitada pela equipa ou software destas instâncias.
-    followers_count: Número de seguidores
-    lock_link: Bloquear a tua conta
-    purge: Eliminar dos seguidores
-    success:
-      one: No processo de bloqueio suave de seguidores de outro domínio...
-      other: No processo de bloqueio suave de seguidores de outros %{count} domínios...
-    true_privacy_html: Por favor leva em conta que <strong>a verdadeira privacidade só pode ser alcançada através de encriptação ponto-a-ponto</strong>.
-    unlocked_warning_html: Qualquer pessoa pode seguir-te e ver as tuas publicações privadas. %{lock_link} para ser capaz de revisar e rejeitar seguidores.
-    unlocked_warning_title: A tua conta não está bloqueada
+  featured_tags:
+    add_new: Adicionar nova
+    errors:
+      limit: Já atingiste o limite máximo de hashtags
+  filters:
+    contexts:
+      home: Cronologia inicial
+      notifications: Notificações
+      public: Cronologias públicas
+      thread: Conversações
+    edit:
+      title: Editar filtros
+    errors:
+      invalid_context: Inválido ou nenhum contexto fornecido
+      invalid_irreversible: Filtragem irreversível só funciona no contexto das notificações ou do início
+    index:
+      delete: Apagar
+      title: Filtros
+    new:
+      title: Adicionar novo filtro
+  footer:
+    developers: Responsáveis pelo desenvolvimento
+    more: Mais…
+    resources: Recursos
   generic:
     changes_saved_msg: Alterações guardadas!
+    copy: Copiar
     save_changes: Guardar alterações
     validation_errors:
       one: Algo não está correcto. Por favor vê o erro abaixo
       other: Algo não está correto. Por favor vê os %{count} erros abaixo
   imports:
+    modes:
+      merge: Juntar
+      merge_long: Manter os registos existentes e adicionar novos registos
+      overwrite: Escrever por cima
+      overwrite_long: Substituir os registos atuais pelos novos
     preface: Podes importar dados que tenhas exportado de outra instância, como a lista de pessoas que segues ou bloqueadas.
     success: Os teus dados foram enviados com sucesso e serão processados em breve
     types:
       blocking: Lista de bloqueio
+      domain_blocking: Lista de domínios bloqueados
       following: Lista de pessoas que estás a seguir
       muting: Lista de utilizadores silenciados
     upload: Enviar
@@ -426,9 +611,11 @@ pt:
       '21600': 6 horas
       '3600': 1 hora
       '43200': 12 horas
+      '604800': 1 semana
       '86400': 1 dia
     expires_in_prompt: Nunca
     generate: Gerar
+    invited_by: 'Tu foste convidado por:'
     max_uses:
       one: 1 uso
       other: "%{count} usos"
@@ -486,68 +673,61 @@ pt:
       body: 'O teu post foi partilhado por %{name}:'
       subject: "%{name} partilhou o teu post"
       title: Nova partilha
-  number:
-    human:
-      decimal_units:
-        format: "%n%u"
-        units:
-          billion: B
-          million: M
-          quadrillion: Q
-          thousand: K
-          trillion: T
-          unit: ''
   pagination:
+    newer: Mais nova
     next: Seguinte
+    older: Mais velha
     prev: Anterior
-    truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: Tu já votaste nesta sondagem
+      duplicate_options: contém itens duplicados
+      duration_too_long: está demasiado à frente no futuro
+      duration_too_short: é demasiado cedo
+      expired: A sondagem já terminou
+      over_character_limit: não pode ter mais do que %{max} caracteres cada um
+      too_few_options: tem de ter mais do que um item
+      too_many_options: não pode conter mais do que %{max} itens
   preferences:
-    languages: Idiomas
     other: Outro
-    publishing: Publicação
-    web: Web
   remote_follow:
     acct: Entre seu usuário@domínio do qual quer seguir
     missing_resource: Não foi possível achar a URL de redirecionamento para sua conta
+    no_account_html: Não tens uma conta? Tu podes <a href='%{sign_up_path}' target='_blank'> aderir aqui</a>
     proceed: Prossiga para seguir
     prompt: 'Você vai seguir:'
+    reason_html: "<strong> Porque é que este passo é necessário?</strong> <code>%{instance}</code> pode não ser o servidor onde tu estás registado. Por isso, nós precisamos de te redirecionar para o teu servidor inicial em primeiro lugar."
+  remote_interaction:
+    favourite:
+      proceed: Prosseguir para os favoritos
+      prompt: 'Queres favoritar esta publicação:'
+    reblog:
+      proceed: Prosseguir com partilha
+      prompt: 'Queres partilhar esta publicação:'
+    reply:
+      proceed: Prosseguir com resposta
+      prompt: 'Queres responder a esta publicação:'
+  remote_unfollow:
+    error: Erro
+    title: Título
+    unfollowed: Não seguido
+  scheduled_statuses:
+    over_daily_limit: Excedeste o limite de %{limit} publicações agendadas para esse dia
+    over_total_limit: Tu excedeste o limite de %{limit} publicações agendadas
+    too_soon: A data de agendamento tem de ser futura
   sessions:
     activity: Última atividade
     browser: Navegador
     browsers:
-      alipay: Alipay
-      blackberry: Blackberry
-      chrome: Chrome
-      edge: Microsoft Edge
-      electron: Electron
-      firefox: Firefox
       generic: Navegador desconhecido
-      ie: Internet Explorer
-      micro_messenger: MicroMessenger
       nokia: Navegador Nokia S40 Ovi
-      opera: Opera
-      phantom_js: PhantomJS
-      qq: QQ Browser
-      safari: Safari
-      uc_browser: UCBrowser
-      weibo: Weibo
+      otter: Lontra
     current_session: Sessão atual
     description: "%{browser} em %{platform}"
     explanation: Estes são os navegadores que estão conectados com a tua conta do Mastodon.
-    ip: IP
     platforms:
-      adobe_air: Adobe Air
-      android: Android
-      blackberry: Blackberry
-      chrome_os: ChromeOS
-      firefox_os: Firefox OS
-      ios: iOS
-      linux: Linux
-      mac: Mac
+      firefox_os: SO Firefox
       other: Plataforma desconhecida
-      windows: Windows
-      windows_mobile: Windows Mobile
-      windows_phone: Windows Phone
     revoke: Revogar
     revoke_success: Sessão revogada com sucesso
     title: Sessões
@@ -558,15 +738,27 @@ pt:
     development: Desenvolvimento
     edit_profile: Editar perfil
     export: Exportar dados
-    followers: Seguidores autorizados
+    featured_tags: Hashtags destacadas
     import: Importar
     migrate: Migração de conta
     notifications: Notificações
     preferences: Preferências
-    settings: Configurações
     two_factor_authentication: Autenticação em dois passos
-    your_apps: As tuas aplicações
   statuses:
+    attached:
+      description: 'Anexadas: %{attached}'
+      image:
+        one: "%{count} imagem"
+        other: "%{count} imagens"
+      video:
+        one: "%{count} vídeo"
+        other: "%{count} vídeos"
+    boosted_from_html: Partilhadas de %{acct_link}
+    content_warning: 'Aviso de conteúdo: %{warning}'
+    disallowed_hashtags:
+      one: 'continha uma hashtag proibida: %{tags}'
+      other: 'continha as hashtags proibidas: %{tags}'
+    language_detection: Detectar automaticamente a língua
     open_in_web: Abrir no browser
     over_character_limit: limite de caracter excedeu %{max}
     pin_errors:
@@ -574,8 +766,13 @@ pt:
       ownership: Posts de outras pessoas não podem ser fixados
       private: Post não-público não pode ser fixado
       reblog: Não podes fixar uma partilha
+    poll:
+      total_votes:
+        one: "%{count} voto"
+        other: "%{count} votos"
+      vote: Votar
     show_more: Mostrar mais
-    title: '%{name}: "%{quote}"'
+    sign_in_to_participate: Inicie a sessão para participar na conversa
     visibilities:
       private: Mostrar apenas para seguidores
       private_long: Mostrar apenas para seguidores
@@ -585,15 +782,95 @@ pt:
       unlisted_long: Todos podem ver, porém não será postado nas timelines públicas
   stream_entries:
     pinned: Toot fixado
-    reblogged: boosted
+    reblogged: partilhado
     sensitive_content: Conteúdo sensível
   terms:
+    body_html: |
+      <h2>Política de privacidade</h2>
+      <h3 id="collect">Que informação nós recolhemos?</h3>
+
+      <ul>
+      <li><em>Informação básica da conta</em>: Se te registares neste servidor, pode-te ser pedido que indiques um nome de utilizador, um endereço de e-mail e uma palavra-passe. Também podes introduzir informação adicional de perfil, tal como um nome a mostrar e dados biográficos, que carregues uma fotografia para o teu perfil e para o cabeçalho. O nome de utilizador, o nome a mostrar, a biografia, a imagem de perfil e a imagem de cabeçalho são sempre listados publicamente.</li>
+      <li><em>Publicações, seguimento e outra informação pública</em>: A lista de pessoas que tu segues é pública, o mesmo é verdade para os teus seguidores. Quando tu publicas uma mensagem, a data e a hora são guardados, tal como a aplicação a partir da qual a mensagem foi enviada. As mensagens podem conter anexos multimédia, tais como fotografias ou vídeos. Publicações públicas e não listadas são acessíveis publicamente. Quando expões uma publicação no teu perfil, isso é também informação disponível publicamente. As tuas publicações são enviadas aos teus seguidores. Em alguns casos isso significa que elas são enviadas para servidores diferentes onde são guardadas cópias. Quando tu apagas publicações, isso também é enviado para os teus seguidores. A acção de republicar ou favoritar outra publicação é sempre pública.</li>
+      <li><em>Publicações directas e exclusivas para seguidores</em>: Todas as publicações são guardadas e processadas no servidor. Publicações exclusivas para seguidores são enviadas para os teus seguidores e para utilizadores que são nelas mencionados. As publicações directas são enviadas apenas para os utilizadores nelas mencionados. Em alguns casos isso significa que elas são enviadas para diferentes servidores onde são guardadas cópias das mesmas. Nós fazemos um grande esforço para limitar o acesso a estas publicações aos utilizadores autorizados, mas outros servidores podem falhar neste objectivo.  Por isso, tu deves rever os servidores a que os teus seguidores pertencem. Tu podes activar uma opção para aprovar e rejeitar manualmente novos seguidores nas configurações. <em>Por favor, tem em mente que os gestores do servidor e qualquer servidor que receba a publicação pode lê-la</em>e que os destinatários podem fazer uma captura de tela, copiar ou partilhar a publicação. <em>Não partilhes qualquer informação perigosa no Mastodon.</em></li>
+      <li><em>IPs e outros metadados</em>: Quando inicias sessão, nós guardamos o endereço de IP a partir do qual iniciaste a sessão, tal como o nome do teu navegador. Todas as sessões estão disponíveis para verificação e revogação nas configurações. O último endereço de IP usado é guardado até 12 meses. Nós também podemos guardar registos de servidor, os quais incluem o endereço de IP de cada pedido dirigido ao nosso servidor.</li>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="use">Para que usamos a tua informação?</h3>
+
+      <p>Qualquer informação que recolhemos sobre ti pode ser usada dos seguintes modos:</p>
+
+      <ul>
+      <li>Para providenciar a funcionalidade central do Mastodon. Tu só podes interagir com o conteúdo de outras pessoas e publicar o teu próprio conteúdo depois de teres iniciado sessão. Por exemplo, tu podes seguir outras pessoas para veres as suas publicações na tua cronologia inicial personalizada. </li>
+      <li>Para ajudar na moderação da comunidade para, por exemplo, comparar o teu endereço IP com outros conhecidos, para determinar a fuga ao banimento ou outras violações.</li>
+      <li>O endereço de e-mail que tu forneces pode ser usado para te enviar informações e/ou notificações sobre outras pessoas que estão a interagir com o teu conteúdo ou a enviar-te mensagens, para responderes a inquéritos e/ou outros pedidos ou questões.</li>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="protect">Como é que nós protegemos a tua informação?</h3>
+
+      <p>Nós implementamos uma variedade de medidas de segurança para garantir a segurança da tua informação pessoal quando tu introduzes, submetes ou acedes à mesma. Entre outras coisas, a tua sessão de navegação, tal como o tráfego entre as tuas aplicações e a API, estão seguras por SSL e a tua palavra-passe é codificada usando um forte algoritmo de sentido único. Tu podes activar a autenticação em dois passos para aumentares ainda mais a segurança do acesso à tua conta.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="data-retention">Qual é a nossa política de retenção de dados?</h3>
+
+      <p>Nós envidaremos todos os esforços no sentido de:</p>
+
+      <ul>
+      <li>Guardar registos do servidor contendo o endereço de IP de todos os pedidos feitos a este  servidor, considerando que estes registos não serão guardados por mais de 90 dias.</li>
+      <li>Guardar os endereços de IP associados aos utilizadores registados durante um período que não ultrapassará os 12 meses.</li>
+      </ul>
+
+      <p>Tu podes pedir e descarregar um ficheiro com o teu conteúdo, incluindo as tuas publicações, os ficheiros multimédia, a imagem de perfil e a imagem de cabeçalho.</p>
+
+      <p>Tu podes apagar a tua conta de modo definitivo e a qualquer momento.</p>
+
+      <hr class="spacer"/>
+
+      <h3 id="cookies">Usamos cookies?</h3>
+
+      <p>Sim. Cookies são pequenos ficheiros que um site ou o seu fornecedor de serviço transfere para o disco rígido do teu computador através do teu navegador (se tu permitires). Estes cookies permitem ao site reconhecer o teu navegador e, se tu tiveres uma conta registada, associá-lo a ela.</p>
+
+      <p>Nós usamos os cookies para compreender e guardar as tuas preferências para as visitas futuras.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="disclose">Nós divulgamos alguma informação para entidades externas?</h3>
+
+      <p>Nós não vendemos, trocamos ou transferimos de qualquer modo a tua informação pessoal que seja identificável para qualquer entidade externa. Isto não inclui terceiros de confiança que nos ajudam a manter o nosso site, conduzir o nosso negócio ou prestar-te este serviço, desde que esses terceiros concordem em manter essa informação confidencial. Poderemos também revelar a tua informação quando nós acreditamos que isso é apropriado para cumprir a lei, forçar a aplicação dos nossos termos de serviço ou proteger os direitos, propriedade e segurança, nossos e de outrem.</p>
+
+      <p>O teu conteúdo público pode ser descarregado por outros servidores na rede. As tuas publicações públicas e exclusivas para os teus seguidores são enviadas para os servidores onde os teus seguidores residem e as mensagens directas são entregues aos servidores dos seus destinatários, no caso desses seguidores ou destinatários residirem num servidor diferente deste.</p>
+
+      <p>Quando tu autorizas uma aplicação a usar a tua conta, dependendo da abrangência das permissões que tu aprovas, ela pode ter acesso à informação pública do teu perfil, à lista de quem segues, aos teus seguidores, às tuas listas, a todas as tuas publicações e aos teus favoritos. As aplicações nunca terão acesso ao teu endereço de e-mail ou à tua palavra-passe.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="children">Utilização do site por crianças</h3>
+
+      <p>Se este servidor estiver na EU ou na EEA: O nosso site, produtos e serviços são todos dirigidos a pessoas que têm, pelo menos, 16 de idade. Se tu tens menos de 16 anos, devido aos requisitos da GDPR (<a href="https://en.wikipedia.org/wiki/General_Data_Protection_Regulation">General Data Protection Regulation</a>) não uses este site.</p>
+
+      <p>Se este servidor estiver nos EUA: O nosso site, produtos e serviços são todos dirigidos a pessoas que têm, pelo menos, 13 anos de idade. Se tu tens menos de 13 anos de idade, devido aos requisitos da COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) não uses este site.</p>
+
+      <p>Os requisitos legais poderão ser diferentes se este servidor estiver noutra jurisdição.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="changes">Alterações à nossa Política de Privacidade</h3>
+
+      <p>Se nós decidirmos alterar a nossa política de privacidade, nós iremos publicar essas alterações nesta página.</p>
+
+      <p>Este documento é CC-BY-SA. Ele foi actualizado pela última vez em 7 de Março 2018.</p>
+
+      <p>Originalmente adaptado de <a href="https://github.com/discourse/discourse">Discourse privacy policy</a>.</p>
     title: "%{instance} Termos de Serviço e Política de Privacidade"
   themes:
+    contrast: Mastodon (Elevado contraste)
     default: Mastodon
-  time:
-    formats:
-      default: "%b %d, %Y, %H:%M"
+    mastodon-light: Mastodon (Leve)
   two_factor_authentication:
     code_hint: Entre o código gerado pelo seu aplicativo para confirmar
     description_html: Se ativar a <strong>autenticação em dois passos</strong>, quando logar será necessário o seu telefone que vai gerar os tokens para validação.
@@ -607,9 +884,54 @@ pt:
     manual_instructions: 'Se você não puder scanear o código QR e precisa digita-los manualmente, aqui está o segredo em texto.:'
     recovery_codes: Cópia de segurança dos códigos de recuperação
     recovery_codes_regenerated: Códigos de recuperação foram gerados com sucesso
+    recovery_instructions_html: Se tu alguma vez perderes o teu smartphone, to poderás usar um dos códigos de recuperação para voltares a ter acesso à tua conta. <strong>Mantém os códigos de recuperação seguros</strong>. Por exemplo, tu podes imprimi-los e guardá-los junto a outros documentos importantes.
     setup: Configurar
     wrong_code: O código inserido é invalido! O horário do servidor e o horário do seu aparelho estão corretos?
+  user_mailer:
+    backup_ready:
+      explanation: Pediste uma cópia completa da tua conta Mastodon. Ela já está pronta para descarregares!
+      subject: O teu arquivo está pronto para descarregar
+      title: Arquivo de ficheiros
+    warning:
+      explanation:
+        disable: Enquanto a tua conta está congelada, os seus dados permanecem intactos, mas tu não podes executar quaisquer acções até que ela seja desbloqueada.
+        silence: Enquanto a tua conta estiver limitada, só pessoas que já estiveres a seguir irão ver as tuas publicações neste servidor e poderás ser excluído de várias listagens públicas. No entanto, outros ainda te poderão seguir de forma manual.
+        suspend: A tua conta foi suspensa e todas as tuas publicações e os teus ficheiros de media foram irreversivelmente removidos deste servidor e dos servidores onde tinhas seguidores.
+      review_server_policies: Revê as políticas do servidor
+      subject:
+        disable: A tua conta %{acct} foi congelada
+        none: Aviso para %{acct}
+        silence: A tua conta %{acct} foi limitada
+        suspend: A tua conta %{acct} foi suspensa
+      title:
+        disable: Conta congelada
+        none: Aviso
+        silence: Conta limitada
+        suspend: Conta suspensa
+    welcome:
+      edit_profile_action: Configura o perfil
+      edit_profile_step: Tu podes personalizar o teu perfil por carregar um avatar, cabeçalho, alterar o teu nickname e mais. Se tu preferires rever os novos seguidores antes deles te poderem seguir, podes bloquear a tua conta.
+      explanation: Aqui estão algumas dicas para começares
+      final_action: Começa a publicar
+      final_step: 'Começa a publicar! Mesmo sem seguidores, as tuas mensagens públicas podem ser vistas por outros, por exemplo, na cronologia local e em hashtags. Tu podes querer apresentar-te na hashtag #introductions.'
+      full_handle: O teu nome completo
+      full_handle_hint: Isto é o que tu dirias aos teus amigos para que eles te possam enviar mensagens ou seguir-te a partir de outro servidor.
+      review_preferences_action: Alterar preferências
+      review_preferences_step: Certifica-te de configurar as tuas preferências, tais como os e-mails que gostarias de receber ou o nível de privacidade que desejas que as tuas publicações tenham por defeito. Se não sofres de enjoo, podes activar a opção GIF autoplay.
+      subject: Bem-vindo ao Mastodon
+      tip_federated_timeline: A cronologia federativa é uma visão global da rede Mastodon. Mas só inclui pessoas que os teus vizinhos subscrevem, por isso não é uma visão completa.
+      tip_following: Tu segues o(s) administrador(es) do teu servidor por defeito. Para encontrares mais pessoas interessantes, procura nas cronologias local e federativa.
+      tip_local_timeline: A cronologia local é uma visão global das pessoas em %{instance}. Estes são os teus vizinhos próximos!
+      tip_mobile_webapp: Se o teu navegador móvel te oferecer a possibilidade de adicionar o Mastodon ao teu homescreen, tu podes receber notificações push. Ele age como uma aplicação nativa de vários modos!
+      tips: Dicas
+      title: Bem-vindo a bordo, %{name}!
   users:
+    follow_limit_reached: Não podes seguir mais do que %{limit} pessoas
     invalid_email: O endereço de e-mail é inválido
     invalid_otp_token: Código de autenticação inválido
+    otp_lost_help_html: Se tu perdeste acesso a ambos, tu podes entrar em contacto com %{email}
+    seamless_external_login: Tu estás ligado via um serviço externo. Por isso, as configurações da palavra-passe e do e-mail não estão disponíveis.
     signed_in_as: 'Registado como:'
+  verification:
+    explanation_html: 'Tu podes <strong>comprovar que és o dono dos links nos metadados do teu perfil</strong>. Para isso, o website para o qual o link aponta tem de conter um link para o teu perfil do Mastodon. Este link <strong>tem</strong> de ter um <code>rel="me"</code> atributo. O conteúdo do texto não é relevante. Aqui está um exemplo:'
+    verification: Verificação
diff --git a/config/locales/ro.yml b/config/locales/ro.yml
index aa4d3c967c485039b4248d30a6bad8ddd2e662d5..6e6c6f403ec985c1a3485018f82564adb683d6b8 100644
--- a/config/locales/ro.yml
+++ b/config/locales/ro.yml
@@ -1,16 +1,8 @@
 ---
 ro:
   about:
-    features:
-      not_a_product_title: Ești o persoană, nu un produs
     hosted_on: Mastodon găzduit de %{domain}
-  accounts:
-    posts:
-      few: Toots
-      one: Toot
-      other: Toots
   auth:
-    agreement_html: Prin apăsarea butonului Înscriere de mai jos ești deacord cu <a href="%{rules_path}">regulile acestei instanțe</a> și <a href="%{terms_path}">termenii de utilizare al acestui serviciu</a>.
     change_password: Parolă
     confirm_email: Confirmă email
     delete_account: Șterge contul
@@ -22,13 +14,8 @@ ro:
     logout: Deconectare
     migrate_account: Transfer către un alt cont
     migrate_account_html: Dacă dorești să redirecționezi acest cont către un altul, poți <a href="%{path}">configura asta aici</a>.
-    or: sau
     or_log_in_with: Sau conectează-te cu
-    providers:
-      cas: CAS
-      saml: SAML
     register: ÃŽnregistrare
-    register_elsewhere: Înregistrează-te pe un alt server
     resend_confirmation: Retrimite instrucțiunile de confirmare
     reset_password: Resetare parolă
     security: Securitate
@@ -55,9 +42,7 @@ ro:
       less_than_x_seconds: Chiar acum
       over_x_years: "%{count}ani"
       x_days: "%{count}z"
-      x_minutes: "%{count}m"
       x_months: "%{count}l"
-      x_seconds: "%{count}s"
   deletes:
     bad_password_msg: Bună încercare, hackere! Parolă incorectă
     confirm_password: Introdu parola curentă pentru a-ți verifica identitatea
@@ -93,7 +78,6 @@ ro:
       request: Cere arhiva ta
       size: Dimensiune
     blocks: Blocați
-    csv: CSV
     follows: Tu urmărești
     mutes: Opriți
     storage: Depozitare media
@@ -113,9 +97,11 @@ ro:
       title: Filtre
     new:
       title: Adaugă un filtru nou
-  followers:
-    domain: Domeniu
-    explanation_html: Dacă vrei să fi sigur de confidențialitatea statusurilor tale, ar trebui să fi conștient de cine te urmărește. <strong>Statusurile tale private sunt livrate către toate instanțele unde ai urmăritori</strong>. Este recomandabil să verifici și să ștergi urmăritorii în care nu ai încredere că îți vor respecta intimitatea.
-    followers_count: Numărul de urmăritori
-    lock_link: Privează contul tău
-    purge: Elimină de la urmăritori
+  invites:
+    expires_in:
+      '1800': 30 minutes
+      '21600': 6 hours
+      '3600': 1 hour
+      '43200': 12 hours
+      '604800': 1 week
+      '86400': 1 day
diff --git a/config/locales/ru.yml b/config/locales/ru.yml
index 40765447b5624ae39d5142171b9605f0b79a4e40..7e336be984e7590919fc80a3c2f9fde8f61b807c 100644
--- a/config/locales/ru.yml
+++ b/config/locales/ru.yml
@@ -4,30 +4,30 @@ ru:
     about_hashtag_html: Это публичные статусы, отмеченные хэштегом <strong>#%{hashtag}</strong>. Вы можете взаимодействовать с ними при наличии у Вас аккаунта в глобальной сети Mastodon.
     about_mastodon_html: Mastodon - это <em>свободная</em> социальная сеть с <em>открытым исходным кодом</em>. Как <em>децентрализованная</em> альтернатива коммерческим платформам, Mastodon предотвращает риск монополизации Вашего общения одной компанией. Выберите сервер, которому Вы доверяете &mdash; что бы Вы ни выбрали, Вы сможете общаться со всеми остальными. Любой может запустить свой собственный узел Mastodon и участвовать в <em>социальной сети</em> совершенно бесшовно.
     about_this: Об этом узле
+    active_count_after: активных
+    active_footnote: Ежемесячно активные пользователи (MAU)
     administered_by: 'Администратор узла:'
     api: API
     apps: Приложения
-    closed_registrations: В данный момент регистрация на этом узле закрыта. Но вы можете найти другой узел, создать на нём учётную запись и получить доступ к той же сети оттуда.
+    apps_platforms: Используйте Mastodon на iOS, Android и других платформах
+    browse_directory: Изучайте каталог профилей и ищите по интересам
+    browse_public_posts: Просматривайте в реальном времени новые статусы в Mastodon
     contact: Связаться
-    contact_missing: Не установлено
-    contact_unavailable: Недоступен
+    contact_missing: не указан
+    contact_unavailable: неизв.
+    discover_users: Находите пользователей
+    documentation: Документация
     extended_description_html: |
       <h3>Хорошее место для правил</h3>
       <p>Расширенное описание еще не настроено.</p>
-    features:
-      humane_approach_body: Наученный ошибками других проектов, Mastodon направлен на выбор этичных решений в борьбе со злоупотреблениями возможностями социальных сетей.
-      humane_approach_title: Человечный подход
-      not_a_product_body: Mastodon -  не коммерческая сеть. Здесь нет рекламы, сбора данных, отгороженных мест. Здесь нет централизованного управления.
-      not_a_product_title: Вы - человек, а не продукт
-      real_conversation_body: С 65535 символами в Вашем распоряжении и поддержкой предупреждений о содержании статусов Вы сможете выражать свои мысли так, как Вы этого хотите.
-      real_conversation_title: Создан для настоящего общения
-      within_reach_body: Различные приложения для iOS, Android и других платформ, написанные благодаря дружественной к разработчикам экосистеме API, позволят Вам держать связь с Вашими друзьями где угодно.
-      within_reach_title: Всегда под рукой
+    federation_hint_html: С учётной записью на %{instance} вы сможете подписываться на людей с любого сервера Mastodon и не только.
     generic_description: "%{domain} - один из серверов сети"
+    get_apps: Попробуйте мобильное приложение
     hosted_on: Mastodon размещен на %{domain}
     learn_more: Узнать больше
-    other_instances: Другие узлы
     privacy_policy: Политика конфиденциальности
+    see_whats_happening: Узнавайте, что происходит вокруг
+    server_stats: 'Статистика сервера:'
     source_code: Исходный код
     status_count_after:
       few: статуса
@@ -35,6 +35,7 @@ ru:
       one: статус
       other: статусов
     status_count_before: Опубликовано
+    tagline: Подписывайтесь на друзей и заводите новые знакомства
     terms: Условия использования
     user_count_after:
       few: пользователя
@@ -53,6 +54,8 @@ ru:
       other: подписчиков
     following: подписки
     joined: 'Дата регистрации: %{date}'
+    last_active: последняя активность
+    link_verified_on: Владение этой ссылкой было проверено %{date}
     media: Медиа
     moved_html: "%{name} переехал(а) на %{new_profile_link}:"
     network_hidden: Эта информация недоступна
@@ -73,14 +76,20 @@ ru:
       admin: Администратор
       bot: Бот
       moderator: Модератор
+    unavailable: Профиль недоступен
     unfollow: Отписаться
   admin:
+    account_actions:
+      action: Выполнить действие
+      title: Произвести модерацию аккаунта %{acct}
     account_moderation_notes:
       create: Создать
       created_msg: Заметка модератора успешно создана!
       delete: Удалить
       destroyed_msg: Заметка модератора успешно удалена!
     accounts:
+      approve: Подтвердить
+      approve_all: Подтвердить все
       are_you_sure: Вы уверены?
       avatar: Аватар
       by_domain: Домен
@@ -94,6 +103,7 @@ ru:
       confirm: Подтвердить
       confirmed: Подтверждено
       confirming: Подтверждение
+      deleted: Удалён
       demote: Разжаловать
       disable: Отключить
       disable_two_factor_authentication: Отключить 2FA
@@ -109,8 +119,11 @@ ru:
       followers: Подписчики
       followers_url: URL подписчиков
       follows: Подписки
+      header: Заголовок
       inbox_url: URL входящих
+      invited_by: Приглашение выдал(а)
       ip: IP
+      joined: Дата регистрации
       location:
         all: Все
         local: Локальные
@@ -120,15 +133,20 @@ ru:
       media_attachments: Мультимедийные вложения
       memorialize: Превратить в Памятник
       moderation:
+        active: Действующие
         all: Все
+        pending: В ожидании
         silenced: Заглушенные
         suspended: Заблокированные
         title: Модерация
       moderation_notes: Заметки модератора
       most_recent_activity: Последняя активность
       most_recent_ip: Последний IP
+      no_account_selected: Ничего не выбрано, никакие аккаунты не изменены
+      no_limits_imposed: Без ограничений
       not_subscribed: Не подписаны
       outbox_url: URL исходящих
+      pending: Ожидает рассмотрения
       perform_full_suspension: Полная блокировка
       profile_url: URL профиля
       promote: Повысить
@@ -136,7 +154,10 @@ ru:
       public: Публичный
       push_subscription_expires: Подписка PuSH истекает
       redownload: Обновить аватар
+      reject: Отклонить
+      reject_all: Отклонить все
       remove_avatar: Удалить аватар
+      remove_header: Удалить шапку
       resend_confirmation:
         already_confirmed: Этот пользователь уже подтвержден
         send: Повторно отправить подтверждение по электронной почте
@@ -150,31 +171,35 @@ ru:
         moderator: Модератор
         staff: Персонал
         user: Пользователь
-      salmon_url: Salmon URL
       search: Поиск
       shared_inbox_url: URL общих входящих
       show:
         created_reports: Жалобы, отправленные этим аккаунтом
         targeted_reports: Жалобы на этот аккаунт
-      silence: Глушение
+      silence: Заглушить
+      silenced: Заглушен
       statuses: Статусы
       subscribe: Подписаться
+      suspended: Заморожен
       title: Аккаунты
       unconfirmed_email: Неподтверждённый e-mail
       undo_silenced: Снять глушение
       undo_suspension: Снять блокировку
       unsubscribe: Отписаться
       username: Имя пользователя
+      warn: Предупредить
       web: Веб
     action_logs:
       actions:
         assigned_to_self_report: "%{name} назначил(а) жалобу %{target} на себя"
         change_email_user: "%{name} сменил(а) e-mail пользователя %{target}"
         confirm_user: "%{name} подтвердил(а) e-mail адрес пользователя %{target}"
+        create_account_warning: "%{name} отправил(а) предупреждение для %{target}"
         create_custom_emoji: "%{name} загрузил(а) новый эмодзи %{target}"
         create_domain_block: "%{name} заблокировал(а) домен %{target}"
         create_email_domain_block: "%{name} добавил(а) e-mail домен %{target} в чёрный список"
         demote_user: "%{name} разжаловал(а) пользователя %{target}"
+        destroy_custom_emoji: "%{name} удалил(а) эмодзи %{target}"
         destroy_domain_block: "%{name} разблокировал(а) домен %{target}"
         destroy_email_domain_block: "%{name} добавил(а) e-mail домен %{target} в белый список"
         destroy_status: "%{name} удалил(а) статус пользователя %{target}"
@@ -228,8 +253,10 @@ ru:
       config: Конфигурация
       feature_deletions: Удаление аккаунтов
       feature_invites: Пригласительные ссылки
+      feature_profile_directory: Каталог профилей
       feature_registrations: Регистрация
       feature_relay: Ретрансляторы
+      feature_timeline_preview: Предпросмотр ленты
       features: Возможности
       hidden_service: Федерация со скрытыми сервисами
       open_reports: открытых жалоб
@@ -245,7 +272,7 @@ ru:
       week_users_active: активно на этой неделе
       week_users_new: пользователей на этой неделе
     domain_blocks:
-      add_new: Добавить новую
+      add_new: Заблокировать домен
       created_msg: Блокировка домена обрабатывается
       destroyed_msg: Блокировка домена снята
       domain: Домен
@@ -259,7 +286,14 @@ ru:
           suspend: Блокировка
         title: Новая доменная блокировка
       reject_media: Запретить медиаконтент
-      reject_media_hint: Удаляет локально хранимый медиаконтент и запрещает его загрузку в будущем. Не имеет значения в случае блокировки
+      reject_media_hint: Удаляет локально хранимый медиаконтент и запрещает его загрузку в будущем. Не имеет значения в случае блокировки.
+      reject_reports: Отклонять жалобы
+      reject_reports_hint: Игнорировать все жалобы с этого домена. Не имеет значения в случае блокировки.
+      rejecting_media: отклонение медиафайлов
+      rejecting_reports: отклонение жалоб
+      severity:
+        silence: заглушен
+        suspend: заморожен
       show:
         affected_accounts:
           few: Влияет на %{count} аккаунта в базе данных
@@ -271,7 +305,7 @@ ru:
           suspend: Снять блокировку со всех существующих аккаунтов этого домена
         title: Снять блокировку с домена %{domain}
         undo: Отменить
-      undo: Отменить
+      undo: Отменить блокировку домена
     email_domain_blocks:
       add_new: Добавить новую
       created_msg: Доменная блокировка еmail успешно создана
@@ -282,8 +316,27 @@ ru:
         create: Создать блокировку
         title: Новая доменная блокировка еmail
       title: Доменная блокировка email
+    followers:
+      back_to_account: Вернуться к аккаунту
+      title: Подписчики пользователя %{acct}
     instances:
+      by_domain: Домен
+      delivery_available: Доставка возможна
+      known_accounts:
+        few: "%{count} известных аккаунта"
+        many: "%{count} известных аккаунтов"
+        one: "%{count} известный аккаунт"
+        other: "%{count} известных аккаунтов"
+      moderation:
+        all: Все
+        limited: Ограниченные
+        title: Модерация
       title: Известные узлы
+      total_blocked_by_us: Заблокировано нами
+      total_followed_by_them: Заблокировано ими
+      total_followed_by_us: Наших подписчиков
+      total_reported: Жалобы на них
+      total_storage: Медиафайлы
     invites:
       deactivate_all: Отключить все
       filter:
@@ -292,10 +345,17 @@ ru:
         expired: Истёкшие
         title: Фильтр
       title: Приглашения
+    pending_accounts:
+      title: Ожидающие аккаунты (%{count})
     relays:
       add_new: Добавить ретранслятор
+      delete: Удалить
       description_html: "<strong>Федеративный ретранслятор</strong> – это промежуточный сервер, который передаёт большие объёмы публичных статусов между серверами, которые подписываются и публикуют туда. <strong>Это может помочь небольшим и средним серверам находить записи со всей федерации</strong>, ведь в противном случае пользователям нужно будет вручную подписываться на людей с удалённых узлов."
+      disable: Отключить
+      disabled: Отключено
+      enable: Включить
       enable_hint: Если включено, ваш сервер будет подписан на все публичные статусы с этого ретранслятора и начнёт туда отправлять публичные статусы со своего узла.
+      enabled: Включено
       inbox_url: URL ретранслятора
       pending: Ожидание подтверждения ретранслятора
       save_and_enable: Сохранить и включить
@@ -307,8 +367,8 @@ ru:
       destroyed_msg: Примечание жалобы удалено!
     reports:
       account:
-        note: заметка
-        report: жалоба
+        note: заметок
+        report: жалоб
       action_taken_by: 'Действие предпринято:'
       are_you_sure: Вы уверены?
       assign_to_self: Назначить себе
@@ -328,7 +388,7 @@ ru:
       report: 'Жалоба #%{id}'
       reported_account: Аккаунт нарушителя
       reported_by: Отправитель жалобы
-      resolved: Разрешено
+      resolved: Разрешенные
       resolved_msg: Жалоба успешно обработана!
       status: Статус
       title: Жалобы
@@ -351,12 +411,18 @@ ru:
       hero:
         desc_html: Отображается на главной странице. Рекомендуется разрешение не менее 600х100px. Если не установлено, используется изображение узла
         title: Баннер узла
+      mascot:
+        desc_html: Отображается на различных страницах. Рекомендуется размер не менее 293×205px. Если ничего не выбрано, используется персонаж по умолчанию
+        title: Персонаж сервера
       peers_api_enabled:
         desc_html: Домены, которые были замечены этим узлом среди всей федерации
         title: Публикация списка обнаруженных узлов
       preview_sensitive_media:
         desc_html: Предпросмотр ссылок с остальных веб-сайтов будет показан даже если медиаконтент отмечен как чувствительный
         title: Показывать чувствительный медиаконтент в предпросмотре OpenGraph
+      profile_directory:
+        desc_html: Позволять находить пользователей
+        title: Включить каталог профилей
       registrations:
         closed_message:
           desc_html: Отображается на титульной странице, когда закрыта регистрация<br>Можно использовать HTML-теги
@@ -367,9 +433,12 @@ ru:
         min_invite_role:
           disabled: Никого
           title: Разрешать приглашения от
-        open:
-          desc_html: Позволяет любому создавать аккаунт
-          title: Открыть регистрацию
+      registrations_mode:
+        modes:
+          approved: Для регистрации требуется подтверждение
+          none: Никто не может регистрироваться
+          open: Все могут регистрироваться
+        title: Режим регистраций
       show_known_fediverse_at_about_page:
         desc_html: Если включено, показывает посты со всех известных узлов в предпросмотре ленты. В противном случае отображаются только локальные посты.
         title: Показывать известные узлы в предпросмотре ленты
@@ -416,12 +485,32 @@ ru:
       last_delivery: Последняя доставка
       title: WebSub
       topic: Тема
+    tags:
+      accounts: Аккаунты
+      hidden: Скрыты
+      hide: Скрыть из каталога
+      name: Хэштег
+      title: Хэштеги
+      unhide: Показывать в каталоге
+      visible: Видны
     title: Администрирование
+    warning_presets:
+      add_new: Добавить
+      delete: Удалить
+      edit: Изменить
+      edit_preset: Удалить шаблон предупреждения
+      title: Управление шаблонами предупреждений
   admin_mailer:
+    new_pending_account:
+      body: Ниже указана информация об аккаунте. Вы можете одобрить или отклонить заявку.
+      subject: Новый аккаунт для рассмотрения на %{instance} (%{username})
     new_report:
       body: "%{reporter} подал(а) жалобу на %{target}"
       body_remote: Кто-то с узла %{domain} пожаловался на %{target}
       subject: Новая жалоба, узел %{instance} (#%{id})
+  appearance:
+    advanced_web_interface: Многоколоночный интерфейс
+    sensitive_content: Чувствительное содержимое
   application_mailer:
     notification_preferences: Изменить настройки e-mail
     salutation: "%{name},"
@@ -438,8 +527,9 @@ ru:
     warning: Будьте очень внимательны с этими данными. Не делитесь ими ни с кем!
     your_token: Ваш токен доступа
   auth:
-    agreement_html: Создавая аккаунт, вы соглашаетесь с <a href="%{rules_path}">правилами узла</a> и <a href="%{terms_path}">нашими условиями обслуживания</a>.
+    apply_for_account: Запросить приглашение
     change_password: Пароль
+    checkbox_agreement_html: Я соглашаюсь с <a href="%{rules_path}" target="_blank">правилами сервера</a> и <a href="%{terms_path}" target="_blank">Условиями использования</a>
     confirm_email: Подтвердите email
     delete_account: Удалить аккаунт
     delete_account_html: Если Вы хотите удалить свой аккаунт, вы можете <a href="%{path}">перейти сюда</a>. У Вас будет запрошено подтверждение.
@@ -450,17 +540,17 @@ ru:
     logout: Выйти
     migrate_account: Перенести аккаунт
     migrate_account_html: Если Вы хотите перенести этот аккаунт на другой, вы можете <a href="%{path}">сделать это здесь</a>.
-    or: или
     or_log_in_with: Или войти с помощью
     providers:
       cas: CAS
       saml: SAML
     register: Зарегистрироваться
-    register_elsewhere: Зарегистрироваться на другом узле
+    registration_closed: "%{instance} не принимает новых участников"
     resend_confirmation: Повторить отправку инструкции для подтверждения
     reset_password: Сбросить пароль
     security: Безопасность
     set_new_password: Задать новый пароль
+    trouble_logging_in: Не удаётся войти?
   authorize_follow:
     already_following: Вы уже подписаны на этот аккаунт
     error: К сожалению, при поиске удаленного аккаунта возникла ошибка
@@ -494,6 +584,18 @@ ru:
     success_msg: Ваш аккаунт был успешно удален
     warning_html: Гарантируется удаление контента только на этом узле. Широко распространившийся контент, скорее всего, оставит следы. Сервера, отключенные от сети или отписавшиеся от Ваших обновлений, не обновят свои базы данных.
     warning_title: О доступности распространившегося контента
+  directories:
+    directory: Каталог профилей
+    enabled: В настоящий момент вы указаны в каталоге.
+    enabled_but_waiting: Вы согласились находиться в каталоге, но у вас ещё нет необходимого количества подписчиков (%{min_followers}), чтобы оказаться в каталоге.
+    explanation: Находите пользователей по интересам
+    explore_mastodon: Изучайте %{title}
+    how_to_enable: Вы ещё не находитесь в каталоге. Можете добавиться ниже. Используйте хэштеги в разделе "о себе", чтобы вас находили по этим хэштегам!
+    people:
+      few: "%{count} человека"
+      many: "%{count} человек"
+      one: "%{count} человек"
+      other: "%{count} человек"
   errors:
     '403': У Вас нет доступа к просмотру этой страницы.
     '404': Страница, которую Вы искали, не существует.
@@ -506,6 +608,9 @@ ru:
       content: Приносим извинения, но на нашей стороне что-то пошло не так.
       title: Страница неверна
     noscript_html: Для работы с Mastodon, пожалуйста, включите JavaScript. Кроме того, вы можете использовать одно из <a href="%{apps_path}">приложений</a> Mastodon для Вашей платформы.
+  existing_username_validator:
+    not_found: не удалось найти локального пользователя с таким именем
+    not_found_multiple: не удалось найти %{usernames}
   exports:
     archive_takeout:
       date: Дата
@@ -516,9 +621,15 @@ ru:
       size: Размер
     blocks: Список блокировки
     csv: CSV
+    domain_blocks: Доменные блокировки
     follows: Подписки
+    lists: Списки
     mutes: Список глушения
     storage: Ваш медиаконтент
+  featured_tags:
+    add_new: Добавить
+    errors:
+      limit: Вы уже добавили максимальное число хэштегов
   filters:
     contexts:
       home: Домашняя лента
@@ -535,37 +646,52 @@ ru:
       title: Фильтры
     new:
       title: Добавить фильтр
-  followers:
-    domain: Домен
-    explanation_html: Если Вы хотите быть уверены в приватности Ваших статусов, Вы должны иметь четкое представление о том, кто на Вас подписан. <strong>Ваши приватные статусы отправляются всем узлам, на которых у Вас есть подписчики</strong>. Рекомендуем удалить из подписчиков пользователей узлов, администрации или программному обеспечению которых Вы не доверяете.
-    followers_count: Количество подписчиков
-    lock_link: Закройте аккаунт
-    purge: Удалить из подписчиков
-    success:
-      few: В процессе мягкой блокировки подписчиков с %{count} доменов...
-      many: В процессе мягкой блокировки подписчиков с %{count} доменов...
-      one: В процессе мягкой блокировки подписчиков с одного домена...
-      other: В процессе мягкой блокировки подписчиков с %{count} доменов...
-    true_privacy_html: Пожалуйста, заметьте, что <strong>настоящая конфиденциальность может быть достигнута только при помощи end-to-end шифрования</strong>.
-    unlocked_warning_html: Кто угодно может подписаться на Вас и получить доступ к просмотру Ваших приватных статусов. %{lock_link}, чтобы получить возможность рассматривать и вручную подтверждать запросы о подписке.
-    unlocked_warning_title: Ваш аккаунт не закрыт для подписки
   footer:
     developers: Разработчикам
     more: Ещё…
     resources: Ссылки
   generic:
+    all: Все
     changes_saved_msg: Изменения успешно сохранены!
+    copy: Копировать
+    order_by: Сортировать по
     save_changes: Сохранить изменения
     validation_errors:
       few: Что-то здесь не так! Пожалуйста, прочитайте о %{count} ошибках ниже
       many: Что-то здесь не так! Пожалуйста, прочитайте о %{count} ошибках ниже
       one: Что-то здесь не так! Пожалуйста, прочитайте об ошибке ниже
       other: Что-то здесь не так! Пожалуйста, прочитайте о %{count} ошибках ниже
+  html_validator:
+    invalid_markup: 'невалидная разметка HTML: %{error}'
+  identity_proofs:
+    active: Активно
+    authorize: Да, авторизовать
+    authorize_connection_prompt: Авторизовать эту криптографическую связь?
+    errors:
+      failed: Криптографическое соединение не установлено. Попробуйте ещё раз на %{provider}.
+      keybase:
+        invalid_token: Токены Keybase — это хэши от подписей и должны быть по длине в 66 hex-символов
+        verification_failed: Keybase не распознаёт этот токен как подпись пользователя %{kb_username}. Пожалуйста, повторите на Keybase.
+      wrong_user: Невозможно подтвердить пользователя %{proving}, будучи залогиненным как %{current}. Выполните вход как %{proving} и попробуйте ещё раз.
+    explanation_html: Здесь вы можете криптографически связать свои остальные идентификаторы, такие как профиль Keybase. Это позволит другим дюдям отправлять вам зашифрованные сообщения и верить отправляемым вами сообщениям.
+    i_am_html: Я %{username} на %{service}.
+    identity: Идентификатор
+    inactive: Неактивно
+    publicize_checkbox: 'И опубликуйте текст:'
+    publicize_toot: 'Подтверждено! Я %{username} на %{service}: %{url}'
+    status: Статус подтверждения
+    view_proof: Посмотреть доказательство личности
   imports:
+    modes:
+      merge: Объединить
+      merge_long: Сохранить имеющиеся данные и добавить новые
+      overwrite: Перезаписать
+      overwrite_long: Перезаписать имеющиеся данные новыми
     preface: Вы можете загрузить некоторые данные, например, списки людей, на которых Вы подписаны или которых блокируете, в Ваш аккаунт на этом узле из файлов, экспортированных с другого узла.
     success: Ваши данные были успешно загружены и будут обработаны с должной скоростью
     types:
       blocking: Список блокировки
+      domain_blocking: Список доменных блокировок
       following: Подписки
       muting: Список глушения
     upload: Загрузить
@@ -582,6 +708,7 @@ ru:
       '86400': 1 день
     expires_in_prompt: Никогда
     generate: Сгенерировать
+    invited_by: 'Вас пригласил(а):'
     max_uses:
       few: "%{count} исп."
       many: "%{count} исп."
@@ -604,7 +731,7 @@ ru:
     acct: имя@домен нового аккаунта
     currently_redirecting: 'Ваш профиль будет перенаправлен на:'
     proceed: Сохранить
-    updated_msg: Настройки миграции Вашего аккаунта обновлены!
+    updated_msg: Настройки миграции вашего аккаунта обновлены!
   moderation:
     title: Модерация
   notification_mailer:
@@ -613,28 +740,28 @@ ru:
       body: Кратко о пропущенных Вами сообщениях с Вашего последнего захода %{since}
       mention: "%{name} упомянул(а) Вас в:"
       new_followers_summary:
-        few: У Вас появилось %{count} новых подписчика! Отлично!
-        many: У Вас появилось %{count} новых подписчиков! Отлично!
-        one: Также, пока вас не было, у Вас появился новый подписчик! Ура!
-        other: Также, пока вас не было, у Вас появилось %{count} новых подписчиков! Отлично!
+        few: У вас появилось %{count} новых подписчика! Отлично!
+        many: У вас появилось %{count} новых подписчиков! Отлично!
+        one: Также, пока вас не было, у вас появился новый подписчик! Ура!
+        other: Также, пока вас не было, у вас появилось %{count} новых подписчиков! Отлично!
       subject:
-        few: "%{count} новых уведомления с Вашего последнего захода \U0001F418"
-        many: "%{count} новых уведомлений с Вашего последнего захода \U0001F418"
-        one: "1 новое уведомление с Вашего последнего захода \U0001F418"
-        other: "%{count} новых уведомлений с Вашего последнего захода \U0001F418"
+        few: "%{count} новых уведомления с вашего последнего захода \U0001F418"
+        many: "%{count} новых уведомлений с вашего последнего захода \U0001F418"
+        one: "1 новое уведомление с вашего последнего захода \U0001F418"
+        other: "%{count} новых уведомлений с вашего последнего захода \U0001F418"
       title: В ваше отсутствие…
     favourite:
       body: 'Ваш статус понравился %{name}:'
-      subject: "%{name} понравился Ваш статус"
+      subject: "%{name} понравился ваш статус"
       title: Понравившийся статус
     follow:
-      body: "%{name} теперь подписан(а) на Вас!"
-      subject: "%{name} теперь подписан(а) на Вас"
+      body: "%{name} теперь подписан(а) на вас!"
+      subject: "%{name} теперь подписан(а) на вас"
       title: Новый подписчик
     follow_request:
       action: Управление запросами на подписку
-      body: "%{name} запросил Вас о подписке"
-      subject: "%{name} хочет подписаться на Вас"
+      body: "%{name} запросил вас о подписке"
+      subject: "%{name} хочет подписаться на вас"
       title: Новый запрос о подписке
     mention:
       action: Ответить
@@ -643,7 +770,7 @@ ru:
       title: Новое упоминание
     reblog:
       body: 'Ваш статус был продвинут %{name}:'
-      subject: "%{name} продвинул(а) Ваш статус"
+      subject: "%{name} продвинул(а) ваш статус"
       title: Новое продвижение
   number:
     human:
@@ -655,28 +782,63 @@ ru:
           quadrillion: квадрлн
           thousand: тыс
           trillion: трлн
-          unit: ''
   pagination:
     newer: Новее
     next: След
     older: Старше
     prev: Пред
     truncate: "&hellip;"
+  polls:
+    errors:
+      already_voted: Вы уже голосовали в этом опросе
+      duplicate_options: содержит одинаковые варианты
+      duration_too_long: слишком далеко в будущем
+      duration_too_short: слишком короткий срок
+      expired: Опрос уже завершился
+      over_character_limit: каждый не вариант не может быть длиннее %{max} символов
+      too_few_options: должно быть больше 1 варианта
+      too_many_options: может содержать не больше %{max} вариантов
   preferences:
-    languages: Языки
     other: Другое
-    publishing: Публикация
-    web: WWW
+    public_timelines: Публичные ленты
+  relationships:
+    activity: Активность аккаунта
+    dormant: Заброшенные
+    last_active: Недавно активные
+    most_recent: Новые
+    moved: Переехавший
+    mutual: Общие
+    primary: Основной
+    relationship: Связь
+    remove_selected_domains: Удалить всех подписчиков для выбранных доменов
+    remove_selected_followers: Удалить выбранных подписчиков
+    remove_selected_follows: Отписаться от выбранных пользователей
+    status: Статус аккаунта
   remote_follow:
     acct: Введите свой username@domain для продолжения
     missing_resource: Поиск требуемого перенаправления URL для Вашего аккаунта завершился неудачей
     no_account_html: Нет учётной записи? Вы можете <a href='%{sign_up_path}' target='_blank'>зарегистрироваться здесь</a>
     proceed: Продолжить подписку
     prompt: 'Вы хотите подписаться на:'
+    reason_html: "<strong>Почему это необходимо?</strong> <code>%{instance}</code> может не являться сервером, на котором вы зарегистрированы, поэтому нам сперва нужно перенаправить вас на домашний сервер."
+  remote_interaction:
+    favourite:
+      proceed: Отметить как "нравится"
+      prompt: 'Вы собираетесь поставить отметку "нравится" этому статусу:'
+    reblog:
+      proceed: Продвинуть статус
+      prompt: 'Вы хотите продвинуть этот статус:'
+    reply:
+      proceed: Ответить
+      prompt: 'Вы собираетесь ответить на этот статус:'
   remote_unfollow:
     error: Ошибка
     title: Заголовок
     unfollowed: Отписаны
+  scheduled_statuses:
+    over_daily_limit: Вы превысили лимит в %{limit} запланированных постов на указанный день
+    over_total_limit: Вы превысили лимит на %{limit} запланированных постов
+    too_soon: Запланированная дата должна быть в будущем
   sessions:
     activity: Последняя активность
     browser: Браузер
@@ -719,20 +881,25 @@ ru:
     revoke_success: Сессия завершена успешно
     title: Сессии
   settings:
+    account: Учётная запись
+    account_settings: Настройки учётной записи
+    appearance: Внешний вид
     authorized_apps: Авторизованные приложения
     back: Назад в Mastodon
     delete: Удаление аккаунта
     development: Разработка
     edit_profile: Изменить профиль
     export: Экспорт данных
-    followers: Авторизованные подписчики
+    featured_tags: Особенные хэштеги
+    identity_proofs: Подтверждения личности
     import: Импорт
+    import_and_export: Импорт и экспорт
     migrate: Перенос аккаунта
     notifications: Уведомления
     preferences: Настройки
-    settings: Опции
+    profile: Профиль
+    relationships: Подписки и подписчики
     two_factor_authentication: Двухфакторная аутентификация
-    your_apps: Ваши приложения
   statuses:
     attached:
       description: 'Вложение: %{attached}'
@@ -761,6 +928,13 @@ ru:
       ownership: Нельзя закрепить чужой статус
       private: Нельзя закрепить непубличный статус
       reblog: Нельзя закрепить продвинутый статус
+    poll:
+      total_votes:
+        few: "%{count} голоса"
+        many: "%{count} голосов"
+        one: "%{count} голос"
+        other: "%{count} голосов"
+      vote: Голосовать
     show_more: Ещё
     sign_in_to_participate: Войдите, чтобы принять участие в дискуссии
     title: '%{name}: "%{quote}"'
@@ -781,10 +955,10 @@ ru:
       <h3 id="collect">What information do we collect?</h3>
 
       <ul>
-        <li><em>Basic account information</em>: If you register on this server, you may be asked to enter a username, an e-mail address and a password. You may also enter additional profile information such as a display name and biography, and upload a profile picture and header image. The username, display name, biography, profile picture and header image are always listed publicly.</li>
-        <li><em>Posts, following and other public information</em>: The list of people you follow is listed publicly, the same is true for your followers. When you submit a message, the date and time is stored as well as the application you submitted the message from. Messages may contain media attachments, such as pictures and videos. Public and unlisted posts are available publicly. When you feature a post on your profile, that is also publicly available information. Your posts are delivered to your followers, in some cases it means they are delivered to different servers and copies are stored there. When you delete posts, this is likewise delivered to your followers. The action of reblogging or favouriting another post is always public.</li>
-        <li><em>Direct and followers-only posts</em>: All posts are stored and processed on the server. Followers-only posts are delivered to your followers and users who are mentioned in them, and direct posts are delivered only to users mentioned in them. In some cases it means they are delivered to different servers and copies are stored there. We make a good faith effort to limit the access to those posts only to authorized persons, but other servers may fail to do so. Therefore it's important to review servers your followers belong to. You may toggle an option to approve and reject new followers manually in the settings. <em>Please keep in mind that the operators of the server and any receiving server may view such messages</em>, and that recipients may screenshot, copy or otherwise re-share them. <em>Do not share any dangerous information over Mastodon.</em></li>
-        <li><em>IPs and other metadata</em>: When you log in, we record the IP address you log in from, as well as the name of your browser application. All the logged in sessions are available for your review and revocation in the settings. The latest IP address used is stored for up to 12 months. We also may retain server logs which include the IP address of every request to our server.</li>
+      <li><em>Basic account information</em>: If you register on this server, you may be asked to enter a username, an e-mail address and a password. You may also enter additional profile information such as a display name and biography, and upload a profile picture and header image. The username, display name, biography, profile picture and header image are always listed publicly.</li>
+      <li><em>Posts, following and other public information</em>: The list of people you follow is listed publicly, the same is true for your followers. When you submit a message, the date and time is stored as well as the application you submitted the message from. Messages may contain media attachments, such as pictures and videos. Public and unlisted posts are available publicly. When you feature a post on your profile, that is also publicly available information. Your posts are delivered to your followers, in some cases it means they are delivered to different servers and copies are stored there. When you delete posts, this is likewise delivered to your followers. The action of reblogging or favouriting another post is always public.</li>
+      <li><em>Direct and followers-only posts</em>: All posts are stored and processed on the server. Followers-only posts are delivered to your followers and users who are mentioned in them, and direct posts are delivered only to users mentioned in them. In some cases it means they are delivered to different servers and copies are stored there. We make a good faith effort to limit the access to those posts only to authorized persons, but other servers may fail to do so. Therefore it's important to review servers your followers belong to. You may toggle an option to approve and reject new followers manually in the settings. <em>Please keep in mind that the operators of the server and any receiving server may view such messages</em>, and that recipients may screenshot, copy or otherwise re-share them. <em>Do not share any dangerous information over Mastodon.</em></li>
+      <li><em>IPs and other metadata</em>: When you log in, we record the IP address you log in from, as well as the name of your browser application. All the logged in sessions are available for your review and revocation in the settings. The latest IP address used is stored for up to 12 months. We also may retain server logs which include the IP address of every request to our server.</li>
       </ul>
 
       <hr class="spacer" />
@@ -794,9 +968,9 @@ ru:
       <p>Any of the information we collect from you may be used in the following ways:</p>
 
       <ul>
-        <li>To provide the core functionality of Mastodon. You can only interact with other people's content and post your own content when you are logged in. For example, you may follow other people to view their combined posts in your own personalized home timeline.</li>
-        <li>To aid moderation of the community, for example comparing your IP address with other known ones to determine ban evasion or other violations.</li>
-        <li>The email address you provide may be used to send you information, notifications about other people interacting with your content or sending you messages, and to respond to inquiries, and/or other requests or questions.</li>
+      <li>To provide the core functionality of Mastodon. You can only interact with other people's content and post your own content when you are logged in. For example, you may follow other people to view their combined posts in your own personalized home timeline.</li>
+      <li>To aid moderation of the community, for example comparing your IP address with other known ones to determine ban evasion or other violations.</li>
+      <li>The email address you provide may be used to send you information, notifications about other people interacting with your content or sending you messages, and to respond to inquiries, and/or other requests or questions.</li>
       </ul>
 
       <hr class="spacer" />
@@ -812,8 +986,8 @@ ru:
       <p>We will make a good faith effort to:</p>
 
       <ul>
-        <li>Retain server logs containing the IP address of all requests to this server, in so far as such logs are kept, no more than 90 days.</li>
-        <li>Retain the IP addresses associated with registered users no more than 12 months.</li>
+      <li>Retain server logs containing the IP address of all requests to this server, in so far as such logs are kept, no more than 90 days.</li>
+      <li>Retain the IP addresses associated with registered users no more than 12 months.</li>
       </ul>
 
       <p>You can request and download an archive of your content, including your posts, media attachments, profile picture, and header image.</p>
@@ -855,12 +1029,13 @@ ru:
       <p>Originally adapted from the <a href="https://github.com/discourse/discourse">Discourse privacy policy</a>.</p>
     title: Условия обслуживания и политика конфиденциальности %{instance}
   themes:
-    contrast: Высококонтрастная
-    default: Mastodon
+    contrast: Mastodon (высококонтрастная)
+    default: Mastodon (тёмная)
     mastodon-light: Mastodon (светлая)
   time:
     formats:
-      default: "%b %d, %Y, %H:%M"
+      default: "%d %b %Y, %H:%M"
+      month: "%m.%Y"
   two_factor_authentication:
     code_hint: Для подтверждения введите код, сгенерированный приложением аутентификатора
     description_html: При включении <strong>двухфакторной аутентификации</strong>, вход потребует от Вас использования Вашего телефона, который сгенерирует входные токены.
@@ -882,26 +1057,46 @@ ru:
       explanation: Вы запросили полный архив вашего аккаунта Mastodon. Он готов к загрузке!
       subject: Ваш архив готов к загрузке
       title: Вынос архива
+    warning:
+      explanation:
+        disable: Пока ваш аккаунт заморожен, ваши данные остаются нетронутыми, но вы не можете производить никаких действий до разблокировки.
+        silence: Пока ваш аккаунт ограничен, ваши посты на этом сервере увидят только ваши действующие подписчики, а ваш аккаунт может быть исключён из различных каталогов. Впрочем, остальные могут подписаться на вас вручную.
+        suspend: Ваш аккаунт заблокирован и все ваши посты и загруженные медиафайлы безвозвратно удалены с этого сервера и других серверов, где у вас были подписчики.
+      review_server_policies: Посмотреть правила сервера
+      subject:
+        disable: Ваш аккаунт %{acct} заморожен
+        none: "%{acct}, вам вынесено предупреждение"
+        silence: Ваш аккаунт %{acct} был ограничен
+        suspend: Ваш аккаунт %{acct} был заблокирован
+      title:
+        disable: Аккаунт заморожен
+        none: Предупреждение
+        silence: Аккаунт ограничен
+        suspend: Аккаунт заблокирован
     welcome:
       edit_profile_action: Настроить профиль
-      edit_profile_step: Вы можете настроить свой профиль, загрузив аватар, обложку, сменив имя и много чего ещё. Если Вы хотите фильтровать подписчиков до того, как они смогут на Вас подписаться, Вы можете закрыть свой аккаунт.
+      edit_profile_step: Вы можете настроить свой профиль, загрузив аватар, обложку, сменив имя и много чего ещё. Если вы хотите фильтровать подписчиков до того, как они смогут на вас подписаться, вы можете закрыть свой аккаунт.
       explanation: Несколько советов для новичков
       final_action: Начать постить
-      final_step: 'Начните постить! Ваши публичные посты могут видеть другие, например, в локальной ленте или по хэштегам, даже если у Вас нет подписчиков. Вы также можете поздороваться с остальными и представиться, используя хэштек #приветствие.'
+      final_step: 'Начните постить! Ваши публичные посты могут видеть другие, например, в локальной ленте или по хэштегам, даже если у вас нет подписчиков. Вы также можете поздороваться с остальными и представиться, используя хэштег #приветствие.'
       full_handle: Ваше обращение
       full_handle_hint: То, что Вы хотите сообщить своим друзьям, чтобы они могли написать Вам или подписаться с другого узла.
       review_preferences_action: Изменить настройки
-      review_preferences_step: Проверьте все настройки, например, какие письма Вы хотите получать или уровень приватности статусов по умолчанию. Если Вы не страдаете морской болезнь, можете включить автовоспроизведение GIF.
+      review_preferences_step: Проверьте все настройки, например, какие письма вы хотите получать или уровень приватности статусов по умолчанию. Если вы не страдаете морской болезнью, можете включить автовоспроизведение GIF.
       subject: Добро пожаловать в Mastodon
-      tip_federated_timeline: В глобальной ленте отображается сеть Mastodon. Но в ней показаны посты только от людей, на которых подписаны Вы и Ваши соседи, поэтому лента может быть неполной.
-      tip_following: По умолчанию Вы подписаны на администратора(-ов) Вашего узла. Чтобы найти других интересных людей, проверьте локальную и глобальную ленты.
-      tip_local_timeline: В локальной ленте показаны посты от людей с %{instance}. Это Ваши непосредственные соседи!
-      tip_mobile_webapp: Если Ваш мобильный браузер предлагает добавить иконку Mastodon на домашний экран, то Вы можете получать push-уведомления. Прямо как полноценное приложение!
+      tip_federated_timeline: В глобальной ленте отображается сеть Mastodon. Но в ней показаны посты только от людей, на которых подписаны вы и ваши соседи, поэтому лента может быть неполной.
+      tip_following: По умолчанию вы подписаны на администратора(-ов) вашего узла. Чтобы найти других интересных людей, проверьте локальную и глобальную ленты.
+      tip_local_timeline: В локальной ленте показаны посты от людей с %{instance}. Это ваши непосредственные соседи!
+      tip_mobile_webapp: Если ваш мобильный браузер предлагает добавить иконку Mastodon на домашний экран, то вы можете получать push-уведомления. Прямо как полноценное приложение!
       tips: Советы
       title: Добро пожаловать на борт, %{name}!
   users:
+    follow_limit_reached: Вы не можете подписаться больше, чем на %{limit} человек
     invalid_email: Введенный e-mail неверен
     invalid_otp_token: Введен неверный код двухфакторной аутентификации
     otp_lost_help_html: Если Вы потеряли доступ к обоим, свяжитесь с %{email}
     seamless_external_login: Вы залогинены через сторонний сервис, поэтому настройки e-mail и пароля недоступны.
     signed_in_as: 'Выполнен вход под именем:'
+  verification:
+    explanation_html: 'Вы можете <strong>подтвердить себя как владельца ссылок в вашем профиле</strong>. Для этого указанный веб-сайт должен содержать обратную ссылку на ваш профиль в Mastodon. У обратной ссылки <strong>должен</strong> быть атрибут <code>rel="me"</code>. Сам текст ссылки не имеет значения. Пример:'
+    verification: Подтверждение
diff --git a/config/locales/simple_form.ar.yml b/config/locales/simple_form.ar.yml
index ef1d269eeadb7626ad447d130c93287515d716e4..b948a5c5067037e5643af1ccd615f132a7398bae 100644
--- a/config/locales/simple_form.ar.yml
+++ b/config/locales/simple_form.ar.yml
@@ -17,26 +17,28 @@ ar:
         email: سوف تتلقى رسالة إلكترونية للتأكيد
         fields: يُمكنك عرض 4 عناصر على شكل جدول في ملفك الشخصي
         header: ملف PNG أو GIF أو JPG. حجمه على أقصى تصدير %{size}. سيتم تصغيره إلى %{dimensions}px
-        inbox_url: نسخ العنوان الذي تريد استخدامه مِن صفحة الإستقبال للمُرحَّل
+        inbox_url: نسخ العنوان الذي تريد استخدامه مِن صفحة الاستقبال للمُرحَّل
         irreversible: التبويقات التي تم تصفيتها ستختفي لا محالة حتى و إن تمت إزالة عامِل التصفية لاحقًا
         locale: لغة واجهة المستخدم و الرسائل الإلكترونية و الإشعارات
         locked: يتطلب منك الموافقة يدويا على طلبات المتابعة
         password: يُنصح باستخدام 8 أحرف على الأقل
         phrase: سوف يتم العثور عليه مهما كان نوع النص أو حتى و إن كان داخل الويب فيه تحذير عن المحتوى
-        scopes: ما هي المجالات المسموح بها في التطبيق ؟ إن قمت باختيار أعلى المجالات فيمكنك الإستغناء عن الخَيار اليدوي.
+        scopes: ما هي المجالات المسموح بها في التطبيق ؟ إن قمت باختيار أعلى المجالات فيمكنك الاستغناء عن الخَيار اليدوي.
         setting_aggregate_reblogs: لا تقم بعرض المشارَكات الجديدة لتبويقات قد قُمتَ بمشاركتها سابقا (هذا الإجراء يعني المشاركات الجديدة فقط التي تلقيتَها)
-        setting_default_language: يمكن الكشف التلقائي للّغة اللتي استخدمتها في تحرير تبويقاتك ، غيرَ أنّ العملية ليست دائما دقيقة
         setting_display_media_default: إخفاء الوسائط المُعيَّنة كحساسة
         setting_display_media_hide_all: إخفاء كافة الوسائط دائمًا
         setting_display_media_show_all: دائمًا عرض الوسائط المُعيَّنة كحساسة
         setting_hide_network: الحسابات التي تُتابعها و التي تُتابِعك على حد سواء لن تُعرَض على صفحتك الشخصية
         setting_noindex: ذلك يؤثر على حالة ملفك الشخصي و صفحاتك
-        setting_theme: ذلك يؤثر على الشكل الذي سيبدو عليه ماستدون عندما تقوم بالدخول مِن أي جهاز.
         username: اسم المستخدم الخاص بك سوف يكون فريدا مِن نوعه على %{domain}
+      featured_tag:
+        name: 'رُبَّما تريد/ي استخدام أحد هؤلاء:'
       imports:
-        data: ملف CSV تم تصديره مِن مثيل خادوم ماستدون آخر
+        data: ملف CSV تم تصديره مِن خادوم ماستدون آخر
+      invite_request:
+        text: هذا سوف يساعدنا في مراجعة تطبيقك
       sessions:
-        otp: 'قم بإدخال رمز المصادقة بخطوتين الذي قام بتوليده تطبيق جهازك أو إستخدم أحد رموز النفاذ الإحتياطية :'
+        otp: 'قم بإدخال رمز المصادقة بخطوتين الذي قام بتوليده تطبيق جهازك أو استخدم أحد رموز النفاذ الاحتياطية:'
       user:
         chosen_languages: لن تظهر على الخيوط العمومية إلّا التبويقات المنشورة في اللغات المختارة
     labels:
@@ -67,7 +69,7 @@ ar:
         current_password: كلمة السر الحالية
         data: البيانات
         discoverable: القيام بإدراج هذا الحساب في قائمة دليل الحسابات
-        display_name: الإسم المعروض
+        display_name: الاسم المعروض
         email: عنوان البريد الإلكتروني
         expires_in: تنتهي مدة صلاحيته بعد
         fields: البيانات الوصفية للصفحة الشخصية
@@ -82,42 +84,49 @@ ar:
         otp_attempt: رمز المصادقة بخطوتين
         password: كلمة السر
         phrase: كلمة مفتاح أو عبارة
+        setting_advanced_layout: تمكين واجهة الويب المتقدمة
         setting_aggregate_reblogs: جمع الترقيات في خيوط زمنية
         setting_auto_play_gif: تشغيل تلقائي لِوَسائط جيف المتحركة
         setting_boost_modal: إظهار مربع حوار للتأكيد قبل ترقية أي تبويق
         setting_default_language: لغة النشر
         setting_default_privacy: خصوصية المنشور
-        setting_default_sensitive: إعتبر الوسائط دائما كمحتوى حساس
+        setting_default_sensitive: اعتبر الوسائط دائما كمحتوى حساس
         setting_delete_modal: إظهار مربع حوار للتأكيد قبل حذف أي تبويق
         setting_display_media: عرض الوسائط
         setting_display_media_default: افتراضي
-        setting_display_media_hide_all: اخفاء الكل
+        setting_display_media_hide_all: إخفاء الكل
         setting_display_media_show_all: عرض الكل
         setting_expand_spoilers: توسيع التبويقات التي تحتوي على تحذيرات عن المحتوى تلقائيا
         setting_hide_network: إخفِ شبكتك
         setting_noindex: عدم السماح لمحركات البحث بفهرسة ملفك الشخصي
         setting_reduce_motion: تخفيض عدد الصور في الوسائط المتحركة
-        setting_system_font_ui: إستخدم الخطوط الإفتراضية للنظام
+        setting_show_application: اكشف اسم التطبيقات المستخدمة لنشر التبويقات
+        setting_system_font_ui: استخدم الخطوط الافتراضية للنظام
         setting_theme: سمة الموقع
         setting_unfollow_modal: إظهار مربع حوار للتأكيد قبل إلغاء متابعة أي حساب
         severity: القوّة
-        type: صيغة الإستيراد
-        username: إسم المستخدم
-        username_or_email: إسم المستخدم أو كلمة السر
+        type: صيغة الاستيراد
+        username: اسم المستخدم
+        username_or_email: اسم المستخدم أو كلمة السر
         whole_word: الكلمة كاملة
+      featured_tag:
+        name: الوسم
       interactions:
         must_be_follower: حظر الإخطارات القادمة من حسابات لا تتبعك
         must_be_following: حظر الإخطارات القادمة من الحسابات التي لا تتابعها
         must_be_following_dm: حظر الرسائل المباشرة القادمة من طرف أشخاص لا تتبعهم
+      invite_request:
+        text: لماذا ترغب في الانضمام؟
       notification_emails:
         digest: إرسال ملخصات عبر البريد الإلكتروني
-        favourite: إبعث بريداً إلكترونيًا عندما يُعجَب أحدهم بمنشورك
-        follow: إبعث بريداً إلكترونيًا عندما يتبعك أحد
-        follow_request: إبعث بريدا إلكترونيا عندما يقوم أحدهم بإرسال طلب بالمتابعة
-        mention: إبعث بريداً إلكترونيًا عندما يُشير إليك أو يذكُرك أحدهم
-        reblog: إبعث بريداً إلكترونيًا عندما يقوم أحدهم بترقية منشورك
+        favourite: ابعث بريداً إلكترونيًا عندما يُعجَب أحدهم بمنشورك
+        follow: ابعث بريداً إلكترونيًا عندما يتبعك أحد
+        follow_request: ابعث بريدا إلكترونيا عندما يقوم أحدهم بإرسال طلب بالمتابعة
+        mention: ابعث بريداً إلكترونيًا عندما يُشير إليك أو يذكُرك أحدهم
+        reblog: ابعث بريداً إلكترونيًا عندما يقوم أحدهم بترقية منشورك
         report: إرسال رسالة إلكترونية عند تلقّي إبلاغ جديد
     'no': لا
+    recommended: موصى بها
     required:
       mark: "*"
       text: مطلوب
diff --git a/config/locales/simple_form.ast.yml b/config/locales/simple_form.ast.yml
index b91d5780a9d977087e51fd78d4c07281fa4a8ef8..4ec3935c900be0d8a375c36dd8b868982ad00404 100644
--- a/config/locales/simple_form.ast.yml
+++ b/config/locales/simple_form.ast.yml
@@ -10,7 +10,6 @@ ast:
         irreversible: Los toots peñeraos van desapaecer de mou irreversible, magar que se desanicie la peñera dempués
         password: Usa 8 caráuteres polo menos
         setting_hide_network: La xente que sigas y teas siguiendo nun va amosase nel perfil
-        setting_theme: Afeuta al aspeutu de Mastodon cuando anicies sesión dende cualesquier preséu.
         username: El nome d'usuariu va ser únicu en %{domain}
       imports:
         data: El ficheru CSV esportáu dende otra instancia de Mastodon
@@ -20,7 +19,6 @@ ast:
           name: Etiqueta
           value: Conteníu
       defaults:
-        avatar: Avatar
         bot: Esta cuenta ye d'un robó
         chosen_languages: Peñera de llingües
         confirm_new_password: Confirmación de la contraseña nueva
@@ -36,7 +34,6 @@ ast:
         locked: Bloquiar cuenta
         max_uses: Númberu máximu d'usos
         new_password: Contraseña nueva
-        note: Bio
         otp_attempt: Códigu de verificación en dos pasos
         password: Contraseña
         phrase: Pallabra clave o fras
@@ -61,6 +58,5 @@ ast:
         mention: Unviar un corréu cuando daquién te mente
     'no': Non
     required:
-      mark: "*"
       text: ríquese
     'yes': Sí
diff --git a/config/locales/simple_form.bg.yml b/config/locales/simple_form.bg.yml
index 9441e53b3748ba62ce66b694f0c5b926cad00555..9991bed3dff2949bdb310961319b1e323dbbc30f 100644
--- a/config/locales/simple_form.bg.yml
+++ b/config/locales/simple_form.bg.yml
@@ -39,6 +39,5 @@ bg:
         reblog: Изпращай e-mail, когато някой сподели твоя публикация
     'no': Не
     required:
-      mark: "*"
       text: задължително
     'yes': Да
diff --git a/config/locales/simple_form.bn.yml b/config/locales/simple_form.bn.yml
new file mode 100644
index 0000000000000000000000000000000000000000..152c698290639f4688cdb5184962daafc705fc52
--- /dev/null
+++ b/config/locales/simple_form.bn.yml
@@ -0,0 +1 @@
+bn:
diff --git a/config/locales/simple_form.ca.yml b/config/locales/simple_form.ca.yml
index 4c2b1636dcb535e5064dc8e60ee9dce8e30141ea..d8713e4caee9fceaad504a0bbe5b895c6a563732 100644
--- a/config/locales/simple_form.ca.yml
+++ b/config/locales/simple_form.ca.yml
@@ -27,17 +27,21 @@ ca:
         phrase: Es combinarà independentment del format en el text o l'avís de contingut d'un toot
         scopes: A quines API es permetrà l'accés a l'aplicació. Si selecciones un àmbit d'alt nivell, no cal que seleccionis un d'individual.
         setting_aggregate_reblogs: No mostra els nous impulsos dels toots que ja s'han impulsat recentment (només afecta als impulsos nous rebuts)
-        setting_default_language: La llengua dels teus toots pot ser detectada automàticament però no sempre acuradament
+        setting_default_sensitive: Els mèdia sensibles estan ocults per defecte i es poden revelar amb un clic
         setting_display_media_default: Amaga els multimèdia marcats com a sensibles
         setting_display_media_hide_all: Sempre oculta tots els multimèdia
         setting_display_media_show_all: Mostra sempre els elements multimèdia marcats com a sensibles
         setting_hide_network: Qui tu segueixes i els que et segueixen a tu no es mostraran en el teu perfil
         setting_noindex: Afecta el teu perfil públic i les pàgines d'estat
-        setting_theme: Afecta l'aspecte de Mastodon quan es visita des de qualsevol dispositiu.
+        setting_show_application: L'aplicació que fas servir per a publicar es mostrarà a la vista detallada dels teus toots
         username: El teu nom d'usuari serà únic a %{domain}
         whole_word: Quan la paraula clau o la frase sigui només alfanumèrica, s'aplicarà si coincideix amb la paraula sencera
+      featured_tag:
+        name: 'És possible que vulguis utilitzar un d''aquests:'
       imports:
-        data: Fitxer CSV exportat des de una altra instància de Mastodon
+        data: Fitxer CSV exportat des d'un altre servidor de Mastodon
+      invite_request:
+        text: Això ens ajudarà a revisar la teva petició
       sessions:
         otp: 'Introdueix el codi de dos factors generat per el teu telèfon o utilitza un dels teus codis de recuperació:'
       user:
@@ -85,6 +89,7 @@ ca:
         otp_attempt: Codi de dos factors
         password: Contrasenya
         phrase: Paraula clau o frase
+        setting_advanced_layout: Activar l’interfície web avançada
         setting_aggregate_reblogs: Agrupa impulsos en les línies de temps
         setting_auto_play_gif: Reproducció automàtica de GIFs animats
         setting_boost_modal: Mostra la finestra de confirmació abans d'impulsar
@@ -100,6 +105,7 @@ ca:
         setting_hide_network: Amaga la teva xarxa
         setting_noindex: Desactivació de la indexació del motor de cerca
         setting_reduce_motion: Redueix el moviment en animacions
+        setting_show_application: Desvela l'aplicació utilitzada per enviar toots
         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ú
@@ -108,19 +114,25 @@ ca:
         username: Nom d'usuari
         username_or_email: Nom d'usuari o adreça electrònica
         whole_word: Paraula sencera
+      featured_tag:
+        name: Etiqueta
       interactions:
         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
+      invite_request:
+        text: Per què vols unir-te?
       notification_emails:
         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
+        pending_account: Envia un correu electrònic quan es necessiti revisar un compte nou
         reblog: Envia un correu electrònic si algú comparteix el teu estat
         report: Envia un correu electrònic quan s'enviï un nou informe
     'no': 'No'
+    recommended: Recomanat
     required:
       mark: "*"
       text: necessari
diff --git a/config/locales/simple_form.co.yml b/config/locales/simple_form.co.yml
index 2fb035556934c2153d0722f559e49a9e835df9d6..1f5dba43fb5f55316a8d5e0e2d514cafb9a8213a 100644
--- a/config/locales/simple_form.co.yml
+++ b/config/locales/simple_form.co.yml
@@ -27,17 +27,21 @@ co:
         phrase: Sarà trovu senza primura di e maiuscule o di l'avertimenti
         scopes: L'API à quelle l'applicazione averà accessu. S'è voi selezziunate un parametru d'altu livellu, un c'hè micca bisognu di selezziunà quell'individuali.
         setting_aggregate_reblogs: Ùn mustrà micca e nove spartere per i statuti chì sò stati spartuti da pocu (tocca solu e spartere più ricente)
-        setting_default_language: A lingua di i vostri statuti pò esse induvinata autumaticamente, mà ùn marchja micca sempre bè
+        setting_default_sensitive: I media sensibili sò piattati, salvu un cambiamentu di i paramettri, è ponu esse visti cù un cliccu
         setting_display_media_default: Piattà i media marcati cum'è sensibili
         setting_display_media_hide_all: Sempre piattà tutti i media
         setting_display_media_show_all: Sempre affissà i media marcati cum'è sensibili
         setting_hide_network: I vostri abbunati è abbunamenti ùn saranu micca mustrati nant’à u vostru prufile
         setting_noindex: Tocca à u vostru prufile pubblicu è i vostri statuti
-        setting_theme: Tocca à l’apparenza di Mastodon quandu site cunnettatu·a da qualch’apparechju.
+        setting_show_application: L'applicazione chì voi utilizate per mandà statuti sarà affissata indè a vista ditagliata di quelli
         username: U vostru cugnome sarà unicu nant'à %{domain}
         whole_word: Quandu a parolla o a frasa sana hè alfanumerica, sarà applicata solu s'ella currisponde à a parolla sana
+      featured_tag:
+        name: 'Pudete vulè utilizà unu di quelli:'
       imports:
-        data: Un fugliale CSV da un’altr’istanza di Mastodon
+        data: Un fugliale CSV da un’altru servore di Mastodon
+      invite_request:
+        text: Quessu ci aiutarà à valutà a vostra dumanda
       sessions:
         otp: 'Entrate u codice d’identificazione à dui fattori nant’à u vostru telefuninu, o unu di i vostri codici di ricuperazione:'
       user:
@@ -45,7 +49,7 @@ co:
     labels:
       account:
         fields:
-          name: Label
+          name: Marcu
           value: Cuntinutu
       account_warning_preset:
         text: Testu preselezziunatu
@@ -85,6 +89,7 @@ co:
         otp_attempt: Codice d’identificazione à dui fattori
         password: Chjave d’accessu
         phrase: Parolla-chjave o frasa
+        setting_advanced_layout: Attivà l'interfaccia web avanzata
         setting_aggregate_reblogs: Gruppà e spartere indè e linee
         setting_auto_play_gif: Lettura autumatica di i GIF animati
         setting_boost_modal: Mustrà una cunfirmazione per sparte un statutu
@@ -100,6 +105,7 @@ co:
         setting_hide_network: Piattà a vostra rete
         setting_noindex: Dumandà à i motori di ricerca internet d’un pudè micca esse truvatu·a cusì
         setting_reduce_motion: Fà chì l’animazione vanu più pianu
+        setting_show_application: Indicà u nome di l'applicazione utilizata per mandà statuti
         setting_system_font_ui: Pulizza di caratteri di u sistemu
         setting_theme: Tema di u situ
         setting_unfollow_modal: Mustrà una cunfirmazione per siguità qualch’unu
@@ -108,19 +114,25 @@ co:
         username: Cugnome
         username_or_email: Cugnome o Email
         whole_word: Parolla sana
+      featured_tag:
+        name: Hashtag
       interactions:
         must_be_follower: Piattà e nutificazione di quelli·e ch’ùn vi seguitanu
         must_be_following: Piattà e nutificazione di quelli·e ch’ùn seguitate
         must_be_following_dm: Bluccà e missaghji diretti di quelli·e ch’ùn seguitate
+      invite_request:
+        text: Perchè vulete ghjunghje?
       notification_emails:
         digest: Mandà e-mail di ricapitulazione
         favourite: Mandà un’e-mail quandu qualch’unu aghjunghje i mo statuti à i so favuriti
         follow: Mandà un’e-mail quandu qualch’unu mi seguita
         follow_request: Mandà un’e-mail quandu qualch’unu vole seguitami
         mention: Mandà un’e-mail quandu qualch’unu mi mintuva
+        pending_account: Mandà un'e-mail quandu un novu contu hà bisognu d'esse valutatu
         reblog: Mandà un’e-mail quandu qualch’unu sparte i mo statuti
         report: Mandà un'e-mail quandu c'hè un novu signalamentu
     'no': Nò
+    recommended: Ricumandati
     required:
       mark: "*"
       text: riquisiti
diff --git a/config/locales/simple_form.cs.yml b/config/locales/simple_form.cs.yml
index 0e255e4dc10eb2c0850b672f8ca291a7396df67a..3bf74e9718232a79bb7d23c9879b7e7b06fba09f 100644
--- a/config/locales/simple_form.cs.yml
+++ b/config/locales/simple_form.cs.yml
@@ -6,40 +6,44 @@ cs:
         text: Můžete používat syntaxi tootů, jako například URL, hashtagy a zmínky
       admin_account_action:
         send_email_notification: Uživatel obdrží vysvětlení toho, co se stalo s jeho účtem
-        text_html: Volitelné. Můžete používat syntaxi tootů. Pro ušetření času si můžete <a href="%{path}">přidat přednastavení pro varování</a>
+        text_html: Volitelné. Můžete používat syntaxi tootů. Pro ušetření času si můžete <a href="%{path}">přidat předlohy pro varování</a>
         type_html: Vyberte, co chcete udělat s účtem <strong>%{acct}</strong>
-        warning_preset_id: Volitelné. Můžete stále vložit na konec přednastavení vlastní text
+        warning_preset_id: Volitelné. Můžete stále vložit na konec předlohy vlastní text
       defaults:
         autofollow: Lidé, kteří se zaregistrují přes pozvání, vás budou automaticky sledovat
         avatar: PNG, GIF či JPG. Maximálně %{size}. Bude zmenšen na %{dimensions} px
         bot: Tento účet provádí hlavně automatizované akce a nemusí být spravován
-        context: Jedno či více kontextů, ve kterých má být filtr uplatněn
+        context: Jeden či více kontextů, ve kterých má být filtr uplatněn
         digest: Odesíláno pouze po dlouhé době nečinnosti a pouze, pokud jste při své nepřítomnosti obdržel/a osobní zprávy
-        discoverable_html: <a href="%{path}" target="_blank">Adresář</a> dovoluje lidem najít účty podle zájmů a aktivity. Vyžaduje alespoň %{min_followers} sledovatelů
+        discoverable_html: <a href="%{path}" target="_blank">Adresář</a> dovoluje lidem najít účty podle zájmů a aktivity. Vyžaduje alespoň %{min_followers} sledujících
         email: Bude vám poslán potvrzovací e-mail
         fields: Na profilu můžete mít až 4 položky zobrazené jako tabulka
         header: PNG, GIF či JPG. Maximálně %{size}. Bude zmenšen na %{dimensions} px
         inbox_url: Zkopírujte URL z hlavní stránky mostu, který chcete použít
         irreversible: Filtrované tooty nenávratně zmizí, i pokud bude filtr později odstraněn
         locale: Jazyk uživatelského rozhraní, e-mailů a oznámení push
-        locked: Vyžaduje manuální schvalování sledovatelů
+        locked: Vyžaduje, abyste ručně schvaloval/a sledující
         password: Použijte alespoň 8 znaků
         phrase: Shoda bude nalezena bez ohledu na velikost písmen v těle tootu či varování o obsahu
-        scopes: Které API bude aplikace povolena používat. Pokud vyberete rozsah nejvyššího stupně, nebudete je muset vybírat po jednom.
+        scopes: Která API bude aplikaci povoleno používat. Pokud vyberete rozsah nejvyššího stupně, nebudete je muset vybírat jednotlivě.
         setting_aggregate_reblogs: Nezobrazovat nové boosty pro tooty, které byly nedávno boostnuty (ovlivňuje pouze nově přijaté boosty)
-        setting_default_language: Jazyk vašich tootů může být detekován automaticky, není to však vždy přesné
+        setting_default_sensitive: Citlivá média jsou ve výchozím stavu skryta a mohou být zobrazena kliknutím
         setting_display_media_default: Skrývat média označená jako citlivá
         setting_display_media_hide_all: Vždy skrývat všechna média
         setting_display_media_show_all: Vždy zobrazovat média označená jako citlivá
         setting_hide_network: Koho sledujete a kdo sleduje vás nebude zobrazeno na vašem profilu
-        setting_noindex: Ovlivňuje váš veřejný profil a stránky příspěvků
-        setting_theme: Ovlivňuje jak Mastodon vypadá, jste-li přihlášen na libovolném zařízení.
+        setting_noindex: Ovlivňuje váš veřejný profil a stránky tootů
+        setting_show_application: Aplikace, kterou používáte k psaní tootů, bude zobrazena v detailním zobrazení vašich tootů
         username: Vaše uživatelské jméno bude na %{domain} unikátní
         whole_word: Je-li klíčové slovo či fráze pouze alfanumerická, bude aplikována pouze, pokud se shoduje s celým slovem
+      featured_tag:
+        name: 'Nejspíš budete chtít použít jeden z těchto:'
       imports:
-        data: Soubor CSV exportován z jiné instance Mastodon
+        data: Soubor CSV exportovaný z jiného serveru Mastodon
+      invite_request:
+        text: To nám pomůže posoudit váš požadavek
       sessions:
-        otp: 'Napište dvoufaktorový kód vygenerovaný vaší mobilní aplikací, nebo použijte jeden z vašich záložních kódů:'
+        otp: 'Napište dvoufázový kód vygenerovaný vaší mobilní aplikací, nebo použijte jeden z vašich záložních kódů:'
       user:
         chosen_languages: Je-li tohle zaškrtnuto, budou ve veřejných časových osách zobrazeny pouze tooty ve zvolených jazycích
     labels:
@@ -48,7 +52,7 @@ cs:
           name: Označení
           value: Obsah
       account_warning_preset:
-        text: Text přednastavení
+        text: Text předlohy
       admin_account_action:
         send_email_notification: Informovat uživatele e-mailem
         text: Vlastní varování
@@ -58,7 +62,7 @@ cs:
           none: Nic nedělat
           silence: Utišit
           suspend: Pozastavit a nenávratně smazat data účtu
-        warning_preset_id: Použít přednastavení pro varování
+        warning_preset_id: Použít předlohu pro varování
       defaults:
         autofollow: Pozvat ke sledování vašeho účtu
         avatar: Avatar
@@ -72,19 +76,20 @@ cs:
         discoverable: Zveřejnit tento účet v adresáři
         display_name: Zobrazované jméno
         email: E-mailová adresa
-        expires_in: Expirovat po
+        expires_in: Vypršet za
         fields: Metadata profilu
-        header: Hlavičkový obrázek
-        inbox_url: URL schránky mostu
+        header: Záhlaví
+        inbox_url: URL příchozí schránky mostu
         irreversible: Zahodit místo skrytí
         locale: Jazyk rozhraní
-        locked: Zamknout účet
+        locked: Uzamknout účet
         max_uses: Maximální počet použití
         new_password: Nové heslo
         note: O vás
-        otp_attempt: Dvoufaktorový kód
+        otp_attempt: Dvoufázový kód
         password: Heslo
         phrase: Klíčové slovo či fráze
+        setting_advanced_layout: Povolit pokročilé webové rozhraní
         setting_aggregate_reblogs: Seskupovat boosty v časových osách
         setting_auto_play_gif: Automaticky přehrávat animace GIF
         setting_boost_modal: Zobrazovat před boostnutím potvrzovací okno
@@ -100,6 +105,7 @@ cs:
         setting_hide_network: Skrýt svou síť
         setting_noindex: Neindexovat svůj profil vyhledávači
         setting_reduce_motion: Redukovat pohyb v animacích
+        setting_show_application: Zobrazit aplikaci používanou k psaní tootů
         setting_system_font_ui: Použít výchozí písmo systému
         setting_theme: Motiv stránky
         setting_unfollow_modal: Zobrazovat před zrušením sledování potvrzovací okno
@@ -108,19 +114,25 @@ cs:
         username: Uživatelské jméno
         username_or_email: Uživatelské jméno nebo e-mail
         whole_word: Celé slovo
+      featured_tag:
+        name: Hashtag
       interactions:
         must_be_follower: Blokovat oznámení od lidí, kteří vás nesledují
         must_be_following: Blokovat oznámení od lidí, které nesledujete
         must_be_following_dm: Blokovat přímé zprávy od lidí, které nesledujete
+      invite_request:
+        text: Proč se chcete připojit?
       notification_emails:
         digest: Posílat e-maily s přehledem
-        favourite: Posílat e-maily, když si někdo oblíbí váš příspěvek
+        favourite: Posílat e-maily, když si někdo oblíbí váš toot
         follow: Posílat e-maily, když vás někdo začne sledovat
         follow_request: Posílat e-maily, když vás někdo požádá o sledování
         mention: Posílat e-maily, když vás někdo zmíní
-        reblog: Posílat e-maily, když někdo boostne váš příspěvek
+        pending_account: Posílat e-maily, když je třeba posoudit nový účet
+        reblog: Posílat e-maily, když někdo boostne váš toot
         report: Posílat e-maily, je-li odesláno nové nahlášení
     'no': Ne
+    recommended: Doporučeno
     required:
       mark: "*"
       text: požadováno
diff --git a/config/locales/simple_form.cy.yml b/config/locales/simple_form.cy.yml
index d3f9cb340d8246294e3709c320f724f8c8ed42fa..023506f24fc1060be95add1ea5cd2d26c491a3d7 100644
--- a/config/locales/simple_form.cy.yml
+++ b/config/locales/simple_form.cy.yml
@@ -2,33 +2,46 @@
 cy:
   simple_form:
     hints:
+      account_warning_preset:
+        text: Gallwch defnyddio cystrawen tŵt, fel URLs, hashnodau a sôniadau
+      admin_account_action:
+        send_email_notification: Bydd y defnyddiwr yn derbyn esboniad o beth digwyddodd gyda'i cyfrif
+        text_html: Yn ddewisol. Gallwch defnyddio cystrawen tŵt. Gallwch <a href="%{path}">ychwanegu rhagosodiadau rhybydd</a> i arbed amser
+        type_html: Dewis beth i wneud gyda <strong>%{acct}</strong>
+        warning_preset_id: Yn ddewisol. Gallwch dal ychwanegu testun addasiol I ddiwedd y rhagosodiad
       defaults:
         autofollow: Bydd pobl sy'n cofrestru drwy'r gwahoddiad yn eich dilyn yn awtomatig
         avatar: PNG, GIF neu JPG. %{size} ar y mwyaf. Caiff ei israddio i %{dimensions}px
         bot: Mae'r cyfrif hwn yn perfformio gweithredoedd awtomatig yn bennaf ac mae'n bosib nad yw'n cael ei fonitro
         context: Un neu fwy cyd-destun lle dylai'r hidlydd weithio
         digest: Ond yn cael eu hanfon ar ôl cyfnod hir o anweithgarwch ac ond os ydych wedi derbyn unrhyw negeseuon personol yn eich absenoldeb
+        discoverable_html: Mae'r <a href="%{path}" target="_blank">cyfeiriadur</a> yn gadael i bobl ddarganfod cyfrifau wedi'i seilio ar ddiddordebau a gweithgareddau.. Mae hyn angen o leiaf %{min_followers} o ddilynwyr
         email: Byddwch yn derbyn e-bost i gadarnhau
         fields: Mae modd i chi arddangos hyd at 4 eitem fel tabl ar eich proffil
         header: PNG, GIF neu JPG. %{size} ar y mwyaf. Ceith ei israddio i %{dimensions}px
         inbox_url: Copïwch yr URL o dudalen flaen y relái yr ydych am ei ddefnyddio
         irreversible: Bydd tŵtiau wedi eu hidlo yn diflannu am byth, hyd yn oed os ceith yr hidlydd ei ddileu'n hwyrach
-        locale: Iaith y rhyngwyneb, e-byst a hysbysiadau push
+        locale: Iaith y rhyngwyneb, e-byst a hysbysiadau gwthiadwy
         locked: Ei wneud yn ofynnol i chi i ganiatau dilynwyr a llaw
         password: Defnyddiwch oleiaf 8 nodyn
         phrase: Caiff ei gyfateb heb ystyriaeth o briflythrennu mewn testun neu rhybudd ynghylch cynnwys tŵt
         scopes: Pa APIau y bydd gan y rhaglen ganiatad i gael mynediad iddynt. Os dewiswch maes lefel uchaf, yna nid oes angen dewis rhai unigol.
-        setting_default_language: Mae modd adnabod iaith eich tŵtiau yn awtomatig, ond nid yw bob tro'n gywir
+        setting_aggregate_reblogs: Paid dangos bŵstiau newydd ar gyfer tŵtiau sydd wedi'i fŵstio yn ddiweddar (dim ond yn effeithio bŵstiau newydd ei dderbyn)
+        setting_default_sensitive: Mae cyfryngau sensitif yn cael ei gyddio'n rhagosodiedig, a gall cael eu dangos â chlic
         setting_display_media_default: Cuddio cyfryngau wedi eu marcio'n sensitif
         setting_display_media_hide_all: Cuddio cyfryngau bob tro
         setting_display_media_show_all: Dangos cyfryngau wedi eu marcio'n sensitif bob tro
         setting_hide_network: Ni fydd y rheini yr ydych yn eu dilyn a phwy sy'n eich dilyn chi yn cael ei ddangos ar eich proffil
         setting_noindex: Mae hyn yn effeithio ar eich proffil cyhoeddus a'ch tudalennau statws
-        setting_theme: Mae hyn yn effeithio ar sut olwg sydd ar Matododon pan yr ydych wedi mewngofnodi o unrhyw ddyfais.
+        setting_show_application: Bydd y offer frydych yn defnyddio i dŵtio yn cael ei arddangos yn golwg manwl eich tŵtiau
         username: Bydd eich enw defnyddiwr yn unigryw ar %{domain}
         whole_word: Os yw'r allweddair neu'r ymadrodd yn alffaniwmerig yn unig, mi fydd ond yn cael ei osod os yw'n cyfateb a'r gair cyfan
+      featured_tag:
+        name: 'Efallai hoffech defnyddio un o''r rhain:'
       imports:
         data: Allforiwyd dogfen CSV o achos Mastodon arall
+      invite_request:
+        text: Bydd hyn yn helpu ni adolygu eich cais
       sessions:
         otp: 'Mewnbynnwch y cod dau gam a gynhyrchwyd gan eich ap ffôn neu defnyddiwch un o''ch codau adfer:'
       user:
@@ -38,6 +51,18 @@ cy:
         fields:
           name: Label
           value: Cynnwys
+      account_warning_preset:
+        text: Testun rhagosodedig
+      admin_account_action:
+        send_email_notification: Hysbysu'r defnyddiwr trwy e-bost
+        text: Rhybudd wedi'i addasu
+        type: Gweithredu
+        types:
+          disable: Analluogi
+          none: Gwneud dim
+          silence: Tawelwch
+          suspend: Dileu data cyfrif
+        warning_preset_id: Defnyddiwch ragnod rhag rhybudd
       defaults:
         autofollow: Gwahodd i ddilyn eich cyfrif
         avatar: Afatar
@@ -48,6 +73,7 @@ cy:
         context: Hidlo cyd-destunau
         current_password: Cyfrinair presennol
         data: Data
+        discoverable: Rhestrwch y cyfrif hwn ar y cyfeiriadur
         display_name: Enw arddangos
         email: Cyfeiriad e-bost
         expires_in: Yn dod i ben ar ôl
@@ -63,6 +89,8 @@ cy:
         otp_attempt: Côd dau gam
         password: Cyfrinair
         phrase: Allweddair neu ymadrodd
+        setting_advanced_layout: Alluogi rhyngwyneb wê uwch
+        setting_aggregate_reblogs: Grŵp hybiau mewn ffrydiau
         setting_auto_play_gif: Chwarae GIFs wedi'u hanimeiddio yn awtomatig
         setting_boost_modal: Dangos deialog cadarnhad cyn bŵstio
         setting_default_language: Cyhoeddi iaith
@@ -77,6 +105,7 @@ cy:
         setting_hide_network: Cuddio eich rhwydwaith
         setting_noindex: Dewis peidio mynegeio peiriant chwilota
         setting_reduce_motion: Lleihau mudiant mewn animeiddiadau
+        setting_show_application: Datguddio'r offer defnyddwyd i anfon tŵtiau
         setting_system_font_ui: Defnyddio ffont rhagosodedig y system
         setting_theme: Thema'r wefan
         setting_unfollow_modal: Dangos deialog cadarnhau cyn dad-ddilyn rhywun
@@ -85,19 +114,25 @@ cy:
         username: Enw defnyddiwr
         username_or_email: Enw defnyddiwr neu e-bost
         whole_word: Gair cyfan
+      featured_tag:
+        name: Hashnod
       interactions:
         must_be_follower: Blocio hysbysiadau o bobl nad ydynt yn eich dilyn
         must_be_following: Blocio hysbysiadau o bobl nad ydych yn eu dilyn
         must_be_following_dm: Blocio negeseuon uniongyrchol o bobl nad ydych yn eu dilyn
+      invite_request:
+        text: Pam hoffech ymuno?
       notification_emails:
         digest: Anfonwch e-byst crynhoi
         favourite: Anfon e-bost pan mae rhywun yn ffefrynnu eich statws
         follow: Anfon e-bost pan mae rhywun yn eich dilyn chi
         follow_request: Anfon e-bost pan mae rhywun yn gofyn i chi i'w dilyn
         mention: Anfon e-bost pan mae rhywun yn eich crybwyll
+        pending_account: Anfon ebost pan mae cyfrif newydd angen adolygiad
         reblog: Anfon e-bost pan mae rhywun yn bŵstio eich statws
         report: Anfon e-bost pan y cyflwynir adroddiad newydd
     'no': Na
+    recommended: Argymhellwyd
     required:
       mark: "*"
       text: gofynnol
diff --git a/config/locales/simple_form.da.yml b/config/locales/simple_form.da.yml
index f73dbac9634292170d27f50180f9c5f0eb219fe5..324afece652e63461ee24727bf4c4cef8571ab8a 100644
--- a/config/locales/simple_form.da.yml
+++ b/config/locales/simple_form.da.yml
@@ -20,16 +20,14 @@ da:
         password: Brug mindst 8 tegn
         phrase: Vil blive parret uanset om der er store eller små bogstaver i teksten eller om der er en advarsel om et trut
         scopes: Hvilke APIs applikationen vil få adgang til. Hvis du vælger et højtlevel omfang, behøver du ikke vælge enkeltstående.
-        setting_default_language: Sproget for dine trut kan blive fundet automatisk, men det er ikke altid præcist
         setting_display_media_default: Skjul medier markeret som følsomt
         setting_display_media_hide_all: Skjul altid alle medier
         setting_hide_network: Hvem du følger og hvem der følger dig vil ikke blive vist på din profil
         setting_noindex: PÃ¥virker din offentlige profil og status sider
-        setting_theme: Påvirker hvordan Mastodon ser ud når du er logget ind via en hvilken som helst enhed.
         username: Dit brugernavn vil være unikt på %{domain}
         whole_word: Når nøgle ordet eller udtrykket kun er alfanumerisk, vil det kun blive brugt hvis det passer hele ordet
       imports:
-        data: CSV fil eksporteret fra en anden Mastodon instans
+        data: CSV fil eksporteret fra en anden Mastodon server
       sessions:
         otp: 'Indtast to-faktor koden der generes af appen af appen på din telefon eller brug en af din genoprettelses koder:'
       user:
@@ -53,7 +51,6 @@ da:
         confirm_password: Bekræft adgangskode
         context: Filtrer sammenhænge
         current_password: Nuværende adgangskode
-        data: Data
         display_name: Visningsnavn
         email: E-mail adresse
         expires_in: Udløber efter
@@ -105,6 +102,5 @@ da:
         report: Send email når en ny anmeldelse bliver indsendt
     'no': Nej
     required:
-      mark: "*"
       text: påkrævet
     'yes': Ja
diff --git a/config/locales/simple_form.de.yml b/config/locales/simple_form.de.yml
index 3958e315f665ee661f8d6f88c2bcf5959792be89..61e0f9740d2168f18a228b9039d938766917a9ad 100644
--- a/config/locales/simple_form.de.yml
+++ b/config/locales/simple_form.de.yml
@@ -3,45 +3,49 @@ de:
   simple_form:
     hints:
       account_warning_preset:
-        text: Du kannst Toot-Syntax benutzen, wie zum Beispiel URLs, Hashtags und Erwähnungen
+        text: Du kannst Beitragssyntax benutzen, wie z.B. URLs, Hashtags und Erwähnungen
       admin_account_action:
-        send_email_notification: Der Benutzer erhält eine Erklärung, was mit seinem Account geschehen ist
-        text_html: Optional. Du kannst Toot-Syntax benutzen. Du kannst <a href="%{path}">Warnungsvorlagen</a> benutzen um Zeit zu sparen
+        send_email_notification: Benutzer_in wird Bescheid gegeben, was mit dem Konto geschehen ist
+        text_html: Optional. Du kannst Beitragssyntax nutzen. Du kannst <a href="%{path}">Warnungsvorlagen</a> benutzen um Zeit zu sparen
         type_html: Wähle aus, was du mit <strong>%{acct}</strong> machen möchtest
         warning_preset_id: Optional. Du kannst immer noch eigenen Text an das Ende der Vorlage hinzufügen
       defaults:
         autofollow: Leute, die sich über deine Einladung registrieren, werden dir automatisch folgen
         avatar: PNG, GIF oder JPG. Maximal %{size}. Wird auf %{dimensions} px herunterskaliert
         bot: Dieses Konto führt lediglich automatisierte Aktionen durch und wird möglicherweise nicht überwacht
-        context: Ein oder mehrere Aspekte, wo der Filter greifen soll
-        digest: Wenn du lange Zeit inaktiv bist, wird dir eine Zusammenfassung von Erwähnungen in deiner Abwesenheit zugeschickt
-        discoverable_html: Das <a href="%{path}" target="_blank">Verzeichnis</a> lässt dich basierend auf Interessen und Aktivitäten neue Benutzerkonten finden. Dies benötigt mindestens %{min_followers} Follower
+        context: Ein oder mehrere Kontexte, wo der Filter aktiv werden soll
+        digest: Wenn du eine lange Zeit inaktiv bist, wird dir eine Zusammenfassung von Erwähnungen zugeschickt, die du in deiner Abwesenheit empfangen hast
+        discoverable_html: Das <a href="%{path}" target="_blank">Verzeichnis</a> erlaubt es dein Profil durch deine Hashtags und deine Aktivitäten zu entdecken. Voraussetzung ist allerdings mindestens %{min_followers} Folger_innen
         email: Du wirst eine Bestätigungs-E-Mail erhalten
         fields: Du kannst bis zu 4 Elemente auf deinem Profil anzeigen lassen, die als Tabelle dargestellt werden
         header: PNG, GIF oder JPG. Maximal %{size}. Wird auf %{dimensions} px herunterskaliert
         inbox_url: Kopiere die URL von der Startseite des gewünschten Relays
-        irreversible: Gefilterte Beiträge werden unwiderruflich gefiltert, selbst wenn der Filter später entfernt wurde
+        irreversible: Gefilterte Beiträge werden unwiderruflich gelöscht, selbst wenn der Filter später entfernt wird
         locale: Die Sprache der Oberfläche, E-Mails und Push-Benachrichtigungen
         locked: Wer dir folgen möchte, muss um deine Erlaubnis bitten
         password: Verwende mindestens 8 Zeichen
-        phrase: Wird unabhängig vom umgebenen Text oder Inhaltswarnung eines Beitrags verglichen
+        phrase: Wird schreibungsunabhängig mit dem Text und Inhaltswarnung eines Beitrags verglichen
         scopes: Welche Schnittstellen der Applikation erlaubt sind. Wenn du einen Top-Level-Scope auswählst, dann musst du nicht jeden einzelnen darunter auswählen.
         setting_aggregate_reblogs: Zeige denselben Beitrag nicht nochmal an, wenn er erneut geteilt wurde (dies betrifft nur neulich erhaltene erneut geteilte Beiträge)
-        setting_default_language: Die Sprache der Beiträge kann automatisch erkannt werden, aber dies ist nicht immer genau
+        setting_default_sensitive: Heikle Medien werden erst nach einem Klick sichtbar
         setting_display_media_default: Verstecke Medien, die als sensibel markiert sind
         setting_display_media_hide_all: Alle Medien immer verstecken
         setting_display_media_show_all: Medien, die als sensibel markiert sind, immer anzeigen
         setting_hide_network: Wem du folgst und wer dir folgt, wird in deinem Profil nicht angezeigt
         setting_noindex: Betrifft dein öffentliches Profil und deine Beiträge
-        setting_theme: Wirkt sich darauf aus, wie Mastodon aussieht, egal auf welchem Gerät du eingeloggt bist.
-        username: Dein Benutzer:innen-Name wird auf %{domain} nur einmal vorkommen
-        whole_word: Wenn das Schlagwort oder die Phrase nur Buchstaben und Zahlen enthält, wird es nur angewendet, wenn es dem ganzen Wort entspricht
+        setting_show_application: Die Anwendung die du nutzst wird in der detaillierten Ansicht deiner Beiträge angezeigt
+        username: Dein Profilname wird auf %{domain} einzigartig sein
+        whole_word: Wenn das Schlagwort nur aus Buchstaben und Zahlen besteht, wird es nur angewendet, wenn es dem ganzen Wort entspricht
+      featured_tag:
+        name: 'Du möchtest vielleicht einen von diesen benutzen:'
       imports:
-        data: CSV-Datei, die aus einer anderen Mastodon-Instanz exportiert wurde
+        data: CSV-Datei, die aus einem anderen Mastodon-Server exportiert wurde
+      invite_request:
+        text: Dies wird uns helfen deine Anmeldungsanfrage besser zu verarbeiten
       sessions:
-        otp: 'Gib den Zwei-Faktor-Authentisierungscode von deinem Telefon ein oder benutze einen deiner Wiederherstellungscodes:'
+        otp: 'Gib die Zwei-Faktor-Authentifizierung von deinem Telefon ein oder benutze einen deiner Wiederherstellungscodes:'
       user:
-        chosen_languages: Wenn dies aktiviert ist, dann werden nur Beiträge in den ausgewählten Sprachen auf der öffentlichen Timeline angezeigt
+        chosen_languages: Wenn aktiviert, werden nur Beiträge in den ausgewählten Sprachen auf den öffentlichen Zeitleisten angezeigt
     labels:
       account:
         fields:
@@ -57,70 +61,78 @@ de:
           disable: Deaktivieren
           none: Nichts tun
           silence: Stummschalten
-          suspend: Deaktivieren und unwiderruflich Benutzerdaten löschen
+          suspend: Deaktivieren und Benutzerdaten unwiderruflich löschen
         warning_preset_id: Benutze eine Warnungsvorlage
       defaults:
-        autofollow: Einladen, um deinem Account zu folgen
+        autofollow: Eingeladene Nutzer_innen sollen dir automatisch folgen
         avatar: Profilbild
-        bot: Dieser Benutzer ist ein Bot
+        bot: Dieses Profil ist ein Bot
         chosen_languages: Sprachen filtern
         confirm_new_password: Neues Passwort bestätigen
         confirm_password: Passwort bestätigen
-        context: Aspekte filtern
+        context: In Kontexten filtern
         current_password: Derzeitiges Passwort
         data: Daten
-        discoverable: Dieses Benutzerkonto im Verzeichnis auflisten
+        discoverable: Dieses Profil im Profilverzeichnis zeigen
         display_name: Anzeigename
         email: E-Mail-Adresse
         expires_in: Läuft ab
-        fields: Profil-Metadaten
-        header: Kopfbild
-        inbox_url: Inbox-URL des Relays
+        fields: Tabellenfelder
+        header: Titelbild
+        inbox_url: Inbox-URL des Relais
         irreversible: Verwerfen statt verstecken
         locale: Sprache der Benutzeroberfläche
-        locked: Gesperrtes Profil
+        locked: Profil sperren
         max_uses: Maximale Verwendungen
         new_password: Neues Passwort
         note: Über mich
-        otp_attempt: Zwei-Faktor-Authentisierungs-Code
+        otp_attempt: Zwei-Faktor-Authentifizierung
         password: Passwort
-        phrase: Schlagwort oder Phrase
-        setting_aggregate_reblogs: Gruppiere erneut geteilte Beiträge in Zeitleisten
+        phrase: Schlagwort oder Satz
+        setting_advanced_layout: Fortgeschrittene Benutzeroberfläche benutzen
+        setting_aggregate_reblogs: Gruppiere erneut geteilte Beiträge auf der Startseite
         setting_auto_play_gif: Animierte GIFs automatisch abspielen
         setting_boost_modal: Bestätigungsdialog anzeigen, bevor ein Beitrag geteilt wird
         setting_default_language: Beitragssprache
         setting_default_privacy: Beitragssichtbarkeit
-        setting_default_sensitive: Medien immer als sensibel markieren
+        setting_default_sensitive: Medien immer als heikel markieren
         setting_delete_modal: Bestätigungsdialog anzeigen, bevor ein Beitrag gelöscht wird
         setting_display_media: Medien-Anzeige
-        setting_display_media_default: Standard
-        setting_display_media_hide_all: Alle verstecken
-        setting_display_media_show_all: Alle anzeigen
+        setting_display_media_default: Heikle Inhalte verstecken
+        setting_display_media_hide_all: Alle Medien verstecken
+        setting_display_media_show_all: Alle Medien anzeigen
         setting_expand_spoilers: Beiträge mit Inhaltswarnungen immer ausklappen
-        setting_hide_network: Blende dein Netzwerk aus
+        setting_hide_network: Netzwerk ausblenden
         setting_noindex: Suchmaschinen-Indexierung verhindern
         setting_reduce_motion: Bewegung in Animationen verringern
+        setting_show_application: Anwendung preisgeben, die benutzt wurde um Beiträge zu versenden
         setting_system_font_ui: Standardschriftart des Systems verwenden
-        setting_theme: Theme der Website
+        setting_theme: Theme
         setting_unfollow_modal: Bestätigungsdialog anzeigen, bevor jemandem entfolgt wird
         severity: Schweregrad
-        type: Importtyp
+        type: Art des Imports
         username: Profilname
         username_or_email: Profilname oder E-Mail
         whole_word: Ganzes Wort
+      featured_tag:
+        name: Hashtag
       interactions:
-        must_be_follower: Benachrichtigungen von Nicht-Folgenden blockieren
+        must_be_follower: Benachrichtigungen von Profilen blockieren, die mir nicht folgen
         must_be_following: Benachrichtigungen von Profilen blockieren, denen ich nicht folge
         must_be_following_dm: Private Nachrichten von Profilen, denen ich nicht folge, blockieren
+      invite_request:
+        text: Warum möchtest du beitreten?
       notification_emails:
-        digest: Schicke Übersichts-E-Mails
+        digest: Kurzfassungen über E-Mail senden
         favourite: E-Mail senden, wenn jemand meinen Beitrag favorisiert
         follow: E-Mail senden, wenn mir jemand folgt
         follow_request: E-Mail senden, wenn mir jemand folgen möchte
         mention: E-Mail senden, wenn mich jemand erwähnt
+        pending_account: E-Mail senden, wenn ein neues Benutzerkonto zur Überprüfung aussteht
         reblog: E-Mail senden, wenn jemand meinen Beitrag teilt
         report: E-Mail senden, wenn ein neuer Bericht vorliegt
     'no': Nein
+    recommended: Empfohlen
     required:
       mark: "*"
       text: Pflichtfeld
diff --git a/config/locales/simple_form.el.yml b/config/locales/simple_form.el.yml
index fecddd11f5a4a26f00822607fdf0864b1bbbaa70..67f3b64aa1b6f1be7289bd072e768566a3348f16 100644
--- a/config/locales/simple_form.el.yml
+++ b/config/locales/simple_form.el.yml
@@ -27,17 +27,21 @@ el:
         phrase: Θα ταιριάζει ανεξαρτήτως πεζών/κεφαλαίων ή προειδοποίησης περιεχομένου του τουτ
         scopes: Ποια API θα επιτρέπεται στην εφαρμογή να χρησιμοποιήσεις. Αν επιλέξεις κάποιο υψηλό εύρος εφαρμογής, δε χρειάζεται να επιλέξεις και εξειδικευμένα.
         setting_aggregate_reblogs: Απόκρυψη των νέων προωθήσεωνγια τα τουτ που έχουν προωθηθεί πρόσφατα (επηρεάζει μόνο τις νέες προωθήσεις)
-        setting_default_language: Η γλώσσα των τουτ σου μπορεί να ανιχνευτεί αυτόματα αλλά δεν είναι πάντα ακριβές
+        setting_default_sensitive: Τα ευαίσθητα πολυμέσα είναι κρυμμένα και εμφανίζονται με ένα κλικ
         setting_display_media_default: Απόκρυψη ευαίσθητων πολυμέσων
         setting_display_media_hide_all: Μόνιμη απόκρυψη όλων των πολυμέσων
         setting_display_media_show_all: Μόνιμη εμφάνιση ευαίσθητων πολυμέσων
         setting_hide_network: Δε θα εμφανίζεται στο προφίλ σου ποιους ακολουθείς και ποιοι σε ακολουθούν
         setting_noindex: Επηρεάζει το δημόσιο προφίλ και τις δημοσιεύσεις σου
-        setting_theme: Επηρεάζει την εμφάνιση του Mastodon όταν συνδέεται από οποιαδήποτε συσκευή.
+        setting_show_application: Η εφαρμογή που χρησιμοποιείς για να στέλνεις τα τουτ σου θα εμφανίζεται στις αναλυτικές λεπτομέρειες τους
         username: Το όνομα χρήστη σου θα είναι μοναδικό στο %{domain}
         whole_word: Όταν η λέξη ή η φράση κλειδί είναι μόνο αλφαριθμητική, θα εφαρμοστεί μόνο αν ταιριάζει με ολόκληρη τη λέξη
+      featured_tag:
+        name: 'Ίσως να θες να χρησιμοποιήσεις μια από αυτές:'
       imports:
         data: Αρχείο CSV που έχει εξαχθεί από διαφορετικό κόμβο Mastodon
+      invite_request:
+        text: Αυτό θα μας βοηθήσει να επιθεωρήσουμε την αίτησή σου
       sessions:
         otp: 'Βάλε τον κωδικό δυο παραγόντων (2FA) από την εφαρμογή του τηλεφώνου σου ή χρησιμοποίησε κάποιον από τους κωδικούς ανάκτησης σου:'
       user:
@@ -63,7 +67,7 @@ el:
         autofollow: Προσκάλεσε για να ακολουθήσουν το λογαριασμό σου
         avatar: Αβατάρ
         bot: Αυτός είναι ένας αυτοματοποιημένος λογαριασμός (bot)
-        chosen_languages: Φίλτραρε γλώσσες
+        chosen_languages: Φιλτράρισμα γλωσσών
         confirm_new_password: Επιβεβαίωσε νέο συνθηματικό
         confirm_password: Επιβεβαίωσε συνθηματικό
         context: Πλαίσια φιλτραρίσματος
@@ -85,12 +89,13 @@ el:
         otp_attempt: Κωδικός δυο παραγόντων
         password: Συνθηματικό
         phrase: Λέξη ή φράση κλειδί
+        setting_advanced_layout: Ενεργοποίηση προηγμένης λειτουργίας χρήσης
         setting_aggregate_reblogs: Ομαδοποίηση προωθήσεων στις ροές
         setting_auto_play_gif: Αυτόματη αναπαραγωγή των GIF
         setting_boost_modal: Εμφάνιση ερώτησης επιβεβαίωσης πριν την προώθηση
         setting_default_language: Γλώσσα δημοσιεύσεων
         setting_default_privacy: Ιδιωτικότητα δημοσιεύσεων
-        setting_default_sensitive: Σημείωνε πάντα τα πολυμέσα ως ευαίσθητου περιεχομένου
+        setting_default_sensitive: Σημείωση των πολυμέσων πάντα ως ευαίσθητου περιεχομένου
         setting_delete_modal: Εμφάνιση ερώτησης επιβεβαίωσης πριν διαγράψεις ένα τουτ
         setting_display_media: Εμφάνιση πολυμέσων
         setting_display_media_default: Προκαθορισμένο
@@ -100,6 +105,7 @@ el:
         setting_hide_network: Κρύψε τις διασυνδέσεις σου
         setting_noindex: Επέλεξε να μην συμμετέχεις στα αποτελέσματα μηχανών αναζήτησης
         setting_reduce_motion: Μείωση κίνησης κινουμένων στοιχείων
+        setting_show_application: Αποκάλυψη εφαρμογής που χρησιμοποιήθηκε για την αποστολή των τουτ
         setting_system_font_ui: Χρησιμοποίησε την προεπιλεγμένη γραμματοσειρά του συστήματος
         setting_theme: Θέμα ιστότοπου
         setting_unfollow_modal: Εμφάνιση ερώτησης επιβεβαίωσης πριν διακόψεις την παρακολούθηση κάποιου
@@ -108,19 +114,25 @@ el:
         username: Όνομα χρηστη
         username_or_email: Όνομα ή διεύθυνση email χρήστη
         whole_word: Ολόκληρη λέξη
+      featured_tag:
+        name: Ταμπέλα
       interactions:
         must_be_follower: Μπλόκαρε τις ειδοποιήσεις από όσους δεν ακολουθείς
         must_be_following: Μπλόκαρε τις ειδοποιήσεις που προέρχονται από άτομα που δεν τα ακολουθείς
         must_be_following_dm: Μπλόκαρε τα προσωπικά μηνύματα από όσους δεν ακολουθείς
+      invite_request:
+        text: Γιατί θέλεις να συμμετάσχεις;
       notification_emails:
         digest: Στέλνε συνοπτικά email
         favourite: Στελνε email όταν κάποιος σημειώνει ως αγαπημένη τη δημοσίευσή σου
         follow: Στελνε email όταν κάποιος σε ακολουθεί
         follow_request: Στέλνε email όταν κάποιος ζητάει να σε ακολουθήσει
         mention: Στέλνε email όταν κάποιος σε αναφέρει
+        pending_account: Αποστολή email όταν υπάρχει νέος λογαριασμός για επιθεώρηση
         reblog: Στέλνε email όταν κάποιος προωθεί τη δημοσίευση σου
         report: Αποστολή email όταν υποβάλλεται νέα καταγγελία
     'no': Όχι
+    recommended: Προτείνεται
     required:
       mark: "*"
       text: απαιτείται
diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml
index 4363c59e429c8ab4706deca90ac38c8818a5cbb7..4602f9cd9d3c466876783cd62034f5c2a4864079 100644
--- a/config/locales/simple_form.en.yml
+++ b/config/locales/simple_form.en.yml
@@ -27,17 +27,21 @@ en:
         phrase: Will be matched regardless of casing in text or content warning of a toot
         scopes: Which APIs the application will be allowed to access. If you select a top-level scope, you don't need to select individual ones.
         setting_aggregate_reblogs: Do not show new boosts for toots that have been recently boosted (only affects newly-received boosts)
-        setting_default_language: The language of your toots can be detected automatically, but it's not always accurate
+        setting_default_sensitive: Sensitive media is hidden by default and can be revealed with a click
         setting_display_media_default: Hide media marked as sensitive
         setting_display_media_hide_all: Always hide all media
         setting_display_media_show_all: Always show media marked as sensitive
         setting_hide_network: Who you follow and who follows you will not be shown on your profile
         setting_noindex: Affects your public profile and status pages
-        setting_theme: Affects how Mastodon looks when you're logged in from any device.
+        setting_show_application: The application you use to toot will be displayed in the detailed view of your toots
         username: Your username will be unique on %{domain}
         whole_word: When the keyword or phrase is alphanumeric only, it will only be applied if it matches the whole word
+      featured_tag:
+        name: 'You might want to use one of these:'
       imports:
-        data: CSV file exported from another Mastodon instance
+        data: CSV file exported from another Mastodon server
+      invite_request:
+        text: This will help us review your application
       sessions:
         otp: 'Enter the two-factor code generated by your phone app or use one of your recovery codes:'
       user:
@@ -85,11 +89,12 @@ en:
         otp_attempt: Two-factor code
         password: Password
         phrase: Keyword or phrase
+        setting_advanced_layout: Enable advanced web interface
         setting_aggregate_reblogs: Group boosts in timelines
         setting_auto_play_gif: Auto-play animated GIFs
         setting_boost_modal: Show confirmation dialog before boosting
         setting_default_language: Posting language
-        setting_default_privacy: Post privacy
+        setting_default_privacy: Posting privacy
         setting_default_sensitive: Always mark media as sensitive
         setting_delete_modal: Show confirmation dialog before deleting a toot
         setting_display_media: Media display
@@ -100,6 +105,7 @@ en:
         setting_hide_network: Hide your network
         setting_noindex: Opt-out of search engine indexing
         setting_reduce_motion: Reduce motion in animations
+        setting_show_application: Disclose application used to send toots
         setting_system_font_ui: Use system's default font
         setting_theme: Site theme
         setting_unfollow_modal: Show confirmation dialog before unfollowing someone
@@ -108,19 +114,25 @@ en:
         username: Username
         username_or_email: Username or Email
         whole_word: Whole word
+      featured_tag:
+        name: Hashtag
       interactions:
         must_be_follower: Block notifications from non-followers
         must_be_following: Block notifications from people you don't follow
         must_be_following_dm: Block direct messages from people you don't follow
+      invite_request:
+        text: Why do you want to join?
       notification_emails:
         digest: Send digest e-mails
         favourite: Send e-mail when someone favourites your status
         follow: Send e-mail when someone follows you
         follow_request: Send e-mail when someone requests to follow you
         mention: Send e-mail when someone mentions you
+        pending_account: Send e-mail when a new account needs review
         reblog: Send e-mail when someone boosts your status
         report: Send e-mail when a new report is submitted
     'no': 'No'
+    recommended: Recommended
     required:
       mark: "*"
       text: required
diff --git a/config/locales/simple_form.en_GB.yml b/config/locales/simple_form.en_GB.yml
index d9e1a256f6c9a5842d1647e5207699a27c1afc83..8752d81bb076d9dc40527d1e98326d0135a179f4 100644
--- a/config/locales/simple_form.en_GB.yml
+++ b/config/locales/simple_form.en_GB.yml
@@ -1,2 +1,131 @@
 ---
-{}
+en_GB:
+  simple_form:
+    hints:
+      account_warning_preset:
+        text: You can use toot syntax, such as URLs, hashtags and mentions
+      admin_account_action:
+        send_email_notification: The user will receive an explanation of what happened with their account
+        text_html: Optional. You can use toot syntax. You can <a href="%{path}">add warning presets</a> to save time
+        type_html: Choose what to do with <strong>%{acct}</strong>
+        warning_preset_id: Optional. You can still add custom text to end of the preset
+      defaults:
+        autofollow: People who sign up through the invite will automatically follow you
+        avatar: PNG, GIF or JPG. At most %{size}. Will be downscaled to %{dimensions}px
+        bot: This account mainly performs automated actions and might not be monitored
+        context: One or multiple contexts where the filter should apply
+        digest: Only sent after a long period of inactivity and only if you have received any personal messages in your absence
+        discoverable_html: The <a href="%{path}" target="_blank">directory</a> lets people find accounts based on interests and activity. Requires at least %{min_followers} followers
+        email: You will be sent a confirmation e-mail
+        fields: You can have up to 4 items displayed as a table on your profile
+        header: PNG, GIF or JPG. At most %{size}. Will be downscaled to %{dimensions}px
+        inbox_url: Copy the URL from the frontpage of the relay you want to use
+        irreversible: Filtered toots will disappear irreversibly, even if filter is later removed
+        locale: The language of the user interface, e-mails and push notifications
+        locked: Requires you to manually approve followers
+        password: Use at least 8 characters
+        phrase: Will be matched regardless of casing in text or content warning of a toot
+        scopes: Which APIs the application will be allowed to access. If you select a top-level scope, you don't need to select individual ones.
+        setting_aggregate_reblogs: Do not show new boosts for toots that have been recently boosted (only affects newly-received boosts)
+        setting_display_media_default: Hide media marked as sensitive
+        setting_display_media_hide_all: Always hide all media
+        setting_display_media_show_all: Always show media marked as sensitive
+        setting_hide_network: Who you follow and who follows you will not be shown on your profile
+        setting_noindex: Affects your public profile and status pages
+        setting_show_application: The application you use to toot will be displayed in the detailed view of your toots
+        username: Your username will be unique on %{domain}
+        whole_word: When the keyword or phrase is alphanumeric only, it will only be applied if it matches the whole word
+      featured_tag:
+        name: 'You might want to use one of these:'
+      imports:
+        data: CSV file exported from another Mastodon server
+      sessions:
+        otp: 'Enter the two-factor code generated by your phone app or use one of your recovery codes:'
+      user:
+        chosen_languages: When checked, only toots in selected languages will be displayed in public timelines
+    labels:
+      account:
+        fields:
+          name: Label
+          value: Content
+      account_warning_preset:
+        text: Preset text
+      admin_account_action:
+        send_email_notification: Notify the user per e-mail
+        text: Custom warning
+        type: Action
+        types:
+          disable: Disable
+          none: Do nothing
+          silence: Silence
+          suspend: Suspend and irreversibly delete account data
+        warning_preset_id: Use a warning preset
+      defaults:
+        autofollow: Invite to follow your account
+        avatar: Avatar
+        bot: This is a bot account
+        chosen_languages: Filter languages
+        confirm_new_password: Confirm new password
+        confirm_password: Confirm password
+        context: Filter contexts
+        current_password: Current password
+        data: Data
+        discoverable: List this account on the directory
+        display_name: Display name
+        email: E-mail address
+        expires_in: Expire after
+        fields: Profile metadata
+        header: Header
+        inbox_url: URL of the relay inbox
+        irreversible: Drop instead of hide
+        locale: Interface language
+        locked: Lock account
+        max_uses: Max number of uses
+        new_password: New password
+        note: Bio
+        otp_attempt: Two-factor code
+        password: Password
+        phrase: Keyword or phrase
+        setting_aggregate_reblogs: Group boosts in timelines
+        setting_auto_play_gif: Auto-play animated GIFs
+        setting_boost_modal: Show confirmation dialog before boosting
+        setting_default_language: Posting language
+        setting_default_privacy: Post privacy
+        setting_default_sensitive: Always mark media as sensitive
+        setting_delete_modal: Show confirmation dialog before deleting a toot
+        setting_display_media: Media display
+        setting_display_media_default: Default
+        setting_display_media_hide_all: Hide all
+        setting_display_media_show_all: Show all
+        setting_expand_spoilers: Always expand toots marked with content warnings
+        setting_hide_network: Hide your network
+        setting_noindex: Opt-out of search engine indexing
+        setting_reduce_motion: Reduce motion in animations
+        setting_show_application: Disclose application used to send toots
+        setting_system_font_ui: Use system's default font
+        setting_theme: Site theme
+        setting_unfollow_modal: Show confirmation dialog before unfollowing someone
+        severity: Severity
+        type: Import type
+        username: Username
+        username_or_email: Username or Email
+        whole_word: Whole word
+      featured_tag:
+        name: Hashtag
+      interactions:
+        must_be_follower: Block notifications from non-followers
+        must_be_following: Block notifications from people you don't follow
+        must_be_following_dm: Block direct messages from people you don't follow
+      notification_emails:
+        digest: Send digest e-mails
+        favourite: Send e-mail when someone favourites your status
+        follow: Send e-mail when someone follows you
+        follow_request: Send e-mail when someone requests to follow you
+        mention: Send e-mail when someone mentions you
+        reblog: Send e-mail when someone boosts your status
+        report: Send e-mail when a new report is submitted
+    'no': 'No'
+    required:
+      mark: "*"
+      text: required
+    'yes': 'Yes'
diff --git a/config/locales/simple_form.eo.yml b/config/locales/simple_form.eo.yml
index b78d2dd81399afe956c2d88ca6e76b91ba75c4aa..1b63b27a894b809581f200242336a6e41070ec9c 100644
--- a/config/locales/simple_form.eo.yml
+++ b/config/locales/simple_form.eo.yml
@@ -2,12 +2,20 @@
 eo:
   simple_form:
     hints:
+      account_warning_preset:
+        text: Vi povas uzi skribmanierojn de mesaĝoj, kiel URL-ojn, kradvortojn kaj menciojn
+      admin_account_action:
+        send_email_notification: La uzanto ricevos klarigon pri tio, kio okazis al ties konto
+        text_html: Malnepra. Vi povas uzi skribmanierojn de mesaĝoj. Vi povas <a href="%{path}">aldoni avertajn antaŭagordojn</a> por ŝpari tempon
+        type_html: Elektu kion fari kun <strong>%{acct}</strong>
+        warning_preset_id: Malnepra. Vi povas ankoraÅ­ aldoni propran tekston al la fino de la antaÅ­agordo
       defaults:
         autofollow: Homoj, kiuj registriĝos per la invito aŭtomate sekvos vin
         avatar: Formato PNG, GIF aÅ­ JPG. Äœis %{size}. Estos malgrandigita al %{dimensions}px
         bot: Tiu konto ĉefe faras aŭtomatajn agojn, kaj povas esti ne kontrolata
         context: Unu ol pluraj kuntekstoj kie la filtrilo devus agi
         digest: Sendita nur post longa tempo de neaktiveco, kaj nur se vi ricevis personan mesaĝon en via foresto
+        discoverable_html: La <a href="%{path}" target="_blank">profilujo</a> permesas al homoj trovi kontojn laÅ­ interesoj kaj aktiveco. Postulas almenaÅ­ %{min_followers} sekvantojn
         email: Vi ricevos konfirman retmesaĝon
         fields: Vi povas havi ĝis 4 tabelajn elementojn en via profilo
         header: Formato PNG, GIF aÅ­ JPG. Äœis %{size}. Estos malgrandigita al %{dimensions}px
@@ -17,17 +25,23 @@ eo:
         locked: Vi devos aprobi ĉiun peton de sekvado mane
         password: Uzu almenaÅ­ 8 signojn
         phrase: Estos provita senzorge pri la uskleco de teksto aŭ averto pri enhavo de mesaĝo
-        setting_default_language: La lingvo de viaj mesaĝoj povas esti aŭtomate detektitaj, sed tio ne ĉiam ĝustas
+        scopes: Kiujn API-ojn la aplikaĵo permesiĝos atingi. Se vi elektas supran amplekson, vi ne bezonas elekti la individuajn.
+        setting_aggregate_reblogs: Ne montri novajn diskonigojn de mesaĝoj laste diskonigitaj (nur efikas al novaj diskonigoj)
+        setting_default_sensitive: Sentema komunikilo estas kaŝita defaŭlte kaj povas esti rivelita per alklako
         setting_display_media_default: Kaŝi aŭdovidaĵojn markitajn kiel tiklaj
         setting_display_media_hide_all: Ĉiam kaŝi ĉiujn aŭdovidaĵojn
         setting_display_media_show_all: Ĉiam montri aŭdovidaĵojn markitajn kiel tiklaj
         setting_hide_network: Tiuj, kiujn vi sekvas, kaj tiuj, kiuj sekvas vin ne estos videblaj en via profilo
         setting_noindex: Influas vian publikan profilon kaj mesaĝajn paĝojn
-        setting_theme: Influas kiel Mastodon aspektas post ensaluto de ajna aparato.
+        setting_show_application: La aplikaĵo, kiun vi uzas por afiŝi, estos montrita en la detala vido de viaj mesaĝoj
         username: Via uzantnomo estos unika ĉe %{domain}
         whole_word: Kiam la vorto aŭ frazo estas nur litera aŭ cifera, ĝi estos uzata nur se ĝi kongruas kun la tuta vorto
+      featured_tag:
+        name: 'Vi povus uzi iun el la jenaj:'
       imports:
-        data: CSV-dosiero el alia nodo de Mastodon
+        data: CSV-dosiero el alia Mastodon-servilo
+      invite_request:
+        text: Ĉi tio helpos nin revizii vian kandidatiĝon
       sessions:
         otp: 'Enmetu la kodon de dufaktora aÅ­tentigo el via telefono aÅ­ uzu unu el viaj realiraj kodoj:'
       user:
@@ -37,6 +51,18 @@ eo:
         fields:
           name: Etikedo
           value: Enhavo
+      account_warning_preset:
+        text: AntaÅ­agordita teksto
+      admin_account_action:
+        send_email_notification: Atentigi la uzanton retpoŝte
+        text: Propra averto
+        type: Ago
+        types:
+          disable: Malebligi
+          none: Fari nenion
+          silence: Silentigi
+          suspend: Haltigi kaj nemalfereble forigi kontajn datumojn
+        warning_preset_id: Uzi antaÅ­agorditan averton
       defaults:
         autofollow: Inviti al sekvi vian konton
         avatar: Profilbildo
@@ -47,6 +73,7 @@ eo:
         context: Filtri kuntekstojn
         current_password: Nuna pasvorto
         data: Datumoj
+        discoverable: Montri ĉi tiun konton en la profilujo
         display_name: Publika nomo
         email: Retadreso
         expires_in: Eksvalidiĝas post
@@ -62,6 +89,8 @@ eo:
         otp_attempt: Kodo de dufaktora aÅ­tentigo
         password: Pasvorto
         phrase: Vorto aÅ­ frazo
+        setting_advanced_layout: Ebligi altnivelan retpaĝan interfacon
+        setting_aggregate_reblogs: Grupigi diskonigojn en tempolinioj
         setting_auto_play_gif: AÅ­tomate ekigi GIF-ojn
         setting_boost_modal: Montri fenestron por konfirmi antaÅ­ ol diskonigi
         setting_default_language: Publikada lingvo
@@ -76,6 +105,7 @@ eo:
         setting_hide_network: Kaŝi viajn sekvantojn kaj sekvatojn
         setting_noindex: Ellistiĝi de retserĉila indeksado
         setting_reduce_motion: Malrapidigi animaciojn
+        setting_show_application: Publikigi la aplikaĵon uzatan por sendi mesaĝojn
         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
@@ -84,19 +114,25 @@ eo:
         username: Uzantnomo
         username_or_email: Uzantnomo aÅ­ Retadreso
         whole_word: Tuta vorto
+      featured_tag:
+        name: Kradvorto
       interactions:
         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
+      invite_request:
+        text: Kial vi volas aliĝi?
       notification_emails:
         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
+        pending_account: Sendi retmesaĝon kiam nova konto bezonas kontrolon
         reblog: Sendi retmesaĝon kiam iu diskonigas vian mesaĝon
         report: Sendi retmesaĝon kiam nova signalo estas sendita
     'no': Ne
+    recommended: Rekomendita
     required:
       mark: "*"
       text: bezonata
diff --git a/config/locales/simple_form.es.yml b/config/locales/simple_form.es.yml
index c0d72dc2782acb3c870f4c918f3c4be93f0e2efd..7b871e8ba0bf6c4475c93ae544c33941f30d402e 100644
--- a/config/locales/simple_form.es.yml
+++ b/config/locales/simple_form.es.yml
@@ -2,27 +2,34 @@
 es:
   simple_form:
     hints:
+      account_warning_preset:
+        text: Puede usar sintaxis de toots, como URLs, hashtags y menciones
+      admin_account_action:
+        send_email_notification: El usuario recibirá una explicación de lo que sucedió con respecto a su cuenta
       defaults:
         autofollow: Los usuarios que se registren mediante la invitación te seguirán automáticamente
         avatar: PNG, GIF o JPG. Máximo %{size}. Será escalado a %{dimensions}px
         bot: Esta cuenta ejecuta principalmente acciones automatizadas y podría no ser monitorizada
         context: Uno o múltiples contextos en los que debe aplicarse el filtro
         digest: Solo enviado tras un largo periodo de inactividad y solo si has recibido mensajes personales durante tu ausencia
+        email: Se le enviará un correo de confirmación
         fields: Puedes tener hasta 4 elementos mostrándose como una tabla en tu perfil
         header: PNG, GIF o JPG. Máximo %{size}. Será escalado a %{dimensions}px
         inbox_url: Copia la URL de la página principal del relés que quieres utilizar
         irreversible: Los toots filtrados desaparecerán irreversiblemente, incluso si este filtro es eliminado más adelante
         locale: El idioma de la interfaz de usuario, correos y notificaciones push
         locked: Requiere que manualmente apruebes seguidores y las publicaciones serán mostradas solamente a tus seguidores
+        password: Utilice al menos 8 caracteres
         phrase: Se aplicará sin importar las mayúsculas o los avisos de contenido de un toot
         scopes: Qué APIs de la aplicación tendrán acceso. Si seleccionas el alcance de nivel mas alto, no necesitas seleccionar las individuales.
-        setting_default_language: El idioma de tus toots podrá detectarse automáticamente, pero no siempre es preciso
         setting_hide_network: A quién sigues y quién te sigue no será mostrado en tu perfil
         setting_noindex: Afecta a tu perfil público y páginas de estado
-        setting_theme: Afecta al aspecto de Mastodon cuando te identificas desde cualquier dispositivo.
+        setting_show_application: La aplicación que utiliza usted para publicar toots se mostrará en la vista detallada de sus toots
         whole_word: Cuando la palabra clave o frase es solo alfanumérica, solo será aplicado si concuerda con toda la palabra
       imports:
         data: Archivo CSV exportado desde otra instancia de Mastodon
+      invite_request:
+        text: Esto nos ayudará a revisar su aplicación
       sessions:
         otp: 'Introduce el código de autenticación de dos factores geberado por tu aplicación de teléfono o usa uno de tus códigos de recuperación:'
       user:
@@ -32,9 +39,15 @@ es:
         fields:
           name: Etiqueta
           value: Contenido
+      admin_account_action:
+        send_email_notification: Notificar al usuario por correo electrónico
+        text: Aviso personalizado
+        type: Acción
+        types:
+          disable: Deshabilitar
+          silence: Silenciar
       defaults:
         autofollow: Invitar a seguir tu cuenta
-        avatar: Avatar
         bot: Esta es una cuenta bot
         chosen_languages: Filtrar idiomas
         confirm_new_password: Confirmar nueva contraseña
@@ -66,6 +79,7 @@ es:
         setting_hide_network: Ocultar tu red
         setting_noindex: Excluirse del indexado de motores de búsqueda
         setting_reduce_motion: Reducir el movimiento de las animaciones
+        setting_show_application: Mostrar aplicación usada para publicar toots
         setting_system_font_ui: Utilizar la tipografía por defecto del sistema
         setting_theme: Tema del sitio
         setting_unfollow_modal: Mostrar diálogo de confirmación antes de dejar de seguir a alguien
@@ -78,16 +92,19 @@ es:
         must_be_follower: Bloquear notificaciones de personas que no te siguen
         must_be_following: Bloquear notificaciones de personas que no sigues
         must_be_following_dm: Bloquear mensajes directos de la gente que no sigues
+      invite_request:
+        text: "¿Por qué quiere unirse usted?"
       notification_emails:
         digest: Enviar resumen de correos electrónicos
         favourite: Enviar correo electrónico cuando alguien de a favorito en su publicación
         follow: Enviar correo electrónico cuando alguien te siga
         follow_request: Enviar correo electrónico cuando alguien solicita seguirte
         mention: Enviar correo electrónico cuando alguien te mencione
+        pending_account: Enviar correo electrónico cuando una nueva cuenta necesita revisión
         reblog: Enviar correo electrónico cuando alguien comparta su publicación
         report: Enviar un correo cuando se envía un nuevo informe
     'no': 'No'
+    recommended: Recomendado
     required:
-      mark: "*"
       text: necesario
     'yes': Sí
diff --git a/config/locales/simple_form.eu.yml b/config/locales/simple_form.eu.yml
index 0ffc22b53d158dad6ae7012bcc79a294ecaf0ff6..acd5fd6d98b41cda86f79ffec92e88dbac1ced70 100644
--- a/config/locales/simple_form.eu.yml
+++ b/config/locales/simple_form.eu.yml
@@ -27,17 +27,21 @@ eu:
         phrase: Bat egingo du Maiuskula/minuskula kontuan hartu gabe eta edukiaren abisua kontuan hartu gabe
         scopes: Zeintzuk API atzitu ditzakeen aplikazioak. Goi mailako arloa aukeratzen baduzu, ez dituzu azpikoak aukeratu behar.
         setting_aggregate_reblogs: Ez erakutsi buktzada berriak berriki bultzada jaso duten tootentzat (berriki jasotako bultzadei eragiten die besterik ez)
-        setting_default_language: Zure Toot-en hizkuntza automatikoki antzeman daiteke, baina ez da beti zehatza
+        setting_default_sensitive: Multimedia hunkigarria lehenetsita ezkutatzen da, eta sakatuz ikusi daiteke
         setting_display_media_default: Ezkutatu hunkigarri gisa markatutako multimedia
         setting_display_media_hide_all: Ezkutatu multimedia guztia beti
         setting_display_media_show_all: Erakutsi beti hunkigarri gisa markatutako multimedia
         setting_hide_network: Nor jarraitzen duzun eta nork jarraitzen zaituen ez da bistaratuko zure profilean
         setting_noindex: Zure profil publiko eta Toot-en orrietan eragina du
-        setting_theme: Edozein gailutik konektatzean Mastodon-en itxuran eragiten du.
+        setting_show_application: Tootak bidaltzeko erabiltzen duzun aplikazioa zure tooten ikuspegi xehetsuan bistaratuko da
         username: Zure erabiltzaile-izena bakana izango da %{domain} domeinuan
         whole_word: Hitz eta esaldi gakoa alfanumerikoa denean, hitz osoarekin bat datorrenean besterik ez da aplikatuko
+      featured_tag:
+        name: 'Hauetakoren bat erabili zenezake:'
       imports:
-        data: Beste Mastodon instantzia batetik esportatutako CSV fitxategia
+        data: Beste Mastodon zerbitzari batetik esportatutako CSV fitxategia
+      invite_request:
+        text: Honek zure eskaera berrikustean lagunduko digu
       sessions:
         otp: 'Sartu zure telefonoko aplikazioak sortutako bi faktoreetako kodea, edo erabili zure berreskuratze kodeetako bat:'
       user:
@@ -57,6 +61,7 @@ eu:
           disable: Desaktibatu
           none: Ez egin ezer
           silence: Isiltarazi
+          suspend: Kanporatu eta behin betiko ezabatu kontuko datuak
         warning_preset_id: Erabili aurre-ezarritako abisu bat
       defaults:
         autofollow: Gonbidatu zure kontua jarraitzera
@@ -84,6 +89,7 @@ eu:
         otp_attempt: Bi faktoreetako kodea
         password: Pasahitza
         phrase: Hitz edo esaldi gakoa
+        setting_advanced_layout: Gaitu web interfaze aurreratua
         setting_aggregate_reblogs: Taldekatu bultzadak denbora-lerroetan
         setting_auto_play_gif: Erreproduzitu GIF animatuak automatikoki
         setting_boost_modal: Erakutsi baieztapen elkarrizketa-koadroa bultzada eman aurretik
@@ -99,6 +105,7 @@ eu:
         setting_hide_network: Ezkutatu zure sarea
         setting_noindex: Atera bilaketa motorraren indexaziotik
         setting_reduce_motion: Murriztu animazioen mugimenduak
+        setting_show_application: Utzi agerian tootak bidaltzeko erabilitako aplikazioa
         setting_system_font_ui: Erabili sistemako tipografia lehenetsia
         setting_theme: Gunearen gaia
         setting_unfollow_modal: Erakutsi baieztapen elkarrizketa-koadroa inor jarraitzeari utzi aurretik
@@ -107,19 +114,25 @@ eu:
         username: Erabiltzaile-izena
         username_or_email: Erabiltzaile-izena edo e-mail helbidea
         whole_word: Hitz osoa
+      featured_tag:
+        name: Traola
       interactions:
         must_be_follower: Blokeatu jarraitzaile ez direnen jakinarazpenak
         must_be_following: Blokeatu zuk jarraitzen ez dituzunen jakinarazpenak
         must_be_following_dm: Blokeatu zuk jarraitzen ez dituzunen mezu zuzenak
+      invite_request:
+        text: Zergatik elkartu nahi duzu?
       notification_emails:
         digest: Bidali laburpenak e-mail bidez
         favourite: Bidali e-mail bat norbaitek zure mezua gogoko duenean
         follow: Bidali e-mail bat norbaitek jarraitzen zaituenean
         follow_request: Bidali e-mail bat norbaitek zu jarraitzea eskatzen duenean
         mention: Bidali e-mail bat norbaitek zu aipatzean
+        pending_account: Bidali e-mail bat kontu bat berrikusi behar denean
         reblog: Bidali e-mail bat norbaitek zure mezuari bultzada ematen badio
         report: Bidali e-maila txosten berri bat aurkezten denean
     'no': Ez
+    recommended: Aholkatua
     required:
       mark: "*"
       text: beharrezkoa
diff --git a/config/locales/simple_form.fa.yml b/config/locales/simple_form.fa.yml
index 2eeacade62761337197bf331869e75c96b668c6a..7d2dbd8a94bc9785b5b1b64badf0c5cb6eb9abec 100644
--- a/config/locales/simple_form.fa.yml
+++ b/config/locales/simple_form.fa.yml
@@ -2,12 +2,20 @@
 fa:
   simple_form:
     hints:
+      account_warning_preset:
+        text: می‌توانید مانند بوق‌های معمولی کاربران دیگر را نام ببرید یا پیوند و برچسب بگذارید
+      admin_account_action:
+        send_email_notification: توضیحی که کاربر می‌بینید که برای حسابش چه رخ داده است
+        text_html: اختیاری. می‌توانید مثل بوق‌های معمولی بنویسید. می‌توانید برای صرفه‌جویی در زمان <a href="%{path}">هشدارهای ازپیش‌آماده بیفزایید</a>
+        type_html: با حساب <strong>%{acct}</strong> می‌خواهید چه کار کنید؟‌
+        warning_preset_id: اختیاری. همچنان می‌توانید در پایان متن آماده چیزی بیفزایید
       defaults:
         autofollow: کسانی که از راه دعوت‌نامه عضو می‌شوند به طور خودکار پیگیر شما خواهند شد
         avatar: یکی از قالب‌های PNG یا  GIF یا JPG. بیشترین اندازه %{size}. تصویر به اندازهٔ %{dimensions} پیکسل تبدیل خواهد شد
         bot: این حساب بیشتر به طور خودکار فعالیت می‌کند و نظارت پیوسته‌ای روی آن وجود ندارد
         context: یک یا چند زمینه که فیلتر باید در آن‌ها اعمال شود
         digest: تنها وقتی فرستاده می‌شود که مدتی طولانی فعالیتی نداشته باشید و در این مدت برای شما پیغام خصوصی‌ای نوشته شده باشد
+        discoverable_html: با <a href="%{path}" target="_blank">فهرست گزیدهٔ کاربران</a> مردم می‌توانند حساب‌های این سرور را بر اساس علاقه‌مندی‌ها و فعالیت‌شان پیدا کنند. هر حساب دست‌کم باید %{min_followers} پیگیر داشته باشد
         email: به شما ایمیل تأییدی فرستاده خواهد شد
         fields: شما می‌توانید تا چهار مورد را در یک جدول در نمایهٔ خود نمایش دهید
         header: یکی از قالب‌های PNG یا  GIF یا JPG. بیشترین اندازه %{size}. تصویر به اندازهٔ %{dimensions} پیکسل تبدیل خواهد شد
@@ -18,17 +26,22 @@ fa:
         password: دست‌کم باید ۸ نویسه داشته باشد
         phrase: مستقل از کوچکی و بزرگی حروف، با متن اصلی یا هشدار محتوای بوق‌ها مقایسه می‌شود
         scopes: واسط‌های برنامه‌نویسی که این برنامه به آن دسترسی دارد. اگر بالاترین سطح دسترسی را انتخاب کنید، دیگر نیازی به انتخاب سطح‌های پایینی ندارید.
-        setting_default_language: زبان نوشته‌های شما به طور خودکار تشخیص داده می‌شود، ولی این تشخیص همیشه دقیق نیست
+        setting_aggregate_reblogs: برای بازبوق‌هایی که به تازگی برایتان نمایش داده شده‌اند، بازبوق‌های بیشتر را نشان نده (فقط روی بازبوق‌های اخیر تأثیر می‌گذارد)
+        setting_default_sensitive: تصاویر حساس به طور پیش‌فرض پنهان هستند و می‌توانند با یک کلیک آشکار شوند
         setting_display_media_default: تصویرهایی را که به عنوان حساس علامت زده شده‌اند پنهان کن
         setting_display_media_hide_all: همیشه همهٔ عکس‌ها و ویدیوها را پنهان کن
         setting_display_media_show_all: همیشه تصویرهایی را که به عنوان حساس علامت زده شده‌اند را نشان بده
         setting_hide_network: فهرست پیگیران شما و فهرست کسانی که شما پی می‌گیرید روی نمایهٔ شما دیده نخواهد شد
         setting_noindex: روی نمایهٔ عمومی و صفحهٔ نوشته‌های شما تأثیر می‌گذارد
-        setting_theme: ظاهر ماستدون را وقتی که از هر دستگاهی به آن وارد می‌شوید تعیین می‌کند.
+        setting_show_application: برنامه‌ای که به کمک آن بوق می‌زنید، در جزئیات بوق شما نمایش خواهد یافت
         username: نام کاربری شما روی %{domain} یکتا خواهد بود
         whole_word: اگر کلیدواژه فقط دارای حروف و اعداد باشد، تنها وقتی پیدا می‌شود که با کل یک واژه در متن منطبق باشد، نه با بخشی از یک واژه
+      featured_tag:
+        name: 'شاید بخواهید چنین چیزهایی را به کار ببرید:'
       imports:
         data: پروندهٔ CSV که از سرور ماستدون دیگری برون‌سپاری شده
+      invite_request:
+        text: این برای بررسی درخواست شما به ما کمک خواهد کرد
       sessions:
         otp: 'کد تأیید دومرحله‌ای که اپ روی تلفن شما ساخته را وارد کنید یا یکی از کدهای بازیابی را به کار ببرید:'
       user:
@@ -38,6 +51,18 @@ fa:
         fields:
           name: برچسب
           value: محتوا
+      account_warning_preset:
+        text: متن از پیش آماده‌شده
+      admin_account_action:
+        send_email_notification: اطلاع‌رسانی به کاربر از راه ایمیل
+        text: هشدار موردی
+        type: نوع کنش
+        types:
+          disable: غیرفعال‌کردن
+          none: کاری نکن
+          silence: بی‌صدا کردن
+          suspend: تعلیق و پاک‌کردن کامل همهٔ اطلاعات حساب
+        warning_preset_id: یک هشدار از پیش‌آماده را به کار ببرید
       defaults:
         autofollow: دعوت از دیگران برای عضو شدن و پیگیری حساب شما
         avatar: تصویر نمایه
@@ -48,6 +73,7 @@ fa:
         context: زمینه‌های فیلترکردن
         current_password: رمز فعلی
         data: داده‌ها
+        discoverable: این حساب را در فهرست گزیدهٔ کاربران نشان بده
         display_name: نمایش به نام
         email: نشانی ایمیل
         expires_in: تاریخ انقضا
@@ -63,6 +89,8 @@ fa:
         otp_attempt: کد ورود دومرحله‌ای
         password: رمز
         phrase: کلیدواژه یا عبارت
+        setting_advanced_layout: فعال‌سازی رابط کاربری پیشرفته
+        setting_aggregate_reblogs: بازبوق‌ها را متحد کن
         setting_auto_play_gif: پخش خودکار تصویرهای متحرک
         setting_boost_modal: نمایش پیغام تأیید پیش از بازبوقیدن
         setting_default_language: زبان نوشته‌های شما
@@ -77,6 +105,7 @@ fa:
         setting_hide_network: نهفتن شبکهٔ ارتباطی
         setting_noindex: درخواست از موتورهای جستجوگر برای ظاهر نشدن در نتایج جستجو
         setting_reduce_motion: کاستن از حرکت در پویانمایی‌ها
+        setting_show_application: برنامه‌ای که به کار می‌برید آشکار شود
         setting_system_font_ui: به‌کاربردن قلم پیش‌فرض سیستم
         setting_theme: تم سایت
         setting_unfollow_modal: نمایش پیغام تأیید پیش از لغو پیگیری دیگران
@@ -85,19 +114,25 @@ fa:
         username: نام کاربری (لاتین)
         username_or_email: نام کاربری یا ایمیل
         whole_word: تطابق واژهٔ کامل
+      featured_tag:
+        name: برچسب
       interactions:
         must_be_follower: مسدودکردن اعلان‌های همه به جز پیگیران
         must_be_following: مسدودکردن اعلان‌های کسانی که شما پی نمی‌گیرید
         must_be_following_dm: مسدودکردن پیغام‌های خصوصی کسانی که شما پی نمی‌گیرید
+      invite_request:
+        text: چرا می‌خواهید عضو شوید؟
       notification_emails:
         digest: خلاصه‌کردن چند اعلان در یک ایمیل
         favourite: وقتی کسی نوشتهٔ شما را پسندید ایمیل بفرست
         follow: وقتی کسی پیگیر شما شد ایمیل بفرست
         follow_request: وقتی کسی درخواست پیگیری کرد ایمیل بفرست
         mention: وقتی کسی از شما نام برد ایمیل بفرست
+        pending_account: وقتی حساب تازه‌ای نیاز به بازبینی داشت ایمیل بفرست
         reblog: وقتی کسی نوشتهٔ شما را بازبوقید ایمیل بفرست
         report: وقتی گزارش تازه‌ای فرستاده شد ایمیل بفرست
     'no': خیر
+    recommended: توصیه می‌شود
     required:
       mark: "*"
       text: ضروری
diff --git a/config/locales/simple_form.fi.yml b/config/locales/simple_form.fi.yml
index b0f958f2f17323b5b531546bb67f36d7458467a3..2bb56b40ec2cafe47678bacb7bf856fad001838c 100644
--- a/config/locales/simple_form.fi.yml
+++ b/config/locales/simple_form.fi.yml
@@ -2,6 +2,8 @@
 fi:
   simple_form:
     hints:
+      admin_account_action:
+        send_email_notification: Käyttäjä saa selityksen mitä tapahtui hänen tililleen
       defaults:
         avatar: PNG, GIF tai JPG. Enintään %{size}. Skaalataan kokoon %{dimensions} px
         digest: Lähetetään vain pitkän poissaolon jälkeen ja vain, jos olet saanut suoria viestejä poissaolosi aikana
@@ -9,7 +11,6 @@ fi:
         header: PNG, GIF tai JPG. Enintään %{size}. Skaalataan kokoon %{dimensions} px
         locked: Sinun täytyy hyväksyä seuraajat manuaalisesti
         setting_noindex: Vaikuttaa julkiseen profiiliisi ja tilasivuihisi
-        setting_theme: Vaikuttaa Mastodonin ulkoasuun millä tahansa laitteella kirjauduttaessa.
       imports:
         data: Toisesta Mastodon-instanssista tuotu CSV-tiedosto
       sessions:
@@ -63,6 +64,5 @@ fi:
         reblog: Lähetä sähköposti, kun joku buustaa julkaisusi
     'no': Ei
     required:
-      mark: "*"
       text: pakollinen tieto
     'yes': Kyllä
diff --git a/config/locales/simple_form.fr.yml b/config/locales/simple_form.fr.yml
index 730a6952258e8d50635ecdcc853f5785e6d11122..6b3aa9bfbaca910c6bbc3b951e2823aa0e679ac1 100644
--- a/config/locales/simple_form.fr.yml
+++ b/config/locales/simple_form.fr.yml
@@ -5,8 +5,8 @@ fr:
       account_warning_preset:
         text: Vous pouvez utiliser la syntaxe des pouets, comme les URLs, les hashtags et les mentions
       admin_account_action:
-        send_email_notification: L'utilisateur recevra une explication de ce qu'il s'est passé avec son compte
-        text_html: Optionnel. Vous pouvez utilisez la syntaxe des pouets. Vous pouvez <a href="%{path}">ajouter des présélections d'attention</a> pour économiser du temps
+        send_email_notification: L’utilisateur recevra une explication de ce qu’il s’est passé avec son compte
+        text_html: Optionnel. Vous pouvez utilisez la syntaxe des pouets. Vous pouvez <a href="%{path}">ajouter des présélections d’attention</a> pour économiser du temps
         type_html: Choisir que faire avec <strong>%{acct}</strong>
         warning_preset_id: Optionnel. Vous pouvez toujours ajouter un texte personnalisé à la fin de la présélection
       defaults:
@@ -15,7 +15,7 @@ fr:
         bot: Ce compte exécute principalement des actions automatisées et pourrait ne pas être surveillé
         context: Un ou plusieurs contextes où le filtre devrait s’appliquer
         digest: Uniquement envoyé après une longue période d’inactivité et uniquement si vous avez reçu des messages personnels pendant votre absence
-        discoverable_html: L'<a href="%{path}" target="_blank">annuaire</a> permet aux gens de trouver des comptes en se basant sur les intérêts et les activités. Nécessite au moins %{min_followers} abonnés
+        discoverable_html: L’<a href="%{path}" target="_blank">annuaire</a> permet aux gens de trouver des comptes en se basant sur les intérêts et les activités. Nécessite au moins %{min_followers} abonnés
         email: Vous recevrez un courriel de confirmation
         fields: Vous pouvez avoir jusqu’à 4 éléments affichés en tant que tableau sur votre profil
         header: Au format PNG, GIF ou JPG. %{size} maximum. Sera réduit à %{dimensions}px
@@ -26,18 +26,22 @@ fr:
         password: Utilisez au moins 8 caractères
         phrase: Sera trouvé sans que la case ou l’avertissement de contenu du pouet soit pris en compte
         scopes: À quelles APIs l’application sera autorisée à accéder. Si vous sélectionnez un périmètre de haut-niveau, vous n’avez pas besoin de sélectionner les individuels.
-        setting_aggregate_reblogs: Ne pas afficher de nouveaux repartagés pour les pouets qui ont été récemment repartagés (n'affecte que les repartagés nouvellement reçus)
-        setting_default_language: La langue de vos pouets peut être détectée automatiquement, mais ça n’est pas toujours pertinent
-        setting_display_media_default: Masquer les supports marqués comme sensibles
+        setting_aggregate_reblogs: Ne pas afficher de nouveaux repartagés pour les pouets qui ont été récemment repartagés (n’affecte que les repartagés nouvellement reçus)
+        setting_default_sensitive: Les médias sensibles sont cachés par défaut et peuvent être révélés d’un simple clic
+        setting_display_media_default: Masquer les médias marqués comme sensibles
         setting_display_media_hide_all: Toujours masquer tous les médias
         setting_display_media_show_all: Toujours afficher les médias marqués comme sensibles
         setting_hide_network: Ceux que vous suivez et ceux qui vous suivent ne seront pas affichés sur votre profil
         setting_noindex: Affecte votre profil public ainsi que vos statuts
-        setting_theme: Affecte l’apparence de Mastodon quand vous êtes connecté·e depuis n’importe quel appareil.
+        setting_show_application: Le nom de l’application que vous utilisez afin d’envoyer des pouets sera affiché dans la vue détaillée de ceux-ci
         username: Votre nom d’utilisateur sera unique sur %{domain}
         whole_word: Lorsque le mot-clef ou la phrase-clef est uniquement alphanumérique, ça sera uniquement appliqué s’il correspond au mot entier
+      featured_tag:
+        name: 'Vous pourriez vouloir utiliser l’un d’entre eux :'
       imports:
-        data: Un fichier CSV généré par une autre instance de Mastodon
+        data: Un fichier CSV généré par un autre serveur de Mastodon
+      invite_request:
+        text: Cela nous aidera à considérer votre demande
       sessions:
         otp: 'Entrez le code d’authentification à deux facteurs généré par l’application de votre téléphone ou utilisez un de vos codes de récupération :'
       user:
@@ -50,15 +54,15 @@ fr:
       account_warning_preset:
         text: Texte de présélection
       admin_account_action:
-        send_email_notification: Notifier l'utilisateur par courriel
+        send_email_notification: Notifier l’utilisateur par courriel
         text: Attention personnalisée
         type: Action
         types:
           disable: Désactiver
           none: Ne rien faire
-          silence: Silence
+          silence: Masquer
           suspend: Suspendre et effacer les données du compte de manière irréversible
-        warning_preset_id: Utiliser un modèle d'avertissement
+        warning_preset_id: Utiliser un modèle d’avertissement
       defaults:
         autofollow: Invitation à suivre votre compte
         avatar: Image de profil
@@ -69,7 +73,7 @@ fr:
         context: Contextes du filtre
         current_password: Mot de passe actuel
         data: Données
-        discoverable: Inscrire ce compte dans l'annuaire
+        discoverable: Inscrire ce compte dans l’annuaire
         display_name: Nom public
         email: Adresse courriel
         expires_in: Expire après
@@ -85,6 +89,7 @@ fr:
         otp_attempt: Code d’identification à deux facteurs
         password: Mot de passe
         phrase: Mot-clé ou phrase
+        setting_advanced_layout: Activer l’interface Web avancée
         setting_aggregate_reblogs: Repartagés en groupe dans la ligne de temps
         setting_auto_play_gif: Lire automatiquement les GIFs animés
         setting_boost_modal: Afficher une fenêtre de confirmation avant de partager
@@ -100,6 +105,7 @@ fr:
         setting_hide_network: Cacher votre réseau
         setting_noindex: Demander aux moteurs de recherche de ne pas indexer vos informations personnelles
         setting_reduce_motion: Réduire la vitesse des animations
+        setting_show_application: Dévoiler le nom de l’application utilisée pour envoyer des pouets
         setting_system_font_ui: Utiliser la police par défaut du système
         setting_theme: Thème du site
         setting_unfollow_modal: Afficher une fenêtre de confirmation avant de vous désabonner d’un compte
@@ -108,19 +114,25 @@ fr:
         username: Identifiant
         username_or_email: Nom d’utilisateur·ice ou courriel
         whole_word: Mot entier
+      featured_tag:
+        name: Hashtag
       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
         must_be_following_dm: Bloquer les messages directs des personnes que vous ne suivez pas
+      invite_request:
+        text: Pourquoi voulez-vous vous inscrire ?
       notification_emails:
         digest: Envoyer des courriels récapitulatifs
         favourite: Envoyer un courriel lorsque quelqu’un ajoute mes statuts à ses favoris
         follow: Envoyer un courriel lorsque quelqu’un me suit
         follow_request: Envoyer un courriel lorsque quelqu’un demande à me suivre
         mention: Envoyer un courriel lorsque quelqu’un me mentionne
+        pending_account: Envoyer un courriel lorsqu’un nouveau compte est en attente d’approbation
         reblog: Envoyer un courriel lorsque quelqu’un partage mes statuts
         report: Envoyer un courriel lorsqu’un nouveau rapport est soumis
     'no': Non
+    recommended: Recommandé
     required:
       mark: "*"
       text: Champs requis
diff --git a/config/locales/simple_form.gl.yml b/config/locales/simple_form.gl.yml
index d5e0ef574aae9617a5e92f9a905836b047fb457c..22389051fbdd82c6c3353c8cb0b50be619c1d60c 100644
--- a/config/locales/simple_form.gl.yml
+++ b/config/locales/simple_form.gl.yml
@@ -27,21 +27,25 @@ gl:
         phrase: Concordará independentemente das maiúsculas ou avisos de contido no toot
         scopes: A que APIs terá acceso a aplicación. Si selecciona un ámbito de alto nivel, non precisa seleccionar elementos individuais.
         setting_aggregate_reblogs: Non mostrar novas promocións de toots que foron promocionados recentemente (só afecta a promocións recén recibidas)
-        setting_default_language: Pódese detectar automáticamente o idioma dos seus toots, mais non sempre é preciso
+        setting_default_sensitive: Medios sensibles marcados como ocultos por defecto e móstranse cun click
         setting_display_media_default: Ocultar medios marcados como sensibles
         setting_display_media_hide_all: Ocultar sempre os medios
         setting_display_media_show_all: Mostrar sempre os medios marcados como sensibles
         setting_hide_network: Non se mostrará no seu perfil quen a segue e quen a está a seguir
         setting_noindex: Afecta ao seu perfil público e páxinas de estado
-        setting_theme: Afecta ao aspecto de Mastodon en calquer dispositivo cando está conectada.
+        setting_show_application: A aplicación que está a utilizar para enviar toots mostrarase na vista detallada do toot
         username: O seu nome de usuaria será único en %{domain}
         whole_word: Se a chave ou frase de paso é só alfanumérica, só se aplicará se concorda a palabra completa
+      featured_tag:
+        name: 'Podería utilizar algunha de estas:'
       imports:
-        data: Ficheiro CSV exportado desde outra instancia Mastodon
+        data: Ficheiro CSV exportado desde outro servidor Mastodon
+      invite_request:
+        text: Esto axudaranos a revisar a súa aplicación
       sessions:
         otp: 'Introduza o código de doble-factor xerado no aplicativo do seu móbil ou utilice un dos seus códigos de recuperación:'
       user:
-        chosen_languages: Si se marca, só os toots nos idiomas seleccionados serán mostrados en liñas temporais públicas
+        chosen_languages: Se ten marca, só os toots nos idiomas seleccionados serán mostrados en liñas temporais públicas
     labels:
       account:
         fields:
@@ -85,6 +89,7 @@ gl:
         otp_attempt: Código de Doble-Factor
         password: Contrasinal
         phrase: Palabra chave ou frase
+        setting_advanced_layout: Activar interface web avanzada
         setting_aggregate_reblogs: Agrupar promocións nas liñas temporais
         setting_auto_play_gif: Reprodución automática de GIFs animados
         setting_boost_modal: Pedir confirmación antes de promocionar
@@ -97,9 +102,10 @@ gl:
         setting_display_media_hide_all: Ocultar todo
         setting_display_media_show_all: Mostrar todo
         setting_expand_spoilers: Despregar sempre as mensaxes marcadas con avisos de contido
-        setting_hide_network: Agochar a súa rede
+        setting_hide_network: Non mostrar contactos
         setting_noindex: Pedir non aparecer nas buscas dos motores de busca
         setting_reduce_motion: Reducir o movemento nas animacións
+        setting_show_application: Mostrar a aplicación utilizada para tootear
         setting_system_font_ui: Utilizar a tipografía por defecto do sistema
         setting_theme: Decorado da instancia
         setting_unfollow_modal: Solicitar confirmación antes de deixar de seguir alguén
@@ -108,19 +114,25 @@ gl:
         username: Nome de usuaria
         username_or_email: Nome de usuaria ou Correo-e
         whole_word: Palabra completa
+      featured_tag:
+        name: Etiqueta
       interactions:
         must_be_follower: Bloquear as notificacións de non-seguidoras
         must_be_following: Bloquea as notificacións de personas que non segue
         must_be_following_dm: Bloquea as mensaxes directas de personas que non segue
+      invite_request:
+        text: Por que quere unirse?
       notification_emails:
         digest: Enviar correos con resumos
         favourite: Enviar un correo cando alguén marca como favorita unha das súas publicacións
         follow: Enviar un correo cando alguén a segue
         follow_request: Enviar un correo cando alguén solicita seguila
         mention: Enviar un correo cando alguén a menciona
+        pending_account: Enviar correo-e cando unha nova conta precisa revisión
         reblog: Enviar un correo cando alguén promociona a súa mensaxe
         report: Enviar un correo cando se envíe un novo informe
     'no': Non
+    recommended: Recomendado
     required:
       mark: "*"
       text: requerido
diff --git a/config/locales/simple_form.he.yml b/config/locales/simple_form.he.yml
index c86498c66aa99f893b2aff57786b12d50d086739..36d7cbf6723e049be54f82e1eaf269858ac9ad1d 100644
--- a/config/locales/simple_form.he.yml
+++ b/config/locales/simple_form.he.yml
@@ -8,7 +8,6 @@ he:
         header: PNG, GIF או JPG. מקסימום %{size}. גודל התמונה יוקטן %{dimensions}px
         locked: מחייב אישור עוקבים באופן ידני. פרטיות ההודעות תהיה עוקבים-בלבד אלא אם יצוין אחרת
         setting_noindex: משפיע על הפרופיל הציבורי שלך ועמודי ההודעות
-        setting_theme: משפיע על המראה של מסטודון בעת החיבור המזוהה מכל מכשיר שהוא.
       imports:
         data: קובץ CSV שיוצא משרת מסטודון אחר
       sessions:
@@ -57,6 +56,5 @@ he:
         reblog: שליחת דוא"ל כשמהדהדים חצרוץ שלך
     'no': לא
     required:
-      mark: "*"
       text: שדה חובה
     'yes': כן
diff --git a/config/locales/simple_form.hr.yml b/config/locales/simple_form.hr.yml
index 4b1d2b1e0a224163939faf39a443a5ed1a087917..083343307f6a5f1d504a3cc4fc6fce0a10fc84dc 100644
--- a/config/locales/simple_form.hr.yml
+++ b/config/locales/simple_form.hr.yml
@@ -10,18 +10,15 @@ hr:
         data: CSV fajl izvezen iz druge Mastodon instance
     labels:
       defaults:
-        avatar: Avatar
         confirm_new_password: Potvrdi novu lozinku
         confirm_password: Potvrdi lozinku
         current_password: Trenutna lozinka
         data: Podaci
         display_name: Ime koje ću prikazati
         email: E-mail adresa
-        header: Header
         locale: Jezik
         locked: Učini račun privatnim
         new_password: Nova lozinka
-        note: Bio
         otp_attempt: Dvo-faktorski kod
         password: Lozinka
         setting_auto_play_gif: Automatski pokreni animirane GIFove
@@ -40,6 +37,5 @@ hr:
         reblog: Pošalji mi e-mail kad netko rebloga moj status
     'no': Ne
     required:
-      mark: "*"
       text: traženo
     'yes': Da
diff --git a/config/locales/simple_form.hu.yml b/config/locales/simple_form.hu.yml
index f36fabda1b91472014a988613abb751e991b281d..7e5e4e79d51baee9a356caa77fc3c3450c7e3d14 100644
--- a/config/locales/simple_form.hu.yml
+++ b/config/locales/simple_form.hu.yml
@@ -2,60 +2,137 @@
 hu:
   simple_form:
     hints:
+      account_warning_preset:
+        text: Használhatod a tülkökben szokásos szintaxist, URL-eket, hashtageket, megemlítéseket
+      admin_account_action:
+        send_email_notification: A felhasználó magyarázatot kap arra, mi történt a fiókjával
+        text_html: Opcionális. A tülk szintaxis használható. Egyszerűsítés végett létre is hozhatsz <a href="%{path}">figyelmeztetéseket</a>
+        type_html: Megmondhatod, mi legyen vele <strong>%{acct}</strong>
+        warning_preset_id: Opcionális. A figyelmeztetés végére saját szöveget is írhatsz
       defaults:
-        avatar: PNG, GIF vagy JPG. Maximum %{size}. Át lesz méretezve %{dimensions} pixelre
-        digest: Csak hosszú távollét esetén küldve és csak ha személyes üzenetet kaptál távollétedben
-        header: PNG, GIF vagy JPG. Maximum %{size}. Át lesz méretezve %{dimensions} pixelre
+        autofollow: Akik meghívón keresztül regisztrálnak, automatikusan követni fognak téged
+        avatar: PNG, GIF vagy JPG. Maximum %{size}. Átméretezzük %{dimensions} pixelre
+        bot: Ez a fiók automatikus műveleteket végez és valószínűleg nem figyeljük
+        context: Kontextusok, ahol a szűrőnek működnie kell
+        digest: Csak hosszú távollét esetén küldődik és csak ha személyes üzenetet kaptál távollétedben
+        discoverable_html: A <a href="%{path}" target="_blank">profilok</a> adatbázisa lehetővé teszi, hogy embereket közös érdeklődés vagy tevékenység alapján találj meg. Legalább %{min_followers} követőre van szükség az adatbázisba való bekerüléshez
+        email: Kapsz egy megerősítő e-mailt
+        fields: A profilodon legfeljebb 4 bejegyzés szerepelhet táblázatos formában
+        header: PNG, GIF vagy JPG. Maximum %{size}. Átméretezzük %{dimensions} pixelre
+        inbox_url: Másold ki a használandó relé szerver kezdőoldalának URL-jét
+        irreversible: A kiszűrt tülkök visszafordíthatatlanul eltűnnek, a szűrő későbbi törlése esetén is
+        locale: A felhasználói felület, e-mailek, push üzenetek nyelve
         locked: Egyenként engedélyezned kell a követőidet
-        setting_noindex: A publikus profilodra és státusz oldalra vonatkozik
-        setting_theme: A bármely eszközről bejelentkezett felület kinézetére vonatkozik.
+        password: Legalább 8 karakter
+        phrase: Illeszkedni fog kis/nagybetű függetlenül, és tartalom-figyelmeztetések mögött is
+        scopes: Mely API-kat érheti el az alkalmazás. Ha felső szintű hatáskört választasz, nem kell egyesével kiválasztanod az alatta lévőeket.
+        setting_aggregate_reblogs: Ne mutassunk megtolásokat olyan tülkökhöz, melyeket nemrég toltak meg (csak új megtolásokra lép életbe)
+        setting_default_sensitive: A szenzitív médiát alapesetben elrejtjük, de egyetlen kattintással előhozható
+        setting_display_media_default: Szenzitív tartalomként jelölt média elrejtése
+        setting_display_media_hide_all: Mindig minden média elrejtése
+        setting_display_media_show_all: Mindig mutasd a szenzitív tartalomként jelölt médiát
+        setting_hide_network: Nem látszik majd a profilodon, kik követnek és te kiket követsz
+        setting_noindex: A nyilvános profilodra és a tülkjeidre vonatkozik
+        setting_show_application: A tülkök részletes nézetében látszani fog, milyen alkalmazást használtál a tülköléshez
+        username: A felhasználói neved egyedi lesz a %{domain} domainen
+        whole_word: Ha a kulcsszó alfanumerikus, csak akkor minősül majd találatnak, ha teljes szóra illeszkedik
+      featured_tag:
+        name: 'Ezeket esetleg használhatod:'
       imports:
         data: Egy másik Mastodon szerverről exportált CSV fájl
+      invite_request:
+        text: Ez segít nekünk átnézni a jelentkezésedet
       sessions:
-        otp: Add meg a Második-faktor kódodat a telefonodról vagy használd az egyik tartalék bejelentkező kódodat.
+        otp: 'Add meg a telefonodon generált kétlépcsős azonosító kódodat vagy használd az egyik tartalék bejelentkező kódot:'
+      user:
+        chosen_languages: Ha aktív, csak a kiválasztott nyelvű tülkök jelennek majd meg a nyilvános idővonalon
     labels:
+      account:
+        fields:
+          name: Címke
+          value: Tartalom
+      account_warning_preset:
+        text: Figyelmeztető szöveg
+      admin_account_action:
+        send_email_notification: Figyelmeztessük a felhasználót e-mailben
+        text: Egyedi figyelmeztetés
+        type: Művelet
+        types:
+          disable: Letiltás
+          none: Ne csinálj semmit
+          silence: Elnémítás
+          suspend: Fiók felfüggesztése, adatok törlése visszaállíthatatlanul
+        warning_preset_id: Figyelmeztetés használata
       defaults:
+        autofollow: Meghívás a fiókod követésére
         avatar: Profilkép
+        bot: Ez a fiók egy bot
+        chosen_languages: Nyelvek szűrése
         confirm_new_password: Új jelszó megerősítése
         confirm_password: Jelszó megerősítése
+        context: Szűrés kontextusai
         current_password: Jelenlegi jelszó
         data: Adatok
+        discoverable: Fiók listázása a profilok adatbázisában
         display_name: Megjelenített név
         email: E-mail cím
         expires_in: Elévül
+        fields: Profil metaadatok
         header: Fejléc
-        locale: Nyelv
-        locked: Zárt felhasználói fiók
-        max_uses: Felhasználhatóság
+        inbox_url: Relé inbox-hoz tartozó URL
+        irreversible: Eldobás elrejtés helyett
+        locale: Felhasználói felület nyelve
+        locked: Felhasználói fiók lezárása
+        max_uses: Hányszor használható
         new_password: Új jelszó
-        note: Önéletrajz
-        otp_attempt: Második-faktor kód
+        note: Bemutatkozás
+        otp_attempt: Kétlépcsős azonosító kód
         password: Jelszó
+        phrase: Kulcsszó vagy kifejezés
+        setting_advanced_layout: Haladó webes felület engedélyezése
+        setting_aggregate_reblogs: Megtolások csoportosítása az idővonalakon
         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_boost_modal: Megerősítés kérése megtolás előtt
+        setting_default_language: Tülkölés nyelve
+        setting_default_privacy: Tülkök alapértelmezett láthatósága
         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_display_media: Média megjelenítése
+        setting_display_media_default: Alapértelmezés
+        setting_display_media_hide_all: Mindent elrejt
+        setting_display_media_show_all: Mindent mutat
+        setting_expand_spoilers: Tartalom figyelmeztetéssel ellátott tülkök automatikus kinyitása
+        setting_hide_network: Hálózatod elrejtése
         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_show_application: A tülkölésre használt alkalmazás feltüntetése
         setting_system_font_ui: Rendszer betűtípusának használata
-        setting_theme: Oldalsablon
+        setting_theme: Megjelenítési sablon
         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
+        username_or_email: Felhasználónév vagy E-mail
+        whole_word: Teljes szó
+      featured_tag:
+        name: Hashtag
       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
+      invite_request:
+        text: Miért akarsz csatlakozni?
       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
+        favourite: E-mail küldése, amikor valaki kedvencnek jelöli a tülködet
+        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
+        pending_account: E-mail küldése, ha új fiókot kell engedélyezni
+        reblog: E-mail küldése, amikor valaki megtolja a tülködet
+        report: E-mail küldése, ha új bejelentés érkezett
     'no': Nem
+    recommended: Ajánlott
     required:
       mark: "*"
       text: kötelező
diff --git a/config/locales/simple_form.hy.yml b/config/locales/simple_form.hy.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c406540162aa8f9ae59ae2d79f75097ce1af0c26
--- /dev/null
+++ b/config/locales/simple_form.hy.yml
@@ -0,0 +1 @@
+hy:
diff --git a/config/locales/simple_form.id.yml b/config/locales/simple_form.id.yml
index c6da2beff3c3a9fe5a41dc05703cbeb46f1b72ce..ba9fbb4e88180c16ef4253801127cb0c5b1ab9f2 100644
--- a/config/locales/simple_form.id.yml
+++ b/config/locales/simple_form.id.yml
@@ -12,18 +12,14 @@ id:
         otp: Masukkan kode dua-faktor dari handphone atau gunakan kode pemulihan anda.
     labels:
       defaults:
-        avatar: Avatar
         confirm_new_password: Konfirmasi kata sandi baru
         confirm_password: Konfirmasi kata sandi
         current_password: Kata sandi sekarang
-        data: Data
         display_name: Nama yang ditampilkan
         email: Alamat e-mail
-        header: Header
         locale: Bahasa
         locked: Buat akun menjadi pribadi
         new_password: Password baru
-        note: Bio
         otp_attempt: Kode dua-faktor
         password: Kata sandi
         setting_boost_modal: Tampilkan dialog konfirmasi dialog sebelum boost
@@ -43,6 +39,5 @@ id:
         reblog: Kirim email saat seseorang mem-boost status anda
     'no': Tidak
     required:
-      mark: "*"
       text: wajib
     'yes': Ya
diff --git a/config/locales/simple_form.io.yml b/config/locales/simple_form.io.yml
index c9fd9899e87332f4579cf799118052d6a6343489..4d640fd9ad314fb1ed83f89e7046693f07079bcb 100644
--- a/config/locales/simple_form.io.yml
+++ b/config/locales/simple_form.io.yml
@@ -26,10 +26,7 @@ io:
         note: Suprizento
         otp_attempt: Dufaktora identigilo
         password: Pasvorto
-        setting_auto_play_gif: Auto-play animated GIFs
-        setting_boost_modal: Show confirmation dialog before boosting
         setting_default_privacy: Videbleso di la mesaji
-        severity: Severity
         type: Tipo di importaco
         username: Uzernomo
       interactions:
@@ -42,8 +39,5 @@ io:
         follow_request: Sendar retpost-mesajo, kande ulu diskonocigas mesajo da tu
         mention: Sendar retpost-mesajo, kande ulu mencionas tu
         reblog: Sendar retpost-mesajo, kande ulu diskonocigas mesajo da tu
-    'no': 'No'
     required:
-      mark: "*"
       text: bezonata
-    'yes': 'Yes'
diff --git a/config/locales/simple_form.it.yml b/config/locales/simple_form.it.yml
index dd43898d2536bc3faf717fe10407127c7904d5da..377a552935ab6f5c670b3d35a47ea71f2c2ae952 100644
--- a/config/locales/simple_form.it.yml
+++ b/config/locales/simple_form.it.yml
@@ -27,17 +27,21 @@ it:
         phrase: Il confronto sarà eseguito ignorando minuscole/maiuscole e i content warning
         scopes: A quali API l'applicazione potrà avere accesso. Se selezionate un ambito di alto livello, non c'è bisogno di selezionare quelle singole.
         setting_aggregate_reblogs: Non mostrare nuove condivisioni per toot che sono stati condivisi di recente (ha effetto solo sulle nuove condivisioni)
-        setting_default_language: La lingua dei tuoi toot può essere individuata automaticamente, ma il risultato non è sempre accurato
+        setting_default_sensitive: Media con contenuti sensibili sono nascosti in modo predefinito e possono essere rivelati con un click
         setting_display_media_default: Nascondi media segnati come sensibili
         setting_display_media_hide_all: Nascondi sempre tutti i media
         setting_display_media_show_all: Nascondi sempre i media segnati come sensibili
         setting_hide_network: Chi segui e chi segue te non saranno mostrati sul tuo profilo
         setting_noindex: Ha effetto sul tuo profilo pubblico e sulle pagine degli status
-        setting_theme: Ha effetto sul modo in cui Mastodon verrà visualizzato quando sarai collegato da qualsiasi dispositivo.
+        setting_show_application: L'applicazione che usi per pubblicare i toot sarà mostrata nella vista di dettaglio dei tuoi toot
         username: Il tuo nome utente sarà unico su %{domain}
         whole_word: Quando la parola chiave o la frase è solo alfanumerica, si applica solo se corrisponde alla parola intera
+      featured_tag:
+        name: 'Eccone alcuni che potresti usare:'
       imports:
-        data: File CSV esportato da un'altra istanza di Mastodon
+        data: File CSV esportato da un altro server Mastodon
+      invite_request:
+        text: Questo ci aiuterà ad esaminare la tua richiesta
       sessions:
         otp: 'Inserisci il codice a due fattori generato dall''app del tuo telefono o usa uno dei codici di recupero:'
       user:
@@ -61,7 +65,7 @@ it:
         warning_preset_id: Usa un avviso preimpostato
       defaults:
         autofollow: Invita a seguire il tuo account
-        avatar: Avatar
+        avatar: Immagine di profilo
         bot: Questo account è un bot
         chosen_languages: Filtra lingue
         confirm_new_password: Conferma nuova password
@@ -85,6 +89,7 @@ it:
         otp_attempt: Codice due-fattori
         password: Password
         phrase: Parola chiave o frase
+        setting_advanced_layout: Abilita interfaccia web avanzata
         setting_aggregate_reblogs: Raggruppa condivisioni in timeline
         setting_auto_play_gif: Play automatico GIF animate
         setting_boost_modal: Mostra dialogo di conferma prima del boost
@@ -100,27 +105,34 @@ it:
         setting_hide_network: Nascondi la tua rete
         setting_noindex: Non farti indicizzare dai motori di ricerca
         setting_reduce_motion: Riduci movimento nelle animazioni
+        setting_show_application: Rendi pubblica l'applicazione usata per inviare i toot
         setting_system_font_ui: Usa il carattere predefinito del sistema
         setting_theme: Tema sito
-        setting_unfollow_modal: Mostra dialogo di conferma prima di smettere di seguire qualcuno
+        setting_unfollow_modal: Chiedi conferma prima di smettere di seguire qualcuno
         severity: Severità
         type: Tipo importazione
         username: Nome utente
         username_or_email: Nome utente o email
         whole_word: Parola intera
+      featured_tag:
+        name: Etichetta
       interactions:
         must_be_follower: Blocca notifiche da chi non ti segue
         must_be_following: Blocca notifiche dalle persone che non segui
         must_be_following_dm: Blocca i messaggi diretti dalle persone che non segui
+      invite_request:
+        text: Perchè vuoi unirti?
       notification_emails:
         digest: Invia email riassuntive
         favourite: Invia email quando segna come preferito al tuo stato
         follow: Invia email quando qualcuno ti segue
         follow_request: Invia email quando qualcuno richiede di seguirti
         mention: Invia email quando qualcuno ti menziona
+        pending_account: Invia e-mail quando un nuovo account richiede l'approvazione
         reblog: Invia email quando qualcuno da un boost al tuo stato
         report: Manda una mail quando viene inviato un nuovo rapporto
     'no': 'No'
+    recommended: Consigliato
     required:
       mark: "*"
       text: richiesto
diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml
index f9beedb7e1b1125be4ae710527881b9553d00187..ccc6c5ca1c73b2c767c14cc81ae29e5b219c6eff 100644
--- a/config/locales/simple_form.ja.yml
+++ b/config/locales/simple_form.ja.yml
@@ -27,17 +27,21 @@ ja:
         phrase: トゥートの大文字小文字や閲覧注意に関係なく一致
         scopes: アプリの API に許可するアクセス権を選択してください。最上位のスコープを選択する場合、個々のスコープを選択する必要はありません。
         setting_aggregate_reblogs: 最近ブーストされたトゥートが新たにブーストされても表示しません (設定後受信したものにのみ影響)
-        setting_default_language: トゥートの言語は自動的に検出されますが、必ずしも正確とは限りません
+        setting_default_sensitive: 閲覧注意状態のメディアはデフォルトでは内容が伏せられ、クリックして初めて閲覧できるようになります
         setting_display_media_default: 閲覧注意としてマークされたメディアは隠す
         setting_display_media_hide_all: 全てのメディアを常に隠す
         setting_display_media_show_all: 閲覧注意としてマークされたメディアも常に表示する
         setting_hide_network: フォローとフォロワーの情報がプロフィールページで見られないようにします
         setting_noindex: 公開プロフィールおよび各投稿ページに影響します
-        setting_theme: ログインしている全てのデバイスで適用されるデザインです。
+        setting_show_application: トゥートするのに使用したアプリがトゥートの詳細ビューに表示されるようになります
         username: あなたのユーザー名は %{domain} の中で重複していない必要があります
         whole_word: キーワードまたはフレーズが英数字のみの場合、単語全体と一致する場合のみ適用されるようになります
+      featured_tag:
+        name: 'これらを使うといいかもしれません:'
       imports:
-        data: 他の Mastodon インスタンスからエクスポートしたCSVファイルを選択して下さい
+        data: 他の Mastodon サーバーからエクスポートしたCSVファイルを選択して下さい
+      invite_request:
+        text: このサーバーは現在承認制です。申請を承認する際に役立つメッセージを添えてください
       sessions:
         otp: '携帯電話のアプリで生成された二段階認証コードを入力するか、リカバリーコードを使用してください:'
       user:
@@ -85,6 +89,7 @@ ja:
         otp_attempt: 二段階認証コード
         password: パスワード
         phrase: キーワードまたはフレーズ
+        setting_advanced_layout: 上級者向け UI を有効にする
         setting_aggregate_reblogs: ブーストをまとめる
         setting_auto_play_gif: アニメーションGIFを自動再生する
         setting_boost_modal: ブーストする前に確認ダイアログを表示する
@@ -100,6 +105,7 @@ ja:
         setting_hide_network: 繋がりを隠す
         setting_noindex: 検索エンジンによるインデックスを拒否する
         setting_reduce_motion: アニメーションの動きを減らす
+        setting_show_application: 送信したアプリを開示する
         setting_system_font_ui: システムのデフォルトフォントを使う
         setting_theme: サイトテーマ
         setting_unfollow_modal: フォローを解除する前に確認ダイアログを表示する
@@ -108,19 +114,25 @@ ja:
         username: ユーザー名
         username_or_email: ユーザー名またはメールアドレス
         whole_word: 単語全体にマッチ
+      featured_tag:
+        name: ハッシュタグ
       interactions:
         must_be_follower: フォロワー以外からの通知をブロック
         must_be_following: フォローしていないユーザーからの通知をブロック
         must_be_following_dm: フォローしていないユーザーからのダイレクトメッセージをブロック
+      invite_request:
+        text: 意気込みをお聞かせください
       notification_emails:
         digest: タイムラインからピックアップしてメールで通知する
         favourite: お気に入りに登録された時にメールで通知する
         follow: フォローされた時にメールで通知する
         follow_request: フォローリクエストを受けた時にメールで通知する
         mention: 返信が来た時にメールで通知する
+        pending_account: 新しいアカウントの承認が必要な時にメールで通知する
         reblog: トゥートがブーストされた時にメールで通知する
         report: 通報を受けた時にメールで通知する
     'no': いいえ
+    recommended: おすすめ
     required:
       mark: "*"
       text: å¿…é ˆ
diff --git a/config/locales/simple_form.ka.yml b/config/locales/simple_form.ka.yml
index 6bccb3134629d352ab84c7dba25a6d9308aa5468..2df3db45bffe596225b1328b494a12f3c333bffa 100644
--- a/config/locales/simple_form.ka.yml
+++ b/config/locales/simple_form.ka.yml
@@ -16,10 +16,8 @@ ka:
         locked: საჭიროებს თქვენ მიერ მიმდევრების ხელით დადასტურებას
         phrase: დამთხვევა მოხდება დიდი და პატარა ასოების ან კონტენტის გაფრთხილების გათვალისწინების გარეშე
         scopes: რომელი აპიებისადმი ექნება აპლიკაციას ცვდომა. თუ არიჩევთ უმთავრეს ფარგლებს, არ დაგჭირდებათ ინდივიდუალურების ამორჩევა.
-        setting_default_language: თქვენი ტუტების ენა შეიძლება დადგინდეს ავტომატურად, მაგრამ ეს არაა ყოველთვის ზუსტი
         setting_hide_network: ვის მიყვებით და ვინ მოგყვებათ არ გამოჩნდება აქ
         setting_noindex: გავლენას ახდენს თქვენს ღია პროფილისა და სტატუსის გვერდებზე
-        setting_theme: გავლენას ახდენს თუ როგორ გამოიყურება მასტოდონი, როდესაც შესული ხართ რომელიმე მოწყობილობიდან.
         whole_word: როდესაც სიტყვა ან ფრაზა მხოლოდ ალფა-ნუმერიკულია, ის დაფიქსირდება თუ ემთხვევა სრულ სიტყვას
       imports:
         data: ცსვ ფაილის ექსპორტი მოხდა მასტოდონის სხვა ინსტანციიდან
@@ -87,6 +85,5 @@ ka:
         reblog: გამოიგზავნოს წერილი როდესაც ვინმე გაზრდის თქვენს სტატუსს
     'no': არა
     required:
-      mark: "*"
       text: აუცილებელი
     'yes': კი
diff --git a/config/locales/simple_form.kk.yml b/config/locales/simple_form.kk.yml
new file mode 100644
index 0000000000000000000000000000000000000000..1dcc9b127cff7008730fd51cf49664fb85866d18
--- /dev/null
+++ b/config/locales/simple_form.kk.yml
@@ -0,0 +1 @@
+kk:
diff --git a/config/locales/simple_form.ko.yml b/config/locales/simple_form.ko.yml
index fd0a1940ee12abd04ba12daf7336048d35fc125a..8147cde5dbb8abd80fdd93ccb20cd9bd406b1972 100644
--- a/config/locales/simple_form.ko.yml
+++ b/config/locales/simple_form.ko.yml
@@ -27,17 +27,21 @@ ko:
         phrase: 툿 내용이나 CW 내용 안에서 대소문자 구분 없이 매칭 됩니다
         scopes: 애플리케이션에 허용할 API들입니다. 최상위 스코프를 선택하면 개별적인 것은 선택하지 않아도 됩니다.
         setting_aggregate_reblogs: 내가 부스트 했던 툿은 새로 부스트 되어도 보여주지 않습니다
-        setting_default_language: 작성한 툿의 언어는 자동으로 인식할 수 있지만, 언제나 정확한 건 아닙니다
+        setting_default_sensitive: 민감한 미디어는 기본적으로 가려져 있으며 클릭해서 볼 수 있습니다
         setting_display_media_default: 민감함으로 설정 된 미디어 가리기
         setting_display_media_hide_all: 항상 모든 미디어를 가리기
         setting_display_media_show_all: 민감함으로 설정 된 미디어를 항상 보이기
         setting_hide_network: 나를 팔로우 하는 사람들과 내가 팔로우 하는 사람들이 내 프로필에 표시되지 않게 합니다
         setting_noindex: 공개 프로필 및 각 툿페이지에 영향을 미칩니다
-        setting_theme: 로그인중인 모든 디바이스에 적용되는 디자인입니다.
+        setting_show_application: 당신이 툿을 작성하는데에 사용한 앱이 툿의 상세정보에 표시 됩니다
         username: 당신의 유저네임은 %{domain} 안에서 유일해야 합니다
         whole_word: 키워드가 영문과 숫자로만 이루어 진 경우, 단어 전체에 매칭 되었을 때에만 작동하게 합니다
+      featured_tag:
+        name: '이것들을 사용하면 좋을 것 같습니다:'
       imports:
-        data: 다른 마스토돈 인스턴스에서 추출된 CSV 파일
+        data: 다른 마스토돈 서버에서 추출된 CSV 파일
+      invite_request:
+        text: 이 정보는 우리가 심사를 하는 데에 참고할 수 있습니다
       sessions:
         otp: '휴대전화에서 생성 된 2단계 인증 코드를 입력하거나, 복구 코드 중 하나를 사용하세요:'
       user:
@@ -64,10 +68,10 @@ ko:
         avatar: 아바타
         bot: 이것은 봇 계정입니다
         chosen_languages: 언어 필터링
-        confirm_new_password: 새로운 비밀번호 다시 입력
-        confirm_password: 현재 비밀번호 다시 입력
+        confirm_new_password: 암호 다시 입력
+        confirm_password: 암호 다시 입력
         context: 필터 컨텍스트
-        current_password: 현재 비밀번호 입력
+        current_password: 현재 암호 입력
         data: 데이터
         discoverable: 이 계정을 디렉토리에서 찾을 수 있도록 합니다
         display_name: 표시되는 이름
@@ -80,11 +84,12 @@ ko:
         locale: 인터페이스 언어
         locked: 계정 잠금
         max_uses: 사용 횟수 제한
-        new_password: 새로운 비밀번호 입력
+        new_password: 새로운 암호 입력
         note: 자기소개
         otp_attempt: 2단계 인증 코드
-        password: 비밀번호
+        password: 암호
         phrase: 키워드 또는 문장
+        setting_advanced_layout: 고급 웹 UI 활성화
         setting_aggregate_reblogs: 타임라인의 부스트를 그룹화
         setting_auto_play_gif: 애니메이션 GIF를 자동 재생
         setting_boost_modal: 부스트 전 확인 창을 표시
@@ -100,6 +105,7 @@ ko:
         setting_hide_network: 내 네트워크 숨기기
         setting_noindex: 검색엔진의 인덱싱을 거절
         setting_reduce_motion: 애니메이션 줄이기
+        setting_show_application: 툿 작성에 사용한 앱을 공개
         setting_system_font_ui: 시스템의 초기 설정 폰트를 사용
         setting_theme: 사이트 테마
         setting_unfollow_modal: 언팔로우 전 언팔로우 확인 표시
@@ -108,20 +114,25 @@ ko:
         username: 유저 이름
         username_or_email: 유저네임 또는 이메일
         whole_word: 단어 전체에 매칭
+      featured_tag:
+        name: 해시태그
       interactions:
         must_be_follower: 나를 팔로우 하지 않는 사람에게서 온 알림을 차단
         must_be_following: 내가 팔로우 하지 않는 사람에게서 온 알림을 차단
         must_be_following_dm: 내가 팔로우 하지 않은 사람에게서 오는 다이렉트메시지를 차단
+      invite_request:
+        text: 가입하려는 이유가 무엇인가요?
       notification_emails:
         digest: 요약 이메일 보내기
         favourite: 누군가 내 상태를 즐겨찾기로 등록했을 때 이메일 보내기
         follow: 누군가 나를 팔로우 했을 때 이메일 보내기
         follow_request: 누군가 나를 팔로우 하길 원할 때 이메일 보내기
         mention: 누군가 나에게 답장했을 때 이메일 보내기
+        pending_account: 새 계정이 심사가 필요할 때 이메일 보내기
         reblog: 누군가 내 툿을 부스트 했을 때 이메일 보내기
         report: 새 신고 등록시 이메일로 알리기
     'no': 아니오
+    recommended: 추천함
     required:
-      mark: "*"
       text: 필수 항목
     'yes': 네
diff --git a/config/locales/simple_form.lt.yml b/config/locales/simple_form.lt.yml
new file mode 100644
index 0000000000000000000000000000000000000000..6c5cb837ac8c136ddd4d85ef0a39145c386d62af
--- /dev/null
+++ b/config/locales/simple_form.lt.yml
@@ -0,0 +1 @@
+lt:
diff --git a/config/locales/simple_form.lv.yml b/config/locales/simple_form.lv.yml
new file mode 100644
index 0000000000000000000000000000000000000000..1be0eabc091569fadd234dc415e9a399b26e32c1
--- /dev/null
+++ b/config/locales/simple_form.lv.yml
@@ -0,0 +1 @@
+lv:
diff --git a/config/locales/simple_form.ms.yml b/config/locales/simple_form.ms.yml
new file mode 100644
index 0000000000000000000000000000000000000000..2925688a0330ed791a036a41ffcb8fc31c75352f
--- /dev/null
+++ b/config/locales/simple_form.ms.yml
@@ -0,0 +1 @@
+ms:
diff --git a/config/locales/simple_form.nl.yml b/config/locales/simple_form.nl.yml
index 6eb784c303eacf5f998fedda54e542c1a74d1e60..58d29ce12c036755ccba4da4fcbfa580796898f3 100644
--- a/config/locales/simple_form.nl.yml
+++ b/config/locales/simple_form.nl.yml
@@ -27,17 +27,21 @@ nl:
         phrase: Komt overeen ongeacht hoofd-/kleine letters of tekstwaarschuwingen
         scopes: Tot welke API's heeft de toepassing toegang. Wanneer je een toestemming van het bovenste niveau kiest, hoef je geen individuele toestemmingen meer te kiezen.
         setting_aggregate_reblogs: Geen nieuwe boosts tonen voor toots die recentelijk nog zijn geboost (heeft alleen effect op nieuw ontvangen boosts)
-        setting_default_language: De taal van jouw toots kan automatisch worden gedetecteerd, maar het is niet altijd accuraat
+        setting_default_sensitive: Gevoelige media wordt standaard verborgen en kan met één klik worden getoond
         setting_display_media_default: Als gevoelig gemarkeerde media verbergen
         setting_display_media_hide_all: Media altijd verbergen
         setting_display_media_show_all: Als gevoelig gemarkeerde media altijd verbergen
         setting_hide_network: Wie jij volgt en wie jou volgen wordt niet op jouw profiel getoond
         setting_noindex: Heeft invloed op jouw openbare profiel en toots
-        setting_theme: Heeft invloed op hoe de webapp van Mastodon eruitziet (op elk apparaat waarmee je inlogt).
+        setting_show_application: De toepassing de je gebruikt om te tooten wordt in de gedetailleerde weergave van de toot getoond
         username: Jouw gebruikersnaam is uniek op %{domain}
         whole_word: Wanneer het trefwoord of zinsdeel alfanumeriek is, wordt het alleen gefilterd wanneer het hele woord overeenkomt
+      featured_tag:
+        name: 'Je wilt misschien een van deze gebruiken:'
       imports:
         data: CSV-bestand dat op een andere Mastodonserver werd geëxporteerd
+      invite_request:
+        text: Dit helpt ons om jouw aanvraag te beoordelen
       sessions:
         otp: 'Voer de tweestaps-aanmeldcode vanaf jouw mobiele telefoon in of gebruik een van jouw herstelcodes:'
       user:
@@ -85,6 +89,7 @@ nl:
         otp_attempt: Tweestaps-aanmeldcode
         password: Wachtwoord
         phrase: Trefwoord of zinsdeel
+        setting_advanced_layout: Geavanceerde webomgeving inschakelen
         setting_aggregate_reblogs: Boosts in tijdlijnen groeperen
         setting_auto_play_gif: Speel geanimeerde GIF's automatisch af
         setting_boost_modal: Vraag voor het boosten van een toot een bevestiging
@@ -100,6 +105,7 @@ nl:
         setting_hide_network: Jouw volgers en wie je volgt verbergen
         setting_noindex: Jouw toots niet door zoekmachines laten indexeren
         setting_reduce_motion: Langzamere animaties
+        setting_show_application: Toepassing onthullen die je voor het verzenden van toots gebruikt
         setting_system_font_ui: Standaardlettertype van jouw systeem gebruiken
         setting_theme: Thema website
         setting_unfollow_modal: Vraag voor het ontvolgen van iemand een bevestiging
@@ -108,19 +114,25 @@ nl:
         username: Gebruikersnaam
         username_or_email: Gebruikersnaam of e-mailadres
         whole_word: Heel woord
+      featured_tag:
+        name: Hashtag
       interactions:
         must_be_follower: Meldingen van mensen die jou niet volgen blokkeren
         must_be_following: Meldingen van mensen die jij niet volgt blokkeren
         must_be_following_dm: Directe berichten van mensen die jij niet volgt blokkeren
+      invite_request:
+        text: Waarom wil jij je aanmelden?
       notification_emails:
         digest: Periodiek e-mails met een samenvatting versturen
         favourite: Een e-mail versturen wanneer iemand jouw toot aan hun favorieten heeft toegevoegd
         follow: Een e-mail versturen wanneer iemand jou volgt
         follow_request: Een e-mail versturen wanneer iemand jou wil volgen
         mention: Een e-mail versturen wanneer iemand jou vermeld
+        pending_account: Een e-mail verzenden wanneer een nieuw account moet worden beoordeeld
         reblog: Een e-mail versturen wanneer iemand jouw toot heeft geboost
         report: Verstuur een e-mail wanneer een nieuw rapportage is ingediend
     'no': Nee
+    recommended: Aanbevolen
     required:
       mark: "*"
       text: vereist
diff --git a/config/locales/simple_form.no.yml b/config/locales/simple_form.no.yml
index fc339c3f27b633b9fd6fc55c8d93052241a95ccf..9393e37d12b77009b92ff8b99a6a0c21e64cb2f5 100644
--- a/config/locales/simple_form.no.yml
+++ b/config/locales/simple_form.no.yml
@@ -8,18 +8,15 @@
         header: PNG, GIF eller JPG. Maksimalt %{size}. Vil bli nedskalert til %{dimensions}px
         locked: Krever at du manuelt godkjenner følgere
         setting_noindex: PÃ¥virker din offentlige profil og statussider
-        setting_theme: Påvirker hvordan Mastodon ser ut når du er logget inn fra uansett enhet.
       imports:
         data: CSV-fil eksportert fra en annen Mastodon-instans
       sessions:
         otp: Angi tofaktorkoden fra din telefon eller bruk en av dine gjenopprettingskoder.
     labels:
       defaults:
-        avatar: Avatar
         confirm_new_password: Bekreft nytt passord
         confirm_password: Bekreft passord
         current_password: Nåværende passord
-        data: Data
         display_name: Visningsnavn
         email: E-postadresse
         expires_in: Utløper etter
@@ -57,6 +54,5 @@
         reblog: Send e-post når noen fremhever din status
     'no': Nei
     required:
-      mark: "*"
       text: obligatorisk
     'yes': Ja
diff --git a/config/locales/simple_form.oc.yml b/config/locales/simple_form.oc.yml
index 6ded448e903373c173609b0293442e1408fbbade..e0bfcfef9c57864c842fd4b3389c20035e978174 100644
--- a/config/locales/simple_form.oc.yml
+++ b/config/locales/simple_form.oc.yml
@@ -27,17 +27,20 @@ oc:
         phrase: Serà pres en compte que siá en majuscula o minuscula o dins un avertiment de contengut sensible
         scopes: A quinas APIs poiràn accedir las aplicacions. Se seleccionatz un encastre de naut nivèl, fa pas mestièr de seleccionar los nivèls mai basses.
         setting_aggregate_reblogs: Mostrar pas los nòus partatges que son estats partejats recentament (afecta pas que los nòus partatges recebuts)
-        setting_default_language: La lenga de vòstres tuts pòt èsser detectada automaticament, mas de còps es pas corrèctament determinada
         setting_display_media_default: Rescondre los mèdias marcats coma sensibles
         setting_display_media_hide_all: Totjorn rescondre los mèdias
         setting_display_media_show_all: Totjorn mostrar los mèdias marcats coma sensibles
         setting_hide_network: Vòstre perfil mostrarà pas los que vos sègon e lo monde que seguètz
         setting_noindex: Aquò es destinat a vòstre perfil public e vòstra pagina d’estatuts
-        setting_theme: Aquò càmbia lo tèma grafic de Mastodon quand sètz connectat qual que siasque lo periferic.
+        setting_show_application: Lo nom de l’aplicacion qu’utilizatz per publicar serà mostrat dins la vista detalhada de vòstres tuts
         username: Vòstre nom d’utilizaire serà unic sus %{domain}
         whole_word: Quand lo mot-clau o frasa es solament alfranumeric, serà pas qu’aplicat se correspond al mot complèt
+      featured_tag:
+        name: 'Benlèu que volètz utilizar una d’aquestas causas :'
       imports:
-        data: Fichièr CSV exportat d’una autra instància Mastodon
+        data: Fichièr CSV exportat d’un autre servidor Mastodon
+      invite_request:
+        text: Aquò nos ajudarà per validar vòstra demanda
       sessions:
         otp: 'Picatz lo còdi d’autentificacion en dos temps (Two factor code) de vòstra aplicacion mobil o utilizatz un de vòstres còdis de recuperacion :'
       user:
@@ -61,7 +64,6 @@ oc:
         warning_preset_id: Utilizar un avertiment predefinit
       defaults:
         autofollow: Convidar a sègre vòstre compte
-        avatar: Avatar
         bot: Aquò es lo compte a un robòt
         chosen_languages: Filtrar las lengas
         confirm_new_password: Confirmacion del nòu senhal
@@ -81,7 +83,6 @@ oc:
         locked: Far venir lo compte privat
         max_uses: Limit d’utilizacions
         new_password: Nòu senhal
-        note: Bio
         otp_attempt: Còdi Two-factor
         password: Senhal
         phrase: Senhal o frasa
@@ -100,6 +101,7 @@ oc:
         setting_hide_network: Amagar vòstre malhum
         setting_noindex: Èsser pas indexat pels motors de recèrca
         setting_reduce_motion: Reduire la velocitat de las animacions
+        setting_show_application: Revelar lo nom de l’aplicacion utilizada per enviar de tuts
         setting_system_font_ui: Utilizar la polissa del sistèma
         setting_theme: Tèma del site
         setting_unfollow_modal: Mostrar una confirmacion abans de quitar de sègre qualqu’un
@@ -108,20 +110,24 @@ oc:
         username: Nom d’utilizaire
         username_or_email: Nom d’utilizaire o corrièl
         whole_word: Mot complèt
+      featured_tag:
+        name: Etiqueta
       interactions:
         must_be_follower: Blocar las notificacions del mond que vos sègon pas
         must_be_following: Blocar las notificacions del mond que seguètz pas
         must_be_following_dm: Blocar los messatges del monde que seguètz pas
+      invite_request:
+        text: Perqué volètz vos marcar ?
       notification_emails:
         digest: Enviar un corrièl recapitulatiu
         favourite: Enviar un corrièl quand qualqu’un plaça vòstre estatut en favorit
         follow: Enviar un corrièl quand qualqu’un vos sèc
         follow_request: Enviar un corrièl quand qualqu’un demanda de vos sègre
         mention: Enviar un corrièl quand qualqu’un vos menciona
+        pending_account: Enviar un corrièl quand cal validar un compte novèl
         reblog: Enviar un corrièl quand qualqu’un tòrna partejar vòstre estatut
         report: Enviar un corrièl pels nòus senhalaments
     'no': Non
     required:
-      mark: "*"
       text: requesit
     'yes': Ã’c
diff --git a/config/locales/simple_form.pl.yml b/config/locales/simple_form.pl.yml
index bbc55e8a913fa06a214f5199160a267216846dc0..2f9bf5329f17d78d06b644109e1d0fa3cbfb8e39 100644
--- a/config/locales/simple_form.pl.yml
+++ b/config/locales/simple_form.pl.yml
@@ -27,17 +27,21 @@ pl:
         phrase: Zostanie wykryte nawet, gdy znajduje się za ostrzeżeniem o zawartości
         scopes: Wybór API, do których aplikacja będzie miała dostęp. Jeżeli wybierzesz nadrzędny zakres, nie musisz wybierać jego elementów.
         setting_aggregate_reblogs: Nie pokazuj nowych podbić dla wpisów, które zostały niedawno podbite (dotyczy tylko nowo otrzymanych podbić)
-        setting_default_language: Język Twoich wpisów może być wykrywany automatycznie, ale nie zawsze jest to dokładne
+        setting_default_sensitive: Wrażliwe multimedia są domyślnie schowane i mogą być odkryte kliknięciem
         setting_display_media_default: Ukrywaj zawartość oznaczoną jako wrażliwa
-        setting_display_media_hide_all: Zawsze ukrywaj zawartość multimedialną
-        setting_display_media_show_all: Zawsze pokazuj zawartość multimedialną jako wrażliwą
+        setting_display_media_hide_all: Zawsze oznaczaj zawartość multimedialną jako wrażliwą
+        setting_display_media_show_all: Nie ukrywaj zawartości multimedialnej oznaczonej jako wrażliwa
         setting_hide_network: Informacje o tym, kto Cię śledzi i kogo śledzisz nie będą widoczne
         setting_noindex: Wpływa na widoczność strony profilu i Twoich wpisów
-        setting_theme: Zmienia wyglÄ…d Mastodona po zalogowaniu z dowolnego urzÄ…dzenia.
+        setting_show_application: W informacjach o wpisie będzie widoczna informacja o aplikacji, z której został wysłany
         username: Twoja nazwa użytkownika będzie niepowtarzalna na %{domain}
         whole_word: Jeśli słowo lub fraza składa się jedynie z liter lub cyfr, filtr będzie zastosowany tylko do pełnych wystąpień
+      featured_tag:
+        name: 'Sugerujemy użycie jednego z następujących:'
       imports:
-        data: Plik CSV wyeksportowany z innej instancji Mastodona
+        data: Plik CSV wyeksportowany z innego serwera Mastodona
+      invite_request:
+        text: To pomoże nam w recenzji Twojej aplikacji
       sessions:
         otp: 'Wprowadź kod weryfikacji dwuetapowej z telefonu lub wykorzystaj jeden z kodów zapasowych:'
       user:
@@ -85,7 +89,7 @@ pl:
         otp_attempt: Kod uwierzytelnienia dwustopniowego
         password: Hasło
         phrase: Słowo kluczowe lub fraza
-        scopes: Do których API aplikacja będzie miała dostęp. Jeżeli wybierzesz zakres wyższego poziomu, nie musisz zaznaczać bardziej szczegółowych.
+        setting_advanced_layout: Włącz zaawansowany interfejs użytkownika
         setting_aggregate_reblogs: Grupuj podbicia na osiach czasu
         setting_auto_play_gif: Automatycznie odtwarzaj animowane GIFy
         setting_boost_modal: Pytaj o potwierdzenie przed podbiciem
@@ -101,6 +105,7 @@ pl:
         setting_hide_network: Ukryj swoją sieć
         setting_noindex: Nie indeksuj mojego profilu w wyszukiwarkach internetowych
         setting_reduce_motion: Ogranicz ruch w animacjach
+        setting_show_application: Informuj o aplikacji z której wysłano wpisy
         setting_system_font_ui: Używaj domyślnej czcionki systemu
         setting_theme: Motyw strony
         setting_unfollow_modal: Pytaj o potwierdzenie przed cofnięciem śledzenia
@@ -109,19 +114,25 @@ pl:
         username: Nazwa użytkownika
         username_or_email: Nazwa użytkownika lub adres e-mail
         whole_word: Całe słowo
+      featured_tag:
+        name: Hasztag
       interactions:
         must_be_follower: Nie wyświetlaj powiadomień od osób, które Cię nie śledzą
         must_be_following: Nie wyświetlaj powiadomień od osób, których nie śledzisz
         must_be_following_dm: Nie wyświetlaj wiadomości bezpośrednich od osób, których nie śledzisz
+      invite_request:
+        text: Czemu chcesz dołączyć?
       notification_emails:
         digest: Wysyłaj podsumowania e-mailem
         favourite: Powiadamiaj mnie e-mailem, gdy ktoś polubi mój wpis
         follow: Powiadamiaj mnie e-mailem, gdy ktoś zacznie mnie śledzić
         follow_request: Powiadamiaj mnie e-mailem, gdy ktoś poprosi o pozwolenie na śledzenie mnie
         mention: Powiadamiaj mnie e-mailem, gdy ktoÅ› o mnie wspomni
+        pending_account: Wyślij e-mail kiedy nowe konto potrzebuje recenzji
         reblog: Powiadamiaj mnie e-mailem, gdy ktoś podbije mój wpis
         report: Powiadamiaj mnie e-mailem, gdy zostanie utworzone nowe zgłoszenie
     'no': Nie
+    recommended: Polecane
     required:
       mark: "*"
       text: pole wymagane
diff --git a/config/locales/simple_form.pt-BR.yml b/config/locales/simple_form.pt-BR.yml
index 664c07a463ce1200b5a08b72c0ad4320be5bb34a..10475e51549631168b04c5851f8c91a069b89c03 100644
--- a/config/locales/simple_form.pt-BR.yml
+++ b/config/locales/simple_form.pt-BR.yml
@@ -6,7 +6,7 @@ pt-BR:
         text: Você pode usar a sintaxe de um toot, como URLs, hashtags e menções
       admin_account_action:
         send_email_notification: O usuário vai receber uma explicação do que aconteceu com a sua conta
-        text_html: Opcional. Você pode usar a sintaxe de toots. Você pode <a href="%{path}">adicionar avisos pré-definidos</a> para ganhar tempo.
+        text_html: Opcional. Você pode usar a sintaxe de toots. Você pode <a href="%{path}">adicionar avisos pré-definidos</a> para ganhar tempo
         type_html: Escolha o que fazer com <strong>%{acct}</strong>
         warning_preset_id: Opcional. Você ainda pode adicionar texto customizado no fim do texto pré-definido
       defaults:
@@ -27,17 +27,20 @@ pt-BR:
         phrase: Vai coincidir, independente de maiúsculas ou minúsculas, no texto ou no aviso de conteúdo de um toot
         scopes: Quais APIs a aplicação vai ter permissão de acessar. Se você selecionar um escopo de alto nível, você não precisa selecionar individualmente os outros.
         setting_aggregate_reblogs: Não mostrar novos compartilhamentos para toots que foram compartilhados recentemente (afeta somente novos compartilhamentos recebidos)
-        setting_default_language: O idioma de seus toots pode ser detectado automaticamente, mas isso nem sempre é preciso
         setting_display_media_default: Esconder mídia marcada como sensível
         setting_display_media_hide_all: Sempre esconder todas as mídias
         setting_display_media_show_all: Sempre mostrar mídia marcada como sensível
         setting_hide_network: Quem você segue e quem segue você não serão exibidos no seu perfil
         setting_noindex: Afeta seu perfil público e as páginas de suas postagens
-        setting_theme: Afeta a aparência do Mastodon quando em sua conta em qualquer aparelho.
+        setting_show_application: A aplicação que você usar para enviar seus toots vai aparecer na visão detalhada dos seus toots
         username: Seu nome de usuário será único em %{domain}
         whole_word: Quando a palavra ou frase é inteiramente alfanumérica, ela será aplicada somente se corresponder a palavra inteira
+      featured_tag:
+        name: 'Você pode querer usar um destes:'
       imports:
         data: Arquivo CSV exportado de outra instância do Mastodon
+      invite_request:
+        text: Isso vai nos ajudar a revisar sua aplicação
       sessions:
         otp: 'Insira o código de autenticação gerado pelo app no seu celular ou use um dos códigos de recuperação:'
       user:
@@ -61,7 +64,6 @@ pt-BR:
         warning_preset_id: Usar um aviso pré-definido
       defaults:
         autofollow: Convite para seguir a sua conta
-        avatar: Avatar
         bot: Esta é uma conta-robô
         chosen_languages: Filtros de idioma
         confirm_new_password: Confirmar nova senha
@@ -81,7 +83,6 @@ pt-BR:
         locked: Trancar conta
         max_uses: Número máximo de usos
         new_password: Nova senha
-        note: Bio
         otp_attempt: Código de autenticação em dois passos
         password: Senha
         phrase: Palavra-chave ou frase
@@ -100,6 +101,7 @@ pt-BR:
         setting_hide_network: Esconder as suas redes
         setting_noindex: Não quero ser indexado por mecanismos de busca
         setting_reduce_motion: Reduz movimento em animações
+        setting_show_application: Mostrar o nome da aplicação utilizada para enviar os toots
         setting_system_font_ui: Usar a fonte padrão de seu sistema
         setting_theme: Tema do site
         setting_unfollow_modal: Mostrar diálogo de confirmação antes de deixar de seguir alguém
@@ -112,16 +114,18 @@ pt-BR:
         must_be_follower: Bloquear notificações de não-seguidores
         must_be_following: Bloquear notificações de pessoas que você não segue
         must_be_following_dm: Bloquear mensagens diretas de pessoas que você não segue
+      invite_request:
+        text: Por que você quer se cadastrar?
       notification_emails:
         digest: Mandar e-mails com relatórios
         favourite: Mandar um e-mail quando alguém favoritar suas postagens
         follow: Mandar um e-mail quando alguém te seguir
         follow_request: Mandar um e-maill quando alguém solicitar ser seu seguidor
         mention: Mandar um e-mail quando alguém te mencionar
+        pending_account: Mandar um -mail quando uma nova conta precisar ser revisada
         reblog: Mandar um e-mail quando alguém compartilhar suas postagens
         report: Mandar um e-mail quando uma nova denúncia é submetida
     'no': Não
     required:
-      mark: "*"
       text: obrigatório
     'yes': Sim
diff --git a/config/locales/simple_form.pt.yml b/config/locales/simple_form.pt.yml
index 88be3ac70fff8292db92fd1bb7c7b17c530b5d69..bf638188984afe3e3b01e0590473a49aa6212d86 100644
--- a/config/locales/simple_form.pt.yml
+++ b/config/locales/simple_form.pt.yml
@@ -2,28 +2,82 @@
 pt:
   simple_form:
     hints:
+      account_warning_preset:
+        text: Tu podes usar sintaxe de escrita, como URLs, hashtags e referências
+      admin_account_action:
+        send_email_notification: O utilizador receberá uma explicação sobre o que aconteceu com a sua conta
+        text_html: Opcional. Tu podes usar sintaxe de escrita. Tu podes <a href="%{path}"> adicionar predefinições de aviso</a> para poupar tempo
+        type_html: Escolhe o que fazer com <strong>%{acct}</strong>
+        warning_preset_id: Opcional. Tu ainda podes adicionar texto personalizado no fim do predefinido
       defaults:
+        autofollow: As pessoas que aderem através do convite seguir-te-ão automaticamente
         avatar: PNG, GIF or JPG. Arquivos até %{size}. Vão ser reduzidos para %{dimensions}px
+        bot: Esta conta executa essencialmente acções automáticas e pode não poder ser monitorizada
+        context: Um ou múltiplos contextos nos quais o filtro deve ser aplicado
         digest: Enviado após um longo período de inatividade e apenas se foste mencionado na tua ausência
+        discoverable_html: O <a href="%{path}" target="_blank">directory</a> permite encontrar contas de pessoas com base nos seus interesses e actividades. Exige, pelo menos %{min_followers} seguidores
+        email: Será enviado um e-mail de confirmação
+        fields: Podes ter até 4 itens expostos, em forma de tabela, no teu perfil
         header: PNG, GIF or JPG. Arquivos até %{size}. Vão ser reduzidos para %{dimensions}px
+        inbox_url: Copia a URL da página inicial do repetidor que queres usar
+        irreversible: Publicações filtradas irão desaparecer irremediavelmente, mesmo que o filtro seja removido posteriormente
+        locale: A língua da interface de utilizador, e-mails e notificações push
         locked: Requer aprovação manual de seguidores
+        password: Usa, pelo menos, 8 caracteres
+        phrase: Será correspondido independentemente da capitalização ou do aviso de conteúdo duma publicação
+        scopes: Quais as APIs a que será concedido acesso. Se escolheres uma abrangência de nível superior, não precisarás de as seleccionar individualmente.
+        setting_aggregate_reblogs: Não mostrar novas partilhas que foram partilhadas recentemente (só afecta as novas partilhas)
+        setting_display_media_default: Esconder media marcada como sensível
+        setting_display_media_hide_all: Esconder sempre toda a media
+        setting_display_media_show_all: Mostrar sempre a media marcada como sensível
+        setting_hide_network: Quem tu segues e quem te segue não será mostrado no teu perfil
         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.
+        setting_show_application: A aplicação que tu usas para publicar será mostrada na vista detalhada das tuas publicações
+        username: O teu nome de utilizador será único em %{domain}
+        whole_word: Quando a palavra-chave ou expressão-chave é somente alfanumérica, ela só será aplicada se corresponder à palavra completa
+      featured_tag:
+        name: 'Poderás querer usar um destes:'
       imports:
-        data: Arquivo CSV exportado de outra instância do Mastodon
+        data: Arquivo CSV exportado de outro servidor do Mastodon
       sessions:
-        otp: Inserir o código de autenticação de dois factores do teu telemóvel ou usa um dos códigos de recuperação.
+        otp: 'Insere o código de autenticação em dois passos gerado pelo teu telemóvel ou usa um dos teus códigos de recuperação:'
+      user:
+        chosen_languages: Quando seleccionado, só publicações nas línguas escolhidas serão mostradas nas cronologias públicas
     labels:
+      account:
+        fields:
+          name: Rótulo
+          value: Conteúdo
+      account_warning_preset:
+        text: Texto pré-definido
+      admin_account_action:
+        send_email_notification: Notificar o utilizador por e-mail
+        text: Aviso personalizado
+        type: Acção
+        types:
+          disable: Desactivar
+          none: Não fazer algo
+          silence: Silenciar
+          suspend: Suspender e apagar irreversivelmente os dados da conta
+        warning_preset_id: Usar um aviso pré-definido
       defaults:
+        autofollow: Convidar para seguir a tua conta
         avatar: Imagem de Perfil
+        bot: Esta é uma conta robô
+        chosen_languages: Filtrar línguas
         confirm_new_password: Confirmar nova palavra-passe
         confirm_password: Confirmar palavra-passe
+        context: Filtrar contextos
         current_password: Palavra-passe actual
         data: Dados
+        discoverable: Listar esta conta no directório
         display_name: Nome Público
         email: Endereço de e-mail
         expires_in: Expira em
+        fields: Meta-dados de perfil
         header: Cabeçalho
+        inbox_url: URL da caixa de entrada do repetidor
+        irreversible: Expandir em vez de esconder
         locale: Idioma
         locked: Trancar conta
         max_uses: Número máximo de utilizações
@@ -31,19 +85,31 @@ pt:
         note: Biografia
         otp_attempt: Código de autenticação em dois passos
         password: Palavra-passe
+        phrase: Palavra ou expressão-chave
+        setting_aggregate_reblogs: Agrupar partilhas em cronologias
         setting_auto_play_gif: Reproduzir GIFs automaticamente
         setting_boost_modal: Solicitar confirmação antes de partilhar uma publicação
+        setting_default_language: Língua de 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_display_media: Exposição de media
+        setting_display_media_default: Pré-definição
+        setting_display_media_hide_all: Esconder todos
+        setting_display_media_show_all: Mostrar todos
+        setting_expand_spoilers: Expandir sempre as publicações marcadas com avisos de conteúdo
+        setting_hide_network: Esconder a tua rede
         setting_noindex: Não quero ser indexado por motores de pesquisa
         setting_reduce_motion: Reduz movimento em animações
+        setting_show_application: Revelar sempre qual a aplicação usada para enviar as publicaçõ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
+        username_or_email: Nome de utilizador ou e-mail
+        whole_word: Palavra completa
       interactions:
         must_be_follower: Bloquear notificações de não-seguidores
         must_be_following: Bloquear notificações de pessoas que não segues
@@ -55,8 +121,8 @@ pt:
         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
+        report: Enviar um e-mail quando um novo relatório é submetido
     'no': Não
     required:
-      mark: "*"
       text: obrigatório
     'yes': Sim
diff --git a/config/locales/simple_form.ro.yml b/config/locales/simple_form.ro.yml
index 757b8720434521413af3a21ad350c88dfd60fd24..4df2fe16100d1f84b9b3df9bf27a5d41954a1bb7 100644
--- a/config/locales/simple_form.ro.yml
+++ b/config/locales/simple_form.ro.yml
@@ -27,13 +27,11 @@ ro:
         phrase: Vor fi potrivite indiferent de textul din casetă sau advertismentul unei postări
         scopes: La care API-uri aplicația are nevoie de acces. Dacă selectezi un scop principal nu mai e nevoie să selectezi fiecare sub-scop al acestuia.
         setting_aggregate_reblogs: Nu afișa redistribuirile noi pentru postările care au fost deja recent redistribuite (afectează doar noile redistribuiri primite)
-        setting_default_language: Limba postărilor tale poate fi detectată automat, dar nu este întotdeauna precisă
         setting_display_media_default: Ascunde conținutul media marcat ca sensibil (NSFW)
         setting_display_media_hide_all: Întotdeauna ascunde tot conținutul media
         setting_display_media_show_all: Întotdeauna afișează conținutul media marcat ca sensibil
         setting_hide_network: Pe cine urmărești și cine te urmărește nu vor fi afișați pe profilul tău
         setting_noindex: Afecteazâ profilul tău public și statusurile tale
-        setting_theme: Afecteazâ modul în care arată interfața pe toate dispozitivele pe care ești conectat.
         username: Numele tău de utilizator va fi unic pe %{domain}
         whole_word: Când fraza sau cuvântul este doar alfanumeric, acesta se aplică doar dacă există o potrivire completă
       imports:
@@ -68,7 +66,6 @@ ro:
         confirm_password: Confirmă parola
         context: Contextele filtrului
         current_password: Parola actuală
-        data: Data
         discoverable: Listează acest cont in director
         display_name: Numele afișat
         email: Adresa de e-mail
@@ -117,6 +114,5 @@ ro:
         report: Trimite e-mail când un raport nou este trimis
     'no': Nu
     required:
-      mark: "*"
       text: obligatoriu
     'yes': Da
diff --git a/config/locales/simple_form.ru.yml b/config/locales/simple_form.ru.yml
index 44cd7ccd6265b145ec4d2f1a472c960cdfec1190..26a73c3c6d9925306cc07d39722e9d965b9ccb56 100644
--- a/config/locales/simple_form.ru.yml
+++ b/config/locales/simple_form.ru.yml
@@ -2,29 +2,48 @@
 ru:
   simple_form:
     hints:
+      account_warning_preset:
+        text: Вы можете использовать всё, что в обычных постах — ссылки, хэштеги, упоминания и т.д.
+      admin_account_action:
+        send_email_notification: Пользователь получит сообщение о том, что случилось с его/её аккаунтом
+        text_html: (Необязательно) Можно использовать обычный синтаксис. Для экономии времени <a href="%{path}">добавьте шаблоны предупреждений</a>
+        type_html: Выберите, что делать с аккаунтом <strong>%{acct}</strong>
+        warning_preset_id: Необязательно. Вы можете добавить собственный текст в конце шаблона
       defaults:
         autofollow: Люди, пришедшие по этому приглашению автоматически будут подписаны на Вас
         avatar: PNG, GIF или JPG. Максимально %{size}. Будет уменьшено до %{dimensions}px
         bot: Этот аккаунт обычно выполяет автоматизированные действия и может не просматриваться владельцем
         context: Один или несколько контекстов, к которым должны быть применены фильтры
-        digest: Отсылается лишь после длительной неактивности, если Вы в это время получали личные сообщения
+        digest: Отсылается лишь после длительной неактивности, если вы в это время получали личные сообщения
+        discoverable_html: <a href="%{path}" target="_blank">Каталог</a> позволяет пользователям искать людей по интересам и активности. Необходимо наличие не менее %{min_followers} подписчиков
+        email: Вам будет отправлено электронное письмо с подтверждением
         fields: В профиле можно отобразить до 4 пунктов как таблицу
         header: PNG, GIF или JPG. Максимально %{size}. Будет уменьшено до %{dimensions}px
-        inbox_url: Копировать URL с главной страницы ретранслятора, который Вы хотите использовать
+        inbox_url: Копировать URL с главной страницы ретранслятора, который вы хотите использовать
         irreversible: Отфильтрованные статусы будут утеряны навсегда, даже если в будущем фильтр будет убран
         locale: Язык интерфейса, e-mail писем и push-уведомлений
-        locked: Потребует от Вас ручного подтверждения подписчиков, изменит приватность постов по умолчанию на "только для подписчиков"
+        locked: Потребует от вас ручного подтверждения подписчиков, изменит приватность постов по умолчанию на "только для подписчиков"
+        password: Укажите не менее 8 символов
         phrase: Будет сопоставлено независимо от присутствия в тексте или предупреждения о содержании статуса
-        scopes: Какие API приложению будет позволено использовать. Если Вы выберите самый верхний, нижестоящие будут выбраны автоматически.
-        setting_default_language: Язык Ваших статусов может быть определён автоматически, но не всегда правильно
-        setting_hide_network: Те, на кого Вы подписаны и кто подписан на Вас, не будут отображены в Вашем профиле
-        setting_noindex: Относится к Вашему публичному профилю и страницам статусов
-        setting_theme: Влияет на внешний вид Mastodon при выполненном входе в аккаунт.
+        scopes: Какие API приложению будет позволено использовать. Если вы выберете самый верхний, нижестоящие будут выбраны автоматически.
+        setting_aggregate_reblogs: Не показывать новые продвижения статусов, которые уже были недавно продвинуты (относится только к новым продвижениям)
+        setting_default_sensitive: Чувствительные медиафайлы скрыты по умолчанию и могут быть показаны по нажатию на них
+        setting_display_media_default: Скрывать чувствительные медиафайлы
+        setting_display_media_hide_all: Всегда скрывать любые медиафайлы
+        setting_display_media_show_all: Всегда показывать чувствительные медиафайлы
+        setting_hide_network: Те, на кого вы подписаны и кто подписан на Вас, не будут отображены в вашем профиле
+        setting_noindex: Относится к вашему публичному профилю и страницам статусов
+        setting_show_application: В окне просмотра вашего статуса будет видно, с какого приложения он был отправлен
+        username: Ваш юзернейм будет уникальным на %{domain}
         whole_word: Если слово или фраза состоит только из букв и цифр, сопоставление произойдёт только по полному совпадению
+      featured_tag:
+        name: 'Возможно, вы захотите выбрать из них:'
       imports:
         data: Файл CSV, экспортированный с другого узла Mastodon
+      invite_request:
+        text: Это поможет нам рассмотреть вашу заявку
       sessions:
-        otp: 'Введите код двухфакторной аутентификации, сгенерированный в мобильном приложении, или используйте один из Ваших кодов восстановления:'
+        otp: 'Введите код двухфакторной аутентификации, сгенерированный в мобильном приложении, или используйте один из ваших кодов восстановления:'
       user:
         chosen_languages: Если выбрано, то в публичных лентах будут показаны только посты на выбранных языках
     labels:
@@ -32,6 +51,18 @@ ru:
         fields:
           name: Пункт
           value: Значение
+      account_warning_preset:
+        text: Текст шаблона
+      admin_account_action:
+        send_email_notification: Уведомить юзера по e-mail
+        text: Свой текст предупреждения
+        type: Действие
+        types:
+          disable: Заморозить
+          none: Ничего не делать
+          silence: Заглушить
+          suspend: Заблокировать и безвозвратно удалить все данные аккаунта
+        warning_preset_id: Использовать шаблон
       defaults:
         autofollow: Пригласите подписаться на Ваш аккаунт
         avatar: Аватар
@@ -42,6 +73,7 @@ ru:
         context: Контекст фильтра
         current_password: Текущий пароль
         data: Данные
+        discoverable: Показывать этот аккаунт в каталоге
         display_name: Показываемое имя
         email: Адрес e-mail
         expires_in: Истекает через
@@ -57,15 +89,23 @@ ru:
         otp_attempt: Двухфакторный код
         password: Пароль
         phrase: Слово или фраза
+        setting_advanced_layout: Включить многоколоночный интерфейс
+        setting_aggregate_reblogs: Группировать продвижения в лентах
         setting_auto_play_gif: Автоматически проигрывать анимированные GIF
         setting_boost_modal: Показывать диалог подтверждения перед продвижением
         setting_default_language: Язык отправляемых статусов
         setting_default_privacy: Видимость постов
         setting_default_sensitive: Всегда отмечать медиаконтент как чувствительный
         setting_delete_modal: Показывать диалог подтверждения перед удалением
+        setting_display_media: Отображение медиафайлов
+        setting_display_media_default: По умолчанию
+        setting_display_media_hide_all: Скрывать все
+        setting_display_media_show_all: Показывать все
+        setting_expand_spoilers: Всегда раскрывать статусы, имеющие предупреждение о содержании
         setting_hide_network: Скрыть свои связи
         setting_noindex: Отказаться от индексации в поисковых машинах
         setting_reduce_motion: Уменьшить движение в анимации
+        setting_show_application: Раскрывать приложение, с которого отправляются статусы
         setting_system_font_ui: Использовать шрифт системы по умолчанию
         setting_theme: Тема сайта
         setting_unfollow_modal: Показывать диалог подтверждения перед тем, как отписаться от аккаунта
@@ -74,19 +114,25 @@ ru:
         username: Имя пользователя
         username_or_email: Имя пользователя или e-mail
         whole_word: Слово целиком
+      featured_tag:
+        name: Хэштег
       interactions:
         must_be_follower: Заблокировать уведомления не от подписчиков
-        must_be_following: Заблокировать уведомления от людей, на которых Вы не подписаны
-        must_be_following_dm: Заблокировать личные сообщения от людей, на которых Вы не подписаны
+        must_be_following: Заблокировать уведомления от людей, на которых вы не подписаны
+        must_be_following_dm: Заблокировать личные сообщения от людей, на которых вы не подписаны
+      invite_request:
+        text: Почему вы хотите присоединиться к нам?
       notification_emails:
         digest: Присылать дайджест по e-mail
-        favourite: Уведомлять по e-mail, когда кому-то нравится Ваш статус
-        follow: Уведомлять по e-mail, когда кто-то подписался на Вас
+        favourite: Уведомлять по e-mail, когда кому-то нравится ваш статус
+        follow: Уведомлять по e-mail, когда кто-то подписался на вас
         follow_request: Уведомлять по e-mail, когда кто-то запрашивает разрешение на подписку
-        mention: Уведомлять по e-mail, когда кто-то упомянул Вас
-        reblog: Уведомлять по e-mail, когда кто-то продвинул Ваш статус
+        mention: Уведомлять по e-mail, когда кто-то упомянул вас
+        pending_account: Отправлять e-mail при наличии новых заявок на присоединение
+        reblog: Уведомлять по e-mail, когда кто-то продвинул ваш статус
         report: Уведомлять по e-mail при создании жалобы
     'no': Нет
+    recommended: Рекомендуется
     required:
       mark: "*"
       text: обязательно
diff --git a/config/locales/simple_form.sk.yml b/config/locales/simple_form.sk.yml
index f2d26cf026ece21e483ed7c6ff456214debe75d7..8470f793912267482982ee814e00735efe419693 100644
--- a/config/locales/simple_form.sk.yml
+++ b/config/locales/simple_form.sk.yml
@@ -14,7 +14,7 @@ sk:
         avatar: PNG, GIF alebo JPG. Maximálne %{size}. Bude zmenšený na %{dimensions}px
         bot: Tento účet vykonáva hlavne automatizované akcie, a je pravdepodobne nespravovaný
         context: Jedno, alebo viac kritérií, v ktorých má byť filtrovanie uplatnené
-        digest: Odoslané iba v prípade dlhodobej neprítomnosti, a len ak si obdŕžal/a nejaké osobné správy kým si bol/a preč
+        digest: Odoslané iba v prípade dlhodobej neprítomnosti, a len ak si obdržal/a nejaké osobné správy kým si bol/a preč
         discoverable_html: Táto <a href="%{path}" target="_blank">databáza</a> umožňuje ľudom nájsť profily podľa záujmu a aktívnosti. Vyžaduje aby mali aspoň %{min_followers} sledovateľov
         email: Bude ti odoslaný potvrdzujúci email
         fields: Až štyri položky môžeš mať na svojom profile zobrazené vo forme tabuľky
@@ -22,26 +22,30 @@ sk:
         inbox_url: Skopíruj adresu z hlavnej stránky mostíka, ktorý chceš používať
         irreversible: Vytriedené príspevky zmiznú nenávratne, aj keď triedenie neskôr zrušíš
         locale: Jazyk užívateľského rozhrania, emailových, a nástenkových oboznámení
-        locked: Vyžaduje, aby si manuálne schvaľoval/a následovateľov
+        locked: Vyžaduje sa manuálne schvaľovanie sledujúcich
         password: Zadaj aspoň osem znakov
         phrase: Zhoda sa nájde nezávisle od toho, či je text napísaný, veľkými, alebo malými písmenami, či už v tele, alebo v hlavičke
         scopes: Ktoré API budú povolené aplikácii pre prístup. Ak vyberieš vrcholný stupeň, nemusíš už potom vyberať po jednom.
-        setting_aggregate_reblogs: Neukazuj nové vyzdvihnutia pre príspevky, ktoré už boli len nedávno povýšené (týka sa iba nanovo získaných vyzdvihnutí)
-        setting_default_language: Jazyk tvojích príspevkov môže byť zistený automaticky, ale nieje to vždy presné
-        setting_display_media_default: Skryť médiá označené ako citlivé
-        setting_display_media_hide_all: Vždy ukryť všetky médiá
-        setting_display_media_show_all: Stále ukazuj médiá označené ako citlivé
-        setting_hide_network: Koho následuješ, a kto následuje teba nebude zobrazené na tvojom profile
+        setting_aggregate_reblogs: Nezobrazuj nové vyzdvihnutia pre príspevky, ktoré už boli len nedávno povýšené (týka sa iba nanovo získaných povýšení)
+        setting_default_sensitive: Chúlostivé médiá sú štandardne ukryté, a môžu byť zobrazené kliknutím
+        setting_display_media_default: Ukry médiá označené ako citlivé
+        setting_display_media_hide_all: Vždy ukry všetky médiá
+        setting_display_media_show_all: Stále zobrazuj médiá označené ako citlivé
+        setting_hide_network: Koho následuješ, a kto následuje teba, nebude zobrazené na tvojom profile
         setting_noindex: Ovplyvňuje verejný profil a stránky s príspevkami
-        setting_theme: Ovplyvňuje ako Mastodon vyzerá pri prihlásení z hociakého zariadenia.
+        setting_show_application: Aplikácia, ktorú používaš na písanie príspevkov, bude zobrazená v podrobnom náhľade jednotlivých tvojích príspevkov
         username: Tvoja prezývka bude unikátna pre server %{domain}
         whole_word: Ak je kľúčové slovo, alebo fráza poskladaná iba s písmen a čísel, bude použité iba ak sa zhoduje s celým výrazom
+      featured_tag:
+        name: 'Možno by si chcel/a použiť niektoré z týchto:'
       imports:
-        data: CSV súbor vyexportovaný z inej Mastodon inštancie
+        data: CSV súbor vyexportovaný z iného Mastodon serveru
+      invite_request:
+        text: Toto pomôže s vyhodnocovaním tvojej žiadosti
       sessions:
         otp: 'Napíš sem dvoj-faktorový kód z telefónu, alebo použi jeden z tvojích obnovovacích kódov:'
       user:
-        chosen_languages: Keď je zaškrtnuté, tak iba príspevky vo vybraných jazykoch budú zobrazené vo verejnej osi
+        chosen_languages: Keď je zaškrtnuté, vo verejnej osi budú zobrazené iba príspevky vo vybraných jazykoch
     labels:
       account:
         fields:
@@ -50,18 +54,18 @@ sk:
       account_warning_preset:
         text: Text predlohy
       admin_account_action:
-        send_email_notification: Oznám užívateľovi cez email
+        send_email_notification: Oznam užívateľovi cez email
         text: Špecifické varovanie
         type: Úkon
         types:
           disable: Deaktivuj
           none: Neurob nič
-          silence: Utíšenie
+          silence: Utíš
           suspend: Vylúč a nenávratne vymaž dáta na účte
         warning_preset_id: Použi varovnú predlohu
       defaults:
         autofollow: Pozvi k následovaniu tvojho profilu
-        avatar: Avatar
+        avatar: Maskot
         bot: Toto je automatizovaný bot účet
         chosen_languages: Filtruj jazyky
         confirm_new_password: Znovu tvoje nové heslo, pre potvrdenie
@@ -69,22 +73,23 @@ sk:
         context: Triedenie kontextov
         current_password: Súčasné heslo
         data: Dáta
-        discoverable: Zaraď tento účet do databázy
-        display_name: Meno
+        discoverable: Zaraď tento účet do databázy profilov
+        display_name: Zobrazované meno
         email: Emailová adresa
-        expires_in: Expirovať po
+        expires_in: Expiruj po
         fields: Metadáta profilu
         header: Obrázok v hlavičke
         inbox_url: URL adresa prechodnej schránky
-        irreversible: Zahoď, namiesto skritia
+        irreversible: Zahoď, namiesto ukrytia
         locale: Jazyk rozhrania
         locked: Zamknúť účet
-        max_uses: Maximálne možno použiť
+        max_uses: Najviac možno použiť
         new_password: Nové heslo
         note: O tebe
         otp_attempt: Dvoj-faktorový overovací (2FA) kód
         password: Heslo
         phrase: Kľúčové slovo, alebo fráza
+        setting_advanced_layout: Zapni pokročilé užívateľské rozhranie
         setting_aggregate_reblogs: Zoskupuj vyzdvihnutia v časovej osi
         setting_auto_play_gif: Automaticky prehrávaj animované GIFy
         setting_boost_modal: Zobrazuj potvrdzovacie okno pred povýšením
@@ -94,34 +99,40 @@ sk:
         setting_delete_modal: Zobrazuj potvrdzovacie okno pred vymazaním toot-u
         setting_display_media: Zobrazovanie médií
         setting_display_media_default: Å tandard
-        setting_display_media_hide_all: Skryť všetky
+        setting_display_media_hide_all: Ukry všetky
         setting_display_media_show_all: Ukáž všetky
         setting_expand_spoilers: Stále rozbaľ príspevky označené varovaním o obsahu
-        setting_hide_network: Ukri svoju sieť kontaktov
+        setting_hide_network: Ukry svoju sieť kontaktov
         setting_noindex: Nezaraďuj príspevky do indexu pre vyhľadávče
-        setting_reduce_motion: Redukovať pohyb v animáciách
-        setting_system_font_ui: Použiť základné systémové písmo
+        setting_reduce_motion: Mierni pohyb pri animáciách
+        setting_show_application: Zverejni akú aplikáciu používaš na posielanie príspevkov
+        setting_system_font_ui: Použi základné systémové písmo
         setting_theme: Vzhľad webu
-        setting_unfollow_modal: Zobrazuj potvrdzovacie okno pred skončením sledovania iného užívateľa
+        setting_unfollow_modal: Vyžaduj potvrdenie pred skončením sledovania iného užívateľa
         severity: Závažnosť
         type: Typ importu
         username: Prezývka
-        username_or_email: Prezívka, alebo email
+        username_or_email: Prezývka, alebo email
         whole_word: Celé slovo
+      featured_tag:
+        name: Haštag
       interactions:
-        must_be_follower: Blokuj oboznámenia ohľadom užívateľov, ktorí ťa nesledujú
-        must_be_following: Blokuj oboznámenia ohľadom ľudí ktorých nesleduješ
-        must_be_following_dm: Blokuj súkromné správy od ľudí ktorých nesleduješ
+        must_be_follower: Blokuj oboznámenia od užívateľov, ktorí ma nenásledujú
+        must_be_following: Blokuj oboznámenia od ľudí, ktorých nesledujem
+        must_be_following_dm: Blokuj súkromné správy od ľudí ktorých nesledujem
+      invite_request:
+        text: Prečo sa k nám chceš pridať?
       notification_emails:
-        digest: Posielaj súhrnné emaily
-        favourite: Poslať email ak si niekto obľúbi tvoj príspevok
-        follow: Poslať email, ak ťa niekto začne následovať
-        follow_request: Zaslať email ak ti niekto pošle žiadosť o sledovanie
-        mention: Poslať email ak ťa niekto spomenie v svojom príspevku
-        reblog: Poslať email ak niekto re-tootne tvoj príspevok
-        report: Poslať e-mail ak niekto dodá nové hlásenie
+        digest: Zasielať súhrnné emaily
+        favourite: Zaslať email, ak si niekto obľúbi tvoj príspevok
+        follow: Zaslať email, ak ťa niekto začne následovať
+        follow_request: Zaslať email, ak ti niekto pošle žiadosť o sledovanie
+        mention: Zaslať email, ak ťa niekto spomenie vo svojom príspevku
+        pending_account: Zaslať email, ak treba prehodnotiť nový účet
+        reblog: Zaslať email, ak niekto re-tootne tvoj príspevok
+        report: Zaslať email, ak niekto podá nové nahlásenie
     'no': Nie
+    recommended: Odporúčané
     required:
-      mark: "*"
       text: povinné
     'yes': Áno
diff --git a/config/locales/simple_form.sl.yml b/config/locales/simple_form.sl.yml
index 890cbac418fe4c0b3951f0becca3e3a8d6ccb91f..2e0495551f4a0063b6659c5f0c6d4929671931df 100644
--- a/config/locales/simple_form.sl.yml
+++ b/config/locales/simple_form.sl.yml
@@ -18,13 +18,11 @@ sl:
         password: Uporabite najmanj 8 znakov
         phrase: Se bo ujemal, ne glede na začetnice v tekstu ali opozorilo o vsebini troba
         scopes: Do katerih API-jev bo imel program dostop. Če izberete obseg najvišje ravni, vam ni treba izbrati posameznih.
-        setting_default_language: Jezik vaših trobov je lahko samodejno zaznan, vendar ni vedno pravilen
         setting_display_media_default: Skrij medij, ki je označen kot občutljiv
         setting_display_media_hide_all: Vedno skrij vse medije
         setting_display_media_show_all: Vedno pokaži medij, ki je označen kot občutljiv
         setting_hide_network: Kogar spremljate in kdo vas spremlja ne bo prikazano na vašem profilu
         setting_noindex: Vpliva na vaš javni profil in na strani s stanjem
-        setting_theme: Vpliva na to, kako izgleda Mastodon, ko ste prijavljeni s katero koli napravo.
         username: Vaše uporabniško ime bo edinstveno na %{domain}
         whole_word: Ko je ključna beseda ali fraza samo alfanumerična, se bo uporabljala le, če se bo ujemala s celotno besedo
       imports:
@@ -59,7 +57,6 @@ sl:
         locked: Zaklenjen račun
         max_uses: Največje število uporabnikov
         new_password: Novo geslo
-        note: Bio
         otp_attempt: Dvofaktorska koda
         password: Geslo
         phrase: Ključna beseda ali fraza
@@ -96,9 +93,8 @@ sl:
         follow_request: Pošlji e-pošto, ko vam nekdo želi slediti
         mention: Pošlji e-pošto, ko vas nekdo omeni
         reblog: Pošlji e-pošto, ko nekdo sune vaše stanje
-        report: Pošlji e-pošto, ko je oddano novo poročilo
+        report: Pošlji e-pošto, ko je oddana nova prijava
     'no': Ne
     required:
-      mark: "*"
       text: zahtevano
     'yes': Da
diff --git a/config/locales/simple_form.sq.yml b/config/locales/simple_form.sq.yml
new file mode 100644
index 0000000000000000000000000000000000000000..04ef12c9a79347bf1ba130fa9a5300ec5af8c3d1
--- /dev/null
+++ b/config/locales/simple_form.sq.yml
@@ -0,0 +1,127 @@
+---
+sq:
+  simple_form:
+    hints:
+      account_warning_preset:
+        text: Mund të përdorni sintaksë mesazhesh, të tillë si URL, hashtagë dhe përmendje
+      admin_account_action:
+        send_email_notification: Përdoruesi do të marrë një shpjegim mbi çfarë ndodhi me llogarinë e tij
+        text_html: Opsionale. Mund të përdorni sintaksë mesazhesh. Për të kursyer kohë, mund të <a href="%{path}">shtoni paracaktime sinjalizimesh</a>
+        type_html: Zgjidhni ç’të bëhet me <strong>%{acct}</strong>
+        warning_preset_id: Opsionale. Mundeni sërish të shtoni tekst vetjak në fund të paracaktimit
+      defaults:
+        autofollow: Personat që regjistrohen përmes ftesës do t’ju ndjekin vetvetiu
+        avatar: PNG, GIF ose JPG. Maksimumi %{size}. Do të zvogëlohen në %{dimensions}px
+        bot: Kjo llogari kryesisht bën veprime të automatizuara dhe mund të mos mbikëqyret dot
+        context: Një ose disa kontekste kur duhet të zbatohet filtri
+        digest: I dërguar vetëm pas një periudhe të gjatë pasiviteti dhe vetëm nëse keni marrë ndonjë mesazh personal gjatë mungesës suaj
+        discoverable_html: <a href="%{path}" target="_blank">Drejtoria</a> u lejon njerëzve të gjejnë llogari bazuar në interesat dhe veprimtarinë. Lyp të paktën %{min_followers} ndjekës
+        email: Do t’ju dërgohet një email ripohimi
+        fields: Te profili juaj mund të keni deri në 4 objekte të shfaqur si tabelë
+        header: PNG, GIF ose JPG. E shumta %{size}. Do të ripërmasohet në %{dimensions}px
+        inbox_url: Kopjoni URL-në prej faqes ballore të relesë që doni të përdorni
+        irreversible: Mesazhet e filtruar do të zhduket në mënyrë të pakthyeshme, edhe nëse filtri hiqet më vonë
+        locale: Gjuha e ndërfaqes së përdoruesit, email-eve dhe njoftimeve <em>push</em>
+        locked: Lyp që ju të miratoni dorazi ndjekësit
+        password: Përdorni të paktën 8 shenja
+        phrase: Do të kërkohet përputhje pavarësish se teksti ose sinjalizimi mbi lëndën e një mesazhi është shkruar me të mëdha apo me të vogla
+        scopes: Cilat API do të lejohet të përdorë aplikacioni. Nëse përzgjidhni një shkallë të epërme, nuk ju duhet të përzgjidhni individualet një nga një.
+        setting_aggregate_reblogs: Mos shfaq përforcime të reja për mesazhe që janë përforcuar tani së fundi (prek vetëm përforcime të marra rishtas)
+        setting_display_media_default: Fshih media me shenjën rezervat
+        setting_display_media_hide_all: Fshih përherë krejt mediat
+        setting_display_media_show_all: Mediat me shenjën rezervat shfaqi përherë
+        setting_hide_network: Cilët ndiqni dhe cilët ju ndjekin nuk do të shfaqen në profilin tuaj
+        setting_noindex: Prek faqet e profilit tuaj publik dhe gjendjeve
+        setting_show_application: Aplikacioni që përdorni për mesazhe do të shfaqet te pamja e hollësishme për mesazhet tuaj
+        username: Emri juaj i përdoruesit do të jetë unik në %{domain}
+        whole_word: Kur fjalëkyçi ose fraza është vetëm numerike, do të aplikohet vetëm nëse përputhet me krejt fjalën
+      featured_tag:
+        name: 'Mund të doni të përdorni një nga këto:'
+      imports:
+        data: Kartelë CSV të eksportuar nga një tjetër shërbyes Mastodon
+      sessions:
+        otp: 'Jepni kodin dyfaktorësh të prodhuar nga aplikacioni i telefonit tuaj ose përdorni një nga kodet tuaj të rikthimive:'
+      user:
+        chosen_languages: Në iu vëntë shenjë, te rrjedha kohore publike do të shfaqen vetëm mesazhe në gjjuhët e përzgjedhura
+    labels:
+      account:
+        fields:
+          name: Etiketë
+          value: Lëndë
+      account_warning_preset:
+        text: Tekst i paracaktuar
+      admin_account_action:
+        send_email_notification: Njoftoje përdoruesin me email
+        text: Sinjalizim vetjak
+        type: Veprim
+        types:
+          disable: Çaktivizoje
+          none: Mos bëj gjë
+          silence: Heshtje
+          suspend: Pezulloje dhe fshi në mënyrë të pakthyeshme të dhënat e llogarisë
+        warning_preset_id: Përdor një sinjalizim të paracaktuar
+      defaults:
+        autofollow: Ftesë për ndjekje të llogarisë tuaj
+        bot: Kjo është një llogari robot
+        chosen_languages: Filtro gjuhë
+        confirm_new_password: Ripohoni fjalëkalimin e ri
+        confirm_password: Ripohoni fjalëkalimin
+        context: Filtroni kontekste
+        current_password: Fjalëkalimi i tanishëm
+        data: Të dhëna
+        discoverable: Shfaqe këtë llogari te lista
+        display_name: Emër në ekran
+        email: Adresë email
+        expires_in: Skadon pas
+        fields: Tejtëdhëna profili
+        header: Krye
+        inbox_url: URL e Të marrëve të relesë
+        irreversible: Heqje, në vend se fshehje
+        locale: Gjuhë ndërfaqeje
+        locked: Kyçe llogarinë
+        max_uses: Numër maksimum përdorimesh
+        new_password: Fjalëkalim i ri
+        note: Jetëshkrim
+        otp_attempt: Kod mirëfilltësimi dyfaktorësh
+        password: Fjalëkalim
+        phrase: Fjalëkyç ose frazë
+        setting_aggregate_reblogs: Grupoji përforcimet në rrjedha kohore
+        setting_auto_play_gif: Vetëluaji GIF-et e animuar
+        setting_boost_modal: Shfaq dialog ripohimi përpara përforcimi
+        setting_default_language: Gjuhë postimi
+        setting_default_privacy: Privatësi postim
+        setting_default_sensitive: Mediave vëru përherë shenjë si rezervat
+        setting_delete_modal: Shfaq dialog ripohimi përpara fshirjes së një mesazhi
+        setting_display_media: Shfaqje mediash
+        setting_display_media_default: Parazgjedhje
+        setting_display_media_hide_all: Fshihi krejt
+        setting_display_media_show_all: Shfaqi krejt
+        setting_expand_spoilers: Mesazhet me sinjalizime mbi lëndën, zgjeroji përherë
+        setting_hide_network: Fshiheni rrjetin tuaj
+        setting_noindex: Përfundim i indeksimit nga motor kërkimesh
+        setting_reduce_motion: Zvogëlo lëvizjen në animacione
+        setting_show_application: Tregoje aplikacionin e përdorur për të dërguar mesazhe
+        setting_system_font_ui: Përdor shkronja parazgjedhje të sistemit
+        setting_theme: Temë sajti
+        setting_unfollow_modal: Shfaq dialog ripohimi përpara heqjes së ndjekjes për dikë
+        severity: Rreptësi
+        type: Lloj importimi
+        username: Emër përdoruesi
+        username_or_email: Emër përdoruesi ose Email
+        whole_word: Krejt fjalën
+      interactions:
+        must_be_follower: Blloko njoftime nga jo-ndjekës
+        must_be_following: Blloko njoftime nga persona që nuk i ndiqni
+        must_be_following_dm: Blloko mesazhe të drejtpërdrejt nga persona që nuk i ndiqni
+      notification_emails:
+        digest: Dërgo email-e përmbledhës
+        favourite: Të dërgohet email kur dikush parapëlqen gjendjen tuaj
+        follow: Të dërgohet email kur dikush fillon t’ju ndjekë
+        follow_request: Të dërgohet email kur dikush kërkon t’ju ndjekë
+        mention: Të dërgohet email kur dikush ju përmend
+        reblog: Dërgo email kur dikush përforcon gjendjen time
+        report: Dërgo email kur parashtrohet një raportim i ri
+    'no': Jo
+    required:
+      text: e domosdoshme
+    'yes': Po
diff --git a/config/locales/simple_form.sr-Latn.yml b/config/locales/simple_form.sr-Latn.yml
index eac64988fecac1502ce39ef06d22aaa3de95eec4..66efa3db8dfec5f2a4c318e4d429a3918b55436a 100644
--- a/config/locales/simple_form.sr-Latn.yml
+++ b/config/locales/simple_form.sr-Latn.yml
@@ -8,14 +8,12 @@ sr-Latn:
         header: PNG, GIF ili JPG. Najviše %{size}. Biće smanjena na %{dimensions}px
         locked: Zahteva da pojedinačno odobrite pratioce
         setting_noindex: Utiče na Vaš javni profil i statusne strane
-        setting_theme: Utiče kako će Mastodont izgledati kada ste prijavljeni sa bilo kog uređaja.
       imports:
         data: CSV fajl izvezen sa druge Mastodont instance
       sessions:
         otp: 'Unesite dvofaktorski kod sa Vašeg telefona ili koristite jedan od kodova za oporavak:'
     labels:
       defaults:
-        avatar: Avatar
         confirm_new_password: Potvrdite novu lozinku
         confirm_password: Potvrdite lozinku
         current_password: Trenutna lozinka
@@ -57,6 +55,5 @@ sr-Latn:
         reblog: Šalji e-poštu kada neko podrži Vaš status
     'no': Ne
     required:
-      mark: "*"
       text: obavezno
     'yes': Da
diff --git a/config/locales/simple_form.sr.yml b/config/locales/simple_form.sr.yml
index 7e3c6685e09104123352211eb28620d68b8eeb88..a097be5dd3e2c0f227e21c01e2693fad15054de5 100644
--- a/config/locales/simple_form.sr.yml
+++ b/config/locales/simple_form.sr.yml
@@ -27,13 +27,11 @@ sr:
         phrase: Биће упарена без обзира на велико или мало слово у тексту или упозорења о садржају трубе
         scopes: Којим API-јима ће апликација дозволити приступ. Ако изаберете опсег највишег нивоа, не морате одабрати појединачне.
         setting_aggregate_reblogs: Не показуј нова дељења за трубе које су недавно подељене (утиче само на недавно примљена дељења)
-        setting_default_language: Језик ваших труба може бити аутоматски откривен, али није увек прецизан
         setting_display_media_default: Сакриј медије означене као осетљиве
         setting_display_media_hide_all: Увек сакриј све медије
         setting_display_media_show_all: Увек прикажи медије означене као осетљиве
         setting_hide_network: Кога пратите и ко вас прати неће бити приказано на вашем профилу
         setting_noindex: Утиче на Ваш јавни профил и статусне стране
-        setting_theme: Утиче како ће Мастодонт изгледати када сте пријављени са било ког уређаја.
         username: Ваш надимак ће бити јединствен на %{domain}
         whole_word: Када је кључна реч или фраза искључиво алфанумеричка, биће примењена само ако се подудара са целом речи
       imports:
@@ -122,6 +120,5 @@ sr:
         report: Пошаљи Е-пошту када се поднесе нова пријава
     'no': Не
     required:
-      mark: "*"
       text: обавезно
     'yes': Да
diff --git a/config/locales/simple_form.sv.yml b/config/locales/simple_form.sv.yml
index 8bc82c6093d84d306f012a6b3471973fd47a8715..171714ab081562b5ab25f73fc0c3c02322bfbeb6 100644
--- a/config/locales/simple_form.sv.yml
+++ b/config/locales/simple_form.sv.yml
@@ -2,19 +2,25 @@
 sv:
   simple_form:
     hints:
+      account_warning_preset:
+        text: Du kan använda inläggssyntax som webbadresser, hashtaggar och omnämnanden
+      admin_account_action:
+        send_email_notification: Användaren kommer att få en förklaring av vad som hände med sitt konto
+        type_html: Välj vad du vill göra med <strong>%{acct}</strong>
       defaults:
         autofollow: Användarkonton som skapas genom din inbjudan kommer automatiskt följa dig
-        avatar: Högst %{size}. Kommer att skalas ner till %{dimensions}px
+        avatar: PNG, GIF eller JPG. Högst %{size}. Kommer att skalas ner till %{dimensions}px
         bot: Detta konto utför huvudsakligen automatiserade åtgärder och kanske inte övervakas
         digest: Skickas endast efter en lång period av inaktivitet och endast om du har fått några personliga meddelanden i din frånvaro
+        email: Ett konfirmationsmeddelande kommer att skickas till dig via epost
         fields: Du kan ha upp till 4 objekt visade som en tabell på din profil
-        header: NG, GIF eller JPG. Högst %{size}. Kommer nedskalas till %{dimensions}px
-        locale: Användargränssnittets språk, e-post och push aviseringar
+        header: PNG, GIF eller JPG. Högst %{size}. Kommer att skalas ner till %{dimensions}px
+        irreversible: Filtrerade inlägg kommer att försvinna oåterkalleligt, även om filter tas bort senare
+        locale: Användargränssnittets språk, e-post och push-aviseringar
         locked: Kräver att du manuellt godkänner följare
-        setting_default_language: Språket av dina inlägg kan upptäckas automatiskt, men det är inte alltid rätt
+        password: Använd minst 8 tecken
         setting_hide_network: Vem du följer och vilka som följer dig kommer inte att visas på din profilsida
         setting_noindex: PÃ¥verkar din offentliga profil och statussidor
-        setting_theme: Påverkar hur Mastodon ser ut oavsett från vilken enhet du är inloggad.
       imports:
         data: CSV-fil som exporteras från en annan Mastodon-instans
       sessions:
@@ -28,13 +34,11 @@ sv:
           value: Innehåll
       defaults:
         autofollow: Bjud in till att följa ditt konto
-        avatar: Avatar
         bot: Detta är ett botkonto
         chosen_languages: Filtrera språk
         confirm_new_password: Bekräfta nytt lösenord
         confirm_password: Bekräfta lösenord
         current_password: Nuvarande lösenord
-        data: Data
         display_name: Visningsnamn
         email: E-postadress
         expires_in: Förfaller efter
@@ -76,6 +80,5 @@ sv:
         reblog: Skicka e-post när någon knuffar din status
     'no': Nej
     required:
-      mark: "*"
       text: obligatorisk
     'yes': Ja
diff --git a/config/locales/simple_form.ta.yml b/config/locales/simple_form.ta.yml
new file mode 100644
index 0000000000000000000000000000000000000000..4320953ce2ab23ded9cc319b3002dfc1bc13903a
--- /dev/null
+++ b/config/locales/simple_form.ta.yml
@@ -0,0 +1 @@
+ta:
diff --git a/config/locales/simple_form.te.yml b/config/locales/simple_form.te.yml
new file mode 100644
index 0000000000000000000000000000000000000000..34c54f18f624c6d89026a04bd92ebc0df9c63e48
--- /dev/null
+++ b/config/locales/simple_form.te.yml
@@ -0,0 +1 @@
+te:
diff --git a/config/locales/simple_form.th.yml b/config/locales/simple_form.th.yml
index a8611c2f77a41a8a427e6974f105a65d04c50c17..9d6b75ed0d7cf3cde54e8125b5cafa657263f0bb 100644
--- a/config/locales/simple_form.th.yml
+++ b/config/locales/simple_form.th.yml
@@ -2,48 +2,138 @@
 th:
   simple_form:
     hints:
+      account_warning_preset:
+        text: คุณสามารถใช้ไวยากรณ์โพสต์ เช่น URL, แฮชแท็ก และการกล่าวถึง
+      admin_account_action:
+        send_email_notification: ผู้ใช้จะได้รับคำอธิบายว่าเกิดอะไรขึ้นกับบัญชีของเขา
+        text_html: ตัวเลือกเพิ่มเติม คุณสามารถใช้ไวยากรณ์โพสต์ คุณสามารถ <a href="%{path}">เพิ่มคำเตือนที่ตั้งไว้ล่วงหน้า</a> เพื่อประหยัดเวลา
+        type_html: เลือกสิ่งที่จะทำกับ <strong>%{acct}</strong>
+        warning_preset_id: ตัวเลือกเพิ่มเติม คุณยังคงสามารถเพิ่มข้อความที่กำหนดเองที่จุดสิ้นสุดของค่าที่ตั้งไว้ล่วงหน้า
       defaults:
-        avatar: PNG, GIF or JPG. At most %{size}. Will be downscaled to %{dimensions}px
-        header: PNG, GIF or JPG. At most %{size}. Will be downscaled to %{dimensions}px
-        locked: Requires you to manually approve followers and defaults post privacy to followers-only
+        autofollow: ผู้คนที่ลงทะเบียนผ่านคำเชิญจะติดตามคุณโดยอัตโนมัติ
+        avatar: PNG, GIF หรือ JPG สูงสุด %{size} จะถูกย่อขนาดเป็น %{dimensions}px
+        bot: บัญชีนี้ทำการกระทำอัตโนมัติเป็นหลักและอาจไม่ได้รับการสังเกตการณ์
+        context: บริบทจำนวนหนึ่งหรือมากกว่าที่ตัวกรองควรใช้
+        digest: ส่งเฉพาะหลังจากไม่มีการใช้งานเป็นเวลานานและในกรณีที่คุณได้รับข้อความส่วนบุคคลใด ๆ เมื่อคุณไม่อยู่เท่านั้น
+        discoverable_html: <a href="%{path}" target="_blank">ไดเรกทอรี</a> ช่วยให้ผู้คนค้นหาบัญชีตามความสนใจและกิจกรรม ต้องการอย่างน้อย %{min_followers} ผู้ติดตาม
+        email: คุณจะได้รับอีเมลยืนยัน
+        fields: คุณสามารถมีได้มากถึง 4 รายการแสดงเป็นตารางในโปรไฟล์ของคุณ
+        header: PNG, GIF หรือ JPG สูงสุด %{size} จะถูกย่อขนาดเป็น %{dimensions}px
+        inbox_url: คัดลอก URL จากหน้าแรกของรีเลย์ที่คุณต้องการใช้
+        irreversible: โพสต์ที่กรองจะหายไปอย่างถาวร แม้ว่าจะเอาตัวกรองออกในภายหลัง
+        locale: ภาษาของส่วนติดต่อผู้ใช้, อีเมล และการแจ้งเตือนแบบผลัก
+        locked: คุณต้องอนุมัติผู้ติดตามด้วยตนเอง
+        password: ใช้อย่างน้อย 8 ตัวอักษร
+        phrase: จะถูกจับคู่โดยไม่คำนึงถึงตัวอักษรใหญ่เล็กในข้อความหรือคำเตือนเนื้อหาของโพสต์
+        scopes: API ใดที่แอปพลิเคชันจะได้รับอนุญาตให้เข้าถึง หากคุณเลือกขอบเขตระดับบนสุด คุณไม่จำเป็นต้องเลือกแต่ละขอบเขต
+        setting_aggregate_reblogs: ไม่แสดงการดันใหม่สำหรับโพสต์ที่เพิ่งดัน (มีผลต่อการดันที่ได้รับใหม่เท่านั้น)
+        setting_default_sensitive: ซ่อนสื่อที่ละเอียดอ่อนโดยค่าเริ่มต้นและสามารถเปิดเผยได้ด้วยการคลิก
+        setting_display_media_default: ซ่อนสื่อที่ถูกทำเครื่องหมายว่าละเอียดอ่อน
+        setting_display_media_hide_all: ซ่อนสื่อทั้งหมดเสมอ
+        setting_display_media_show_all: แสดงสื่อที่ถูกทำเครื่องหมายว่าละเอียดอ่อนเสมอ
+        setting_hide_network: จะไม่แสดงผู้ที่คุณติดตามและผู้ที่ติดตามคุณในโปรไฟล์ของคุณ
+        setting_noindex: มีผลต่อโปรไฟล์สาธารณะและหน้าสถานะของคุณ
+        setting_show_application: จะแสดงแอปพลิเคชันที่คุณใช้เพื่อโพสต์ในมุมมองโดยละเอียดของโพสต์ของคุณ
+        username: ชื่อผู้ใช้ของคุณจะไม่ซ้ำกันบน %{domain}
+        whole_word: เมื่อคำสำคัญหรือวลีมีแค่ตัวอักษรและตัวเลข จะถูกใช้หากตรงกันทั้งคำเท่านั้น
+      featured_tag:
+        name: 'คุณอาจต้องการใช้หนึ่งในนี้:'
       imports:
-        data: CSV file exported from another Mastodon instance
+        data: ไฟล์ CSV ที่ส่งออกจากเซิร์ฟเวอร์ Mastodon อื่น
+      invite_request:
+        text: นี่จะช่วยให้เราตรวจทานใบสมัครของคุณ
       sessions:
-        otp: Enter the Two-factor code from your phone or use one of your recovery codes.
+        otp: 'ป้อนรหัสสองปัจจัยที่สร้างโดยแอปในโทรศัพท์ของคุณหรือใช้หนึ่งในรหัสกู้คืนของคุณ:'
+      user:
+        chosen_languages: เมื่อกาเครื่องหมาย จะแสดงเฉพาะโพสต์ในภาษาที่เลือกในเส้นเวลาสาธารณะ
     labels:
+      account:
+        fields:
+          name: ป้ายชื่อ
+          value: เนื้อหา
+      account_warning_preset:
+        text: ข้อความที่ตั้งไว้ล่วงหน้า
+      admin_account_action:
+        send_email_notification: แจ้งเตือนผู้ใช้ทางอีเมล
+        text: คำเตือนที่กำหนดเอง
+        type: การกระทำ
+        types:
+          disable: ปิดใช้งาน
+          none: ไม่ทำสิ่งใด
+          silence: เงียบ
+          suspend: ระงับและลบข้อมูลบัญชีอย่างถาวร
+        warning_preset_id: ใช้คำเตือนที่ตั้งไว้ล่วงหน้า
       defaults:
-        avatar: Avatar
-        confirm_new_password: Confirm new password
-        confirm_password: Confirm password
-        current_password: Current password
+        autofollow: เชิญให้ติดตามบัญชีของคุณ
+        avatar: ภาพประจำตัว
+        bot: นี่คือบัญชีบอต
+        chosen_languages: กรองภาษา
+        confirm_new_password: ยืนยันรหัสผ่านใหม่
+        confirm_password: ยืนยันรหัสผ่าน
+        context: บริบทตัวกรอง
+        current_password: รหัสผ่านปัจจุบัน
         data: ข้อมูล
-        display_name: Display name
-        email: E-mail address
-        header: Header
-        locale: ภาษา
-        locked: Lock account
-        new_password: New password
-        note: Bio
-        otp_attempt: Two-factor code
-        password: พาร์สเวิร์ด
-        setting_auto_play_gif: Auto-play animated GIFs
-        setting_boost_modal: Show confirmation dialog before boosting
-        setting_default_privacy: Post privacy
-        severity: Severity
-        type: Import type
-        username: Username
+        discoverable: แสดงรายการบัญชีนี้ในไดเรกทอรี
+        display_name: ชื่อที่แสดง
+        email: ที่อยู่อีเมล
+        expires_in: หมดอายุหลังจาก
+        fields: ข้อมูลเมตาโปรไฟล์
+        header: ส่วนหัว
+        inbox_url: URL กล่องขาเข้าแบบรีเลย์
+        irreversible: ลบแทนที่จะซ่อน
+        locale: ภาษาส่วนติดต่อ
+        locked: ล็อคบัญชี
+        max_uses: จำนวนการใช้งานสูงสุด
+        new_password: รหัสผ่านใหม่
+        note: ชีวประวัติ
+        otp_attempt: รหัสสองปัจจัย
+        password: รหัสผ่าน
+        phrase: คำสำคัญหรือวลี
+        setting_advanced_layout: เปิดใช้งานส่วนติดต่อเว็บขั้นสูง
+        setting_aggregate_reblogs: จัดกลุ่มการดันในเส้นเวลา
+        setting_auto_play_gif: เล่น GIF แบบเคลื่อนไหวโดยอัตโนมัติ
+        setting_boost_modal: แสดงกล่องโต้ตอบการยืนยันก่อนดัน
+        setting_default_language: ภาษาที่โพสต์
+        setting_default_privacy: ความเป็นส่วนตัวของโพสต์
+        setting_default_sensitive: ทำเครื่องหมายสื่อว่าละเอียดอ่อนเสมอ
+        setting_delete_modal: แสดงกล่องโต้ตอบการยืนยันก่อนลบโพสต์
+        setting_display_media: การแสดงสื่อ
+        setting_display_media_default: ค่าเริ่มต้น
+        setting_display_media_hide_all: ซ่อนทั้งหมด
+        setting_display_media_show_all: แสดงทั้งหมด
+        setting_expand_spoilers: ขยายโพสต์ที่ทำเครื่องหมายด้วยคำเตือนเนื้อหาเสมอ
+        setting_hide_network: ซ่อนเครือข่ายของคุณ
+        setting_noindex: เลือกไม่รับการทำดัชนีโดยเครื่องมือค้นหา
+        setting_reduce_motion: ลดการเคลื่อนไหวในภาพเคลื่อนไหว
+        setting_show_application: เปิดเผยแอปพลิเคชันที่ใช้ในการส่งโพสต์
+        setting_system_font_ui: ใช้แบบอักษรเริ่มต้นของระบบ
+        setting_theme: ชุดรูปแบบไซต์
+        setting_unfollow_modal: แสดงกล่องโต้ตอบการยืนยันก่อนเลิกติดตามใครสักคน
+        severity: ความรุนแรง
+        type: ชนิดการนำเข้า
+        username: ชื่อผู้ใช้
+        username_or_email: ชื่อผู้ใช้หรืออีเมล
+        whole_word: ทั้งคำ
+      featured_tag:
+        name: แฮชแท็ก
       interactions:
-        must_be_follower: Block notifications from non-followers
-        must_be_following: Block notifications from people you don't follow
+        must_be_follower: ปิดกั้นการแจ้งเตือนจากที่ไม่ใช่ผู้ติดตาม
+        must_be_following: ปิดกั้นการแจ้งเตือนจากผู้คนที่คุณไม่ได้ติดตาม
+        must_be_following_dm: ปิดกั้นข้อความโดยตรงจากผู้คนที่คุณไม่ได้ติดตาม
+      invite_request:
+        text: ทำไมคุณจึงต้องการเข้าร่วม?
       notification_emails:
-        digest: Send digest e-mails
-        favourite: Send e-mail when someone favourites your status
-        follow: Send e-mail when someone follows you
-        follow_request: Send e-mail when someone requests to follow you
-        mention: Send e-mail when someone mentions you
-        reblog: Send e-mail when someone boosts your status
+        digest: ส่งอีเมลสรุป
+        favourite: ส่งอีเมลเมื่อใครสักคนชื่นชอบสถานะของคุณ
+        follow: ส่งอีเมลเมื่อใครสักคนติดตามคุณ
+        follow_request: ส่งอีเมลเมื่อใครสักคนขอติดตามคุณ
+        mention: ส่งอีเมลเมื่อใครสักคนกล่าวถึงคุณ
+        pending_account: ส่งอีเมลเมื่อบัญชีใหม่ต้องการการตรวจทาน
+        reblog: ส่งอีเมลเมื่อใครสักคนดันสถานะของคุณ
+        report: ส่งอีเมลเมื่อมีการส่งรายงานใหม่
     'no': ไม่
+    recommended: แนะนำ
     required:
       mark: "*"
-      text: required
+      text: ต้องระบุ
     'yes': ใช่
diff --git a/config/locales/simple_form.tr.yml b/config/locales/simple_form.tr.yml
index d0b50609b0dfa7625a6f32af1b5cd66405d33280..68b4c24c974fc753ca23db3900c645adcced9daa 100644
--- a/config/locales/simple_form.tr.yml
+++ b/config/locales/simple_form.tr.yml
@@ -2,7 +2,11 @@
 tr:
   simple_form:
     hints:
+      admin_account_action:
+        send_email_notification: Kullanıcı, hesabına ne olduğu hakkında bir bildirim alacak
+        warning_preset_id: İsteğe bağlı. Hazır ayarın sonuna hala özel metin ekleyebilirsiniz
       defaults:
+        autofollow: Davetiyeyle kaydolan kiÅŸiler sizi otomatik olarak takip eder
         avatar: En fazla %{size} olacak şekilde PNG, GIF veya JPG formatında yükleyiniz. %{dimensions}px büyüklüğüne indirgenecektir
         header: En fazla %{size} olacak şekilde PNG, GIF veya JPG formatında yükleyiniz. %{dimensions}px büyüklüğüne indirgenecektir.
         locked: Takipçilerinizi manuel olarak kabul etmenizi ve gönderilerinizi varsayılan olarak sadece takipçilerinizin göreceği şekilde paylaşmanızı sağlar.
@@ -44,6 +48,5 @@ tr:
         reblog: Biri durumumu paylaştığında, bana e-posta gönder
     'no': Hayır
     required:
-      mark: "*"
       text: gerekli
     'yes': Evet
diff --git a/config/locales/simple_form.uk.yml b/config/locales/simple_form.uk.yml
index 05d57509e0bb179986e95529b09090e5e08bc27c..35b20d8a98a6444d42222afad648f998806f0d50 100644
--- a/config/locales/simple_form.uk.yml
+++ b/config/locales/simple_form.uk.yml
@@ -45,6 +45,5 @@ uk:
         reblog: Надсилати листа, коли хтось передмухує Ваш статус
     'no': Ні
     required:
-      mark: "*"
       text: обов'язкове
     'yes': Так
diff --git a/config/locales/simple_form.zh-CN.yml b/config/locales/simple_form.zh-CN.yml
index cfa6840a6a0d22601153debac327375662def064..b781deb32b154664df3213152e04e72b24b0474a 100644
--- a/config/locales/simple_form.zh-CN.yml
+++ b/config/locales/simple_form.zh-CN.yml
@@ -2,21 +2,46 @@
 zh-CN:
   simple_form:
     hints:
+      account_warning_preset:
+        text: 你可以使用嘟文格式,在嘟文中加入 URL、话题标签和提及“@”
+      admin_account_action:
+        send_email_notification: 用户将收到对其帐号上发生的事的解释
+        text_html: 可选。你可以使用嘟文格式。你可以<a href="%{path}">预置警告</a>以节省时间
+        type_html: 用<strong>%{acct}</strong>选择做什么
+        warning_preset_id: 可选。你可以在预置文本末尾添加自定义文本
       defaults:
         autofollow: 通过邀请链接注册的用户将会自动关注你
         avatar: 文件大小限制 %{size},只支持 PNG、GIF 或 JPG 格式。图片分辨率将会压缩至 %{dimensions}px
         bot: 来自这个帐户的绝大多数操作都是自动进行的,并且可能无人监控
+        context: 过滤器的应用场景
         digest: 仅在你长时间未登录,且收到了私信时发送
+        discoverable_html: <a href="%{path}" target="_blank">目录</a> 让大家能根据兴趣和活动寻找用户。需要至少 %{min_followers} 位关注者
+        email: 我们会向你发送一封确认邮件
         fields: 这将会在个人资料页上以表格的形式展示,最多 4 个项目
         header: 文件大小限制 %{size},只支持 PNG、GIF 或 JPG 格式。图片分辨率将会压缩至 %{dimensions}px
+        inbox_url: 从你想要使用的中继的主页上复制 URL
+        irreversible: 已过滤的嘟文会不可逆转地消失,即便移除过滤器之后也一样
         locale: 用户界面、电子邮件和推送通知中使用的语言
         locked: 你需要手动审核所有关注请求
-        setting_default_language: 嘟文语言自动检测的结果有可能不准确(此设置仅影响你的嘟文)
+        password: 至少需要8个字符
+        phrase: 匹配将无视大小写和嘟文的内容警告
+        scopes: 哪些 API 被允许使用。如果你选中了更高一级的范围,就不能单个选中了。
+        setting_aggregate_reblogs: 请不要显示最近已经被转嘟过的转嘟(只会影响新收到的转嘟)
+        setting_default_sensitive: 敏感内容默认隐藏,并在点击后显示
+        setting_display_media_default: 隐藏被标记为敏感内容的媒体
+        setting_display_media_hide_all: 总是隐藏所有媒体
+        setting_display_media_show_all: 总是显示被标记为敏感内容的媒体
         setting_hide_network: 你关注的人和关注你的人将不会在你的个人资料页上展示
         setting_noindex: 此设置会影响到你的公开个人资料以及嘟文页面
-        setting_theme: 此设置会影响到所有已登录设备上 Mastodon 的显示样式
+        setting_show_application: 你用来发表嘟文的应用程序将会在你嘟文的详细内容中显示
+        username: 你的用户名在 %{domain} 上是独特的
+        whole_word: 如果关键词只包含字母和数字,就只会在整个词被匹配时才会套用
+      featured_tag:
+        name: 你可能想要使用以下之一:
       imports:
-        data: 请上传从其他 Mastodon 实例导出的 CSV 文件
+        data: 从其他 Mastodon 服务器导出的 CSV 文件
+      invite_request:
+        text: 这会有助于我们处理你的申请
       sessions:
         otp: 输入你手机应用上生成的双重认证码,或者任意一个恢复代码:
       user:
@@ -26,6 +51,18 @@ zh-CN:
         fields:
           name: 标签
           value: 内容
+      account_warning_preset:
+        text: 预置文本
+      admin_account_action:
+        send_email_notification: 通过邮件提醒此用户
+        text: 内容警告
+        type: 动作
+        types:
+          disable: 禁用
+          none: 忽略
+          silence: 静音
+          suspend: 停用并永久删除账户数据
+        warning_preset_id: 使用预置警告
       defaults:
         autofollow: 让被邀请人关注你的帐户
         avatar: 头像
@@ -33,13 +70,17 @@ zh-CN:
         chosen_languages: 语言过滤
         confirm_new_password: 确认新密码
         confirm_password: 确认密码
+        context: 过滤器场景
         current_password: 当前密码
         data: 数据文件
+        discoverable: 在本站用户资料目录中列出此账户
         display_name: 昵称
         email: 电子邮件地址
         expires_in: 失效时间
         fields: 个人资料附加信息
         header: 个人资料页横幅图片
+        inbox_url: 中继收件箱的 URL
+        irreversible: 放弃而非隐藏
         locale: 界面语言
         locked: 保护你的帐户(锁嘟)
         max_uses: 最大使用次数
@@ -47,15 +88,24 @@ zh-CN:
         note: 简介
         otp_attempt: 双重认证代码
         password: 密码
+        phrase: 关键词
+        setting_advanced_layout: 启用高级 web 界面
+        setting_aggregate_reblogs: 在时间轴中合并转嘟
         setting_auto_play_gif: 自动播放 GIF 动画
         setting_boost_modal: 在转嘟前询问我
         setting_default_language: 发布语言
         setting_default_privacy: 嘟文默认可见范围
         setting_default_sensitive: 总是将我发送的媒体文件标记为敏感内容
         setting_delete_modal: 在删除嘟文前询问我
+        setting_display_media: 媒体展示
+        setting_display_media_default: 默认
+        setting_display_media_hide_all: 隐藏全部
+        setting_display_media_show_all: 显示全部
+        setting_expand_spoilers: 始终展开具有内容警告的嘟文
         setting_hide_network: 隐藏你的社交网络
         setting_noindex: 禁止搜索引擎建立索引
         setting_reduce_motion: 降低过渡动画效果
+        setting_show_application: 展示你用来发嘟的应用
         setting_system_font_ui: 使用系统默认字体
         setting_theme: 站点主题
         setting_unfollow_modal: 在取消关注前询问我
@@ -63,19 +113,26 @@ zh-CN:
         type: 导入数据类型
         username: 用户名
         username_or_email: 用户名或电子邮件地址
+        whole_word: 整个词条
+      featured_tag:
+        name: 话题标签
       interactions:
         must_be_follower: 屏蔽来自未关注我的用户的通知
         must_be_following: 屏蔽来自我未关注的用户的通知
         must_be_following_dm: 屏蔽来自我未关注的用户的私信
+      invite_request:
+        text: 你为什么想要加入?
       notification_emails:
         digest: 发送摘要邮件
         favourite: 当有用户收藏了我的嘟文时,发送电子邮件提醒我
         follow: 当有用户关注我时,发送电子邮件提醒我
         follow_request: 当有用户向我发送关注请求时,发送电子邮件提醒我
         mention: 当有用户在嘟文中提及我时,发送电子邮件提醒我
+        pending_account: 在有账户需要审核时,发送电子邮件提醒我
         reblog: 当有用户转嘟了我的嘟文时,发送电子邮件提醒我
+        report: 在提交新举报时,发送电子邮件提醒我
     'no': 否
+    recommended: 推荐
     required:
-      mark: "*"
       text: å¿…å¡«
     'yes': 是
diff --git a/config/locales/simple_form.zh-HK.yml b/config/locales/simple_form.zh-HK.yml
index e28f935c2cd96cbf247003792550f3dd4e1b2209..2cb2d75b223cf2840e510f97fe94e9bc379b01da 100644
--- a/config/locales/simple_form.zh-HK.yml
+++ b/config/locales/simple_form.zh-HK.yml
@@ -11,10 +11,8 @@ zh-HK:
         header: 支援 PNG, GIF 或 JPG 圖片,檔案最大為 %{size},會縮裁成 %{dimensions}px
         locale: 使用者介面、電郵和通知的語言
         locked: 你必須人手核准每個用戶對你的關注請求,而你的文章私隱會被預設為「只有關注你的人能看」
-        setting_default_language: 你文章的語言會被自動偵測,但不一定完全準確
         setting_hide_network: 你關注的人和關注你的人將不會在你的個人資料頁上顯示
         setting_noindex: 此設定會影響到你的公開個人資料以及文章頁面
-        setting_theme: 此設置會影響到你從任意設備登入時 Mastodon 的顯示樣式。
       imports:
         data: 自其他服務站匯出的 CSV 檔案
       sessions:
@@ -76,6 +74,5 @@ zh-HK:
         reblog: 當有用戶轉推你的文章時,發電郵通知
     'no': 否
     required:
-      mark: "*"
       text: 必須填寫
     'yes': 是
diff --git a/config/locales/simple_form.zh-TW.yml b/config/locales/simple_form.zh-TW.yml
index 3747fbb983f59b0b5e65253d490996608543987f..4da117b61a2ba3baad683cd98dbe452cc404b208 100644
--- a/config/locales/simple_form.zh-TW.yml
+++ b/config/locales/simple_form.zh-TW.yml
@@ -2,92 +2,129 @@
 zh-TW:
   simple_form:
     hints:
+      account_warning_preset:
+        text: 您可使用嘟文語法,例如網址、「#」標籤和提及功能
+      admin_account_action:
+        send_email_notification: 使用者將收到帳戶發生之事情的解釋
+        text_html: 選用。您能使用嘟文語法。您可 <a href="%{path}">新增警告預設</a> 來節省時間
+        type_html: 設定要使用 <strong>%{acct}</strong> 做的事
+        warning_preset_id: 選用。您仍可在預設的結尾新增自訂文字
       defaults:
-        autofollow: 通過邀請網址註冊的使用者將會自動關注你
-        avatar: 支援 PNG, GIF 或 JPG 圖片,檔案最大為 %{size},會縮裁成 %{dimensions}px
-        bot: 這個帳號由程式進行自動式操作
+        autofollow: 通過邀請網址註冊的使用者將自動關注你
+        avatar: 支援 PNG, GIF 或 JPG 圖片,檔案最大為 %{size},會等比例縮減成 %{dimensions} 像素
+        bot: 此帳戶主要執行自動操作且可能未被監控
         context: 應該套用過濾器的一項或多項內容
-        digest: 僅在你長時間未登入,並且收到了私訊時發送
-        fields: 個人資訊頁至多可顯示 4 個項目
-        header: 支援 PNG, GIF 或 JPG 圖片,檔案最大為 %{size},會縮裁成 %{dimensions}px
-        inbox_url: 從您想要使用的中繼首頁複製 URL
-        irreversible: 已過濾的嘟文將會不可逆的消失,即便過濾器之後也一樣
-        locale: 使用者介面、 E-mail 與通知的語言
-        locked: 你必須手動核准每個使用者對你的關注請求,而你的貼文隱私將會被設定為「只有關注你的人能看」
+        digest: 僅在你長時間未登入且在未登入期間收到私訊時傳送
+        discoverable_html: <a href="%{path}" target="_blank">目錄</a> 讓使用者們能基於興趣與活動尋找帳戶。需要至少 %{min_followers} 位關注者
+        email: 您將收到一封確認電子郵件
+        fields: 您可在個人資料上有至多 4 個以表格形式顯示的項目
+        header: 支援 PNG, GIF 或 JPG 圖片,檔案最大為 %{size},會按比例縮小成 %{dimensions} 像素
+        inbox_url: 從您想要使用的中繼首頁複製網址
+        irreversible: 已過濾的嘟文將會不可逆的消失,即便過濾器移除之後也一樣
+        locale: 使用者介面、電子信件和推送通知的語言
+        locked: 需要您手動核准關注請求
+        password: 使用至少 8 個字元
         phrase: 無論是嘟文的本文或是內容警告都會被過濾
-        scopes: 應用程式將會被允許存取哪些 API。若您選取了最高階的範圍,您就不需要再選取單獨的了。
-        setting_default_language: 你嘟文的語言會被自動偵測,但不一定完全準確
+        scopes: 允許讓應用程式存取的 API。 若您選擇最高階範圍,則無須選擇個別項目。
+        setting_aggregate_reblogs: 請勿顯示最近已被轉嘟之嘟文的最新轉嘟(只影響最新收到的嘟文)
+        setting_display_media_default: 隱藏標為敏感的媒體
+        setting_display_media_hide_all: 總是隱藏所有媒體
+        setting_display_media_show_all: 總是顯示標為敏感的媒體
         setting_hide_network: 你關注的人與關注你的人將不會在你的個人資料頁上顯示
-        setting_noindex: 此設定會影響到你的公開個人資料與嘟文頁面
-        setting_theme: 此設定會影響到你從任意設備登入 Mastodon 時的顯示樣式。
-        whole_word: 如果關鍵字或詞組僅有字母與數字,它將只會在符合整個單字的時候才會套用
+        setting_noindex: 會影響您的公開個人資料與嘟文頁面
+        setting_show_application: 您用來發嘟文的應用程式將會在您嘟文的詳細檢視顯示
+        username: 您的使用者名稱將在 %{domain} 是獨一無二的
+        whole_word: 如果關鍵字或詞組僅有字母與數字,則其將只在符合整個單字的時候才會套用
+      featured_tag:
+        name: 您可能想使用其中一個:
       imports:
-        data: 自其他站點匯出的 CSV 檔案
+        data: 從其他 Mastodon 伺服器匯出的 CSV 檔案
       sessions:
-        otp: 輸入你手機上產生的兩階段認證碼,或著任意一個備用驗證碼:
+        otp: 請輸入產生自您手機 App 的兩步驟驗證碼,或輸入其中一個復原代碼:
       user:
-        chosen_languages: 只有被選擇的語言會在公開時間軸內顯示
+        chosen_languages: 當核取時,只有選取語言的嘟文會在公開時間軸中顯示
     labels:
       account:
         fields:
           name: 標籤
           value: 內容
+      account_warning_preset:
+        text: 預設文字
+      admin_account_action:
+        send_email_notification: 透過電子信件通知使用者
+        text: 自訂警告
+        type: 動作
+        types:
+          disable: 停用
+          none: 什麼也不做
+          silence: 安靜
+          suspend: 停權並不可逆的刪除帳戶資料
+        warning_preset_id: 使用警告預設
       defaults:
         autofollow: 邀請別人關注你的帳戶
-        avatar: 頭像
-        bot: 這個帳號是機器人
-        chosen_languages: 語言篩選
+        avatar: 大頭貼
+        bot: 此帳號是台機器人
+        chosen_languages: 過濾語言
         confirm_new_password: 確認新密碼
         confirm_password: 確認密碼
-        context: 過濾範圍
+        context: 過濾情境
         current_password: 目前密碼
         data: 資料
+        discoverable: 在目錄列出此帳戶
         display_name: 顯示名稱
-        email: E-mail
+        email: 電子信箱位址
         expires_in: 失效時間
-        fields: 資料
-        header: 個人頁面圖片
+        fields: 個人資料中繼資料
+        header: 頁面頂端
         inbox_url: 中繼收件匣的 URL
         irreversible: 放棄而非隱藏
         locale: 介面語言
-        locked: 將帳號轉為「私密」
+        locked: 鎖定帳號
         max_uses: 最大使用次數
         new_password: 新密碼
         note: 簡介
-        otp_attempt: 兩階段認證碼
+        otp_attempt: 兩步驟驗證碼
         password: 密碼
         phrase: 關鍵字或片語
-        setting_auto_play_gif: 自動播放 GIF
+        setting_aggregate_reblogs: 時間軸中的群組轉嘟
+        setting_auto_play_gif: 自動播放 GIF 動畫
         setting_boost_modal: 在轉嘟前先詢問我
         setting_default_language: 嘟文語言
-        setting_default_privacy: 嘟文預設為
+        setting_default_privacy: 嘟文可見範圍
         setting_default_sensitive: 總是將媒體標記為敏感內容
         setting_delete_modal: 刪除嘟文前先詢問我
-        setting_hide_network: 隱藏你的社交網路
-        setting_noindex: 阻止搜尋引擎收錄
-        setting_reduce_motion: 減低動畫效果
+        setting_display_media: 媒體顯示
+        setting_display_media_default: 預設
+        setting_display_media_hide_all: 全部隱藏
+        setting_display_media_show_all: 全部顯示
+        setting_expand_spoilers: 永遠展開標有內容警告的嘟文
+        setting_hide_network: 隱藏您的社交網路
+        setting_noindex: 阻止搜尋引擎建立索引
+        setting_reduce_motion: 減少過渡動畫效果
+        setting_show_application: 顯示用來傳送嘟文的應用程式
         setting_system_font_ui: 使用系統預設字型
-        setting_theme: 主題外觀
-        setting_unfollow_modal: 取消關注前先詢問我
-        severity: 等級
-        type: 匯入資料類型
+        setting_theme: 站點主題
+        setting_unfollow_modal: 取消關注某人前先詢問我
+        severity: 優先級
+        type: 匯入類型
         username: 使用者名稱
-        username_or_email: 使用者名稱或 E-mail
-        whole_word: 整個詞
+        username_or_email: 使用者名稱或電子信箱位址
+        whole_word: 整個詞彙
+      featured_tag:
+        name: "「#」標籤"
       interactions:
-        must_be_follower: 隱藏沒有關注你的使用者通知
-        must_be_following: 隱藏你沒關注的使用者通知
-        must_be_following_dm: 隱藏你沒關注的使用者私訊
+        must_be_follower: 封鎖非關注者的通知
+        must_be_following: 封鎖您未關注之使用者的通知
+        must_be_following_dm: 封鎖您未關注之使用者的私訊
       notification_emails:
-        digest: 定期發送摘要郵件
-        favourite: 當有使用者喜歡你的嘟文時,發送 E-mail 通知
-        follow: 當有使用者關注你時,發送 E-mail 通知
-        follow_request: 當有使用者要求關注你時,發送 E-mail 通知
-        mention: 當有使用者在嘟文提及你時,發送 E-mail 通知
-        reblog: 都有使用者轉嘟你的嘟文時,發送 E-mail 通知
-        report: 當遞交新報告時傳送電子郵件
+        digest: 傳送摘要信件
+        favourite: 當有使用者喜歡你的嘟文時,傳送電子信件通知
+        follow: 當有使用者關注你時,傳送電子信件通知
+        follow_request: 當有使用者請求關注你時,傳送電子信件通知
+        mention: 當有使用者在嘟文提及你時,傳送電子信件通知
+        reblog: 當有使用者轉嘟你的嘟文時,傳送電子信件通知
+        report: 當提交新檢舉時傳送電子郵件
     'no': 否
     required:
-      mark: "*"
       text: 必須填寫
     'yes': 是
diff --git a/config/locales/sk.yml b/config/locales/sk.yml
index 209b955dcdb00b71f74be74eb80818952c5010be..75a43e322f6e345064c711626f886afc12738f9a 100644
--- a/config/locales/sk.yml
+++ b/config/locales/sk.yml
@@ -1,55 +1,58 @@
 ---
 sk:
   about:
-    about_hashtag_html: Toto sú verejné príspevky otagované pod <strong>#%{hashtag}</strong>. Ak máš účet hocikde v rámci fediversa, môžeš ich využívať.
+    about_hashtag_html: Toto sú verejné príspevky, otagované pod <strong>#%{hashtag}</strong>. Ak máš účet hocikde v rámci fediversa, môžeš s nimi narábať.
     about_mastodon_html: Mastodon je sociálna sieť založená na otvorených webových protokoloch a na slobodnom softvéri. Je decentralizovaná, podobne ako email.
-    about_this: O tejto instancii
+    about_this: O tomto serveri
+    active_count_after: aktívni
+    active_footnote: Mesačne aktívnych užívateľov (MAU)
     administered_by: 'Správcom je:'
     api: API
     apps: Aplikácie
-    closed_registrations: Registrácie sú na tomto serveri momentálne uzatvorené. Avšak, môžeš nájsť nejaký iný Mastodon server kde si založ účet a získaj tak prístup do presne tej istej siete odtiaľ.
+    apps_platforms: Uživaj Mastodon z iOSu, Androidu a iných platforiem
+    browse_directory: Prehľadávaj databázu profilov, filtruj podľa záujmov
+    browse_public_posts: Prebádaj naživo prúd verejných príspevkov na Mastodone
     contact: Kontakt
     contact_missing: Nezadaný
-    contact_unavailable: Neuvedený
+    contact_unavailable: Neuvedený/á
+    discover_users: Objavuj užívateľov
     documentation: Dokumentácia
     extended_description_html: |
       <h3>Pravidlá</h3>
-      <p>Žiadne zatiaľ nie sú</p>
-    features:
-      humane_approach_body: Poučený z chýb iných sociálnych sietí, Mastodon sa snaží bojovať so zneužívaním siete voľbou etických návrhov.
-      humane_approach_title: Ľudskejší prístup
-      not_a_product_body: Mastodon nie je komerčná sieť. Žiadne reklamy, žiadne dolovanie dát, žiadne múry. Nieje tu žiadna centrálna autorita.
-      not_a_product_title: Si človekom, nie produktom
-      real_conversation_body: K dispozícii s 65535 znakmi a podporou pre varovania o obsahu a médiách sa môžeš vyjadriť tak ako budeš chcieť.
-      real_conversation_title: Vytvorený pre naozajstnú konverzáciu
-      within_reach_body: Viacero aplikácií pre iOS, Android a iné platformy, ktoré ti vďaka jednoduchému API ekosystému dovoľujú byť online so svojimi priateľmi kdekoľvek.
-      within_reach_title: Stále v dosahu
+      <p>Žiadne zatiaľ uvedené nie sú</p>
+    federation_hint_html: S účtom na %{instance} budeš môcť následovať ľúdí na hociakom Mastodon serveri, ale aj inde.
     generic_description: "%{domain} je jeden server v sieti"
+    get_apps: Vyskúšaj aplikácie
     hosted_on: Mastodon hostovaný na %{domain}
     learn_more: Zisti viac
-    other_instances: Zoznam ďalších inštancií
     privacy_policy: Ustanovenia o súkromí
+    see_whats_happening: Pozoruj, čo sa deje
+    server_stats: 'Serverové štatistiky:'
     source_code: Zdrojový kód
     status_count_after:
       few: príspevkov
+      many: príspevkov
       one: príspevok
-      other: príspevkov
+      other: príspevky
     status_count_before: Ktorí napísali
+    tagline: Následuj kamarátov, a objavuj nových
     terms: Podmienky užívania
     user_count_after:
-      few: užívatelia
+      few: užívateľov
+      many: užívateľov
       one: užívateľ
-      other: užívatelia
+      other: uživatelia
     user_count_before: Domov pre
     what_is_mastodon: ÄŒo je Mastodon?
   accounts:
     choices_html: "%{name}vé voľby:"
-    follow: Sleduj
+    follow: Následuj
     followers:
-      few: Sledovatelia
+      few: Sledovateľov
+      many: Sledovateľov
       one: Sledujúci
       other: Sledovatelia
-    following: Sledovaní
+    following: Následujem
     joined: Pridal/a sa v %{date}
     last_active: naposledy aktívny
     link_verified_on: Vlastníctvo tohto odkazu bolo skontrolované %{date}
@@ -63,15 +66,17 @@ sk:
       following: Musíš už následovať toho človeka, ktorého si praješ zviditeľniť
     posts:
       few: Príspevkov
+      many: Príspevkov
       one: Príspevok
-      other: Príspevkov
+      other: Príspevky
     posts_tab_heading: Príspevky
     posts_with_replies: Príspevky s odpoveďami
-    reserved_username: Prihlasovacie meno je rezervované
+    reserved_username: Prihlasovacie meno je vyhradené
     roles:
-      admin: Administrátor
-      bot: Automat
+      admin: Správca
+      bot: Bot
       moderator: Moderátor
+    unavailable: Profil nieje dostupný
     unfollow: Prestaň sledovať
   admin:
     account_actions:
@@ -80,103 +85,111 @@ sk:
     account_moderation_notes:
       create: Zanechaj poznámku
       created_msg: Poznámka moderátora bola úspešne vytvorená!
-      delete: Zmazať
-      destroyed_msg: Poznámka moderátora bola úspešne zmazaná!
+      delete: Vymaž
+      destroyed_msg: Moderátorska poznámka bola úspešne zmazaná!
     accounts:
-      are_you_sure: Si si istý?
+      approve: Schváľ
+      approve_all: Schváľ všetky
+      are_you_sure: Si si istý/á?
       avatar: Maskot
       by_domain: Doména
       change_email:
-        changed_msg: Email k tomuto účtu bol úspešne zmenený!
-        current_email: Súčastný email
+        changed_msg: Email pre tento účet bol úspešne zmenený!
+        current_email: Súčasný email
         label: Zmeň email
         new_email: Nový email
         submit: Zmeň email
         title: Zmeň email pre %{username}
-      confirm: Potvrdiť
+      confirm: Potvrď
       confirmed: Potvrdený
       confirming: Potvrdzujúci
-      deleted: Zmazané
-      demote: Degradovať
-      disable: Zablokovať
-      disable_two_factor_authentication: Zakázať 2FA
+      deleted: Vymazané
+      demote: Degraduj
+      disable: Zablokuj
+      disable_two_factor_authentication: Zakáž 2FA
       disabled: Blokovaný
-      display_name: Zobraziť meno
+      display_name: Ukáž meno
       domain: Doména
       edit: Uprav
       email: Email
       email_status: Stav emailu
-      enable: Povoliť
+      enable: Povoľ
       enabled: Povolený
-      feed_url: URL časovej osi
+      feed_url: adresa časovej osi
       followers: Sledujúci
-      followers_url: URL sledujúcich
+      followers_url: URL adresa sledujúcich
       follows: Sledovania
-      header: Hlavička
-      inbox_url: URL prijatých správ
+      header: Záhlavie
+      inbox_url: URL adresa prijatých správ
       invited_by: Pozvaný/á užívateľom
-      ip: IP
+      ip: IP adresa
       joined: Pridal/a sa
       location:
         all: Všetko
         local: Miestne
         remote: Federované
-        title: Lokácia
-      login_status: Status prihlásenia
+        title: Umiestnenie
+      login_status: Stav prihlásenia
       media_attachments: Prílohy
-      memorialize: Zmeniť na "Navždy budeme spomínať"
+      memorialize: Zmeň na "Navždy budeme spomínať"
       moderation:
         active: Aktívny/a
         all: Všetko
+        pending: Čakajúci
         silenced: Umlčané
         suspended: Vylúčený/á
         title: Moderácia
       moderation_notes: Moderátorské poznámky
       most_recent_activity: Posledná aktivita
-      most_recent_ip: Posledná IP
-      no_limits_imposed: Niesú stanovené žiadné obmedzenia
-      not_subscribed: Nezaregistrované
+      most_recent_ip: Posledná IP adresa
+      no_account_selected: Nedošlo k žiadnému pozmeneniu účtov, keďže žiadne neboli vybrané
+      no_limits_imposed: Nie sú stanovené žiadné obmedzenia
+      not_subscribed: Neodoberá
       outbox_url: URL poslaných
-      perform_full_suspension: Zablokovať
-      profile_url: URL profilu
-      promote: Povýšiť
+      pending: Vyžaduje posúdenie
+      perform_full_suspension: Vylúč
+      profile_url: URL adresa profilu
+      promote: Vyzdvihni
       protocol: Protokol
-      public: Verejná os
+      public: Verejná časová os
       push_subscription_expires: PuSH odoberanie expiruje
       redownload: Obnov profil
-      remove_avatar: Odstrániť avatár
-      remove_header: Odstráň hlavičku
+      reject: Zamietni
+      reject_all: Zamietni všetky
+      remove_avatar: Vymaž avatar
+      remove_header: Vymaž záhlavie
       resend_confirmation:
-        already_confirmed: Tento užívateľ už je potvrdený
-        send: Znovu odoslať potvrdzovací email
+        already_confirmed: Tento užívateľ je už potvrdený
+        send: Odošli potvrdzovací email znovu
         success: Potvrdzujúci email bol úspešne odoslaný!
       reset: Resetuj
       reset_password: Obnov heslo
-      resubscribe: Znovu odoberať
+      resubscribe: Znovu odoberaj
       role: Oprávnenia
       roles:
-        admin: Administrátor
+        admin: Správca
         moderator: Moderátor
         staff: ÄŒlen
         user: Užívateľ
       salmon_url: Salmon adresa
-      search: Hľadať
+      search: Hľadaj
       shared_inbox_url: URL zdieľanej schránky
       show:
         created_reports: Vytvorené hlásenia
         targeted_reports: Nahlásenia od ostatných
-      silence: Stíšiť
-      silenced: Utíšení
+      silence: Stíš
+      silenced: Stíšený/é
       statuses: Príspevky
-      subscribe: Odoberať
-      suspended: Zablokovaní
+      subscribe: Odoberaj
+      suspended: Vylúčený/á
+      time_in_queue: Čakajúci %{time} v poradí
       title: Účty
       unconfirmed_email: Nepotvrdený email
-      undo_silenced: Zrušiť stíšenie
-      undo_suspension: Zrušiť suspendáciu
+      undo_silenced: Zruš stíšenie
+      undo_suspension: Zruš blokovanie
       unsubscribe: Prestaň odoberať
       username: Prezývka
-      warn: Varovať
+      warn: Varuj
       web: Web
     action_logs:
       actions:
@@ -206,7 +219,7 @@ sk:
         silence_account: "%{name} utíšil/a účet %{target}"
         suspend_account: "%{name} zablokoval/a účet používateľa %{target}"
         unassigned_report: "%{name} odobral/a report od %{target}"
-        unsilence_account: "%{name} zrušil/a utíšenie účtu používateľa %{target}"
+        unsilence_account: "%{name} zrušil/a stíšenie účtu používateľa %{target}"
         unsuspend_account: "%{name} zrušil/a blokovanie účtu používateľa %{target}"
         update_custom_emoji: "%{name} aktualizoval/a emoji %{target}"
         update_status: "%{name} aktualizoval/a status pre %{target}"
@@ -214,29 +227,29 @@ sk:
       title: Kontrólny záznam
     custom_emojis:
       by_domain: Doména
-      copied_msg: Lokálna kópia emoji úspešne vytvorená
-      copy: Kopírovať
-      copy_failed_msg: Nebolo možné vytvoriť lokálnu kópiu tohto emoji
+      copied_msg: Miestna kópia emoji bola úspešne vytvorená
+      copy: Kopíruj
+      copy_failed_msg: Nebolo možné vytvoriť miestnu kópiu tohto emoji
       created_msg: Emoji úspešne vytvorené!
-      delete: Zmazať
-      destroyed_msg: Emojo úspešne zničený!
-      disable: Zakázať
+      delete: Zmaž
+      destroyed_msg: Emoji úspešne zničené!
+      disable: Zakáž
       disabled_msg: Emoji bolo úspešne zakázané
       emoji: Emotikony
-      enable: Povoliť
+      enable: Povoľ
       enabled_msg: Emoji bolo úspešne povolené
       image_hint: PNG do 50KB
       listed: V zozname
       new:
-        title: Pridať nový vlastný emoji
-      overwrite: Prepísať
+        title: Pridaj nové, vlastné emoji
+      overwrite: Prepíš
       shortcode: Skratka
-      shortcode_hint: Aspoň 2 znaky, povolené sú alfanumerické alebo podčiarkovník
+      shortcode_hint: Aspoň 2 znaky, povolené sú alfanumerické, alebo podčiarkovník
       title: Vlastné emoji
       unlisted: Nie je na zozname
       update_failed_msg: Nebolo možné aktualizovať toto emoji
       updated_msg: Emoji bolo úspešne aktualizované!
-      upload: Nahrať
+      upload: Nahraj
     dashboard:
       backlog: odložené aktivity
       config: Nastavenia
@@ -245,10 +258,11 @@ sk:
       feature_profile_directory: Katalóg profilov
       feature_registrations: Registrácie
       feature_relay: Federovací mostík
+      feature_timeline_preview: Náhľad časovej osi
       features: Vymoženosti
-      hidden_service: Federácia so skritými službami
+      hidden_service: Federácia so skrytými službami
       open_reports: otvorené hlásenia
-      recent_users: Nedávny užívatelia
+      recent_users: Nedávni užívatelia
       search: Celofrázové vyhľadávanie
       single_user_mode: Jednouživateľské rozhranie
       software: Softvér
@@ -256,47 +270,49 @@ sk:
       title: Spravovacie rozhranie
       total_users: užívateľov celkovo
       trends: Trendy
-      week_interactions: Tohto týždňové interakcie
+      week_interactions: Tohto-týždňové interakcie
       week_users_active: aktívni tento týždeň
       week_users_new: užívateľov počas tohto týždňa
     domain_blocks:
-      add_new: Pridaj nové doménové blokovanie
-      created_msg: Doména je v procese blokovania
+      add_new: Blokuj novú doménu
+      created_msg: Doména je v štádiu blokovania
       destroyed_msg: Blokovanie domény bolo zrušené
       domain: Doména
+      existing_domain_block_html: Pre účet %{name} si už nahodil/a přísnejšie obmedzenie, najskôr ho teda musíš <a href="%{unblock_url}">odblokovať</a>.
       new:
-        create: Blokovať doménu
-        hint: Blokovanie domény stále dovolí vytvárať nové účty v databáze, ale tieto budú automaticky moderované.
+        create: Vytvor blokovanie domény
+        hint: Blokovanie domény stále dovolí vytvárať nové účty v databázi, ale tieto budú spätne automaticky moderované.
         severity:
           desc_html: "<strong>Stíšenie</strong> urobí všetky príspevky daného účtu neviditeľné pre všetkých ktorí nenásledujú tento účet. <strong>Suspendácia</strong> zmaže všetky príspevky, médiá a profilové informácie. Použi <strong>Žiadne</strong>, ak chceš iba neprijímať súbory médií."
           noop: Nič
-          silence: Stíšiť
-          suspend: Suspendovať
+          silence: Stíš
+          suspend: Vylúč
         title: Nové blokovanie domény
-      reject_media: Odmietať súbory s obrázkami alebo videami
-      reject_media_hint: Zmaže lokálne uložené súbory médií a odmietne ich sťahovanie v budúcnosti. Irelevantné pre suspendáciu
+      reject_media: Odmietaj súbory s obrázkami, alebo videami
+      reject_media_hint: Vymaže miestne uložené súbory médií a odmietne ich sťahovanie v budúcnosti. Nepodstatné pri vylúčení
       reject_reports: Zamietni hlásenia
       reject_reports_hint: Ignoruj všetky hlásenia prichádzajúce z tejto domény. Nevplýva na blokovania
       rejecting_media: odmietanie médiálnych súborov
-      rejecting_reports: odmietané hlásenia
+      rejecting_reports: odmietanie hlásení
       severity:
-        silence: utíšené
-        suspend: vylúčený
+        silence: stíšené
+        suspend: vylúčené
       show:
         affected_accounts:
-          few: "%{count} účty v databáze ovplyvnených"
-          one: Jeden účet v databáze bol ovplyvnený
-          other: "%{count} účtov v databáze bolo ovplyvnených"
+          few: "%{count} účtov v databázi ovplyvnených"
+          many: "%{count} účtov v databázi ovplyvnených"
+          one: Jeden účet v databázi ovplyvnený
+          other: "%{count} účty v databázi ovplyvnené"
         retroactive:
-          silence: Zruš stíšenie všetkých existujúcich účtov z tejto domény
-          suspend: Zruš suspendáciu všetkých existujúcich účtov z tejto domény
+          silence: Zruš stíšenie všetkých momentálne utíšených účtov z tejto domény
+          suspend: Zruš suspendáciu všetkých momentálne ovplyvnených účtov z tejto domény
         title: Zruš blokovanie domény %{domain}
-        undo: Vrátiť späť
+        undo: Vráť späť
       undo: Odvolaj blokovanie domény
     email_domain_blocks:
       add_new: Pridaj nový
       created_msg: Emailová doména bola úspešne pridaná do zoznamu zakázaných
-      delete: Zmazať
+      delete: Vymaž
       destroyed_msg: Emailová doména bola úspešne vymazaná zo zoznamu zakázaných
       domain: Doména
       new:
@@ -305,11 +321,13 @@ sk:
       title: Blokované emailové adresy
     followers:
       back_to_account: Späť na účet
-      title: Následovatielia užívateľa %{acct}
+      title: Sledovatielia užívateľa %{acct}
     instances:
+      by_domain: Doména
       delivery_available: Je v dosahu doručovania
       known_accounts:
-        few: "%{count} známe účty"
+        few: "%{count} známych účtov"
+        many: "%{count} známych účtov"
         one: "%{count} známy účet"
         other: "%{count} známe účty"
       moderation:
@@ -323,25 +341,27 @@ sk:
       total_reported: Nahlásenia o nich
       total_storage: Mediálne prílohy
     invites:
-      deactivate_all: Pozastaviť všetky
+      deactivate_all: Pozastav všetky
       filter:
         all: Všetky
         available: Dostupné
         expired: Vypršalo
-        title: Filtrovať
+        title: Filtruj
       title: Pozvánky
+    pending_accounts:
+      title: Čakajúcich účtov (%{count})
     relays:
-      add_new: Pridaj novú priechodnú oporu
+      add_new: Pridaj nový federovací mostík
       delete: Vymaž
-      description_html: "<strong>Federovací mostík</strong> je prechodný server ktorý obmieňa veľké množstvá verejných príspevkov medzi tými servermi ktoré na od neho odoberajú, aj doňho prispievajú. <strong>Môže to pomôcť malým a stredným instanciám objavovať federovaný obsah</strong>, čo inak vyžaduje aby miestni užívatelia ručne následovali iných ľudí zo vzdialených instancií."
-      disable: Pozastav
-      disabled: Zastavené
+      description_html: "<strong>Federovací mostík</strong> je prechodný server, ktorý obmieňa veľké množstvá verejných príspevkov medzi tými servermi ktoré na od neho odoberajú, aj doňho prispievajú. <strong>Môže to pomôcť malým a stredným instanciám objavovať federovaný obsah</strong>, čo inak vyžaduje aby miestni užívatelia ručne následovali iných ľudí zo vzdialených instancií."
+      disable: Vypni
+      disabled: Vypnutý
       enable: Povoľ
       enable_hint: Ak povolíš, tvoj server bude odoberať všetky verejné príspevky z tohto mostu, a začne posielať verejné príspevky tvojho servera na tento most.
       enabled: Povolené
-      inbox_url: URL mostu
-      pending: Čakám na povolenie od prechodného mostu
-      save_and_enable: Uložiť a povoliť
+      inbox_url: URL adresa mostu
+      pending: Čaká sa na povolenie od prechodného mostu
+      save_and_enable: Ulož a povoľ
       setup: Nastav prepojenie s mostom
       status: Stav
       title: Mosty
@@ -354,7 +374,7 @@ sk:
         report: nahlás
       action_taken_by: Zákrok vykonal/a
       are_you_sure: Si si istý/á?
-      assign_to_self: Priraď k sebe
+      assign_to_self: Priraď sebe
       assigned: Priradený moderátor
       comment:
         none: Žiadne
@@ -374,73 +394,76 @@ sk:
       resolved: Vyriešené
       resolved_msg: Hlásenie úspešne vyriešené!
       status: Stav
-      title: Reporty
-      unassign: Odobrať
+      title: Hlásenia
+      unassign: Odober
       unresolved: Nevyriešené
       updated_at: Aktualizované
     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
+        desc_html: Sčítanie miestne uverejnený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.
+        desc_html: Ak je prezývok viacero, každú oddeľ čiarkou. Je možné zadať iba miestne, odomknuté účty. Pokiaľ necháš prázdne, je to pre všetkých miestnych správcov.
         title: Štandardní následovníci nových užívateľov
       contact_information:
-        email: Pracovný e-mail
+        email: Pracovný email
         username: Kontaktné užívateľské meno
       custom_css:
         desc_html: Uprav vzhľad pomocou CSS, ktoré je načítané na každej stránke
         title: Vlastné CSS
       hero:
-        desc_html: Zobrazuje sa na hlavnej stránke. Doporučuje sa rozlišenie aspoň 600x100px Pokiaľ tu nieje nič dodané, bude nastavený základný orázok tohoto serveru
+        desc_html: Zobrazuje sa na hlavnej stránke. Doporučené je rozlišenie aspoň 600x100px. Pokiaľ nič nieje dodané, bude nastavený základný orázok serveru.
         title: Obrázok hrdinu
       mascot:
-        desc_html: Zobrazované na viacerých stránkach. Odporúčaná veľkosť aspoň 293×205px. Pokiaľ nieje nahraté, bude zobrazený základný maskot
+        desc_html: Zobrazované na viacerých stránkach. Odporúčaná veľkosť aspoň 293×205px. Pokiaľ nieje nahraté, bude zobrazený základný maskot.
         title: Obrázok maskota
       peers_api_enabled:
-        desc_html: Domény na ktoré táto instancia už vo fediverse natrafila
-        title: Zverejniť zoznam objavených instancií
+        desc_html: Domény, na ktoré tento server už v rámci fediversa natrafil
+        title: Zverejni zoznam objavených serverov
       preview_sensitive_media:
-        desc_html: Náhľad adresy z iných instancií, bude zobrazený aj vtedy, keď sú dané médiá označené ako senzitívne
+        desc_html: Náhľad odkazov z iných serverov, bude zobrazený aj vtedy, keď sú médiá označené ako citlivé
         title: Ukazuj aj chúlostivé médiá v náhľadoch OpenGraph
       profile_directory:
-        desc_html: Povoliť užívateľom aby boli nájdení
+        desc_html: Povoľ užívateľom, aby mohli byť nájdení
         title: Zapni profilový katalóg
       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
+          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 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
+          desc_html: Dovoľ každému aby si mohli zmazať svok účet
+          title: Sprístupni možnosť vymazať si účet
         min_invite_role:
           disabled: Nikto
-          title: Povoliť pozvánky od
-        open:
-          desc_html: Povoliť každému aby si mohli vytvoriť účet
-          title: Verejná registrácia
+          title: Povoľ pozvánky od
+      registrations_mode:
+        modes:
+          approved: Pre registráciu je nutné povolenie
+          none: Nikto sa nemôže registrovať
+          open: Ktokoľvek sa môže zaregistrovať
+        title: Režím registrácií
       show_known_fediverse_at_about_page:
-        desc_html: Pokiaľ je zapnuté, bude v ukážke osi možné nahliadnúť príspevky z celého známeho fediversa. Inak budú ukázané iba príspevky z miestnej osi.
+        desc_html: Ak je zapnuté, bude v ukážke osi možné nahliadnúť príspevky z celého známeho fediversa. Inak budú ukázané iba príspevky z miestnej osi.
         title: Ukáž celé známe fediverse na náhľade osi
       show_staff_badge:
-        desc_html: Zobraz moderátorsky odznak na užívateľovom profile
-        title: Zobraz značku moderátora
+        desc_html: Ukáž moderátorsky odznak na užívateľovom profile
+        title: Ukáž značku moderátora
       site_description:
-        desc_html: Oboznamujúci paragraf na hlavnej stránke a pri meta tagoch. Opíš, čo robí tento Mastodon server špecifickým, a ďalej hocičo iné, čo považuješ za dôležité. Môžeš použiť HTML kód, hlavne <code>&lt; a &gt;</code>, ale tiež <code>&lt;&gt;</code>.
-        title: Popis instancie
+        desc_html: Oboznamujúci paragraf na hlavnej stránke a pri meta tagoch. Opíš, čo robí tento Mastodon server špecifickým, a ďalej hocičo iné, čo považuješ za dôležité. Môžeš použiť HTML kód, hlavne <code>&lt;a&gt;</code> a <code>&lt;em&gt;</code>.
+        title: Popis servera
       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
+        desc_html: Toto je vhodné miesto pre tvoje pravidlá o prevádzke, pokyny, podmienky a iné veci, ktorými je tvoj server špecifický. Je možné tu používať HTML tagy
         title: Vlastné doplňujúce informácie
       site_short_description:
-        desc_html: Zobrazené na bočnom paneli a pri meta tagoch. Popíš čo je Mastodon, a čo robí tento server iným, v jednom paragrafe. Pokiaľ toto necháš prázdne, bude tu zobrazený základný popis instancie.
-        title: Krátky popis instancie
+        desc_html: Zobrazené na bočnom paneli a pri meta tagoch. Popíš čo je Mastodon, a čo robí tento server iným, v jednom paragrafe. Pokiaľ toto necháš prázdne, bude tu zobrazený základný popis servera.
+        title: Krátky popis serveru
       site_terms:
-        desc_html: Môžete si napísať vaše vlastné pravidla o súkromí, prevádzke, alebo aj iné legality. Môžete tu používať HTML kód
+        desc_html: Môžeš si napísať svoje vlastné pravidla o súkromí, prevádzke, alebo aj iné legality. Môžeš tu používať HTML kód
         title: Vlastné pravidlá prevádzky
-      site_title: Názov instancie
+      site_title: Názov servera
       thumbnail:
         desc_html: Používané pre náhľady cez OpenGraph a API. Doporučuje sa rozlišenie 1200x630px
-        title: Miniatúra instancie
+        title: Miniatúra servera
       timeline_preview:
         desc_html: Zobraziť verejnú nástenku na hlavnej stránke
         title: Náhľad nástenky
@@ -448,7 +471,7 @@ sk:
     statuses:
       back_to_account: Späť na účet
       batch:
-        delete: Vymazať
+        delete: Vymaž
         nsfw_off: Označ ako nechúlostivé
         nsfw_on: Označ ako chúlostivé
       failed_to_execute: Nepodarilo sa vykonať
@@ -481,49 +504,54 @@ sk:
       edit_preset: Uprav varovnú predlohu
       title: Spravuj varovné predlohy
   admin_mailer:
+    new_pending_account:
+      body: Podrobnosti o novom účte sú uvedené nižšie. Môžeš túto registračnú požiadavku buď prijať, alebo zamietnúť.
+      subject: Nový účet očakáva preverenie na %{instance} (%{username})
     new_report:
       body: "%{reporter} nahlásil/a %{target}"
       body_remote: Niekto z %{domain} nahlásil/a %{target}
       subject: Nové hlásenie pre %{instance} (#%{id})
+  appearance:
+    advanced_web_interface: Pokročilé webové rozhranie
+    animations_and_accessibility: Animácie a prístupnosť
+    confirmation_dialogs: Potvrdzovacie dialógy
+    sensitive_content: Chúlostivý obsah
   application_mailer:
-    notification_preferences: Zmeniť e-mailové voľby
-    salutation: "%{name},"
-    settings: 'Zmeniť e-mailové voľby: %{link}'
+    notification_preferences: Zmeň emailové voľby
+    settings: 'Zmeň emailové voľby: %{link}'
     view: 'Zobraziť:'
-    view_profile: Zobraziť profil
-    view_status: Zobraziť status
+    view_profile: Zobraz profil
+    view_status: Zobraz status
   applications:
     created: Aplikácia bola vytvorená úspešne
     destroyed: Aplikáciu sa podarilo odstrániť
     invalid_url: Zadaná URL adresa je nesprávna
     regenerate_token: Znovu vygenerovať prístupový token
     token_regenerated: Prístupový token bol úspešne vygenerovaný znova
-    warning: Na tieto údaje dávajte ohromný pozor. Nikdy ich s nikým nezďieľajte!
-    your_token: Váš prístupový token
+    warning: Na tieto údaje dávaj ohromný pozor. Nikdy ich s nikým nezďieľaj!
+    your_token: Tvoj prístupový token
   auth:
-    agreement_html: V rámci registrácie súhlasíš, že sa budeš riadiť <a href="%{rules_path}"> pravidlami tejto instancie</a>, a taktiež <a href="%{terms_path}"> našími prevoznými podmienkami</a>.
+    apply_for_account: Vyžiadaj si pozvánku
     change_password: Heslo
-    confirm_email: Potvrdiť email
-    delete_account: Vymazať účet
-    delete_account_html: Pokiaľ chceš vymazať svoj účet, môžeš tak <a href="%{path}">urobiť tu</a>. Budeš požiadaný/á o potvrdenie tohto kroku.
-    didnt_get_confirmation: Neobdŕžal/a si kroky pre potvrdenie?
+    checkbox_agreement_html: Súhlasím s <a href="%{rules_path}" target="_blank">pravidlami servera</a>, aj s <a href="%{terms_path}" target="_blank">prevoznými podmienkami</a>
+    confirm_email: Potvrď email
+    delete_account: Vymaž účet
+    delete_account_html: Pokiaľ chceš svoj účet odtiaľto vymazať, môžeš tak <a href="%{path}">urobiť tu</a>. Budeš požiadaný/á o potvrdenie tohto kroku.
+    didnt_get_confirmation: Neobdržal/a si kroky na potvrdenie?
     forgot_password: Zabudnuté heslo?
     invalid_reset_password_token: Token na obnovu hesla vypršal. Prosím vypítaj si nový.
     login: Prihlás sa
     logout: Odhlás sa
-    migrate_account: Presunúť sa na iný účet
-    migrate_account_html: Pokiaľ si želáš presmerovať tento účet na nejaký iný, môžeš to <a href="%{path}">urobiť tu</a>.
-    or: alebo
-    or_log_in_with: Alebo prihlásiť z
-    providers:
-      cas: CAS
-      saml: SAML
+    migrate_account: Presúvam sa na iný účet
+    migrate_account_html: Ak si želáš presmerovať tento účet na nejaký iný, môžeš si to <a href="%{path}">nastaviť tu</a>.
+    or_log_in_with: Alebo prihlás s
     register: Zaregistruj sa
-    register_elsewhere: Zaregistruj sa na inom serveri
-    resend_confirmation: Poslať potvrdzujúce pokyny znovu
-    reset_password: Resetovať heslo
+    registration_closed: "%{instance} neprijíma nových členov"
+    resend_confirmation: Zašli potvrdzujúce pokyny znovu
+    reset_password: Obnov heslo
     security: Zabezpečenie
-    set_new_password: Nastaviť nové heslo
+    set_new_password: Nastav nové heslo
+    trouble_logging_in: Problém s prihlásením?
   authorize_follow:
     already_following: Tento účet už následuješ
     error: Naneštastie nastala chyba pri hľadaní vzdialeného účtu
@@ -555,7 +583,7 @@ sk:
     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: Vymaž účet
     success_msg: Tvoj účet bol úspešne vymazaný
-    warning_html: Iba vymazanie obsahu z tejto konkrétnej instancie je zaručené. Obsah, ktorý bol zdieľaný široko-ďaleko pravdepodobne zanechá nejaké stopy. Servery ktoré sú offline a tie ktoré ignorujú tvoje zmeny teda nezaktualizujú svoje databázy.
+    warning_html: Iba vymazanie obsahu z tohto konkrétneho serveru je zaručené. Obsah, ktorý bol zdieľaný široko-ďaleko pravdepodobne zanechá nejaké stopy. Servery ktoré sú offline a tie ktoré ignorujú tvoje zmeny teda nezaktualizujú svoje databázy.
     warning_title: Dostupnosť rozšírovaného obsahu
   directories:
     directory: Katalóg profilov
@@ -565,26 +593,30 @@ sk:
     explore_mastodon: Prebádaj %{title}
     how_to_enable: Momentálne niesi zaradený/á do verejnej profilovej databázy. Prihlásiť sa môžeš nižšie. Použi haštagy vo svojom biografickom popise na profile, ak chceš byť uvedený/á aj pod konkrétnými haštagmi!
     people:
-      few: "%{count} ľudia"
+      few: "%{count} ľudí"
+      many: "%{count} ľudí"
       one: "%{count} človek"
       other: "%{count} ľudia"
   errors:
-    '403': Nemáš povolenie na zobrazenie tejto stránky.
-    '404': Stránka ktorú si hľadal/a sa tu nenachádza.
-    '410': Stránka ktorú si tu hľadal/a už viac neexistuje.
+    '403': Nemáš povolenie pre zobrazenie tejto stránky.
+    '404': Stránka ktorú hľadáš nieje tu.
+    '410': Stránka ktorú si tu hľadal/a sa tu už viac nenachádza.
     '422':
       content: Bezpečtnostné overenie zlyhalo. Blokuješ cookies?
       title: Bezpečtnostné overenie zlyhalo
     '429': Zamlčané
     '500':
-      content: Ospravedlňujeme sa. Niečo sa pokazilo na našom konci.
+      content: Ospravedlňujem 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="%{apps_path}"> aplikácii </a> dostupných pre vašu platformu.
+    noscript_html: Aby bolo možné používať Mastodon web aplikáciu, povoľ prosím JavaScript. Alebo skús jednu z <a href="%{apps_path}"> aplikácii </a> dostupných pre vašu platformu.
+  existing_username_validator:
+    not_found: nepodarilo sa nájsť miestného užívateľa s takouto prezývkou
+    not_found_multiple: nepodarilo sa nájsť %{usernames}
   exports:
     archive_takeout:
       date: Dátum
       download: Stiahni si svoj archív
-      hint_html: Môžeš si opýtať <strong>archív svojích príspevkov a nahratých médií</strong>. Exportované dáta budú v ActivityPub formáte, čítateľné hociakým kompatibilným softvérom. Archív si je možné vyžiadať každých sedem dní.
+      hint_html: Môžeš si vyžiadať <strong>archív svojích príspevkov a nahratých médií</strong>. Exportované dáta budú v ActivityPub formáte, čítateľné hociakým kompatibilným softvérom. Archív si je možné vyžiadať každých sedem dní.
       in_progress: Balím tvoj archív...
       request: Vyžiadaj si tvoj archív
       size: Veľkosť
@@ -595,10 +627,14 @@ sk:
     lists: Zoznamy
     mutes: Stíšil/a si
     storage: Úložisko médií
+  featured_tags:
+    add_new: Pridaj nový
+    errors:
+      limit: Už si si predvolil/a najvyšší možný počet obľúbených haštagov
   filters:
     contexts:
       home: Domáca os
-      notifications: Oboznámenia
+      notifications: Oznámenia
       public: Verejné osi
       thread: Konverzácie
     edit:
@@ -607,46 +643,50 @@ sk:
       invalid_context: Nebola poskytnutá žiadna, alebo ide o neplatnú súvislosť
       invalid_irreversible: Nezvratné filtrovanie funguje iba so súvislostiami domovskej osi a oboznámení
     index:
-      delete: Vymazať
+      delete: Vymaž
       title: Triedenia
     new:
       title: Pridaj nové triedenie
-  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:
-      few: Počas utišovania sledovateľov z %{count} domén...
-      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 ber na vedomie, <strong> že ozajstné súkromie sa dá dosiahnúť iba za pomoci end-to-end enkrypcie</strong>.
-    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ý
   footer:
     developers: Vývojári
     more: Viac…
     resources: Podklady
   generic:
+    all: Všetko
     changes_saved_msg: Zmeny boli úspešne uložené!
-    copy: Kopírovať
+    copy: Kopíruj
+    order_by: Zoraď podľa
     save_changes: Ulož zmeny
-    validation_errors:
-      few: Niečo ešte stále nieje v poriadku! Prosím skontroluj všetky %{count} chyby
-      one: Niečo nieje úplne v poriadku! Prosím skontroluj danú chybu
-      other: Niečo ešte stále nieje v poriadku! Prosím skontroluj všetky %{count} nižšie uvedené pochybenia
+  identity_proofs:
+    active: Aktívne
+    authorize: Áno, povoľ
+    authorize_connection_prompt: Povoliť toto kryptografické prepojenie?
+    errors:
+      failed: Kryptografické prepojenie sa nepodarilo. Prosím skús to znova z %{provider}.
+    i_am_html: Na %{service} som %{username}.
+    identity: Identita
+    inactive: Neaktívne
+    publicize_checkbox: 'A poslať toto:'
+    publicize_toot: 'Je to dokázané! Na %{service} som %{username}: %{url}'
+    status: Stav overenia
+    view_proof: Ukáž overenie
   imports:
+    modes:
+      merge: Spoj dohromady
+      merge_long: Ponechaj existujúce záznamy a pridaj k nim nové
+      overwrite: Prepíš
+      overwrite_long: Nahraď súčasné záznamy novými
     preface: Môžeš nahrať 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 teraz budú spracované v danom čase
     types:
       blocking: Zoznam blokovaných
+      domain_blocking: Zoznam blokovaných domén
       following: Zoznam sledovaných
       muting: Zoznam ignorovaných
-    upload: Nahrať
+    upload: Nahraj
   in_memoriam_html: V pamäti.
   invites:
-    delete: Deaktivovať
+    delete: Deaktivuj
     expired: Neplatné
     expires_in:
       '1800': 30 minút
@@ -657,13 +697,14 @@ sk:
       '86400': 1 deň
     expires_in_prompt: Nikdy
     generate: Vygeneruj
-    invited_by: 'Bol/a si pozvan/á užívateľom:'
+    invited_by: 'Bol/a si pozvaný/á užívateľom:'
     max_uses:
-      few: "%{count} použitia"
-      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
+      few: "%{count} využití"
+      many: "%{count} využití"
+      one: 1 využitie
+      other: "%{count} využitia"
+    max_uses_prompt: Bez obmedzení
+    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
@@ -687,17 +728,9 @@ sk:
       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:
-        few: Taktiež, získal/a si %{count} nových následovníkov za tú dobu čo si bol/a preč. Yay!
-        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:
-        few: "%{count} nové notifikácie od tvojej poslednej návštevy \U0001F418"
-        one: "1 nová notifikácia od tvojej poslednej návštevy \U0001F418"
-        other: "%{count} nových notifikácií 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}:'
+      body: 'Tvoj príspevok bol uložený medzi obľúbené užívateľa %{name}:'
       subject: "%{name} si obľúbil/a tvoj príspevok"
       title: Nové obľúbené
     follow:
@@ -708,41 +741,50 @@ sk:
       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
+      title: Nová žiadosť o následovanie
     mention:
       action: Odpovedať
       body: "%{name} ťa spomenul/a v:"
       subject: Bol/a si spomenutý/á užívateľom %{name}
       title: Novo spomenutý/á
     reblog:
-      body: 'Tvoj príspevok bol pozdvihnutý užívateľom %{name}:'
-      subject: "%{name} pozdvihli tvoj príspevok"
-      title: Novo pozdvyhnuté
-  number:
-    human:
-      decimal_units:
-        format: "%n%u"
-        units:
-          billion: B
-          million: M
-          quadrillion: Q
-          thousand: K
-          trillion: T
+      body: 'Tvoj príspevok bol vyzdvihnutý užívateľom %{name}:'
+      subject: "%{name} vyzdvihli tvoj príspevok"
+      title: Novo vyzdvyhnuté
   pagination:
     newer: Novšie
     next: Ďalšie
     older: Staršie
-    prev: Predošlé
-    truncate: "&hellip;"
+    prev: Predchádzajúce
+  polls:
+    errors:
+      already_voted: V tejto ankete si už hlasoval/a
+      duplicate_options: obsahuje opakujúce sa položky
+      duration_too_long: je príliš ďaleko do budúcnosti
+      duration_too_short: je príliš skoro
+      expired: Anketa už skončila
+      over_character_limit: každá nemôže byť dlhšia ako %{max} znakov
+      too_few_options: musí mať viac ako jednu položku
+      too_many_options: nemôže zahŕňať viac ako %{max} položiek
   preferences:
-    languages: Jazyky
     other: Ostatné
-    publishing: Publikovanie
-    web: Web
+    public_timelines: Verejné časové osi
+  relationships:
+    activity: Aktivita účtu
+    dormant: Spiace
+    last_active: Naposledy aktívny
+    most_recent: Najnovšie
+    moved: Presunuli sa
+    mutual: Spoločné
+    primary: Hlavné
+    relationship: Vzťah
+    remove_selected_followers: Odstráň vybraných následovatrľov
+    remove_selected_follows: Prestaň sledovať vybraných užívateľov
+    status: Stav účtu
   remote_follow:
     acct: Napíš svoju prezývku@doménu z ktorej chceš následovať
-    missing_resource: Nemôžeme nájsť potrebnú presmerovaciu adresu k tvojmu účtu
-    no_account_html: Nemáš ešte účet? Môžeš sa <a href='%{sign_up_path}' target='_blank'>zaregistrovať tu</a>
+    missing_resource: Nemožno nájsť potrebnú presmerovaciu adresu k tvojmu účtu
+    no_account_html: Nemáš účet? Môžeš sa <a href='%{sign_up_path}' target='_blank'>zaregistrovať tu</a>
     proceed: Začni následovať
     prompt: 'Budeš sledovať:'
     reason_html: "<strong>Načo je tento krok potrebný?</strong> <code>%{instance}</code> nemusí byť práve tým serverom na ktorom si zaregistrovaný/á, takže je ťa najprv potrebné presmerovať na tvoj domáci server."
@@ -768,75 +810,54 @@ sk:
     activity: Najnovšia aktivita
     browser: Prehliadač
     browsers:
-      alipay: Alipay
       blackberry: RIM Blackberry
       chrome: Google Chrome
-      edge: Microsoft Edge
-      electron: Electron
       firefox: Mozilla Firefox
       generic: Neznámy prehliadač
-      ie: Internet Explorer
-      micro_messenger: MicroMessenger
       nokia: Nokia Ovi Browser
-      opera: Opera
       otter: Prehliadač Otter
-      phantom_js: PhantomJS
       qq: QQ Prehliadač
       safari: Apple Safari
-      uc_browser: UCBrowser
       weibo: Sina/Tencent Weibo
     current_session: Aktuálna sezóna
     description: "%{browser} na %{platform}"
     explanation: Tieto sú prehliadače ktoré sú teraz prihlásené na tvoj Mastodon účet.
     ip: IP adresa
     platforms:
-      adobe_air: Adobe Air
-      android: Android
-      blackberry: Blackberry
       chrome_os: Google ChromeOS
-      firefox_os: Firefox OS
       ios: Apple iOS
       linux: GNU/Linux
       mac: MacOSX
       other: neznáma platforma
       windows: Microsoft Windows
-      windows_mobile: Windows Mobile
-      windows_phone: Windows Phone
     revoke: Zamietni
     revoke_success: Sezóna úspešne zamietnutá
     title: Sezóny
   settings:
+    account: Účet
+    account_settings: Nastavenia účtu
+    appearance: Vzhľad
     authorized_apps: Povolené aplikácie
     back: Späť na Mastodon
     delete: Vymazanie účtu
     development: Vývoj
     edit_profile: Uprav profil
-    export: Exportovať dáta
-    followers: Povolení následovatelia
-    import: Importovať
-    migrate: Presunúť účet
+    export: Exportuj dáta
+    featured_tags: Zvýraznené haštagy
+    identity_proofs: Overenia identity
+    import: Importuj
+    import_and_export: Import a export
+    migrate: Presuň účet
     notifications: Oboznámenia
     preferences: Voľby
-    settings: Nastavenia
+    profile: Profil
+    relationships: Následovaní a následovatelia
     two_factor_authentication: Dvoj-faktorové overenie
-    your_apps: Tvoje aplikácie
   statuses:
     attached:
       description: 'Priložené: %{attached}'
-      image:
-        few: "%{count} obrázky"
-        one: "%{count} obrázok"
-        other: "%{count} obrázkov"
-      video:
-        few: "%{count} videá"
-        one: "%{count} video"
-        other: "%{count} videí"
-    boosted_from_html: Povýšené od %{acct_link}
+    boosted_from_html: Vyzdvihnuté od %{acct_link}
     content_warning: 'Varovanie o obsahu: %{warning}'
-    disallowed_hashtags:
-      few: 'obsahoval nepovolené hashtagy: %{tags}'
-      one: 'obsahoval nepovolený hashtag: %{tags}'
-      other: 'obsahoval nepovolené hashtagy: %{tags}'
     language_detection: Zisti automaticky
     open_in_web: Otvor v okne na webe
     over_character_limit: limit %{max} znakov bol presiahnutý
@@ -844,7 +865,9 @@ sk:
       limit: Už si si pripol ten najvyšší možný počet hlášok
       ownership: Nieje možné pripnúť hlášku od niekoho iného
       private: Neverejné príspevky nemôžu byť pripnuté
-      reblog: Pozdvihnutie sa nedá pripnúť
+      reblog: Vyzdvihnutie sa nedá pripnúť
+    poll:
+      vote: Hlasuj
     show_more: Ukáž viac
     sign_in_to_participate: Prihlás sa pre zapojenie do diskusie
     title: '%{name}: „%{quote}"'
@@ -856,43 +879,49 @@ sk:
       unlisted: Nezaradené
       unlisted_long: Všetci môžu vidieť, ale nieje zaradené do verejnej osi
   stream_entries:
-    pinned: Pripnutý toot
+    pinned: Pripnutý príspevok
     reblogged: vyzdvihnutý
     sensitive_content: Senzitívny obsah
   terms:
     body_html: |
       <h2>Podmienky súkromia</h2>
 
-      <h3 id="collect">Aké informácie zbierame?</h3>
+      <h3 id="collect">Aké informácie sú zbierané?</h3>
 
       <ul>
       <li><em>Základné informácie o účte</em>: Ak sa na tomto serveri zaregistruješ, budeš môcť byť požiadaný/á zadať prezývku, emailovú adresu a heslo. Budeš tiež môcť zadať aj ďalšie profilové údaje, ako napríklad meno a životopis, a nahrať profilovú fotku aj obrázok v záhlaví. Tvoja prezývka, meno, životopis, profilová fotka a obrázok v záhlaví sú vždy zobrazené verejne.</li><li><em>Príspevky, sledovania a iné verejné informácie</em>:
       Zoznam ľudí, ktorých sleduješ je zobrazený verejne, a to isté platí aj pre zoznam tvojích následovateľov. Keď pošleš správu, ukladá sa jej dátum a čas, ale aj z akej aplikácie bola poslaná. Správy môžu obsahovať mediálne prílohy, ako obrázky a videá. Verejné, a nezaradené príspevky sú verejne prístupné. Keď si pripneš príspevok na svoj profil, toto je tiež verejne dostupnou informáciou. Tvoje príspevky sú takisto doručené tvojím sledovateľom, a to aj v rámci iných serverov, kde je potom uložená kópia tvojho príspevku. Ak vymažeš príspevok, táto akcia bude takisto doručená tvojím sledovateľom. Vyzdvihnutie, alebo obľúbenie iného príspevku je vždy verejne viditeľné.</li>
 
-      <li><em>Priame príspevky, a príspevky iba pre sledovateľov</em>: Všetky príspevky sú uložené a spracované na serveri. Príspevky iba pre sledovateľov sú doručené tvojím sledovateľom a užívateľom ktorí sú v nich spomenutí, pričom priame príspevky sú doručené iba tím užívateľom ktorí sú v nich spomenutí. V niektorých prípadoch to môže znamenať, že tieto príspevkz sú doručené aj v rámci iných serverov, a kópie príspevkov sú na nich uložené.
+      <li><em>Priame príspevky, a príspevky určené iba pre sledovateľov</em>: Všetky príspevky sú uložené a spracované na serveri. Príspevky iba pre sledovateľov sú doručené tvojím sledovateľom a užívateľom ktorí sú v nich spomenutí, pričom priame príspevky sú doručené iba tím užívateľom ktorí sú v nich spomenutí. V niektorých prípadoch to môže znamenať, že tieto príspevkz sú doručené aj v rámci iných serverov, a kópie príspevkov sú na nich uložené.
       V dobrej viere robíme všetko preto, aby bol prístup k tímto príspevkom vymedzený iba pre oprávnených používateľov, ale môže sa stať, že iné servery v tomto ohľade zlyhajú. Preto je dôležité prezrieť si a zhodnotiť, na aké servery patria tvoji následovatelia. V nastaveniach si môžeš zapnúť voľbu ručne povoľovať a odmietať nových následovateľov.
-      <em>Prosím maj na pamäti, že správcovia tvojho, aj vzdialeného obdŕžiavajúceho servera majú možnosť vidieť dané príspevky a správy, ale aj že obdŕžitelia týchto správ si ich môzu odfotiť, skopírovať, alebo ich inak zdieľať. <em>Nezdieľaj žiadne nebezpečné, alebo ohrozujúce správy pomocou Mastodonu!</em></li>
+      <em>Prosím maj na pamäti, že správcovia tvojho, aj vzdialeného obdŕžiavajúceho servera majú možnosť vidieť dané príspevky a správy, ale aj, že obdŕžitelia týchto správ si ich môzu odfotiť, skopírovať, alebo ich inak zdieľať. <em>Nezdieľaj žiadne nebezpečné, alebo ohrozujúce správy pomocou Mastodonu!</em></li>
 
-       <li><em>IPky a iné metadáta</em>: Keď sa prihlásiš, zaznamenáva sa IP adresa z ktorej si sa prihlásil/a, takisto ako aj názov tvojho prehliadača. Všetky zaznamenané sezóny sú pre teba dostupné na konktolu, alebo na zamietnutie prístupu v nastaveniach. Posledná použitá IP adresa je uložená až po dobu dvanástich mesiacov. Môžeme si tiež ponechať serverové záznamy, ktoré obsahujú IP adresu každej požiadavky na tento server.</li>
+      <li><em>IPky a iné metadáta</em>: Keď sa prihlásiš, zaznamenáva sa IP adresa z ktorej si sa prihlásil/a, takisto ako aj názov tvojho prehliadača. Všetky zaznamenané sezóny sú pre teba dostupné na konktolu, alebo na zamietnutie prístupu v nastaveniach. Posledná použitá IP adresa je uložená až po dobu dvanástich mesiacov. Môžeme si tiež ponechať serverové záznamy, ktoré obsahujú IP adresu každej požiadavky na tento server.</li>
       </ul>
 
       <hr class="spacer" />
 
-      <h3 id="use">
+      <h3 id="use">Načo sú tvoje údaje používané?</h3>
+
+      <p>Hociktorá z informácií, ktoré sú o tebe zozbierané, môže byť použité následujúcimi spôsobmi:</p>
+      <ul>
+      <li>Pre zabezpečenie základného fungovania Mastodonu. Narábať s užívateľským obsahom iných, ako aj prispievať svoj vlastný obsah, možeš len keď si prihlásený/á. Môžeš napríklad následovať iných ľudí, aby si potom videl/a ich príspevky v rámci svojej osobne prispôsobenej domácej osi.</li>
+      <li>Pre lepšie moderovanie komunity sa napríklad môže tvoja IP adresa porovnať s ostatnými už známimi adresami, aby bolo možné zistiť, či nedochádza napríklad k obchádzaniu pravidiel vylúčenia, aleb k iným porušeniam zásad.</li>
+      <li>Emailová adresa, ktorú poskytneš, môže byť použitá na zasielanie informácií, oboznámení keď ostatní užívatelia interaktujú s tvojím obsahom, alebo na posielanie správ, odpovedí na otázky a iné požiadavky.</li>
+      </ul>
     title: Podmienky užívania, a pravidlá súkromia pre %{instance}
   themes:
-    contrast: Vysoký kontrast
-    default: Mastodon
+    contrast: Mastodon (vysoký kontrast)
+    default: Mastodon (tmavý)
     mastodon-light: Mastodon (svetlý)
   time:
     formats:
       default: "%b %d, %R, %H:%M"
-      month: "%b %Y"
   two_factor_authentication:
     code_hint: Pre potvrdenie teraz zadaj kód vygenerovaný pomocou tvojej overovacej aplikácie
     description_html: Ak povolíš <strong> dvoj-faktorové overovanie</strong>, na prihlásenie potom budeš potrebovať svoj telefón, ktorý vygeneruje prístupové kódy, čo musíš zadať.
     disable: Zakáž
-    enable: Povoliť
+    enable: Povoľ
     enabled: Dvoj-faktorové overovanie je povolené
     enabled_success: Dvoj-faktorové overovanie bolo úspešne povolené
     generate_recovery_codes: Vygeneruj zálohové kódy
@@ -912,7 +941,7 @@ sk:
     warning:
       explanation:
         disable: Pokiaľ je tvoj účet zamrazený, tvoje dáta zostávajú nedoknuté, ale nemôžeš v rámci neho nič robiť, až kým nebude odomknutý.
-        silence: Kým je účet obmedzený, tvoje príspevky na tomto serveri uvidia iba tí ľudia, ktorí ťa už následujú, a môžeš byť vylúčený/á z rôznych verejných záznamov. Ostatní ťa však stále budú môcť následovať manuálne.
+        silence: Kým máš účet obmedzený, tvoje príspevky na tomto serveri uvidia iba tí ľudia, ktorí ťa už následujú, a môžeš byť vylúčený/á z rôznych verejných záznamov. Ostatní ťa však stále budú môcť následovať manuálne.
         suspend: Tvoj účet bol vylúčený, a všetky tvoje príspevky a nahraté médiálné súbory boli nenávratne zmazané z tohto serveru, a zo serverov na ktorých si mal následovateľov.
       review_server_policies: Prehodnoť pravidlá servera
       subject:
@@ -930,9 +959,9 @@ sk:
       edit_profile_step: Profil si môžeš prispôsobiť nahratím portrétu a hlavičky, môžeš upraviť svoje meno a viac. Pokiaľ chceš preverovať nových následovateľov predtým než ťa budú môcť sledovať, môžeš uzamknúť svoj účet.
       explanation: Tu nájdeš nejaké tipy do začiatku
       final_action: Začni prispievať
-      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.'
+      final_step: 'Začni písať! Aj bez následovateľov budú tvoje verejné príspevky videné ostatnými, napríklad na miestnej osi a pod haštagmi. Ak chceš, môžeš sa ostatným predstaviť pod haštagom #introductions.'
       full_handle: Adresa tvojho profilu v celom formáte
-      full_handle_hint: Toto je čo musíš dať vedieť svojím priateľom aby ti mohli posielať správy, alebo ťa následovať z inej instancie.
+      full_handle_hint: Toto je čo musíš dať vedieť svojím priateľom aby ti mohli posielať správy, alebo ťa následovať z iného serveru.
       review_preferences_action: Zmeniť nastavenia
       review_preferences_step: Daj si záležať na svojích nastaveniach, napríklad že aké emailové notifikácie chceš dostávať, alebo pod aký level súkromia sa tvoje príspevky majú sami automaticky zaradiť. Pokiaľ nemáš malátnosť z pohybu, môžeš si zvoliť aj automatické spúšťanie GIF animácií.
       subject: Vitaj na Mastodone
@@ -948,7 +977,7 @@ sk:
     invalid_otp_token: Neplatný kód pre dvojfaktorovú autentikáciu
     otp_lost_help_html: Pokiaľ si stratil/a prístup k obom, môžeš dať vedieť %{email}
     seamless_external_login: Si prihlásená/ý cez externú službu, takže nastavenia hesla a emailu ti niesú prístupné.
-    signed_in_as: 'Prihlásený ako:'
+    signed_in_as: 'Prihlásená/ý ako:'
   verification:
-    explanation_html: 'Môžeš sa <strong>overiť ako majiteľ odkazov v metadátach tvojho profilu</strong>. Na to musí ale odkazovaná stránka obsahovať odkaz späť na tvoj Mastodon profil. Tento spätný odkaz <strong>musí</strong> mať prívlastok <code>rel="me"</code>. Na texte odkazu nezáleží. Tu je príklad:'
+    explanation_html: 'Môžeš sa <strong>overiť ako majiteľ odkazov v metadátach tvojho profilu</strong>. Na to ale musí odkazovaná stránka obsahovať odkaz späť na tvoj Mastodon profil. Tento spätný odkaz <strong>musí</strong> mať prívlastok <code>rel="me"</code>. Na texte odkazu nezáleží. Tu je príklad:'
     verification: Overenie
diff --git a/config/locales/sl.yml b/config/locales/sl.yml
index 594c58acc1e73106d034de9d320bb9e98a27eca7..85e167ca9d8a2fc3a6c63a1d97dfe63488c4af3b 100644
--- a/config/locales/sl.yml
+++ b/config/locales/sl.yml
@@ -5,9 +5,7 @@ sl:
     about_mastodon_html: Mastodon je socialno omrežje, ki temelji na odprtih spletnih protokolih in prosti ter odprtokodni programski opremi. Je decentraliziran, kot e-pošta.
     about_this: O Mastodonu
     administered_by: 'Upravlja:'
-    api: API
     apps: Mobilne aplikacije
-    closed_registrations: Registracije so trenutno zaprte na tem vozlišču. Vendar! Tukaj lahko najdete druga vozlišča, na katerih se prijavite in dostopate do istega omrežja od tam.
     contact: Kontakt
     contact_missing: Ni nastavljeno
     contact_unavailable: Ni na voljo
@@ -15,32 +13,22 @@ sl:
     extended_description_html: |
       <h3>Dober prostor za pravila</h3>
       <p>Razširjen opis še ni bil nastavljen.</p>
-    features:
-      humane_approach_body: Na podlagi učenja od neuspehov drugih omrežij, želi Mastodon oblikovati etične načrte za boj proti zlorabi socialnih medijev.
-      humane_approach_title: Bolj human pristop
-      not_a_product_body: Mastodon ni komercialno omrežje. Brez oglaševanja, brez podatkovnega rudarjenja, brez obzidanih vrtov. Ni osrednjega organa.
-      not_a_product_title: Ti si oseba, ne izdelek
-      real_conversation_body: S 500 znaki, ki so vam na voljo, in podporo za zrnate vsebine ter opozorila pred mediji, se lahko izrazite tako, kot želite.
-      real_conversation_title: Zgrajen za pravi pogovor
-      within_reach_body: Zahvaljujoč razvijalcem prijaznemu API ekosistemu, obstaja več aplikacija za iOS, Arduino in druge platforme, ki vam omogočajo, da sledite svojim prijateljem kjerkoli.
-      within_reach_title: Vedno na dosegu roke
     generic_description: "%{domain} je en strežnik v omrežju"
     hosted_on: Mastodon gostuje na %{domain}
     learn_more: Spoznaj več
-    other_instances: Seznam vozlišč
     privacy_policy: Politika zasebnosti
     source_code: Izvorna koda
     status_count_after:
       few: stanja
       one: stanje
-      other: stanja
+      other: stanj
       two: stanja
-    status_count_before: Kdo je avtor
+    status_count_before: Ki so avtorji
     terms: Pogoji storitve
     user_count_after:
       few: uporabniki
       one: uporabnik
-      other: uporabniki
+      other: uporabnikov
       two: uporabniki
     user_count_before: Dom za
     what_is_mastodon: Kaj je Mastodon?
@@ -54,6 +42,7 @@ sl:
       two: Sledilci
     following: Sledim
     joined: Se je pridružil na %{date}
+    last_active: zadnji aktivni
     link_verified_on: Lastništvo te povezave je bilo preverjeno na %{date}
     media: Medij
     moved_html: "%{name} se je prestavil na %{new_profile_link}:"
@@ -74,17 +63,18 @@ sl:
     roles:
       admin: Skrbnik
       bot: Robot
-      moderator: Mod
     unfollow: Prenehaj slediti
   admin:
+    account_actions:
+      action: Izvedi dejanje
+      title: Izvedi moderirano dejanje %{acct}
     account_moderation_notes:
-      create: Pusti sporočilo
+      create: Pusti opombo
       created_msg: Uspešno ustvarjena opomba moderiranja!
       delete: Izbriši
       destroyed_msg: Moderirana opomba je uspešno uničena!
     accounts:
       are_you_sure: Ali si prepričan?
-      avatar: Avatar
       by_domain: Domena
       change_email:
         changed_msg: E-pošta računa je uspešno spremenjena!
@@ -96,6 +86,7 @@ sl:
       confirm: Potrdi
       confirmed: Potrjeno
       confirming: Potrjujem
+      deleted: Izbrisano
       demote: Ponižaj
       disable: Onemogoči
       disable_two_factor_authentication: Onemogoči 2FA
@@ -111,8 +102,10 @@ sl:
       followers: Sledilci
       followers_url: URL sledilci
       follows: Sledi
+      header: Glava
       inbox_url: URl v mapi "Prejeto"
-      ip: IP
+      invited_by: Povabljen od
+      joined: Pridružil
       location:
         all: Vse
         local: Lokalno
@@ -122,6 +115,7 @@ sl:
       media_attachments: Medijske priloge
       memorialize: Spremenite v spomin
       moderation:
+        active: Dejaven
         all: Vse
         silenced: Utišan
         suspended: Suspendiran
@@ -129,7 +123,277 @@ sl:
       moderation_notes: Opombe moderiranja
       most_recent_activity: Zadnja aktivnost
       most_recent_ip: Zadnji IP
+      no_limits_imposed: Brez omejitev
+      not_subscribed: Ni naročeno
+      outbox_url: URl za pošiljanje
+      perform_full_suspension: Začasno ustavi
+      profile_url: URL profila
       promote: Spodbujanje
+      protocol: Protokol
+      public: Javen
+      push_subscription_expires: Naročnina PuSH preteče
+      redownload: Osveži profil
+      remove_avatar: Odstrani podobo
+      remove_header: Odstrani glavo
+      resend_confirmation:
+        already_confirmed: Ta uporabnik je že potrjen
+        send: Ponovno pošlji potrditveno e-pošto
+        success: Potrditvena e-pošta je uspešno poslana!
+      reset: Ponastavi
+      reset_password: Ponastavi geslo
+      resubscribe: Ponovno se naroči
+      role: Dovoljenja
+      roles:
+        admin: Skrbnik
+        staff: Osebje
+        user: Uporabnik
+      search: Poišči
+      shared_inbox_url: URL mape "Prejeto v skupni rabi"
+      show:
+        created_reports: Narejene prijave
+        targeted_reports: Prijavili drugi
+      silence: Utišaj
+      silenced: Utišan
+      statuses: Stanja
+      subscribe: Naroči
+      suspended: Suspendiran
+      title: Računi
+      unconfirmed_email: Nepotrjena e-pošta
+      undo_silenced: Razveljavi utišanje
+      undo_suspension: Razveljavi suspendiranje
+      unsubscribe: Odjavi se od naročnine
+      username: Uporabniško ime
+      warn: Opozori
+      web: Splet
+    action_logs:
+      actions:
+        assigned_to_self_report: "%{name} je prijavil %{target} sebi"
+        change_email_user: "%{name} je spremenil naslov e-pošte uporabnika %{target}"
+        confirm_user: "%{name} je potrdil naslov e-pošte uporabnika %{target}"
+        create_account_warning: "%{name} je poslal opozorilo %{target}"
+        create_custom_emoji: "%{name} je poslal nove emotikone %{target}"
+        create_domain_block: "%{name} je blokiral domeno %{target}"
+        create_email_domain_block: "%{name} je dal na črni seznam e-pošto domene %{target}"
+        demote_user: "%{name} je degradiral uporabnika %{target}"
+        destroy_custom_emoji: "%{name} je uničil emotikon %{target}"
+        destroy_domain_block: "%{name} je odblokiral domeno %{target}"
+        destroy_email_domain_block: "%{name} je dal na beli seznam e-pošto domene %{target}"
+        destroy_status: "%{name} je odstranil stanje od %{target}"
+        disable_2fa_user: "%{name} je onemogočil dvofaktorsko zahtevo za uporabnika %{target}"
+        disable_custom_emoji: "%{name} je onemogočil emotikon %{target}"
+        disable_user: "%{name} je onemogočil prijavo za uporabnika %{target}"
+        enable_custom_emoji: "%{name} je omogočil emotikon %{target}"
+        enable_user: "%{name} je omogočil prijavo za uporabnika %{target}"
+        memorialize_account: "%{name} je spremenil račun od %{target} v stran spominov"
+        promote_user: "%{name} je spodbudil uporabnika %{target}"
+        remove_avatar_user: "%{name} je odstranil podobo od %{target}"
+        reopen_report: "%{name} je ponovno odprl prijavo %{target}"
+        reset_password_user: "%{name} je ponastavil geslo od uporabnika %{target}"
+        resolve_report: "%{name} je razrešil prijavo %{target}"
+        silence_account: "%{name} je utišal račun od %{target}"
+        suspend_account: "%{name} je začasno ustavil račun od %{target}"
+        unassigned_report: "%{name} je nedodeljeno prijavil %{target}"
+        unsilence_account: "%{name} je preklical utišanje računa od %{target}"
+        unsuspend_account: "%{name} je aktiviral račun od %{target}"
+        update_custom_emoji: "%{name} je posodobil emotikone %{target}"
+        update_status: "%{name} je posodobil stanje od %{target}"
+      deleted_status: "(izbrisano stanje)"
+      title: Dnevnik revizije
+    custom_emojis:
+      by_domain: Domena
+      copied_msg: Lokalna kopija emotikona je bila uspešno ustvarjena
+      copy: Kopiraj
+      copy_failed_msg: Lokalne kopije emotikona ni bilo mogoče ustvariti
+      created_msg: Emotikon je uspešno ustvarjen!
+      delete: Izbriši
+      destroyed_msg: Emotikon je uspešno uničen!
+      disable: Onemogoči
+      disabled_msg: Ta emotikon je uspešno onemogočen
+      emoji: Emotikon
+      enable: Omogoči
+      enabled_msg: Ta emotikon je uspešno omogočen
+      image_hint: PNG do 50KB
+      listed: Navedeno
+      new:
+        title: Dodaj nove emotikone
+      overwrite: Prepiši
+      shortcode: Kratka koda
+      shortcode_hint: Najmanj 2 znaka, samo alfanumerični znaki in podčrtaji
+      title: Emotikoni po meri
+      unlisted: Neuvrščeni
+      update_failed_msg: Tega emotikona ni bilo mogoče posodobiti
+      updated_msg: Emotikon je uspešno posodobljen!
+      upload: Pošlji
+    dashboard:
+      backlog: Zaostala opravila
+      config: Nastavitve
+      feature_deletions: Brisanje računov
+      feature_invites: Poveza povabil
+      feature_profile_directory: Mapa profila
+      feature_registrations: Registracije
+      feature_relay: Rele federacije
+      features: Zmožnosti
+      hidden_service: Federacija s skritimi storitvami
+      open_reports: odprte prijave
+      recent_users: Nedavni uporabniki
+      search: Iskanje po celotnem besedilu
+      single_user_mode: Način enega uporabnika
+      software: Programska oprema
+      space: Uporaba prostora
+      title: Nadzorna plošča
+      total_users: Skupaj uporabnikov
+      trends: Trendi
+      week_interactions: interakcije ta teden
+      week_users_active: aktivni ta teden
+      week_users_new: uporabniki ta teden
+    domain_blocks:
+      add_new: Dodaj nov domenski blok
+      created_msg: Domenski blok se sedaj obdeluje
+      destroyed_msg: Domenski blok je bil razveljavljen
+      domain: Domena
+      new:
+        create: Ustvari blok
+        hint: Domenski blok ne bo preprečil ustvarjanja vnosov računov v zbirko podatkov, ampak bo retroaktivno in samodejno uporabil posebne metode moderiranja na teh računih.
+        severity:
+          desc_html: "<strong>Utišaj</strong> bo vse objave računa naredil nevidne vsem, ki jih ne sledijo. <strong>Suspendiraj</strong> bo odstranil vso vsebino, medije in podatke profila računa. Uporabi <strong>nič</strong>, če želite le zavrniti predstavnostne datoteke."
+          noop: Nič
+          silence: Utišaj
+          suspend: Suspendiraj
+        title: Nov domenski blok
+      reject_media: Zavrni predstavnostne datoteke
+      reject_media_hint: Odstrani lokalno shranjene predstavnostne datoteke in zavrača prenašanje le-teh v prihodnosti. Za suspenzije ni pomembno
+      reject_reports: Zavrnjene prijave
+      reject_reports_hint: Prezri vse prijave, ki pridejo iz te domene. Za suspenzije ni pomembno
+      rejecting_media: zavrnitev predstavnostnih datotek
+      rejecting_reports: zavrnitev prijav
+      severity:
+        silence: utišani
+        suspend: suspendirani
+      show:
+        affected_accounts:
+          few: "%{count} računov v bazi podatkov so prizadeti"
+          one: En račun v bazi podatkov je prizadet
+          other: "%{count} računov v bazi podatkov so prizadeti"
+          two: "%{count} računov v bazi podatkov so prizadeti"
+        retroactive:
+          silence: Prekliči utišanje za vse obstoječe račune iz te domene
+          suspend: Odsuspendiraj vse obstoječe račune iz te domene
+        title: Razveljavi domenski blok za %{domain}
+        undo: Razveljavi
+      undo: Razveljavi domenski blok
+    email_domain_blocks:
+      add_new: Dodaj novo
+      created_msg: Domena e-pošte je bila uspešno dodana na črni seznam
+      delete: Izbriši
+      destroyed_msg: Domena e-pošte je bila uspešno izbrisana iz črnega seznama
+      domain: Domena
+      new:
+        create: Dodaj domeno
+        title: Nov vnos e-pošte na črni seznam
+      title: Črni seznam e-pošte
+    followers:
+      back_to_account: Nazaj na račun
+      title: Sledilci od %{acct}
+    instances:
+      delivery_available: Na voljo je dostava
+      known_accounts:
+        few: "%{count} znanih računov"
+        one: "%{count} znan račun"
+        other: "%{count} znanih računov"
+        two: "%{count} znanih računov"
+      moderation:
+        all: Vse
+        limited: Omejeno
+        title: Moderiranje
+      title: Federacija
+      total_blocked_by_us: Blokirano iz naše strani
+      total_followed_by_them: Oni ti sledijo
+      total_followed_by_us: Mi ti sledimo
+      total_reported: Poročila o njih
+      total_storage: Predstavnostne priloge
+    invites:
+      deactivate_all: Onemogoči vse
+      filter:
+        all: Vse
+        available: Razpoložljivo
+        expired: Potekel
+      title: Povabila
+    relays:
+      add_new: Dodaj nov rele
+      delete: Izbriši
+      description_html: "<strong>Rele federacije</strong> je posredniški strežnik, ki si izmenjuje velike količine javnih trobov med strežniki, ki so se naročili in objavili na njem. <strong>Majhnim in srednjim strežnikom lahko pomaga pri odkrivanju vsebine iz sistema fediverse</strong>, kar bi sicer zahtevalo, da lokalni uporabniki ročno sledijo druge osebe na oddaljenih strežnikih."
+      disable: Onemogoči
+      disabled: Onemogočeno
+      enable: Omogoči
+      enable_hint: Ko je omogočen, se bo vaš strežnik naročil na vse javne trobe iz tega releja in začel pošiljati javne trobe tega strežnika.
+      enabled: Omogočeno
+      inbox_url: URL releja
+      pending: ÄŒakanje na odobritev releja
+      save_and_enable: Shrani in omogoči
+      setup: Nastavi povezavo releja
+      status: Stanje
+      title: Releji
+    report_notes:
+      created_msg: Opomba o prijavi je uspešno ustvarjena!
+      destroyed_msg: Opomba o prijavi je uspešno izbrisana!
+    reports:
+      account:
+        note: opomba
+        report: prijava
+      action_taken_by: Dejanje, ki ga je sprejel
+      are_you_sure: Ali ste prepričani?
+      assign_to_self: Dodeli meni
+      assigned: Dodeljen moderator
+      comment:
+        none: Nič
+      created_at: Prijavljeno
+      mark_as_resolved: Označi kot rešeno
+      mark_as_unresolved: Označi kot nerešeno
+      notes:
+        create: Dodaj opombo
+        create_and_resolve: Razreši z opombo
+        create_and_unresolve: Ponovo odpri z opombo
+        delete: Izbriši
+        placeholder: Opišite dejanja, ki ste jih izvedli, ali katere koli druge posodobitve...
+      reopen: Ponovno odpri prijavo
+      report: 'Prijavi #%{id}'
+      reported_account: Prijavljeni račun
+      reported_by: Prijavljen od
+      resolved: Razrešeno
+      resolved_msg: Prijava je uspešno razrešena!
+      status: Stanje
+      title: Prijave
+      unassign: Odstopi
+      unresolved: Nerešeno
+      updated_at: Posodobljen
+    settings:
+      activity_api_enabled:
+        desc_html: Å tevilke lokalno objavljenih stanj, aktivnih uporabnikov in novih registracij na tedenskih seznamih
+        title: Objavi združeno statistiko o dejavnosti uporabnikov
+      bootstrap_timeline_accounts:
+        desc_html: Več uporabniških imen ločite z vejico. Deluje samo na lokalnih in odklenjenih računih. Privzeto, ko je prazno, pri vseh lokalnih skrbnikih.
+        title: Privzeta sledenja za nove uporabnike
+      contact_information:
+        email: Poslovna e-pošta
+        username: Uporabniško ime stika
+      custom_css:
+        desc_html: Spremeni videz z naloženim CSS na vsaki strani
+        title: CSS po meri
+  errors:
+    '403': You don't have permission to view this page.
+    '404': The page you are looking for isn't here.
+    '410': The page you were looking for doesn't exist here anymore.
+    '422': 
+    '429': Throttled
+    '500': 
+  invites:
+    expires_in:
+      '1800': 30 minutes
+      '21600': 6 hours
+      '3600': 1 hour
+      '43200': 12 hours
+      '604800': 1 week
+      '86400': 1 day
   statuses:
     pin_errors:
       ownership: Trob nekoga drugega ne more biti pripet
diff --git a/config/locales/sq.yml b/config/locales/sq.yml
new file mode 100644
index 0000000000000000000000000000000000000000..6cab033321008a32681f8dcb10d0b8dc67bda20b
--- /dev/null
+++ b/config/locales/sq.yml
@@ -0,0 +1,909 @@
+---
+sq:
+  about:
+    about_hashtag_html: Këto janë mesazhe publike të etiketuar me <strong>#%{hashtag}</strong>. Mundeni të ndërveproni me ta, nëse keni një llogari kudo qoftë në fediverse.
+    about_mastodon_html: Mastodon-i është një rrjet shoqëror i bazuar në protokolle web të hapur dhe në software të lirë, me burim të hapur. Është i decentralizuar, si email-ii.
+    about_this: Mbi
+    administered_by: 'Administruar nga:'
+    apps: Aplikacione për celular
+    contact: Kontakt
+    contact_missing: I parregulluar
+    documentation: Dokumentim
+    extended_description_html: |
+      <h3>Një vend i mirë për rregulla</h3>
+      <p>Përshkrimi i zgjeruar s’është sajuar ende.</p>
+    generic_description: "%{domain} është një shërbyes te rrjeti"
+    hosted_on: Mastodon i strehuar në %{domain}
+    learn_more: Mësoni më tepër
+    privacy_policy: Rregulla privatësie
+    source_code: Kod burim
+    status_count_after:
+      one: gjendje
+      other: gjendje
+    status_count_before: Cili krijoi
+    terms: Kushte shërbimi
+    user_count_after:
+      one: përdorues
+      other: përdorues
+    what_is_mastodon: Ç’është Mastodon-i?
+  accounts:
+    choices_html: 'Zgjedhje të %{name}:'
+    follow: Ndiqeni
+    followers:
+      one: Ndjekës
+      other: Ndjekës
+    following: Ndjekje
+    joined: U bë pjesë më %{date}
+    last_active: aktiv së fundi
+    link_verified_on: Pronësia e kësaj lidhjeje qe kontrolluar më %{date}
+    moved_html: "%{name} ka kaluar te %{new_profile_link}:"
+    network_hidden: Këto të dhëna nuk mund të kihen
+    nothing_here: S’ka gjë këtu!
+    people_followed_by: Persona të ndjekur nga %{name}
+    people_who_follow: Persona që ndjekin %{name}
+    pin_errors:
+      following: Duhet ta ndiqni tashmë personin që doni të pasqyroni
+    posts:
+      one: Mesazh
+      other: Mesazhe
+    posts_tab_heading: Mesazhe
+    posts_with_replies: Mesazhe dhe përgjigje
+    reserved_username: Emri i përdoruesit është i ruajtur për dikë
+    roles:
+      admin: Përgjegjës
+    unfollow: Resht së ndjekuri
+  admin:
+    account_actions:
+      action: Kryeje veprimin
+      title: Kryeni veprim moderimi te %{acct}
+    account_moderation_notes:
+      create: Lini një shënim
+      created_msg: Shënimi i moderimit u krijua me sukses!
+      delete: Fshije
+      destroyed_msg: Shënimi i moderimit u asgjësua me sukses!
+    accounts:
+      are_you_sure: A jeni i sigurt?
+      by_domain: Përkatësi
+      change_email:
+        changed_msg: Email-i i llogarisë u ndryshua me sukses!
+        current_email: Email-i i tanishëm
+        label: Ndrysho email-in
+        new_email: Email i ri
+        submit: Ndrysho email-in
+        title: Ndrysho email-in për %{username}
+      confirm: Ripohojeni
+      confirmed: U ripohua
+      confirming: Po ripohohet
+      deleted: U fshi
+      demote: Zhgradoje
+      disable: Çaktivizoje
+      disable_two_factor_authentication: Çaktivizoni 2FA
+      disabled: E çaktivizuar
+      display_name: Emër në ekran
+      domain: Përkatësi
+      edit: Përpunojeni
+      email_status: Gjendje email-i
+      enable: Aktivizoje
+      enabled: E aktivizuar
+      feed_url: URL prurjeje
+      followers: Ndjekës
+      followers_url: URL Ndjekësish
+      follows: Ndjekje
+      header: Krye
+      inbox_url: URL Mesazhesh të Marrë
+      invited_by: Ftuar nga
+      joined: U bë pjesë
+      location:
+        all: Krejt
+        local: Vendore
+        remote: E largët
+        title: Vendndodhje
+      login_status: Gjendje hyrjeje
+      media_attachments: Bashkëngjitje media
+      memorialize: Shndërroje në përkujtimore
+      moderation:
+        active: Aktiv
+        all: Krejt
+        silenced: U heshtua
+        suspended: Të pezulluara
+        title: Moderim
+      moderation_notes: Shënime moderimesh
+      most_recent_activity: Veprimtaria më e freskët
+      most_recent_ip: IP-ja më e freskët
+      no_limits_imposed: Pa imponim kufijsh
+      not_subscribed: Jo i pajtuar
+      outbox_url: URL Mesazhesh të Dërguar
+      perform_full_suspension: Pezulloje
+      profile_url: URL profili
+      promote: Promovojeni
+      protocol: Protokoll
+      public: Publike
+      push_subscription_expires: Pajtimi PuSH skadon më
+      redownload: Rifresko profilin
+      remove_avatar: Hiqe avatarin
+      remove_header: Hiqe kryen
+      resend_confirmation:
+        already_confirmed: Ky përdorues është i ripohuar tashmë
+        send: Ridërgo email ripohimi
+        success: Email-i i ripohimit u dërgua me sukses!
+      reset: Riktheje te parazgjedhjet
+      reset_password: Ricaktoni fjalëkalimin
+      resubscribe: Ripajtohuni
+      role: Leje
+      roles:
+        admin: Përgjegjës
+        staff: Staf
+        user: Përdorues
+      search: Kërkoni
+      shared_inbox_url: URL kutie të përbashkët mesazesh
+      show:
+        created_reports: Ka bërë raportime
+        targeted_reports: Raportuar nga të tjerë
+      silence: Heshtoje
+      silenced: E heshtuar
+      statuses: Gjendje
+      subscribe: Pajtomë
+      suspended: Të pezulluara
+      title: Llogari
+      unconfirmed_email: Email i paripohuar
+      undo_silenced: Zhbëje heshtjen
+      undo_suspension: Zhbëje pezullimin
+      unsubscribe: Shpajtohuni
+      username: Emër përdoruesi
+      warn: Sinjalizoje
+    action_logs:
+      actions:
+        assigned_to_self_report: "%{name} ia kaloi raportimin %{target} në ngarkim vetvetes"
+        change_email_user: "%{name} ndryshoi adresën email të përdoruesit %{target}"
+        confirm_user: "%{name} ripohoi adresën email të përdoruesit %{target}"
+        create_account_warning: "%{name} dërgoi një sinjalizim për %{target}"
+        create_custom_emoji: "%{name} ngarkoi emotikon të ri %{target}"
+        create_domain_block: "%{name} bllokoi përkatësinë %{target}"
+        create_email_domain_block: "%{name} e shtoi në listë bllokimesh përkatësinë %{target}"
+        demote_user: "%{name} zhgradoi përdoruesin %{target}"
+        destroy_custom_emoji: "%{name} asgjësoi emotikonin %{target}"
+        destroy_domain_block: "%{name} zhbllokoi përkatësinë %{target}"
+        destroy_email_domain_block: "%{name} e shtoi në listë të lejuarash përkatësinë %{target}"
+        destroy_status: "%{name} hoqi gjendje nga %{target}"
+        disable_2fa_user: "%{name} çaktivizoi domosdoshmëritë për dyfaktorësh për përdoruesin %{target}"
+        disable_custom_emoji: "%{name} çaktivizoi emotikonin %{target}"
+        disable_user: "%{name} çaktivizoi hyrje për përdoruesin %{target}"
+        enable_custom_emoji: "%{name} aktivizoi emotikonin %{target}"
+        enable_user: "%{name} aktivizoi hyrje për përdoruesin %{target}"
+        memorialize_account: "%{name} e shndërroi llogarinë e %{target} në një faqe përkujtimore"
+        promote_user: "%{name} gradoi përdoruesin %{target}"
+        remove_avatar_user: "%{name} hoqi avatarin e %{target}"
+        reopen_report: "%{name} rihapi raportimin %{target}"
+        reset_password_user: "%{name} ricaktoi fjalëkalimi për përdoruesin %{target}"
+        resolve_report: "%{name} zgjidhi raportimin %{target}"
+        silence_account: "%{name} heshtoi llogarinë e %{target}"
+        suspend_account: "%{name} pezulloi llogarinë e %{target}"
+        unassigned_report: "%{name} rihapi raportimin %{target}"
+        unsilence_account: "%{name} hoqi heshtimin për llogarinë %{target}"
+        unsuspend_account: "%{name} hoqi pezullimin për llogarinë e %{target}"
+        update_custom_emoji: "%{name} përditësoi emotikonin %{target}"
+        update_status: "%{name} përditësoi gjendjen me %{target}"
+      deleted_status: "(fshiu gjendjen)"
+      title: Auditim regjistri
+    custom_emojis:
+      by_domain: Përkatësi
+      copied_msg: Kopja vendore e emotikonëve u krijua me sukses
+      copy: Kopjoje
+      copy_failed_msg: S’u bë dot një kopje vendore e emotikoneve
+      created_msg: Emotikoni u krijua me sukses!
+      delete: Fshije
+      destroyed_msg: Emotikoni u asgjësua me sukses!
+      disable: Çaktivizoje
+      disabled_msg: Ai emotikon u çaktivizua me sukses
+      emoji: Emotikon
+      enable: Aktivizoje
+      enabled_msg: Ai emotikon u aktivizua me sukses
+      image_hint: PNG deri 50KB
+      listed: Në listë
+      new:
+        title: Shtoni emotikon të ri vetjak
+      overwrite: Mbishkruaje
+      shortcode: Kod i shkurtër
+      shortcode_hint: Të paktën 2 shenja, vetëm shenja alfanumerike dhe nënvija
+      title: Emotikone vetjake
+      unlisted: Hequr prej liste
+      update_failed_msg: S’u përditësua dot ai emotikon
+      updated_msg: Emotikoni u përditësua me sukses!
+      upload: Ngarkoje
+    dashboard:
+      backlog: punë të prapambetura
+      config: Formësim
+      feature_deletions: Fshirje llogarish
+      feature_invites: Lidhje ftesash
+      feature_profile_directory: Drejtori profilesh
+      feature_registrations: Regjistrime
+      feature_relay: Rele federimi
+      features: Veçori
+      hidden_service: Federim me shërbime të fshehura
+      open_reports: raportime të hapur
+      recent_users: Përdorues së fundi
+      search: Kërko tekstin e plotë
+      single_user_mode: Mënyrë me përdorues të vetëm
+      space: Përdorim hapësire
+      title: Pult
+      total_users: përdorues gjithsej
+      trends: Tendenca
+      week_interactions: ndërveprime këtë javë
+      week_users_active: aktivë këtë javë
+      week_users_new: përdorues këtë javë
+    domain_blocks:
+      add_new: Shtoni bllokim të ri përkatësie
+      created_msg: Bllokimi i përkatësisë tani po përpunohet
+      destroyed_msg: Bllokimi i përkatësisë u hoq
+      domain: Përkatësi
+      new:
+        create: Krijoni bllokim
+        hint: Bllokimi i përkatësisë nuk do të pengojë krijim zërash llogarie te baza e të dhënave, por do të aplikojë në mënyrë retroaktive dhe të vetvetishme metoda specifike moderimi mbi këto llogari.
+        severity:
+          desc_html: "<strong>Heshtja</strong> do t’i bëjë postimet e llogarisë të padukshme për këdo që nuk i ndjek ato. <strong>Pezullimi</strong> do të heqë krejt lëndën e llogarisë, media, dhe të dhëna profili. Përdorni <strong>Asnjë</strong>, nëse thjesht doni të mos pranohen kartela media."
+          noop: Asnjë
+          silence: Heshtoji
+          suspend: Pezulloje
+        title: Bllokim i ri përkatësie
+      reject_media: Mos prano kartela media
+      reject_media_hint: Heq kartela media të depozituara lokalisht dhe nuk pranon të shkarkohen të tilla në të ardhmen. Pa peshë për pezullimet
+      reject_reports: Hidh tej raportimet
+      reject_reports_hint: Shpërfillini krejt raportimet e ardhura nga kjo përkatësi. Pa peshë për pezullimet
+      rejecting_media: mospranim kartelash media
+      rejecting_reports: mospranim raportimesh
+      severity:
+        silence: e heshtuar
+        suspend: e pezulluar
+      show:
+        affected_accounts:
+          one: Pat ndikim te një llogari në bazën e të dhënave
+          other: Pat ndikim te %{count} llogari në bazën e të dhënave
+        retroactive:
+          silence: Hiqu heshtimin krejt llogarive ekzistuese nga kjo përkatësi
+          suspend: Hiqu pezullimin krejt llogarive ekzistuese nga kjo përkatësi
+        title: Zhbëje bllokimin e përkatësisë për %{domain}
+        undo: Zhbëje
+      undo: Zhbëje bllokimin e përkatësisë
+    email_domain_blocks:
+      add_new: Shtoni të ri
+      created_msg: Përkatësia email u shtua me sukses te lista e bllokimeve
+      delete: Fshije
+      destroyed_msg: Përkatësia email u fshi me sukses nga lista e bllokimeve
+      domain: Përkatësi
+      new:
+        create: Shtoni përkatësi
+        title: Zë i ri email në listë bllokimesh
+      title: Listë bllokimesh email-esh
+    followers:
+      back_to_account: Mbrapsht Te Llogaria
+      title: Ndjekës të %{acct}
+    instances:
+      delivery_available: Ka shpërndarje të mundshme
+      known_accounts:
+        one: "%{count} llogari e njohur"
+        other: "%{count} llogari të njohura"
+      moderation:
+        all: Krejt
+        limited: E kufizuar
+        title: Moderim
+      title: Federim
+      total_blocked_by_us: Bllokuar nga ne
+      total_followed_by_them: Ndjekur prej tyre
+      total_followed_by_us: Ndjekur nga ne
+      total_reported: Raportime rreth tyre
+      total_storage: Bashkëngjitje media
+    invites:
+      deactivate_all: Çaktivizoji krejt
+      filter:
+        all: Krejt
+        available: I përdorshëm
+        expired: I skaduar
+        title: Filtër
+      title: Ftesa
+    relays:
+      add_new: Shtoni rele të re
+      delete: Fshije
+      description_html: Një <strong>rele federimesh</strong> është një shërbyes ndërmjetës që shkëmben vëllime të mëdha mesazhesh publike mes shërbyesve që janë pajtuar në të dhe publikojnë në të. <strong>Mund t’u vijë në ndihmë shërbyesve të vegjël dhe të mesëm të gjejnë lëndë nga fediversi</strong>, gjë që përndryshe do të kërkonte që përdoruesit vendorë të ndiqnin dorazi persona të tjerë nëpër shërbyes të largët.
+      disable: Çaktivizoje
+      disabled: E çaktivizuar
+      enable: Aktivizoje
+      enable_hint: Pasi të aktivizohet, shërbyesi juaj do të pajtohet te krejt mesazhet publike prej kësaj releje, dhe do të fillojë të dërgojë në të mesazhet publike të këtij shërbyesi.
+      enabled: E aktivizuar
+      inbox_url: URL releje
+      pending: Në pritje të miratimit të relesë
+      save_and_enable: Ruaje dhe aktivizoje
+      setup: Ujdisni një lidhje releje
+      status: Gjendje
+      title: Rele
+    report_notes:
+      created_msg: Shënimi i raportimit u krijua me sukses!
+      destroyed_msg: Shënimi i raportimit u fshi me sukses!
+    reports:
+      account:
+        note: shënim
+        report: raportojeni
+      action_taken_by: Veprimi i ndërmarrë nga
+      are_you_sure: A jeni i sigurt?
+      assign_to_self: Caktojani vetes
+      assigned: Iu caktua moderator
+      comment:
+        none: Asnjë
+      created_at: Raportuar më
+      mark_as_resolved: Vëri shenjë si i zgjidhur
+      mark_as_unresolved: Vëri shenjë si të pazgjidhur
+      notes:
+        create: Shtoni shënim
+        create_and_resolve: Zgjidhe me shënim
+        create_and_unresolve: Rihape me shënim
+        delete: Fshije
+        placeholder: Përshkruani ç’veprime janë ndërmarrë, ose çfarëdo përditësimi tjetër që lidhet me të…
+      reopen: Rihape raportimin
+      report: 'Raportim #%{id}'
+      reported_account: Llogari e raportuar
+      reported_by: Raportuar nga
+      resolved: I zgjidhur
+      resolved_msg: Raportimi u zgjidh me sukses!
+      status: Gjendje
+      title: Raportime
+      unassign: Hiqja
+      unresolved: Të pazgjidhur
+      updated_at: U përditësua më
+    settings:
+      activity_api_enabled:
+        desc_html: Numër gjendjesh të postuara lokalisht, përdorues aktivë, dhe regjistrime të reja në kosha javorë
+        title: Botoni statistika përmbledhëse mbi veprimtarinë e përdoruesve
+      bootstrap_timeline_accounts:
+        desc_html: Emrat e përdoruesve ndajini prej njëri-tjetrit me presje. Do të funksionojë vetëm për llogari vendore dhe të pakyçura. Si parazgjedhje, kur lihet e zbrazët, është krejt përgjegjësit vendorë.
+        title: Ndjekje parazgjedhje për përdorues të rinj
+      contact_information:
+        email: Email biznesi
+        username: Emër përdoruesi kontakti
+      custom_css:
+        desc_html: Modifikojeni pamjen me CSS të nagrkuar në çdo faqe
+        title: CSS Vetjake
+      hero:
+        desc_html: E shfaqur në faqen ballore. Këshillohet të paktën 600x100px. Kur nuk caktohet gjë, përdoret miniaturë e shërbyesit
+        title: Figurë heroi
+      mascot:
+        desc_html: E shfaqur në faqe të shumta. Këshillohet të paktën 293x205. Kur nuk caktohet gjë, përdoret simboli parazgjedhje
+        title: Figurë simboli
+      peers_api_enabled:
+        desc_html: Emra përkatësish që ka hasur në fedivers ky shërbyes
+        title: Boto listë shërbyesish të gjetur
+      preview_sensitive_media:
+        desc_html: Në sajte të tjera, paraparjet e lidhjeve do të shfaqin një miniaturë, edhe pse medias i është vënë shenjë si rezervat
+        title: Shfaq në paraparje OpenGraph media me shenjën rezervat
+      profile_directory:
+        desc_html: Lejoju përdoruesve të jenë të zbulueshëm
+        title: Aktivizo drejtori profilesh
+      registrations:
+        closed_message:
+          desc_html: E shfaqur në faqen ballore, kur regjistrimet janë të mbyllura. Mund të përdorni etiketa HTML
+          title: Mesazh mbylljeje regjistrimesh
+        deletion:
+          desc_html: Lejo këdo të fshijë llogarinë e vet
+          title: Hapni fshirje llogarie
+        min_invite_role:
+          disabled: Asnjë
+          title: Lejo vetëm me ftesa
+      show_known_fediverse_at_about_page:
+        desc_html: Kur përdoret, do të shfaqë mesazhe prej krejt fediversit të njohur, si paraparje. Përndryshe do të shfaqë vetëm mesazhe vendore.
+        title: Shfaq te paraparja e rrjedhës kohore fedivers të njohur
+      show_staff_badge:
+        desc_html: Shfaq një stemë stafi në faqen e një përdoruesi
+        title: Shfaq stemë stafi
+      site_description:
+        desc_html: Paragraf hyrës te faqja ballore. Përshkruani ç’e bën special këtë shërbyes Mastodon dhe çfarëdo gjëje tjetër të rëndësishme. Mund të përdorni etiketa HTML, veçanërisht <code>&lt;a&gt;</code> dhe <code>&lt;em&gt;</code>.
+        title: Përshkrim shërbyesi
+      site_description_extended:
+        desc_html: Një vend i mirë për kodin e sjelljes në shërbyesin tuaj, rregulla, udhëzime dhe gjëra të tjera që e bëjnë të veçantë këtë shërbyes. Mund të përdorni etiketa HTML
+        title: Informacion i zgjeruar vetjak
+      site_short_description:
+        desc_html: E shfaqur në anështyllë dhe etiketa meta. Përshkruani në një paragraf të vetëm ç’është Mastodon-i dhe ç’e bën special këtë shërbyes. Në u lëntë i zbrazët, për shërbyesin do të përdoret përshkrimi parazgjedhje.
+        title: Përshkrim i shkurtër shërbyesi
+      site_terms:
+        desc_html: Mund të shkruani rregullat tuaja të privatësisë, kushtet e shërbimit ose gjëra të tjera ligjore. Mund të përdorni etiketa HTML
+        title: Kushte vetjake shërbimi
+      site_title: Emër shërbyesi
+      thumbnail:
+        desc_html: I përdorur për paraparje përmes OpenGraph-it dhe API-t. Këshillohet 1200x630px
+        title: Miniaturë shërbyesi
+      timeline_preview:
+        desc_html: Shfaqni rrjedhë kohore publike te faqja ardhjesh
+        title: Paraparje rrjedhe kohore
+      title: Rregullime sajti
+    statuses:
+      back_to_account: Mbrapsht te faqja e llogarisë
+      batch:
+        delete: Fshije
+        nsfw_off: Vëri shenjë si jo rezervat
+        nsfw_on: Vëri shenjë si rezervat
+      failed_to_execute: S’u arrit të përmbushej
+      no_media: S’ka media
+      no_status_selected: S’u ndryshua ndonjë gjendje, ngaqë s’u përzgjodh ndonjë e tillë
+      title: Gjendje llogarish
+      with_media: Me media
+    subscriptions:
+      callback_url: URL Callback-u
+      confirmed: U ripohua
+      expires_in: Skadon më
+      last_delivery: Dorëzimi e fundit
+      topic: Temë
+    tags:
+      accounts: Llogari
+      hidden: Fshehur
+      hide: Fshihe prej drejtorie
+      title: Hashtage
+      unhide: Shfaqe në drejtori
+      visible: E dukshme
+    title: Administrim
+    warning_presets:
+      add_new: Shtoni të ri
+      delete: Fshije
+      edit: Përpunoni
+      edit_preset: Përpunoni sinjalizim të paracaktuar
+      title: Administroni sinjalizime të paracaktuara
+  admin_mailer:
+    new_report:
+      body: "%{reporter} ka raportuar %{target}"
+      body_remote: Dikush nga %{domain} ka raportuar %{target}
+      subject: Raport i ri për %{instance} (#%{id})
+  application_mailer:
+    notification_preferences: Ndryshoni parapëlqime email-i
+    settings: 'Ndryshoni parapëlqime email-i: %{link}'
+    view: 'Parje:'
+    view_profile: Shihni Profilin
+    view_status: Shihini gjendjen
+  applications:
+    created: Aplikacioni u krijua me sukses
+    destroyed: Aplikacioni u fshi me sukses
+    invalid_url: URL-ja e dhënë është e pavlefshme
+    regenerate_token: Riprodho token hyrjesh
+    token_regenerated: Token-i i hyrjeve u riprodhuan me sukses
+    warning: Hapni sytë me ato të dhëna. Mos ia jepni kurrë njeriu!
+    your_token: Token-i juaj për hyrje
+  auth:
+    change_password: Fjalëkalim
+    confirm_email: Ripohoni email-in
+    delete_account: Fshije llogarinë
+    delete_account_html: Nëse dëshironi të fshihni llogarinë tuaj, mund <a href="%{path}">ta bëni që këtu</a>. Do t’ju kërkohet ta ripohoni.
+    didnt_get_confirmation: S’morët udhëzime ripohimi?
+    forgot_password: Harruat fjalëkalimin tuaj?
+    invalid_reset_password_token: Token-i i ricaktimit të fjalëkalimit është i pavlefshëm ose ka skaduar. Ju lutemi, kërkoni një të ri.
+    login: Hyni
+    logout: Dalje
+    migrate_account: Kaloni në një tjetër llogari
+    migrate_account_html: Nëse doni ta ridrejtoni këtë llogari te një tjetër, këtë mund <a href="%{path}">ta formësoni këtu</a>.
+    or_log_in_with: Ose bëni hyrjen me
+    register: Regjistrohuni
+    resend_confirmation: Ridërgo udhëzime ripohimi
+    reset_password: Ricaktoni fjalëkalimin
+    security: Siguri
+    set_new_password: Caktoni fjalëkalim të ri
+  authorize_follow:
+    already_following: E ndiqni tashmë këtë llogari
+    error: Mjerisht, pati një gabim gjatë kërkimit të llogarisë së largët
+    follow: Ndiqeni
+    follow_request: 'Keni dërguar një kërkesë ndjekjeje te:'
+    following: 'Sukses! Tani e ndiqni:'
+    post_follow:
+      close: Ose, thjesht mund të mbyllni këtë dritare.
+      return: Shfaq profilin e përdoruesit
+      web: Kalo në web
+    title: Ndiq %{acct}
+  datetime:
+    distance_in_words:
+      about_x_hours: "%{count}o"
+      about_x_months: "%{count}mj"
+      about_x_years: "%{count}v"
+      almost_x_years: "%{count}v"
+      half_a_minute: Mu tani
+      less_than_x_seconds: Mu tani
+      over_x_years: "%{count}v"
+      x_months: "%{count}mj"
+  deletes:
+    bad_password_msg: Provë e bukur, trimosha! Fjalëkalim i pasaktë
+    confirm_password: Jepni fjalëkalimin tuaj të tanishëm që të verifikohet identiteti juaj
+    description_html: Kjo të heqë <strong>në mënyrë të përhershme, të pakthyeshme</strong> lëndë nga llogaria juaj dhe do ta çaktivizojë atë. Emri juaj i përdoruesit do të mbetet i rezervuar për të shmangur sozi të ardhme.
+    proceed: Fshini llogarinë
+    success_msg: Llogaria juaj u fshi me sukses
+    warning_html: Garantohet vetëm fshirja e lëndës prej këtij shërbyesi të veçantë. Lënda që është ndarë gjerësisht me të tjerët ka gjasa të lërë gjurmë. Shërbyesit <em>offline</em> dhe shërbyesit që janë shpajtuar prej përditësimeve tuaja, s’do t’i përditësojnë bazat e tyre të të dhënave.
+    warning_title: Mund të ketë lëndë të përhapur
+  directories:
+    directory: Drejtori profilesh
+    enabled: Gjendeni te lista e drejtorisë.
+    enabled_but_waiting: Keni zgjedhur të jeni pjesë e drejtorisë, por ende s’keni numrin minimum të ndjekësve (%{min_followers}) për përfshirje në të.
+    explanation: Zbuloni përdorues bazuar në interesat e tyre
+    explore_mastodon: Eksploroni %{title}
+    how_to_enable: S’keni zgjedhur të jeni i pranishëm te drejtoria. Mund ta bëni më poshtë. Përdorni te teksti i jetëshkrimit tuaj hashtagë, për t’u përfshirë nën hashtagë specifikë!
+  errors:
+    '403': S’keni leje të shihni këtë faqe.
+    '404': Faqja që po kërkonit, s’gjendet këtu.
+    '410': Faqja që po kërkonit, s’gjendet më këtu.
+    '422':
+      content: Verifikimi i sigurisë dështoi. Mos i bllokoni gjë cookie-t?
+      title: Verifikimi i sigurisë dështoi
+    '429': Shumë kërkesa të bëra brenda një intervali të dhënë
+    '500':
+      content: Na ndjeni, diçka shkoi ters në anën tonë.
+      title: Kjo faqe s’është e saktë
+    noscript_html: Që të përdorni aplikacionin web Mastodon, ju lutemi, aktivizoni JavaScript-in. Ndryshe, provoni për Mastodon-in një nga <a href="%{apps_path}">aplikacionet e brendshëm</a> të platformës tuaj.
+  exports:
+    archive_takeout:
+      date: Datë
+      download: Shkarkoni arkivin tuaj
+      hint_html: Mund të kërkoni një arkiv të <strong>mesazheve tuaja dhe medias së ngarkuar</strong> nga ju. Të dhënat e eksportuara do të jenë në formatin ActivityPub, të lexueshme nga cilido software i përputhshëm me të. Mund të kërkoni arkiv çdo 7 ditë.
+      in_progress: Po përpilohet arkivi juaj…
+      request: Kërkoni arkivin tuaj
+      size: Madhësi
+    blocks: Bllokoni
+    domain_blocks: Bllokime përkatësish
+    follows: Ndiqni
+    lists: Lista
+    mutes: Heshtoni
+    storage: Depozitim për media
+  featured_tags:
+    add_new: Shtoni të re
+    errors:
+      limit: Keni përdorur tashmë si të zgjedhur sasinë maksimum të hashtagëve
+  filters:
+    contexts:
+      home: Rrjedhë kohore vetjake
+      notifications: Njoftime
+      public: Rrjedha publike kohore
+      thread: Biseda
+    edit:
+      title: Përpunoni filtër
+    errors:
+      invalid_context: Ose s’u dha fare, ose u dha kontekst i pavlefshëm
+      invalid_irreversible: Filtrim i pakthyeshëm funksionon vetëm me kontekste <em>home</em> ose njoftimesh
+    index:
+      delete: Fshije
+      title: Filtra
+    new:
+      title: Shtoni filtër të ri
+  footer:
+    developers: Zhvillues
+    more: Më tepër…
+    resources: Burime
+  generic:
+    changes_saved_msg: Ndryshimet u ruajtën me sukses!
+    copy: Kopjoje
+    save_changes: Ruaji ndryshimet
+    validation_errors:
+      one: Diçka s’është ende si duhet! Ju lutemi, shqyrtoni gabimin më poshtë
+      other: Diçka s’është ende si duhet! Ju lutemi, shqyrtoni %{count} gabimet më poshtë
+  imports:
+    modes:
+      merge: Përzieji
+      merge_long: Mbaji zërat ekzistues dhe shto të rinjtë
+      overwrite: Mbishkruaje
+      overwrite_long: Zëvendësoji zërat ekzistues me të rinjtë
+    preface: Mund të importoni të dhëna që keni eksportuar nga një shërbyes tjetër, bie fjala, një listë të personave që ndiqni ose bllokoni.
+    success: Të dhënat tuaja u ngarkuan me sukses dhe tani do të përpunohet në kohë
+    types:
+      blocking: Listë bllokimesh
+      domain_blocking: Listë bllokimesh përkatësish
+      following: Listë ndjekjesh
+      muting: Listë heshtimesh
+    upload: Ngarkoje
+  invites:
+    delete: Çaktivizoje
+    expired: Ka skaduar
+    expires_in:
+      '1800': 30 minuta
+      '21600': 6 orë
+      '3600': 1 orë
+      '43200': 12 orë
+      '604800': 1 javë
+      '86400': 1 ditë
+    expires_in_prompt: Kurrë
+    generate: Prodhoje
+    invited_by: 'Qetë ftuar nga:'
+    max_uses:
+      one: 1 përdorim
+      other: "%{count} përdorime"
+    max_uses_prompt: Pa kufi
+    prompt: Prodhoni dhe ndani me të tjerët lidhje për të akorduar hyrje në këtë shërbyes
+    table:
+      expires_at: Skadon më
+      uses: Përdorime
+    title: Ftoni njerëz
+  lists:
+    errors:
+      limit: Keni mbërritur në numrin maksimum të sasisë së listave
+  media_attachments:
+    validations:
+      images_and_video: S’mund të bashkëngjitet video te një gjendje që përmban figura tashmë
+      too_many: S’mund të bashkëngjiten më shumë se 4 kartela
+  migrations:
+    acct: emërpërdoruesi@përkatësi e llogarisë së re
+    currently_redirecting: 'Profili juaj është caktuar të ridrejtojë te:'
+    proceed: Ruaje
+    updated_msg: Rregullimi juaj për migrim llogarish u përditësua me sukses!
+  moderation:
+    title: Moderim
+  notification_mailer:
+    digest:
+      action: Shihini krejt njoftimet
+      body: Ja një përmbledhje e shkurtër e mesazheve që keni humbur që nga vizita juaj e fundit më %{since}
+      mention: "%{name} ju ka përmendur te:"
+      new_followers_summary:
+        one: Veç kësaj, u bëtë me një ndjekës të ri, teksa s’ishit këtu! Ëhë!
+        other: Veç kësaj, u bëtë me %{count} ndjekës të rinj, teksa s’ishit këtu! Shkëlqyeshëm!
+      subject:
+        one: "1 njoftim i ri që nga vizita juaj e fundit \U0001F418"
+        other: "%{count} 1 njoftime të reja që nga vizita juaj e fundit \U0001F418"
+      title: Gjatë mungesës tuaj…
+    favourite:
+      body: 'Gjendja juaj u parapëlqye nga %{name}:'
+      subject: "%{name} parapëlqeu gjendjen tuaj"
+      title: E parapëlqyer e re
+    follow:
+      body: Tani ju ndjek %{name}!
+      subject: Tani ju ndjek %{name}
+      title: Ndjekës i ri
+    follow_request:
+      action: Administroni kërkesa ndjekjeje
+      body: "%{name} ka kërkuar t’ju ndjekë"
+      subject: 'Ndjekës pezull: %{name}'
+      title: Kërkesë e re ndjekjeje
+    mention:
+      action: Përgjigjuni
+      body: 'U përmendët nga %{name} në:'
+      subject: U përmendët nga %{name}
+      title: Përmendje e re
+    reblog:
+      body: 'Gjendja juaj u përforcua nga %{name}:'
+      subject: "%{name} përforcoi gjendjen tuaj"
+      title: Përforcim i ri
+  number:
+    human:
+      decimal_units:
+        units:
+          quadrillion: K
+  pagination:
+    newer: Më të ri
+    next: Pasuesi
+    older: Më të vjetër
+    prev: I mëparshmi
+  preferences:
+    other: Tjetër
+  remote_follow:
+    acct: Jepni çiftin tuaj emërpërdoruesi@përkatësi prej të cilit doni që të veprohet
+    missing_resource: S’u gjet dot URL-ja e domosdoshme e ridrejtimit për llogarinë tuaj
+    no_account_html: S’keni llogari? Mund të <a href='%{sign_up_path}' target='_blank'>regjistroheni këtu</a>
+    proceed: Ripohoni ndjekjen
+    prompt: 'Do të ndiqni:'
+    reason_html: "<strong>Pse është i domosdoshëm ky hap?</strong> <code>%{instance}</code> mund të mos jetë shërbyesi ku jeni regjistruar, ndaj na duhet t’ju ridrejtojmë së pari te shërbyesi juaj Home."
+  remote_interaction:
+    favourite:
+      proceed: Ripohoni parapëlqimin
+      prompt: 'Doni të parapëlqeni këtë mesazh:'
+    reblog:
+      proceed: Ripohoni përforcimin
+      prompt: 'Doni të përforconi këtë mesazh:'
+    reply:
+      proceed: Ripohoni përgjigjen
+      prompt: 'Doni t’i përgjigjeni këtij mesazhi:'
+  remote_unfollow:
+    error: Gabim
+    title: Titull
+    unfollowed: U hoq ndjekja
+  scheduled_statuses:
+    over_daily_limit: Keni tejkaluar kufirin e %{limit} mesazheve të planifikuara për atë ditë
+    over_total_limit: Keni tejkaluar kufirin prej %{limit} mesazhesh të planifikuara
+    too_soon: Data e planifikimit duhet të bjerë në të ardhmen
+  sessions:
+    activity: Veprimtaria e fundit
+    browser: Shfletues
+    browsers:
+      generic: Shfletues i panjohur
+      nokia: Shfletues Nokia S40 Ovi
+    current_session: Sesioni i tanishëm
+    description: "%{browser} në %{platform}"
+    explanation: Këta janë shfletuesit e futur në këtë çast te llogaria juaj Mastodon.
+    platforms:
+      other: platformë e panjohur
+    revoke: Shfuqizoje
+    revoke_success: Sesioni u shfuqizua me sukses
+    title: Sesione
+  settings:
+    authorized_apps: Aplikacione të autorizuara
+    back: Mbrapsht te Mastodon
+    delete: Fshirje llogarie
+    development: Zhvillim
+    edit_profile: Përpunoni profilin
+    export: Eksportim të dhënash
+    featured_tags: Hashtagë të zgjedhur
+    import: Importo
+    migrate: Migrim llogarie
+    notifications: Njoftime
+    preferences: Parapëlqime
+    two_factor_authentication: Mirëfilltësim Dyfaktorësh
+  statuses:
+    attached:
+      description: 'Bashkëngjitur: %{attached}'
+      image:
+        one: "%{count} figurë"
+        other: "%{count} figura"
+    boosted_from_html: Përforcuar nga %{acct_link}
+    content_warning: 'Sinjalizim lënde: %{warning}'
+    disallowed_hashtags:
+      one: 'përmbante një hashtag të palejuar: %{tags}'
+      other: 'përmbante hashtagët e palejuar: %{tags}'
+    language_detection: Zbulo gjuhë vetvetiu
+    open_in_web: Hape në internet
+    over_character_limit: u tejkalua kufi shenjash prej %{max}
+    pin_errors:
+      limit: Keni fiksuar tashmë numrin maksimum të mesazheve
+      ownership: S’mund të fiksohen mesazhet e të tjerëve
+      private: S’mund të fiksohet mesazh jopublik
+      reblog: S’mund të fiksohet një përforcim
+    show_more: Shfaq më tepër
+    sign_in_to_participate: Bëni hyrjen, që të merrni pjesë te biseda
+    visibilities:
+      private: Vetëm ndjekësve
+      private_long: Shfaqua vetëm ndjekësve
+      public: Publike
+      public_long: Mund ta shohë kushdo
+      unlisted: Jo në listë
+      unlisted_long: Mund ta shohë gjithkush, por s’gjendet në rrjedha publike kohore
+  stream_entries:
+    pinned: Mesazh i fiksuar
+    reblogged: të përforcuara
+    sensitive_content: Lëndë me spec
+  terms:
+    body_html: |
+      <h2>Rregulla Privatësie</h2>
+      <h3 id="collect">Ç’të dhëna grumbullojmë?</h3>
+
+      <ul>
+      <li><em>Të dhëna bazë llogarie</em>: Nëse regjistroheni në këtë shërbyes, mund t’ju kërkohet të jepni një emër përdoruesi, një adresë email dhe një fjalëkalim. Mundet të jepni edhe të dhëna shtesë profili, të tilla si emër në ekran dhe jetëshkrim, dhe të ngarkoni një foto profili dhe figurë kryesh. Emri i përdoruesit, emri për në ekran, jetëshkrimi, fotoja e profilit dhe figura për kryet shfaqen përherë publikisht.</li>
+      <li><em>Postime, ndjekje dhe të tjera të dhëna publike</em>: Lista e personave që ndiqni shfaqet publikisht, po njësoj edhe ajo e ndjekësve tuaj. Kur parashtroni një mesazh, depozitohet data dhe koha, si dhe aplikacioni prej nga u parashtrua mesazhi. Mesazhet mund të përmbajnë bashkëngjitje media, bie fjala, foto dhe video. Postimet publike dhe ato të pashfaqura janë të passhme publikisht. Kur një postim e vini të zgjedhur në profilin tuaj, edhe ky është informacion i passhëm publikisht. Postimet tuaja janë u dërgohen ndjekësve tuaj, në disa raste kjo do të thotë se dërgohen në shërbyes të ndryshëm dhe në ta depozitohen kopje të tyre. Kur fshini postime, edhe kjo u dërgohet ndjekësve tuaj. Veprimi i riblogimit apo i parapëlqimit të një postimi tjetër është përherë publik.</li>
+      <li><em>Postime të drejtpërdrejta dhe ato vetëm për ndjekësit</em>: Krejt postimet depozitohen dhe trajtohen te shërbyesi. Postimet vetëm për ndjekës u dërgohen ndjekësve tuaj të cilët përmenden në to, dhe postimet e drejtpërdrejta u dërgohen vetëm përdoruesve të përmendur në to. Në disa raste kjo do të thotë se dërgohen në shërbyes të ndryshëm dhe në ta depozitohen kopje të tyre. Përpiqemi pa hile të kufizojmë hyrjen në këto postime vetëm të personave të autorizuar, por shërbyesit e tjerë mund të mos bëjnë të njëjtën gjë. Ndaj është e rëndësishme të shqyrtoni shërbyesit pjesë e të cilëve janë ndjekësit tuaj. Te rregullimet mund të përdorni një mundësi për të miratuar ose hedhur poshtë dorazi ndjekës të rinj. <em>Ju lutemi, mbani parasysh se operatorët e shërbyesit dhe cilido shërbyes marrës mund t’i shohin mesazhe të tillë</em>, dhe që marrësit mund të bëjnë për ta foto ekrani, t’i kopjojnë ose t’i rindajnë ato me të tjerët. <em>Mos u jepni të tjerëve të dhëna të rrezikshme përmes Mastodon-it.</em></li>
+      <li><em>IP dhe të tjera tejtëdhëna</em>: Kur bëni hyrjen, regjistrojmë adresën IP prej nga hytë, si dhe emrin e shfletuesit tuaj. Krejt sesionet e hyrjeve janë të shqyrtueshme nga ju dhe shfuqizim, që nga rregullimet. Adresa e fundit IP e përdorur depozitohet për 12 muaj. Mund të mbajmë edhe regjistra shërbyesi të cilët përfshijnë adresën IP të çdo kërkese ndaj shërbyesit tonë.</li>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="use">Përse i përdorim të dhënat tuaja?</h3>
+
+      <p>Cilado prej të dhënave që grumbullojmë prej jush mund të përdoret në rrugët vijuese:</p>
+
+      <ul>
+      <li>Për të mundësuar funksionimin bazë të Mastodon-it. Mundeni të ndërveproni me lëndën e personave të tjerë dhe të postoni lëndë tuajën vetëm kur jeni i futur në llogarinë tuaj. Për shembull, mund të ndiqni njerëz të tjerë për të parë postimet e tyre të ndërthurura te rrjedha juaj kohore e përshtatur.</li>
+      <li>Për të ndihmuar moderimin e bashkësisë, për shembull, duke krahasuar adresën tuaj IP me të tjera të njohura, për të përcaktuar shmangie nga dëbime ose cenime të tjera.</li>
+      <li>Adresa email që jepni mund të përdoret për t’ju dërguar informacion, njoftime mbi persona të tjerë që ndërveprojnë me lëndën tuaj ose që ju dërgojnë mesazhe, dhe për t’iu përgjigju pyetjeve dhe/ose kërkesave të tjera.</li>
+      </ul>
+
+      <hr class="spacer" />
+
+      <h3 id="protect">Si i mbrojmë të dhënat tuaja?</h3>
+
+      <p>Vëmë në punë një larmi masash sigurie për të ruajtur të parrezikuara të dhënat tuaja personale kur jepni, parashtroni, ose hyni në to. Mes të tjerash, sesioni juaj i shfletimit, si edhe trafiku mes aplikacioneve tuaja dhe API-t, sigurohen me SSL, dhe fjalëkalimi juaj mbrohet duke përdorur një algoritëm të sigurt njëdrejtimsh. Për të siguruar edhe më hyrjet te llogaria juaj, mund të aktivizoni mirëfilltësimin dyfaktorësh.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="data-retention">Cilat janë rregullat tona mbi mbajtjen e të dhënave?</h3>
+
+      <p>Do të përpiqemi pa hile:</p>
+
+      <ul>
+      <li>Të mbajmë regjistra shërbyesi që përmbajnë adresën IP të krejt kërkesave te ky shërbyes, sa kohë që regjistra të tillë mbahen, për jo më shumë se 90 ditë.</li>
+      <li>Të mbajmë adresat IP përshoqëruar me përdoruesit e regjistruar, për jo më shumë se 12 muaj.</li>
+      </ul>
+
+      <p>Mund të kërkoni dhe të shkarkoni një arkiv të lëndës tuaj, përfshi postimet tuaja, bashkëngjitje media, foto profili, dhe figurë kryesh.</p>
+
+      <p>Mund të fshini në mënyrë të pakthyeshme llogarinë tuaj në çfarëdo kohe.</p>
+
+      <hr class="spacer"/>
+
+      <h3 id="cookies">A përdorim <em>cookies</em>?</h3>
+
+      <p>Po. <em>Cookie</em>-t janë kartela të vockla që një sajt ose furnizuesi i shërbimit për të i depoziton në diskun e kompjuterit tuaj përmes shfletuesit (nëse e lejoni ju). Këto <em>cookies</em> i bëjnë të mundur sajtit të njohë shfletuesin tuaj dhe, nëse keni një llogari të regjistuar, ta përshoqërojë atë    me llogarinë tuaj të regjistuar.</p>
+
+      <p>Ne i përdorim <em>cookie</em>-t për të kuptuar dhe ruajtur parapëlqimet tuaja, për vizita të ardhshme.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="disclose">A u japim palëve të treta ndonjë të dhënë?</h3>
+
+      <p>Nuk u shesim, shkëmbejmë, ose transferojmë në rrugë të tjera palëve të treta të dhëna tuajat personale që lejojnë identifikimin tuaj. Kjo nuk përfshin palë të treta të besuara që nga ndihmojnë të xhirojmë sajtin tonë, të bëjmë punën tonë, ose t’ju shërbejmë juve, sa kohë që këto palë pajtohen t’i mbajnë të fshehta këto të dhëna. Mund të japim të dhëna tuajat kur besojmë se kjo është e nevojshme për të qenë në rregull me ligjin, për të zbatuar rregullat e sajtit tonë, ose për të mbrojtur të drejta, pronësi, ose siguri tonën apo të të tjerëve.</p>
+
+      <p>Lënda juaj publike mund të shkarkohet nga shërbyes të tjerë në rrjet. Postimet tuaja publike dhe ato vetëm për ndjekësit dërgohen te shërbyesit ku gjenden ndjekësit tuaj, dhe mesazhet e drejtpërdrejtë jepen te shërbyesit e marrësve, për rastet ku këta ndjekës apo marrës gjenden në një tjetër shërbyes nga i këtushmi.</p>
+
+      <p>Kur autorizoni një aplikacion të përdorë llogarinë tuaj, në varësi të shtrirje së lejeve që miratoni, aplikacioni mund të hyjë në të dhënat e profilit tuaj publik, listat tuaja të ndjekjeve, ndjekësit tuaj, lista tuajat, krejt postimet tuaja, dhe të parapëlqyerit tuaj. Aplikacionet s’mund të njohin kurrë adresën tuaj email ose fjalëkalimin.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="children">Përdorim i sajtit nga fëmijë</h3>
+
+      <p>Nëse ky shërbyes gjendet në BE apo në ZEE: Krejt sajti, produktet dhe shërbimet tona u drejtohen personave që janë të paktën 16 vjeç. Nëse jeni nën moshën 16 vjeç, sipas kërkesave të GDPR-së (<a href="https://en.wikipedia.org/wiki/General_Data_Protection_Regulation">General Data Protection Regulation</a>), mos e përdorni këtë sajt.</p>
+
+      <p>Nëse ky shërbyes gjendet në ShBA: Krejt sajti, produktet dhe shërbimet tona u drejtohen personave që janë të paktën 13 vjeç. Nëse jeni nën moshën 13 vjeç, sipas kërkesave të COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>), mos e përdorni këtë sajt.</p>
+
+      <p>Domosdoshmëritë e ligjit mund të jenë të ndryshme, nëse ky shërbyes gjendet në një tjetër juridiksion.</p>
+
+      <hr class="spacer" />
+
+      <h3 id="changes">Ndryshime te Rregullat tona të Privatësisë</h3>
+
+      <p>Nëse vendosim të ndryshojmë rregullat tona të privatësisë, këto ndryshime do t’i botojmë në këtë faqe.</p>
+
+      <p>Ky dokument është CC-BY-SA. U përditësua së fundmi më 7 mars, 2018.</p>
+
+      <p>Përshtatur fillimisht nga <a href="https://github.com/discourse/discourse">rregullat e privatësisë në Discourse</a>.</p>
+    title: Kushte Shërbimi dhe Rregulla Privatësie te %{instance}
+  themes:
+    contrast: Mastodon (Me shumë kontrast)
+    default: Mastodon (I errët)
+    mastodon-light: Mastodon (I çelët)
+  time:
+    formats:
+      default: "%d %b, %Y, %H:%M"
+  two_factor_authentication:
+    code_hint: Që të bëhet ripohimi, jepni kodin e prodhuar nga aplikacioni juaj i mirëfilltësimeve
+    description_html: Nëse aktivizoni <strong>mirëfilltësimin dyfaktorësh</strong>, hyrja do të kërkojë të jeni në zotërim të telefonit tuaj, i cili do të prodhojë kod që duhet ta jepni.
+    disable: Çaktivizoje
+    enable: Aktivizoje
+    enabled: Mirëfilltësimi dyfaktorësh është i aktivizuar
+    enabled_success: Mirëfilltësimi dyfaktorësh u aktivizua me sukses
+    generate_recovery_codes: Prodho kode rikthimesh
+    instructions_html: "<strong>Skanojeni këtë kod QR me Google Authenticator ose një aplikacion TOTP të ngjashëm në telefonin tuaj</strong>. Tani e tutje, ai aplikacion do të prodhojë kode të cilët duhet t’i jepni kur bëni hyrje."
+    lost_recovery_codes: Kodet e rikthimit ju lejojnë të rifitoni hyrje në llogarinë tuaj, nëse humbni telefonin tuaj. Nëse keni humbur kodet tuaj të rikthimit, mund t’i prodhoni sërish këtu. Kodet tuaj të vjetër të rikthimit do të bëhen të pavlefshëm.
+    manual_instructions: 'Nëse s’skanoni dot kodin QR dhe ju duhet ta jepni dorazi, ja e fshehta si tekst i thjeshtë:'
+    recovery_codes: Kopjeruani kode rikthimesh
+    recovery_codes_regenerated: Kodet e rikthimeve u riprodhuan me sukses
+    recovery_instructions_html: Në ndodhtë që të humbni hyrje te telefoni juaj, mund të përdorni një nga kodet e rikthimit më poshtë, që të rifitoni hyrje te llogaria juaj. <strong>Mbajini të parrezikuar kodet e rikthimeve</strong>. Për shembull, mund t’i shtypni dhe t’i ruani tok me dokumente të tjerë të rëndësishëm.
+    setup: Rregullojeni
+    wrong_code: Kodi i dhënë është i pavlefshëm! A janë të sakta koha e shërbyesit dhe koha e pajisjes?
+  user_mailer:
+    backup_ready:
+      explanation: Kërkuat një kopjeruajtje të plotë të llogarisë tuaj Mastodon. E keni gati për shkarkim!
+      subject: Arkivi juaj është gati për shkarkim
+      title: Marrje arkivi me vete
+    warning:
+      explanation:
+        disable: Kur llogaria juaj është e ngrirë, të dhënat në llogarinë tuaj mbeten të paprekura, por s’mund të kryeni ndonjë veprim, para se të shkyçet.
+        silence: Kur llogaria juaj është e kufizuar, mesazhet tuaj në këtë shërbyes do t’i shohin vetëm personat që ju ndjekin tashmë. dhe mund të liheni jashtë nga lista të ndryshme publike. Megjithatë, të tjerët prapë mund t’ju ndjekin dorazi.
+        suspend: Llogaria juaj është pezulluar, dhe krejt mesazhet tuaja dhe kartelat media të ngarkuara janë hequr në mënyrë të pakthyeshme nga ky shërbyes, dhe nga shërbyesit te të cilët kishit ndjekës.
+      review_server_policies: Shqyrtoni rregullat e shërbyesit
+      subject:
+        disable: Llogaria juaj %{acct} është ngrirë
+        none: Sinjalizim për %{acct}
+        silence: Llogaria juaj %{acct} është kufizuar
+        suspend: Llogaria juaj %{acct} është pezulluar
+      title:
+        disable: Llogari e ngrirë
+        none: Sinjalizim
+        silence: Llogari e kufizuar
+        suspend: Llogari e pezulluar
+    welcome:
+      edit_profile_action: Rregullim profili
+      edit_profile_step: Profilin mund ta personalizoni duke ngarkuar një avatar, figurë kryesh, duke ndryshuar emrin tuaj në ekran, etj. Nëse dëshironi të shqyrtoni ndjekës të rinj, përpara se të jenë lejuar t’ju ndjekin, mund të kyçni llogarinë tuaj.
+      explanation: Ja disa ndihmëza, sa për t’ia filluar
+      final_action: Filloni të postoni
+      final_step: 'Filloni të postoni! Edhe pse pa ndjekës, mesazhet tuaj publike mund të shihen nga të tjerët, për shembull te rrjedha kohore vendore dhe në hashtagë. Mund të donit të prezantoni veten nën hashtagun #introductions.'
+      full_handle: Identifikuesi juaj i plotë
+      full_handle_hint: Kjo është ajo çka do të duhej t’u tregonit shokëve tuaj, që të mund t’ju dërgojnë mesazhe ose t’ju ndjekin nga një shërbyes tjetër.
+      review_preferences_action: Ndryshoni parapëlqime
+      review_preferences_step: Mos harroni të caktoni parapëlqimet tuaja, fjala vjen, ç’email-e dëshironi të merrni, ose çfarë shkalle privatësie do të donit të kishin, si parazgjedhje, postimet tuaja. Nëse nuk ju merren mendtë nga rrotullimi, mund të zgjidhni të aktivizoni vetëluajtje GIF-esh.
+      subject: Mirë se vini te Mastodon-i
+      tip_federated_timeline: Rrjedha kohore e të federuarve është një pamje e fluksit të rrjetit Mastodon. Por përfshin vetëm persona te të cilët janë pajtuar fqinjët tuaj, pra s’është e plotë.
+      tip_following: Përgjegjësin e shërbyesit tuaj e ndiqni, si parazgjedhje. Për të gjetur më shumë persona interesantë, shihni te rrjedha kohore vendore dhe ajo e të federuarve.
+      tip_local_timeline: Rrjedha kohore vendore është një pamje e fluksit të njerëzve në %{instance}. Këta janë fqinjët tuaj më të afërt!
+      tip_mobile_webapp: Nëse shfletuesi juaj celular ju ofron të shtohet Mastodon-i te skena juaj e kreut, mund të merrni njoftime <em>push</em>. Nga shumë pikëpamje vepron si një aplikacion i brendshëm i platformës së celularit!
+      tips: Ndihmëza
+      title: Mirë se vini, %{name}!
+  users:
+    follow_limit_reached: S’mund të ndiqni më tepër se %{limit} persona
+    invalid_email: Adresa email është e pavlefshme
+    invalid_otp_token: Kod dyfaktorësh i pavlefshëm
+    otp_lost_help_html: Nëse humbi hyrjen te të dy, mund të lidheni me %{email}
+    seamless_external_login: Jeni futur përmes një shërbimi të jashtëm, ndaj s’ka rregullime fjalëkalimi dhe email.
+    signed_in_as: 'I futur si:'
+  verification:
+    explanation_html: 'Mundeni <strong>të verifikoni veten si i zoti i lidhjeve te tejtëdhënat e profilit tuaj</strong>. Për këtë, sajti i lidhur duhet të përmbajë një lidhje për te profili juaj Mastodon. Lidhje për te ajo <strong>duhet</strong> të ketë një atribut <code>rel="me"</code>. Lënda tekst e lidhjes nuk ngre peshë. Ja një shembull:'
+    verification: Verifikim
diff --git a/config/locales/sr-Latn.rb b/config/locales/sr-Latn.rb
new file mode 100644
index 0000000000000000000000000000000000000000..fc2dafc94c2ca2bf3426d261d594abbf3ea61731
--- /dev/null
+++ b/config/locales/sr-Latn.rb
@@ -0,0 +1,3 @@
+require 'rails_i18n/common_pluralizations/romanian'
+
+::RailsI18n::Pluralization::Romanian.with_locale(:'sr-Latn')
diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml
index 6d71b326ed5d33baf7608008c8ad5ea0db4da60a..c75eca533cda02759d146437ef3d314b34c790c9 100644
--- a/config/locales/sr-Latn.yml
+++ b/config/locales/sr-Latn.yml
@@ -4,42 +4,24 @@ sr-Latn:
     about_hashtag_html: Ovo su javni statusi tagovani sa <strong>#%{hashtag}</strong>. Možete odgovarati na njih ako imate nalog bilo gde u fediversu.
     about_mastodon_html: Mastodont je društvena mreža bazirana na otvorenim protokolima i slobodnom softveru otvorenog koda. Decentralizovana je kao što je decentralizovana e-pošta.
     about_this: O instanci
-    closed_registrations: Registracije su trenutno zatvorene na ovoj instanci. Ipak! Možete naći drugu instancu na kojoj ćete napraviti nalog i odatle dobiti pristup istoj ovoj mreži.
     contact: Kontakt
     contact_missing: Nije postavljeno
-    contact_unavailable: N/A
     extended_description_html: |
       <h3>Dobro mesto za pravila</h3>
       <p>Prošireni opis koji još nije postavljen.</p>
-    features:
-      humane_approach_body: Učeći od grešaka sa ostalih mreža, a da bi se borio protiv zloupotreba na društvenim mrežama, Mastodont pokušava da pravi što etičkije odluke prilikom razvoja.
-      humane_approach_title: Humaniji pristup
-      not_a_product_body: Mastodont nije komercijalna mreža. Nema reklama, nema skupljanja privatnih podataka, nema zaštićenih delova. Nema centralnog autoriteta.
-      not_a_product_title: Vi ste osoba, ne proizvod
-      real_conversation_body: Sa 65535 karaktera na raspolaganju i podrškom za granularniji sadržaj i upozorenja na osetljiviji sadržaj, možete se izraziti kako god želite.
-      real_conversation_title: Pravljen za pravi razgovor
-      within_reach_body: Više aplikacija za iOS, Android, kao i druge platforme zahvaljujući ekosistemu dobrih API-ja će Vam omogućiti da ostanete u kontaktu sa prijateljima svuda.
-      within_reach_title: Uvek u kontaktu
     generic_description: "%{domain} je server na mreži"
     hosted_on: Mastodont hostovan na %{domain}
     learn_more: Saznajte više
-    other_instances: Lista instanci
     source_code: Izvorni kod
-    status_count_after: statusa
     status_count_before: Koji su napisali
-    user_count_after: korisnika
     user_count_before: Dom za
     what_is_mastodon: Å ta je Mastodont?
   accounts:
-    follow: Follow
-    followers: Followers
-    following: Following
     media: Multimedija
     moved_html: "%{name} je pomeren na %{new_profile_link}:"
     nothing_here: Ovde nema ništa!
     people_followed_by: Ljudi koje %{name} prati
     people_who_follow: Ljudi koji prate %{name}
-    posts: Tutovi
     posts_with_replies: Tutovi i odgovori
     reserved_username: Korisničko ime je rezervisano
     roles:
@@ -74,7 +56,6 @@ sr-Latn:
       followers_url: Adresa pratioca
       follows: Praćeni
       inbox_url: Adresa sandučeta
-      ip: IP
       location:
         all: Sve
         local: Lokalne
@@ -98,7 +79,6 @@ sr-Latn:
       promote: Unapredi
       protocol: Protokol
       public: Javno
-      push_subscription_expires: PuSH subscription expires
       redownload: Osveži avatar
       resend_confirmation:
         already_confirmed: Ovaj korisnik je već potvrđen
@@ -109,8 +89,6 @@ sr-Latn:
       resubscribe: Ponovo se pretplati
       role: Ovlašćenja
       roles:
-        admin: Administrator
-        moderator: Moderator
         staff: Osoblje
         user: Korisnik
       salmon_url: Salmon adresa
@@ -198,7 +176,6 @@ sr-Latn:
       show:
         affected_accounts:
           few: Utiče na %{count} naloga u bazi
-          many: Utiče na %{count} naloga u bazi
           one: Utiče na jedan nalog u bazi
           other: Utiče na %{count} naloga u bazi
         retroactive:
@@ -224,7 +201,6 @@ sr-Latn:
         all: Sve
         available: Aktivne
         expired: Istekle
-        title: Filter
       title: Pozivnice
     reports:
       action_taken_by: Akciju izveo
@@ -236,7 +212,6 @@ sr-Latn:
       reported_account: Prijavljeni nalog
       reported_by: Prijavio
       resolved: Rešeni
-      status: Status
       title: Prijave
       unresolved: Nerešeni
     settings:
@@ -256,9 +231,6 @@ sr-Latn:
         min_invite_role:
           disabled: Niko
           title: Samo preko pozivnice
-        open:
-          desc_html: Dozvoli svakome da kreira nalog
-          title: Otvorena registracija
       show_staff_badge:
         desc_html: Prikaži bedž osoblja na korisničkoj strani
         title: Prikaži bedž osoblja
@@ -292,19 +264,15 @@ sr-Latn:
       title: Statusi naloga
       with_media: Sa multimedijom
     subscriptions:
-      callback_url: Callback URL
       confirmed: Potvrđeno
       expires_in: Ističe za
       last_delivery: Poslednja dostava
-      title: WebSub
-      topic: Topic
     title: Administracija
   admin_mailer:
     new_report:
       body: "%{reporter} je prijavio %{target}"
       subject: Nova prijava za %{instance} (#%{id})
   application_mailer:
-    salutation: "%{name},"
     settings: 'Promeni podešavanja e-pošte: %{link}'
     view: 'Pogledaj:'
   applications:
@@ -316,7 +284,6 @@ sr-Latn:
     warning: Oprezno sa ovim podacima. Nikad je ne delite ni sa kim!
     your_token: Vaš pristupni token
   auth:
-    agreement_html: Pristupanjem instanci se slažete sa <a href="%{rules_path}">pravilima instance</a> i <a href="%{terms_path}">uslovima korišćenja</a>.
     delete_account: Obriši nalog
     delete_account_html: Ako želite da obrišete Vaš nalog, možete <a href="%{path}">nastaviti ovde</a>. Bićete upitani da potvrdite.
     didnt_get_confirmation: Niste dobili poruku sa uputstvima za potvrdu naloga?
@@ -343,18 +310,13 @@ sr-Latn:
     title: Zaprati %{acct}
   datetime:
     distance_in_words:
-      about_x_hours: "%{count}h"
       about_x_months: "%{count}mesec"
       about_x_years: "%{count}god"
       almost_x_years: "%{count}god"
       half_a_minute: Upravo sad
-      less_than_x_minutes: "%{count}m"
       less_than_x_seconds: Upravo sad
       over_x_years: "%{count}god"
-      x_days: "%{count}d"
-      x_minutes: "%{count}m"
       x_months: "%{count}mesec"
-      x_seconds: "%{count}s"
   deletes:
     bad_password_msg: Dobar pokušaj, hakeri! Neispravna lozinka
     confirm_password: Unesite trenutnu lozinku da bismo proverili Vaš identitet
@@ -368,8 +330,6 @@ sr-Latn:
     '404': Strana koju ste tražili ne postoji.
     '410': Strana koju ste tražili više ne postoji.
     '422':
-      content: Security verification failed. Are you blocking cookies?
-      title: Security verification failed
     '429': Uspored
     '500':
       content: Izvinjavamo se, nešto je pošlo po zlu sa ove strane.
@@ -377,30 +337,14 @@ sr-Latn:
     noscript_html: Da biste koristili Mastodont veb aplikaciju, omogućite JavaScript. U suprotnom, probajte neku od <a href="%{apps_path}">originalnih aplikacija</a> za Mastodont za Vašu platformu.
   exports:
     blocks: Blokirali ste
-    csv: CSV
     follows: Pratite
     mutes: Ućutkali ste
     storage: Multimedijalno skladište
-  followers:
-    domain: Domen
-    explanation_html: Ako želite da osigurate privatnost Vaših statusa, morate biti svesni ko Vas prati. <strong>Vaši privatni statusi se šalju na sve instance na kojima imate pratioce</strong>. Možda želite da ih pregledate i da uklonite one pratioce na onim instancama za koje nemate poverenja da će poštovati Vašu privatnost.
-    followers_count: Broj pratilaca
-    lock_link: Zaključajte nalog
-    purge: Ukloni iz pratioca
-    success:
-      few: U procesu blokiranja pratioca sa %{count} domena...
-      many: U procesu blokiranja pratioca sa %{count} domena...
-      one: U procesu blokiranja pratioca sa jednog domena...
-      other: U procesu blokiranja pratioca sa %{count} domena...
-    true_privacy_html: Zapamtite da se <strong>prava privatnost može postići samo šifrovanjem sa kraja na kraj</strong>.
-    unlocked_warning_html: Svako može da Vas zaprati da odmah vidi Vaše privatne statuse. %{lock_link} da biste pregledali i odbacili pratioce.
-    unlocked_warning_title: Vaš nalog nije zaključan
   generic:
     changes_saved_msg: Izmene uspešno sačuvane!
     save_changes: Snimi izmene
     validation_errors:
       few: Nešto nije baš kako treba! Pregledajte %{count} greške ispod
-      many: Nešto nije baš kako treba! Pregledajte %{count} grešaka ispod
       one: Nešto nije baš kako treba! Pregledajte greške ispod
       other: Nešto nije baš kako treba! Pregledajte %{count} grešaka ispod
   imports:
@@ -411,7 +355,6 @@ sr-Latn:
       following: Lista pratilaca
       muting: Lista ućutkanih
     upload: Otpremi
-  in_memoriam_html: In Memoriam.
   invites:
     delete: Deaktiviraj
     expired: Isteklo
@@ -420,12 +363,12 @@ sr-Latn:
       '21600': 6 sati
       '3600': 1 sad
       '43200': 12 sati
+      '604800': 1 week
       '86400': 1 dan
     expires_in_prompt: Nikad
     generate: Generiši
     max_uses:
       few: "%{count} korišćenja"
-      many: "%{count} korišćenja"
       one: 1 korišćenje
       other: "%{count} korišćenja"
     max_uses_prompt: Bez ograničenja
@@ -454,12 +397,10 @@ sr-Latn:
       mention: "%{name} Vas je pomenuo u:"
       new_followers_summary:
         few: Dobili ste %{count} nova pratioca! Sjajno!
-        many: Dobili ste %{count} novih pratioca! Sjajno!
         one: Dobili ste jednog novog pratioca! Jeee!
         other: Dobili ste %{count} novih pratioca! Sjajno!
       subject:
         few: "%{count} nova obaveštenja od poslednje posete \U0001F418"
-        many: "%{count} novih obaveštenja od poslednje posete \U0001F418"
         one: "1 novo obaveštenje od poslednje posete \U0001F418"
         other: "%{count} novih obaveštenja od poslednje posete \U0001F418"
     favourite:
@@ -477,26 +418,11 @@ sr-Latn:
     reblog:
       body: "%{name} Vam je podržao(la) status:"
       subject: "%{name} je podržao(la) Vaš status"
-  number:
-    human:
-      decimal_units:
-        format: "%n%u"
-        units:
-          billion: B
-          million: M
-          quadrillion: Q
-          thousand: K
-          trillion: T
-          unit: ''
   pagination:
     next: Sledeći
     prev: Prethodni
-    truncate: "&hellip;"
   preferences:
-    languages: Jezici
     other: Ostali
-    publishing: Objavljivanje
-    web: Veb
   remote_follow:
     acct: Unesite Vaš korisnik@domen sa koga želite da pratite
     missing_resource: Ne mogu da nađem zahtevanu adresu preusmeravanja za Vaš nalog
@@ -506,32 +432,18 @@ sr-Latn:
     activity: Poslednja aktivnost
     browser: Veb čitač
     browsers:
-      alipay: Alipay
       blackberry: Blekberi
       chrome: Hrom
-      edge: Microsoft Edge
-      firefox: Firefox
       generic: Nepoznati veb čitač
-      ie: Internet Explorer
-      micro_messenger: MicroMessenger
-      nokia: Nokia S40 Ovi Browser
-      opera: Opera
-      phantom_js: PhantomJS
-      qq: QQ Browser
-      safari: Safari
-      uc_browser: UCBrowser
-      weibo: Weibo
     current_session: Trenutna sesija
     description: "%{browser} sa %{platform}"
     explanation: Ovo su trenutno prijavljeni veb čitači na Vaš Mastodont nalog.
-    ip: IP
     platforms:
       adobe_air: Adobe Air-a
       android: Androida
       blackberry: Blekberija
       chrome_os: Hrom OS-a
       firefox_os: Fajerfoks OS-a
-      ios: iOS
       linux: Linuksa
       mac: Mac-a
       other: nepoznate platforme
@@ -548,14 +460,11 @@ sr-Latn:
     development: Razvoj
     edit_profile: Izmena profila
     export: Izvoz podataka
-    followers: Autorizovani pratioci
     import: Uvoz
     migrate: Prebacivanje naloga
     notifications: Obaveštenja
     preferences: Podešavanja
-    settings: Postavke
     two_factor_authentication: Dvofaktorska identifikacija
-    your_apps: Vaše aplikacije
   statuses:
     open_in_web: Otvori u vebu
     over_character_limit: ograničenje od %{max} karaktera prekoračeno
@@ -565,7 +474,6 @@ sr-Latn:
       private: Tutovi koji nisu javni ne mogu da se prikače
       reblog: Podrška ne može da se prikači
     show_more: Prikaži još
-    title: '%{name}: "%{quote}"'
     visibilities:
       private: Samo pratioci
       private_long: Samo prikaži pratiocima
@@ -581,9 +489,6 @@ sr-Latn:
     title: Uslovi korišćenja i politika privatnosti instance %{instance}
   themes:
     default: Mastodont
-  time:
-    formats:
-      default: "%b %d, %Y, %H:%M"
   two_factor_authentication:
     code_hint: Unesite kod sa Vaše aplikacije za proveru identiteta da potvrdite
     description_html: Ako uključite <strong>dvofaktorsku identifikaciju</strong>, moraćete da imate telefon sa sobom da biste mogli da se prijavite. Telefon će onda generisati tokene za Vašu prijavu.
diff --git a/config/locales/sr.rb b/config/locales/sr.rb
new file mode 100644
index 0000000000000000000000000000000000000000..86b89a07e10d76708766ba49b79187a836afd37c
--- /dev/null
+++ b/config/locales/sr.rb
@@ -0,0 +1,3 @@
+require 'rails_i18n/common_pluralizations/romanian'
+
+::RailsI18n::Pluralization::Romanian.with_locale(:sr)
diff --git a/config/locales/sr.yml b/config/locales/sr.yml
index 6131ed01f26035cc3068a500a40d377a7933e608..1555fb235def46aa834865b8c250be565df82343 100644
--- a/config/locales/sr.yml
+++ b/config/locales/sr.yml
@@ -5,43 +5,28 @@ sr:
     about_mastodon_html: Мастодон је друштвена мрежа базирана на отвореним протоколима и слободном софтверу отвореног кода. Децентрализована је као што је децентрализована е-пошта.
     about_this: О инстанци
     administered_by: 'Администрирано од стране:'
-    api: API
     apps: Мобилне апликације
-    closed_registrations: Регистрације су тренутно затворене на овој инстанци. Међутим! Можете наћи другу инстанцу на којој ћете направити налог и одатле добити приступ на истој овој мрежи.
     contact: Контакт
     contact_missing: Није постављено
-    contact_unavailable: N/A
     documentation: Документација
     extended_description_html: |
       <h3>Добро место за правила</h3>
       <p>Проширени опис који још није постављен.</p>
-    features:
-      humane_approach_body: Учећи од грешака са осталих мрежа, а да би се борио против злоупотреба на друштвеним мрежама, Мастодонт покушава да прави што етичкије одлуке приликом развоја.
-      humane_approach_title: Хуманији приступ
-      not_a_product_body: Мастодонт није комерцијална мрежа. Нема реклама, нема скупљања приватних података, нема заштићених делова. Нема централног ауторитета.
-      not_a_product_title: Ви сте особа, не производ
-      real_conversation_body: Са 65535 карактера на располагању и подршком за грануларнији садржај и упозорења на осетљивији садржај, можете се изразити како год желите.
-      real_conversation_title: Прављен за прави разговор
-      within_reach_body: Више апликација за iOS, Андроид, као и друге платформе захваљујући екосистему добрих API-ја ће Вам омогућити да останете у контакту са пријатељима свуда.
-      within_reach_title: Увек у контакту
     generic_description: "%{domain} је сервер на мрежи"
     hosted_on: Мастодонт хостован на %{domain}
     learn_more: Сазнајте више
-    other_instances: Листа инстанци
     privacy_policy: Полиса приватности
     source_code: Изворни код
     status_count_after:
       few: статуси
-      many: статуси
       one: статус
-      other: статуси
+      other: статуса
     status_count_before: Који су написали
     terms: Услови коришћења
     user_count_after:
       few: корисници
-      many: корисници
       one: корисник
-      other: корисници
+      other: корисника
     user_count_before: Дом за
     what_is_mastodon: Шта је Мастодон?
   accounts:
@@ -49,12 +34,11 @@ sr:
     follow: Запрати
     followers:
       few: Пратиоци
-      many: Пратиоци
       one: Пратиоц
       other: Пратиоци
     following: Пратим
     joined: Придружио/ла се %{date}
-    last_active: последњи активни
+    last_active: последњи пут активни
     link_verified_on: Власништво над овом везом је проверено %{date}
     media: Медији
     moved_html: "%{name} је прешао на %{new_profile_link}:"
@@ -66,7 +50,6 @@ sr:
       following: Морате пратити ову особу ако хоћете да потврдите
     posts:
       few: Трубе
-      many: Трубе
       one: Труба
       other: Трубе
     posts_tab_heading: Трубе
@@ -119,7 +102,6 @@ sr:
       header: Заглавље
       inbox_url: Адреса сандучета
       invited_by: Позван од стране
-      ip: IP
       joined: Придружио се
       location:
         all: Све
@@ -289,7 +271,6 @@ sr:
       show:
         affected_accounts:
           few: Утиче на %{count} налога у бази
-          many: Утиче на %{count} налога у бази
           one: Један налог у бази података је под утицајем
           other: Утиче на %{count} налога у бази података
         retroactive:
@@ -315,7 +296,6 @@ sr:
       delivery_available: Достава је доступна
       known_accounts:
         few: "%{count} знаних налога"
-        many: "%{count} знаних налога"
         one: "%{count} знан налог"
         other: "%{count} знаних налога"
       moderation:
@@ -421,9 +401,6 @@ sr:
         min_invite_role:
           disabled: Нико
           title: Само преко позивнице
-        open:
-          desc_html: Дозволи свакоме да креира налог
-          title: Отворена регистрација
       show_known_fediverse_at_about_page:
         desc_html: Када се упали, показаће трубе из свих знаних федиверса на преглед. У супротном ће само показати локалне трубе.
         title: Покажи познате здружене инстанце у прегледнику временске линије
@@ -464,12 +441,9 @@ sr:
       title: Статуси налога
       with_media: Са мултимедијом
     subscriptions:
-      callback_url: Callback URL
       confirmed: Потврђено
       expires_in: Истиче за
       last_delivery: Последња достава
-      title: WebSub
-      topic: Topic
     tags:
       accounts: Налози
       hidden: Скривено
@@ -492,7 +466,6 @@ sr:
       subject: Нова пријава за %{instance} (#%{id})
   application_mailer:
     notification_preferences: Промени преференце Е-поште
-    salutation: "%{name},"
     settings: 'Промени подешавања е-поште: %{link}'
     view: 'Погледај:'
     view_profile: Погледај профил
@@ -506,7 +479,6 @@ sr:
     warning: Опрезно са овим подацима. Никад је не делите ни са ким!
     your_token: Ваш приступни токен
   auth:
-    agreement_html: Приступањем инстанци се слажете са <a href="%{rules_path}">правилима инстанце</a> и <a href="%{terms_path}">условима коришћења</a>.
     change_password: Лозинка
     confirm_email: Потврдите адресу е-поште
     delete_account: Обриши налог
@@ -518,13 +490,11 @@ sr:
     logout: Одјава
     migrate_account: Помери у други налог
     migrate_account_html: Ако желите да преусмерите овај налог на неки други, можете то <a href="%{path}">подесити овде</a>.
-    or: или
     or_log_in_with: Или се пријавите са
     providers:
       cas: CAS-ом
       saml: SAML-ом
     register: Региструј се
-    register_elsewhere: Региструјте се на другом серверу
     resend_confirmation: Пошаљи поруку са упутствима о потврди налога поново
     reset_password: Ресетуј лозинку
     security: Безбедност
@@ -542,18 +512,14 @@ sr:
     title: Запрати %{acct}
   datetime:
     distance_in_words:
-      about_x_hours: "%{count}h"
       about_x_months: "%{count}месец"
       about_x_years: "%{count}год"
       almost_x_years: "%{count}год"
       half_a_minute: Управо сад
-      less_than_x_minutes: "%{count}m"
       less_than_x_seconds: Управо сад
       over_x_years: "%{count}год"
       x_days: "%{count}д"
-      x_minutes: "%{count}m"
       x_months: "%{count}месец"
-      x_seconds: "%{count}s"
   deletes:
     bad_password_msg: Добар покушај, хакери! Неисправна лозинка
     confirm_password: Унесите тренутну лозинку да бисмо проверили Ваш идентитет
@@ -569,9 +535,8 @@ sr:
     explore_mastodon: Истражи %{title}
     people:
       few: "%{count} људе"
-      many: "%{count} људе"
-      one: "%{count} особу"
-      other: "%{count} људе"
+      one: "%{count} особа/е"
+      other: "%{count} људи"
   errors:
     '403': Немате дозвола да видите ову страну.
     '404': Страна коју сте тражили не постоји.
@@ -593,7 +558,6 @@ sr:
       request: Затражите Вашу архиву
       size: Величина
     blocks: Блокирали сте
-    csv: CSV
     domain_blocks: Блокови домена
     follows: Пратите
     lists: Листе
@@ -615,20 +579,6 @@ sr:
       title: Филтери
     new:
       title: Додај нови филтер
-  followers:
-    domain: Домен
-    explanation_html: Ако желите да осигурате приватност Ваших статуса, морате бити свесни ко Вас прати. <strong>Ваши приватни статуси се шаљу на све инстанце на којима имате пратиоце</strong>. Можда желите да их прегледате и да уклоните оне пратиоце на оним инстанцама за које немате поверења да ће поштовати Вашу приватност.
-    followers_count: Број пратилаца
-    lock_link: Закључајте налог
-    purge: Уклони из пратиоца
-    success:
-      few: У процесу блокирања пратиоца са %{count} домена...
-      many: У процесу блокирања пратиоца са %{count} домена...
-      one: У процесу блокирања пратиоца са једног домена...
-      other: У процесу блокирања пратиоца са %{count} домена...
-    true_privacy_html: Запамтите да се <strong>права приватност може постићи само шифровањем са краја на крај</strong>.
-    unlocked_warning_html: Свако може да Вас запрати да одмах види Ваше приватне статусе. %{lock_link} да бисте прегледали и одбацили пратиоце.
-    unlocked_warning_title: Ваш налог није закључан
   footer:
     developers: Програмери
     more: Више…
@@ -639,7 +589,6 @@ sr:
     save_changes: Сними измене
     validation_errors:
       few: Нешто није баш како треба! Прегледајте %{count} грешке испод
-      many: Нешто није баш како треба! Прегледајте %{count} грешака испод
       one: Нешто није баш како треба! Прегледајте грешке испод
       other: Нешто није баш како треба! Прегледајте %{count} грешака испод
   imports:
@@ -650,7 +599,6 @@ sr:
       following: Листа пратилаца
       muting: Листа ућутканих
     upload: Отпреми
-  in_memoriam_html: In Memoriam.
   invites:
     delete: Деактивирај
     expired: Истекло
@@ -666,7 +614,6 @@ sr:
     invited_by: 'Позвао Вас је:'
     max_uses:
       few: "%{count} коришћења"
-      many: "%{count} коришћења"
       one: 1 коришћење
       other: "%{count} коришћења"
     max_uses_prompt: Без ограничења
@@ -696,12 +643,10 @@ sr:
       mention: "%{name} Вас је поменуо у:"
       new_followers_summary:
         few: Добили сте %{count} нова пратиоца! Сјајно!
-        many: Добили сте %{count} нових пратиоца! Сјајно!
         one: Добили сте једног новог пратиоца! Јеее!
         other: Добили сте %{count} нових пратиоца! Сјајно!
       subject:
         few: "%{count} нова обавештења од последње посете \U0001F418"
-        many: "%{count} нових обавештења од последње посете \U0001F418"
         one: "1 ново обавештење од последње посете \U0001F418"
         other: "%{count} нових обавештења од последње посете \U0001F418"
       title: Док нисте били ту...
@@ -727,28 +672,13 @@ sr:
       body: "%{name} Вам је подржао/ла статус:"
       subject: "%{name} је подржао/ла Ваш статус"
       title: Нова подршка
-  number:
-    human:
-      decimal_units:
-        format: "%n%u"
-        units:
-          billion: B
-          million: M
-          quadrillion: Q
-          thousand: K
-          trillion: T
-          unit: ''
   pagination:
     newer: Новије
     next: Следеће
     older: Старије
     prev: Претходни
-    truncate: "&hellip;"
   preferences:
-    languages: Језици
     other: Остало
-    publishing: Објављивање
-    web: Веб
   remote_follow:
     acct: Унесите Ваш корисник@домен са кога желите да пратите
     missing_resource: Не могу да нађем захтевану адресу преусмеравања за Ваш налог
@@ -795,7 +725,6 @@ sr:
     current_session: Тренутна сесија
     description: "%{browser} са %{platform}"
     explanation: Ово су веб претраживачи који су тренутно пријављени на Ваш Мастодон налог.
-    ip: IP
     platforms:
       adobe_air: Адоб Ер-а
       android: Андроида
@@ -819,32 +748,26 @@ sr:
     development: Развој
     edit_profile: Измена профила
     export: Извоз података
-    followers: Ауторизовани пратиоци
     import: Увоз
     migrate: Пребацивање налога
     notifications: Обавештења
     preferences: Подешавања
-    settings: Поставке
     two_factor_authentication: Двофакторска идентификација
-    your_apps: Ваше апликације
   statuses:
     attached:
       description: 'У прилогу: %{attached}'
       image:
         few: "%{count} слика"
-        many: "%{count} слика"
         one: "%{count} слику"
         other: "%{count} слика"
       video:
         few: "%{count} видео записа"
-        many: "%{count} видео записа"
         one: "%{count} видео запис"
         other: "%{count} видео записа"
     boosted_from_html: Подржано од %{acct_link}
     content_warning: 'Упозорење на садржај: %{warning}'
     disallowed_hashtags:
       few: 'садржи забрањене хештегове: %{tags}'
-      many: 'садржи забрањене хештегове: %{tags}'
       one: 'садржи забрањени хештег: %{tags}'
       other: 'садржи забрањене хештегове: %{tags}'
     language_detection: Аутоматскo откривање језика
@@ -857,7 +780,6 @@ sr:
       reblog: Подршка не може да се прикачи
     show_more: Прикажи још
     sign_in_to_participate: Пријавите се да учествујете у разговору
-    title: '%{name}: "%{quote}"'
     visibilities:
       private: Само пратиоци
       private_long: Прикажи само пратиоцима
@@ -875,10 +797,6 @@ sr:
     contrast: Велики контраст
     default: Мастодон
     mastodon-light: Мастодон (светло)
-  time:
-    formats:
-      default: "%b %d, %Y, %H:%M"
-      month: "%b %Y"
   two_factor_authentication:
     code_hint: Да бисте потврдили, унесите код генерисан од стране ваше апликације за потврду идентитета
     description_html: Ако укључите <strong>двофакторску идентификацију</strong>, мораћете да имате телефон са собом да бисте могли да се пријавите. Телефон ће онда генерисати токене за Вашу пријаву.
diff --git a/config/locales/sv.yml b/config/locales/sv.yml
index 3a006ebe5a1126b3e4b0b98ac2fe2ce51003d455..d3d0cb888d0d1177234d5f793463841e78c7838e 100644
--- a/config/locales/sv.yml
+++ b/config/locales/sv.yml
@@ -5,35 +5,22 @@ sv:
     about_mastodon_html: Mastodon är ett socialt nätverk baserat på öppna webbprotokoll och gratis, öppen källkodsprogramvara. Det är decentraliserat som e-post.
     about_this: Om
     administered_by: 'Administreras av:'
-    closed_registrations: Registreringar är för närvarande stängda i denna instans. Dock så kan du hitta en annan instans för att skapa ett konto och få tillgång till samma nätverk från det.
+    api: API
     contact: Kontakt
     contact_missing: Inte inställd
-    contact_unavailable: N/A
     extended_description_html: |
       <h3>En bra plats för regler</h3>
       <p>Den utökade beskrivningen har inte konfigurerats ännu.</p>
-    features:
-      humane_approach_body: Mastodon, har lärt sig från tidigare misslyckanden i andra nätverk och syftar till att göra etiska designval i Mastodon för att bekämpa missbruk av sociala medier.
-      humane_approach_title: En mer human inställning
-      not_a_product_body: Mastodon är inte ett kommersiellt nätverk. Ingen reklam, ingen datautvinning, inga muromgärdade trädgårdar. Det finns ingen central myndighet.
-      not_a_product_title: Du är en person, inte en produkt
-      real_conversation_body: Med 65535 tecken till ditt förfogande och stöd för granulärt innehåll och mediavarningar så kan du uttrycka dig själv, som du vill.
-      real_conversation_title: Byggd för riktiga konversationer
-      within_reach_body: Flera appar för iOS, Android och andra plattformar tack vare ett utvecklingsvänligt API-ekosystem gör att du kan hålla kontakten med dina vänner var som helst.
-      within_reach_title: Alltid inom räckhåll
     generic_description: "%{domain} är en server i nätverket"
     hosted_on: Mastodon värd på %{domain}
     learn_more: Lär dig mer
-    other_instances: Instanslista
     source_code: Källkod
-    status_count_after: statusar
     status_count_before: Som skapat
-    user_count_after: användare
+    terms: Användarvillkor
     user_count_before: Hem till
     what_is_mastodon: Vad är Mastodon?
   accounts:
     follow: Följa
-    followers: Följare
     following: Följer
     media: Media
     moved_html: "%{name} har flyttat till %{new_profile_link}:"
@@ -41,12 +28,9 @@ sv:
     nothing_here: Det finns inget här!
     people_followed_by: Personer som %{name} följer
     people_who_follow: Personer som följer %{name}
-    posts: Toots
     posts_with_replies: Toots med svar
     reserved_username: Användarnamnet är reserverat
     roles:
-      admin: Admin
-      bot: Bot
       moderator: Moderator
     unfollow: Sluta följa
   admin:
@@ -57,7 +41,6 @@ sv:
       destroyed_msg: Modereringsnotering borttagen utan problem!
     accounts:
       are_you_sure: Är du säker?
-      avatar: Avatar
       by_domain: Domän
       change_email:
         changed_msg: E-postadressen har ändrats!
@@ -85,7 +68,6 @@ sv:
       followers_url: Följare URL
       follows: Följs
       inbox_url: Inkorgs URL
-      ip: IP
       location:
         all: Alla
         local: Lokal
@@ -122,7 +104,6 @@ sv:
       role: Behörigheter
       roles:
         admin: Administratör
-        moderator: Moderator
         staff: Personal
         user: Användare
       salmon_url: Lax URL
@@ -182,7 +163,6 @@ sv:
       destroyed_msg: Emojo borttagen utan problem!
       disable: Inaktivera
       disabled_msg: Inaktiverade emoji utan problem
-      emoji: Emoji
       enable: Aktivera
       enabled_msg: Aktiverade den emoji utan problem
       image_hint: PNG upp till 50KB
@@ -270,7 +250,6 @@ sv:
       reported_by: Anmäld av
       resolved: Löst
       resolved_msg: Anmälan har lösts framgångsrikt!
-      status: Status
       title: Anmälningar
       unassign: Otilldela
       unresolved: Olösta
@@ -301,9 +280,6 @@ sv:
         min_invite_role:
           disabled: Ingen
           title: Tillåt inbjudningar av
-        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
@@ -334,8 +310,6 @@ sv:
         nsfw_off: Markera som ej känslig
         nsfw_on: Markera som känslig
       failed_to_execute: Misslyckades att utföra
-      media:
-        title: Media
       no_media: Ingen media
       title: Kontostatus
       with_media: med media
@@ -344,9 +318,7 @@ sv:
       confirmed: Bekräftad
       expires_in: Utgår om
       last_delivery: Sista leverans
-      title: WebSub
       topic: Ämne
-    title: Administration
   admin_mailer:
     new_report:
       body: "%{reporter} har rapporterat %{target}"
@@ -354,7 +326,6 @@ sv:
       subject: Ny rapport för %{instance} (#%{id})
   application_mailer:
     notification_preferences: Ändra e-postinställningar
-    salutation: "%{name},"
     settings: 'Ändra e-postinställningar: %{link}'
     view: 'Granska:'
     view_profile: Visa profil
@@ -368,7 +339,6 @@ sv:
     warning: Var mycket försiktig med denna data. Dela aldrig den med någon!
     your_token: Din access token
   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: Lösenord
     confirm_email: Bekräfta e-postadress
     delete_account: Ta bort konto
@@ -380,13 +350,11 @@ 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: eller
     or_log_in_with: Eller logga in med
     providers:
       cas: CAS
       saml: SAML
     register: Registrera
-    register_elsewhere: Registrera dig på en annan server
     resend_confirmation: Skicka instruktionerna om bekräftelse igen
     reset_password: Återställ lösenord
     security: Säkerhet
@@ -412,7 +380,6 @@ sv:
       less_than_x_minutes: "%{count}min"
       less_than_x_seconds: Just nu
       over_x_years: "%{count}Ã¥r"
-      x_days: "%{count}d"
       x_minutes: "%{count}min"
       x_months: "%{count}mån"
       x_seconds: "%{count}sek"
@@ -449,18 +416,6 @@ sv:
     follows: Du följer
     mutes: Du tystar
     storage: Medialagring
-  followers:
-    domain: Domän
-    explanation_html: Om du vill försäkra integriteten av dina statusar måste du vara medveten om vem som följer dig. <strong>Dina privata statusar levereras till alla instanser där du har följare</strong>. Du kanske vill granska och eventuellt ta bort följare om du inte litar på att din integritet respekteras hos medarbetarna eller programvara i dessa instanser.
-    followers_count: Antal följare
-    lock_link: LÃ¥s ditt konto
-    purge: Ta bort från följare
-    success:
-      one: I processen med soft-blocking följare från en domän ...
-      other: I processen med soft-blocking följare från %{count} domäner...
-    true_privacy_html: Kom ihåg att <strong>sann integritet kan bara uppnås med end-to-end kryptering</strong>.
-    unlocked_warning_html: Vem som helst kan följa dig för att omedelbart se dina privata statusar. %{lock_link} för att kunna granska och avvisa följare.
-    unlocked_warning_title: Ditt konto är inte låst
   generic:
     changes_saved_msg: Ändringar sparades framgångsrikt!
     save_changes: Spara ändringar
@@ -546,28 +501,13 @@ sv:
       body: 'Din status knuffades av %{name}:'
       subject: "%{name} knuffade din status"
       title: Ny knuff
-  number:
-    human:
-      decimal_units:
-        format: "%n%u"
-        units:
-          billion: B
-          million: M
-          quadrillion: Q
-          thousand: K
-          trillion: T
-          unit: " "
   pagination:
     newer: Nyare
     next: Nästa
     older: Äldre
     prev: Tidigare
-    truncate: "&hellip;"
   preferences:
-    languages: Språk
     other: Annat
-    publishing: Publicering
-    web: Webb
   remote_follow:
     acct: Ange ditt användarnamn@domän du vill följa från
     missing_resource: Det gick inte att hitta den begärda omdirigeringsadressen för ditt konto
@@ -581,23 +521,16 @@ sv:
     activity: Senaste aktivitet
     browser: Webbläsare
     browsers:
-      alipay: Alipay
-      blackberry: Blackberry
-      chrome: Chrome
       edge: Microsoft Edge
       electron: Electron
       firefox: Firefox
       generic: Okänd browser
       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: Nuvarande session
     description: "%{browser} på %{platform}"
     explanation: Detta är inloggade webbläsare på Mastodon just nu.
@@ -613,8 +546,6 @@ sv:
       mac: Mac
       other: okänd plattform
       windows: Windows
-      windows_mobile: Windows Mobile
-      windows_phone: Windows Phone
     revoke: Ã…terkalla
     revoke_success: Sessionen återkallas framgångsrikt
     title: Sessioner
@@ -625,23 +556,16 @@ sv:
     development: Utveckling
     edit_profile: Redigera profil
     export: Exportera data
-    followers: Auktoriserade följare
-    import: Import
     migrate: Kontoflytt
     notifications: Meddelanden
     preferences: Inställningar
-    settings: Inställningar
     two_factor_authentication: Tvåstegsautentisering
-    your_apps: Dina applikationer
   statuses:
     attached:
       description: 'Bifogad: %{attached}'
       image:
         one: "%{count} bild"
         other: "%{count} bilder"
-      video:
-        one: "%{count} video"
-        other: "%{count} videor"
     boosted_from_html: Boosted från %{acct_link}
     content_warning: 'Innehållsvarning: %{warning}'
     disallowed_hashtags:
@@ -656,7 +580,6 @@ sv:
       private: Icke-offentliga toot kan inte fästas
       reblog: Knuffar kan inte fästas
     show_more: Visa mer
-    title: '%{name}: "%{quote}"'
     visibilities:
       private: Endast följare
       private_long: Visa endast till följare
@@ -674,10 +597,10 @@ sv:
       <h3 id="collect">Vilken information samlar vi in?</h3>
 
       <ul>
-        <li><em>Grundläggande kontoinformation</em>: Det användarnamn du väljer, visningsnamn, biografi, avatar/profilbild och bakgrundsbild kommer alltid vara tillgängliga för alla som kan nå webbsidan. </li>
-        <li><em>Inlägg, vem du följer och annan tillgänglig information</em>: Dina följare och de konton du följer är alltid tillgängliga. När du skapar ett nytt inlägg sparas datum och tid för meddelandet, samt vilket program du använde för att skapa inlägget. Detta gäller även bilder och media som inlägg kan innehålla.Både "Publika" och "Olistade" inlägg kan vara tillgängliga för alla som har åtkomst till webbsidan. When you feature a post on your profile, that is also publicly available information. Your posts are delivered to your followers, in some cases it means they are delivered to different servers and copies are stored there. When you delete posts, this is likewise delivered to your followers. The action of reblogging or favouriting another post is always public.</li>
-        <li><em>Direct and followers-only posts</em>: All posts are stored and processed on the server. Followers-only posts are delivered to your followers and users who are mentioned in them, and direct posts are delivered only to users mentioned in them. In some cases it means they are delivered to different servers and copies are stored there. We make a good faith effort to limit the access to those posts only to authorized persons, but other servers may fail to do so. Therefore it's important to review servers your followers belong to. You may toggle an option to approve and reject new followers manually in the settings. <em>Please keep in mind that the operators of the server and any receiving server may view such messages</em>, and that recipients may screenshot, copy or otherwise re-share them. <em>Do not share any dangerous information over Mastodon.</em></li>
-        <li><em>IPs and other metadata</em>: When you log in, we record the IP address you log in from, as well as the name of your browser application. All the logged in sessions are available for your review and revocation in the settings. The latest IP address used is stored for up to 12 months. We also may retain server logs which include the IP address of every request to our server.</li>
+      <li><em>Grundläggande kontoinformation</em>: Det användarnamn du väljer, visningsnamn, biografi, avatar/profilbild och bakgrundsbild kommer alltid vara tillgängliga för alla som kan nå webbsidan. </li>
+      <li><em>Inlägg, vem du följer och annan tillgänglig information</em>: Dina följare och de konton du följer är alltid tillgängliga. När du skapar ett nytt inlägg sparas datum och tid för meddelandet, samt vilket program du använde för att skapa inlägget. Detta gäller även bilder och media som inlägg kan innehålla.Både "Publika" och "Olistade" inlägg kan vara tillgängliga för alla som har åtkomst till webbsidan. When you feature a post on your profile, that is also publicly available information. Your posts are delivered to your followers, in some cases it means they are delivered to different servers and copies are stored there. When you delete posts, this is likewise delivered to your followers. The action of reblogging or favouriting another post is always public.</li>
+      <li><em>Direct and followers-only posts</em>: All posts are stored and processed on the server. Followers-only posts are delivered to your followers and users who are mentioned in them, and direct posts are delivered only to users mentioned in them. In some cases it means they are delivered to different servers and copies are stored there. We make a good faith effort to limit the access to those posts only to authorized persons, but other servers may fail to do so. Therefore it's important to review servers your followers belong to. You may toggle an option to approve and reject new followers manually in the settings. <em>Please keep in mind that the operators of the server and any receiving server may view such messages</em>, and that recipients may screenshot, copy or otherwise re-share them. <em>Do not share any dangerous information over Mastodon.</em></li>
+      <li><em>IPs and other metadata</em>: When you log in, we record the IP address you log in from, as well as the name of your browser application. All the logged in sessions are available for your review and revocation in the settings. The latest IP address used is stored for up to 12 months. We also may retain server logs which include the IP address of every request to our server.</li>
       </ul>
 
       <hr class="spacer" />
@@ -687,9 +610,9 @@ sv:
       <p>Any of the information we collect from you may be used in the following ways:</p>
 
       <ul>
-        <li>To provide the core functionality of Mastodon. You can only interact with other people's content and post your own content when you are logged in. For example, you may follow other people to view their combined posts in your own personalized home timeline.</li>
-        <li>To aid moderation of the community, for example comparing your IP address with other known ones to determine ban evasion or other violations.</li>
-        <li>The email address you provide may be used to send you information, notifications about other people interacting with your content or sending you messages, and to respond to inquiries, and/or other requests or questions.</li>
+      <li>To provide the core functionality of Mastodon. You can only interact with other people's content and post your own content when you are logged in. For example, you may follow other people to view their combined posts in your own personalized home timeline.</li>
+      <li>To aid moderation of the community, for example comparing your IP address with other known ones to determine ban evasion or other violations.</li>
+      <li>The email address you provide may be used to send you information, notifications about other people interacting with your content or sending you messages, and to respond to inquiries, and/or other requests or questions.</li>
       </ul>
 
       <hr class="spacer" />
@@ -705,8 +628,8 @@ sv:
       <p>We will make a good faith effort to:</p>
 
       <ul>
-        <li>Retain server logs containing the IP address of all requests to this server, in so far as such logs are kept, no more than 90 days.</li>
-        <li>Retain the IP addresses associated with registered users no more than 12 months.</li>
+      <li>Retain server logs containing the IP address of all requests to this server, in so far as such logs are kept, no more than 90 days.</li>
+      <li>Retain the IP addresses associated with registered users no more than 12 months.</li>
       </ul>
 
       <p>You can request and download an archive of your content, including your posts, media attachments, profile picture, and header image.</p>
@@ -755,9 +678,6 @@ sv:
     contrast: Hög kontrast
     default: Mastodon
     mastodon-light: Mastodon (ljust)
-  time:
-    formats:
-      default: "%b %d, %Y, %H:%M"
   two_factor_authentication:
     code_hint: Ange koden som genererats av din autentiseringsapp för att bekräfta
     description_html: Om du aktiverar <strong>tvåstegsautentisering</strong> kommer inloggningen kräva att du har din telefon tillgänglig, vilket kommer att generera tokens för dig att uppge.
@@ -794,7 +714,6 @@ sv:
       tip_following: Du följer din servers administratör(er) som standard. För att hitta fler intressanta personer, kolla de lokala och förenade tidslinjerna.
       tip_local_timeline: Den lokala tidslinjen är en störtflodsvy av personer på %{instance}. Det här är dina närmaste grannar!
       tip_mobile_webapp: Om din mobila webbläsare erbjuder dig att lägga till Mastodon till ditt hemskärm kan du få push-meddelanden. Det fungerar som en inbyggd app på många sätt!
-      tips: Tips
       title: Välkommen ombord, %{name}!
   users:
     invalid_email: E-postadressen är ogiltig
diff --git a/config/locales/ta.yml b/config/locales/ta.yml
new file mode 100644
index 0000000000000000000000000000000000000000..eef06fa7caabb2c2129df768eef29391c507c56a
--- /dev/null
+++ b/config/locales/ta.yml
@@ -0,0 +1,17 @@
+---
+ta:
+  errors:
+    '403': You don't have permission to view this page.
+    '404': The page you are looking for isn't here.
+    '410': The page you were looking for doesn't exist here anymore.
+    '422': 
+    '429': Throttled
+    '500': 
+  invites:
+    expires_in:
+      '1800': 30 minutes
+      '21600': 6 hours
+      '3600': 1 hour
+      '43200': 12 hours
+      '604800': 1 week
+      '86400': 1 day
diff --git a/config/locales/te.yml b/config/locales/te.yml
index f0f6942abffae70284d3d13adce95116501d787f..d4a2f507d78e4041b2eb2cc8a215155cae6a5067 100644
--- a/config/locales/te.yml
+++ b/config/locales/te.yml
@@ -5,9 +5,7 @@ te:
     about_mastodon_html: మాస్టొడాన్ అనేది ఒక సామాజిక మాధ్యమం. ఇది పూర్తిగా ఉచితం మరియు స్వేచ్ఛా సాఫ్టువేరు. ఈమెయిల్ లాగానే ఇది వికేంద్రీకరించబడినది.
     about_this: గురించి
     administered_by: 'నిర్వహణలో:'
-    api: API
     apps: మొబైల్ యాప్స్
-    closed_registrations: ప్రస్తుతం ఈ ఇన్స్టెన్స్ లో రిజిస్టేషన్లు మూసివేయబడ్డాయి. అయితే, వేరే ఇన్స్టెన్స్ లో ఖాతా తెరచికూడా ఈ ఇన్స్టెన్స్ ను అక్కడినుండే యాక్సెస్ చేయవచ్చు.
     contact: సంప్రదించండి
     contact_missing: ఇంకా సెట్ చేయలేదు
     contact_unavailable: వర్తించదు
@@ -15,19 +13,9 @@ te:
     extended_description_html: |
       <h3>నియమాలకు ఒక మంచి ప్రదేశం</h3>
       <p>మరింత విశదీకరణ ఇంకా సెట్ చేయబడలేదు.</p>
-    features:
-      humane_approach_body: వేరే సామాజిక మాధ్యమాల వైఫల్యాల నుండి నేర్చుకుని, నైతిక రూపకల్పనలతో సామాజిక మాధ్యమాల దుర్వినియోగంపై  మాస్టొడాన్ పోరాటం చేసే లక్ష్యంతో పనిచేస్తుంది.
-      humane_approach_title: మరింత మానవత్వంతో కూడిన విధానం
-      not_a_product_body: మాస్టొడాన్ వ్యాపార సంబంధిత మాధ్యమం కాదు. ఎటువంటి ప్రకటనలు, డేటా మైనింగ్, కంచెలు లేనిది. ఏ కేంద్ర అధికరమూ లేదు.
-      not_a_product_title: మీరొక వ్యక్తి, వస్తువు కాదు
-      real_conversation_body: With 500 characters at your disposal and support for granular content and media warnings, you can express yourself the way you want to.
-      real_conversation_title: నిజమైన సంభాషణలకోసం నిర్మించబడింది
-      within_reach_body: ఆండ్రాయిడ్, iOS మరియు ఇతర ప్లాట్ఫాంలకు వివిధరకాల యాప్స్ వున్నాయి. డెవలపర్ సహిత API వ్యవస్థే ఇందుకు మూలకారణం. ఇవి మీ స్ణేహితులతో అన్నివేళలా అందుబాటులో వుండడానికి సహాయపడతాయి.
-      within_reach_title: ఎల్లప్పుడూ అందుబాటులో
     generic_description: "%{domain} అనేది నెట్వర్కులోని ఒక సర్వరు"
     hosted_on: మాస్టొడాన్ %{domain} లో హోస్టు చేయబడింది
     learn_more: మరింత తెలుసుకోండి
-    other_instances: ఇన్స్టాన్స్ ల జాబితా
     privacy_policy: గోప్యత విధానము
     source_code: సోర్సు కోడ్
     status_count_after:
@@ -107,9 +95,7 @@ te:
       followers: అనుచరులు
       followers_url: అనుచరుల URL
       follows: అనుసరిస్తున్నారు
-      header: Header
       inbox_url: ఇన్ బాక్స్ URL
-      ip: IP
       location:
         all: అన్నీ
         local: లోకల్
@@ -117,7 +103,6 @@ te:
         title: లొకేషన్
       login_status: లాగిన్ స్థితి
       media_attachments: మీడియా అటాచ్మెంట్లు
-      memorialize: Turn into memoriam
       moderation:
         active: యాక్టివ్
         all: అన్నీ
@@ -127,3 +112,18 @@ te:
       moderation_notes: మోడరేషన్ నోట్స్
       most_recent_activity: ఇటీవల యాక్టివిటీ
       most_recent_ip: ఇటీవలి IP
+  errors:
+    '403': You don't have permission to view this page.
+    '404': The page you are looking for isn't here.
+    '410': The page you were looking for doesn't exist here anymore.
+    '422': 
+    '429': Throttled
+    '500': 
+  invites:
+    expires_in:
+      '1800': 30 minutes
+      '21600': 6 hours
+      '3600': 1 hour
+      '43200': 12 hours
+      '604800': 1 week
+      '86400': 1 day
diff --git a/config/locales/th.yml b/config/locales/th.yml
index 5be8e02c0f0d36d470ac20e766141d299b7b91ec..7a16bc2f3288ffdd34761126e02634bb56883bfd 100644
--- a/config/locales/th.yml
+++ b/config/locales/th.yml
@@ -1,301 +1,680 @@
 ---
 th:
   about:
-    about_mastodon_html: แมสโทดอน เป็น  <em>ดีเซ็นทรัลไลซ์</em><em>ฟรีโอเพ่นซอร์ส</em> โซเชี่ยวเน็ตเวริ์ค.  เป็นทางเลือกทดแทนโซเชี่ยวเน็ตเวิร์คที่ทำเป็นธุรกิจการค้า, ป้องกันการผูกขาดช่องทางการสื่อสารของคุณ. เลือกเซร์ฟเวอร์ที่คุณไว้ใจ &mdash; ที่คุณเลือกได้เอง, สื่อสารกับคนที่คุณต้องการได้เสมอ. ใครๆก็รันแมสโทดอนอินซะแตนซ์ได้ และ เชื่อมต่อกับ<em>โซเชี่ยวเน็ตเวิร์ค</em> โดยไม่มีอะไรมาขวางกั้น.
-    about_this: เกี่ยวกับอินซะแตนซ์นี้
-    closed_registrations: อินซะแตนซ์นี้ปิดรับลงทะเบียนแล้ว.
+    about_mastodon_html: Mastodon เป็นเครือข่ายสังคมที่ทำงานบนโปรโตคอลเว็บแบบเปิดและซอฟต์แวร์เสรีที่เปิดต้นฉบับ กระจายศูนย์เหมือนอีเมล
+    about_this: เกี่ยวกับ
+    active_count_after: ที่ใช้งาน
+    active_footnote: ผู้ใช้งานรายเดือน (MAU)
+    administered_by: 'ดูแลโดย:'
+    api: API
+    apps: แอปสำหรับมือถือ
+    apps_platforms: ใช้ Mastodon จาก iOS, Android และแพลตฟอร์มอื่น ๆ
+    browse_directory: เรียกดูไดเรกทอรีโปรไฟล์และกรองตามความสนใจ
+    browse_public_posts: เรียกดูสตรีมสดของโพสต์สาธารณะใน Mastodon
     contact: ติดต่อ
-    other_instances: อินซะแตนซ์อื่นๆ
-    source_code: ซอร์สโค๊ด
-    status_count_after: สถานะ
-    status_count_before: Who authored
-    user_count_after: ผู้ใช้
-    user_count_before: Home to
+    contact_missing: ไม่ได้ตั้ง
+    contact_unavailable: ไม่มี
+    discover_users: ค้นพบผู้ใช้
+    documentation: เอกสารประกอบ
+    extended_description_html: |
+      <h3>สถานที่ที่ดีสำหรับกฎ</h3>
+      <p>ยังไม่ได้ตั้งคำอธิบายแบบขยาย</p>
+    generic_description: "%{domain} เป็นเซิร์ฟเวอร์หนึ่งในเครือข่าย"
+    get_apps: ลองแอปสำหรับมือถือ
+    learn_more: เรียนรู้เพิ่มเติม
+    privacy_policy: นโยบายความเป็นส่วนตัว
+    see_whats_happening: ดูสิ่งที่กำลังเกิดขึ้น
+    server_stats: 'สถิติเซิร์ฟเวอร์:'
+    source_code: โค้ดต้นฉบับ
+    status_count_after:
+      other: สถานะ
+    status_count_before: ผู้สร้าง
+    terms: เงื่อนไขการให้บริการ
+    user_count_after:
+      other: ผู้ใช้
+    user_count_before: บ้านของ
+    what_is_mastodon: Mastodon คืออะไร?
   accounts:
+    choices_html: 'ทางเลือกของ %{name}:'
     follow: ติดตาม
-    followers: ผู้ติดตาม
+    followers:
+      other: ผู้ติดตาม
     following: กำลังติดตาม
-    nothing_here: ไม่พบสิ่งใดที่นี่!
-    people_followed_by: ถูกติดตามโดย %{name}
-    people_who_follow: คนที่ติดตาม %{name}
-    posts: โพสต์
+    joined: เข้าร่วมเมื่อ %{date}
+    last_active: ใช้งานล่าสุด
+    media: สื่อ
+    moved_html: "%{name} ได้ย้ายไปยัง %{new_profile_link}:"
+    network_hidden: ไม่มีข้อมูลนี้
+    nothing_here: ไม่มีสิ่งใดที่นี่!
+    people_followed_by: ผู้คนที่ %{name} ติดตาม
+    people_who_follow: ผู้คนที่ติดตาม %{name}
+    posts:
+      other: โพสต์
+    posts_tab_heading: โพสต์
+    posts_with_replies: โพสต์และการตอบกลับ
+    roles:
+      admin: ผู้ดูแล
+      bot: บอต
+      moderator: ผู้ควบคุม
+    unavailable: ไม่มีโปรไฟล์
     unfollow: เลิกติดตาม
   admin:
+    account_moderation_notes:
+      created_msg: สร้างหมายเหตุการควบคุมสำเร็จ!
+      delete: ลบ
+      destroyed_msg: ทำลายหมายเหตุการควบคุมสำเร็จ!
     accounts:
-      are_you_sure: แน่ใจนะ?
+      approve: อนุมัติ
+      approve_all: อนุมัติทั้งหมด
+      are_you_sure: คุณแน่ใจหรือไม่?
+      avatar: ภาพประจำตัว
+      by_domain: โดเมน
+      change_email:
+        changed_msg: เปลี่ยนอีเมลบัญชีสำเร็จ!
+        current_email: อีเมลปัจจุบัน
+        label: เปลี่ยนอีเมล
+        new_email: อีเมลใหม่
+        submit: เปลี่ยนอีเมล
+        title: เปลี่ยนอีเมลสำหรับ %{username}
       confirm: ยืนยัน
-      confirmed: ยึนยันแล้ว
-      confirming: ยืนยัน
-      disable_two_factor_authentication: Disable 2FA
-      display_name: ชื่อสำหรับดีสเพล
-      domain: โดแมน
+      confirmed: ยืนยันแล้ว
+      confirming: กำลังยืนยัน
+      deleted: ลบแล้ว
+      demote: ลดระดับ
+      disable: ปิดใช้งาน
+      disable_two_factor_authentication: ปิดใช้งาน 2FA
+      disabled: ปิดใช้งานอยู่
+      display_name: ชื่อที่แสดง
+      domain: โดเมน
       edit: แก้ไข
-      email: อีเมล์
+      email: อีเมล
       email_status: สถานะอีเมล
-      feed_url: Feed URL
+      enable: เปิดใช้งาน
+      enabled: เปิดใช้งานอยู่
+      feed_url: URL ฟีด
       followers: ผู้ติดตาม
-      follows: ติดตาม
+      followers_url: URL ผู้ติดตาม
+      follows: การติดตาม
+      header: ส่วนหัว
+      inbox_url: URL กล่องขาเข้า
+      invited_by: เชิญโดย
+      ip: IP
+      joined: เข้าร่วมเมื่อ
       location:
         all: ทั้งหมด
-        local: โลคอล
-        remote: รีโมทย์
-        title: สถานที่
-      media_attachments: สื่อที่แนบมา
+        local: ในเว็บ
+        remote: ระยะไกล
+        title: ตำแหน่งที่ตั้ง
+      login_status: สถานะการเข้าสู่ระบบ
+      media_attachments: ไฟล์แนบสื่อ
       moderation:
         all: ทั้งหมด
-        silenced: ปิดเสียง
-        suspended: หยุดไว้
-        title: Moderation
+        silenced: เงียบอยู่
+        suspended: ระงับอยู่
+        title: การควบคุม
+      moderation_notes: หมายเหตุการควบคุม
       most_recent_activity: กิจกรรมล่าสุด
       most_recent_ip: IP ล่าสุด
-      not_subscribed: Not subscribed
-      perform_full_suspension: Perform full suspension
-      profile_url: Profile URL
+      not_subscribed: ไม่ได้บอกรับ
+      outbox_url: URL กล่องขาออก
+      perform_full_suspension: ระงับ
+      profile_url: URL โปรไฟล์
+      protocol: โปรโตคอล
       public: สาธารณะ
-      push_subscription_expires: PuSH subscription expires
+      push_subscription_expires: การบอกรับ PuSH หมดอายุเมื่อ
+      redownload: รีเฟรชโปรไฟล์
+      reject: ปฏิเสธ
+      reject_all: ปฏิเสธทั้งหมด
+      remove_avatar: เอาภาพประจำตัวออก
+      remove_header: เอาส่วนหัวออก
       resend_confirmation:
-        already_confirmed: ผู้ใช้รายนี้ได้รับการยืนยันแล้ว
+        already_confirmed: ผู้ใช้นี้ได้รับการยืนยันอยู่แล้ว
         send: ส่งอีเมลยืนยันอีกครั้ง
-        success: ยืนยันอีเมลเรียบร้อยแล้ว!
-      reset_password: รีเซ็ตรหัสผ่าน
-      salmon_url: Salmon URL
+        success: ส่งอีเมลยืนยันสำเร็จ!
+      reset_password: ตั้งรหัสผ่านใหม่
+      resubscribe: บอกรับใหม่
+      role: สิทธิอนุญาต
+      roles:
+        admin: ผู้ดูแล
+        moderator: ผู้ควบคุม
+        staff: พนักงาน
+        user: ผู้ใช้
+      search: ค้นหา
       show:
-        created_reports: รายงานที่ถูกสร้างโดย แอคเคาท์นี้
-        targeted_reports: รายงานเกี่ยวกับแอคเคาท์นี้
-      silence: ปิดเสียง
+        created_reports: รายงานที่สร้าง
+        targeted_reports: รายงานโดยผู้อื่น
+      silence: เงียบ
+      silenced: เงียบอยู่
       statuses: สถานะ
+      subscribe: บอกรับ
+      suspended: ระงับอยู่
       title: บัญชี
-      undo_silenced: ยกเลิกการปิดเสียง
-      undo_suspension: ยกเลิกการหยุด
+      undo_silenced: เลิกทำการเงียบ
+      undo_suspension: เลิกทำการระงับ
+      unsubscribe: เลิกบอกรับ
       username: ชื่อผู้ใช้
+      warn: เตือน
       web: เว็บ
+    action_logs:
+      deleted_status: "(สถานะที่ลบแล้ว)"
+      title: รายการบันทึกการตรวจสอบ
+    custom_emojis:
+      by_domain: โดเมน
+      copy: คัดลอก
+      created_msg: สร้างอีโมจิสำเร็จ!
+      delete: ลบ
+      destroyed_msg: ทำลายอีโมโจสำเร็จ!
+      disable: ปิดใช้งาน
+      disabled_msg: ปิดใช้งานอีโมจินั้นสำเร็จ
+      emoji: อีโมจิ
+      enable: เปิดใช้งาน
+      enabled_msg: เปิดใช้งานอีโมจินั้นสำเร็จ
+      image_hint: PNG สูงสุด 50KB
+      new:
+        title: เพิ่มอีโมจิที่กำหนดเองใหม่
+      overwrite: เขียนทับ
+      shortcode: รหัสย่อ
+      title: อีโมจิที่กำหนดเอง
+      unlisted: ไม่อยู่ในรายการ
+      update_failed_msg: ไม่สามารถอัปเดตอีโมจินั้น
+      updated_msg: อัปเดตอีโมจิสำเร็จ!
+      upload: อัปโหลด
+    dashboard:
+      config: การกำหนดค่า
+      feature_deletions: การลบบัญชี
+      feature_invites: ลิงก์เชิญ
+      feature_profile_directory: ไดเรกทอรีโปรไฟล์
+      feature_registrations: การลงทะเบียน
+      feature_timeline_preview: ตัวอย่างเส้นเวลา
+      features: คุณลักษณะ
+      open_reports: รายงานที่เปิด
+      recent_users: ผู้ใช้ล่าสุด
+      search: การค้นหาข้อความแบบเต็ม
+      single_user_mode: โหมดผู้ใช้เดี่ยว
+      software: ซอฟต์แวร์
+      space: การใช้พื้นที่
+      title: แดชบอร์ด
+      total_users: ผู้ใช้ทั้งหมด
+      trends: แนวโน้ม
+      week_interactions: การโต้ตอบในสัปดาห์นี้
+      week_users_active: ที่ใช้งานในสัปดาห์นี้
+      week_users_new: ผู้ใช้ในสัปดาห์นี้
     domain_blocks:
-      add_new: เพิ่มใหม่
-      created_msg: กำลังบล๊อกโดเมน
-      destroyed_msg: ยกเลิกการบล๊อกโดเมน
+      add_new: เพิ่มการปิดกั้นโดเมนใหม่
+      created_msg: กำลังประมวลผลการปิดกั้นโดเมน
+      destroyed_msg: เลิกทำการปิดกั้นโดเมนแล้ว
       domain: โดเมน
       new:
-        create: สร้างการบล๊อก
-        hint: การบล๊อคโดเมนไม่สามารถป้องกันการสร้างแอคเค๊าท์ในฐานข้อมูล, but will retroactively and automatically apply specific moderation methods on those accounts.
+        create: สร้างการปิดกั้น
+        hint: การปิดกั้นโดเมนจะไม่ป้องกันการสร้างรายการบัญชีในฐานข้อมูล แต่จะใช้วิธีการควบคุมเฉพาะกับบัญชีเหล่านั้นย้อนหลังและโดยอัตโนมัติ
         severity:
-          desc_html: "<strong>การปิดเสียง</strong> จะทำให้ผู้ที่ไมไ่ด้ติดตามไม่เห็นโพสต์ของเขา. <strong>การหยุด</strong> จะนำเนื้อหา สื่อ และ โปรไฟล์ ออก."
-          silence: ปิดเสียง
-          suspend: หยุดไว้
-        title: การบล๊อกโดเมนใหม่
-      reject_media: ไม่อนุมัติไฟล์สื่อ
-      reject_media_hint: ลบไฟล์สื่อที่เก็บไว้ในเครื่อง และ ป้องกันการดาวน์โหลดในอนาคต. Irrelevant for suspensions
+          desc_html: "<strong>เงียบ</strong> จะทำให้โพสต์ของบัญชีมองไม่เห็นกับใครก็ตามที่ไม่ได้กำลังติดตามบัญชี <strong>ระงับ</strong> จะเอาเนื้อหา, สื่อ และข้อมูลโปรไฟล์ทั้งหมดของบัญชีออก ใช้ <strong>ไม่มี</strong> หากคุณเพียงแค่ต้องการปฏิเสธไฟล์สื่อ"
+          noop: ไม่มี
+          silence: เงียบ
+          suspend: ระงับ
+        title: การปิดกั้นโดเมนใหม่
+      reject_media: ปฏิเสธไฟล์สื่อ
+      reject_media_hint: เอาไฟล์สื่อที่จัดเก็บไว้ในเว็บออกและปฏิเสธที่จะดาวน์โหลดไฟล์ใด ๆ ในอนาคต ไม่เกี่ยวข้องกับการระงับ
+      reject_reports: ปฏิเสธรายงาน
+      severity:
+        silence: เงียบอยู่
+        suspend: ระงับอยู่
       show:
         affected_accounts:
-          one: มีผลต่อหนึ่งแอคเค๊าท์ในฐานข้อมูล
-          other: มีผลต่อแอคเค๊าท์ในฐานข้อมูลจำนวน %{count}
+          other: มีผลต่อ %{count} บัญชีในฐานข้อมูล
         retroactive:
-          silence: ยกเลิกการปิดเสียงทุกแอคเค๊าท์จากโดเมน
-          suspend: ยกเลิกการหยุดทุกแอคเค๊าท์จากโดเมน
-        title: ยกเลิกการบล๊อกโดเมน %{domain}
-        undo: ยกเลิก
-      undo: ยกเลิก
+          silence: เลิกเงียบบัญชีที่มีอยู่ทั้งหมดจากโดเมนนี้
+          suspend: เลิกระงับบัญชีที่มีอยู่ทั้งหมดจากโดเมนนี้
+        title: เลิกทำการปิดกั้นโดเมนสำหรับ %{domain}
+        undo: เลิกทำ
+      undo: เลิกทำการปิดกั้นโดเมน
+    email_domain_blocks:
+      add_new: เพิ่มใหม่
+      delete: ลบ
+      domain: โดเมน
+      new:
+        create: เพิ่มโดเมน
+    followers:
+      back_to_account: กลับไปที่บัญชี
+      title: ผู้ติดตามของ %{acct}
     instances:
-      title: Known Instances
+      by_domain: โดเมน
+      moderation:
+        all: ทั้งหมด
+        limited: จำกัดอยู่
+        title: การควบคุม
+      title: การติดต่อกับภายนอก
+      total_storage: ไฟล์แนบสื่อ
+    invites:
+      deactivate_all: ปิดใช้งานทั้งหมด
+      title: คำเชิญ
+    relays:
+      add_new: เพิ่มรีเลย์ใหม่
+      delete: ลบ
+      disable: ปิดใช้งาน
+      disabled: ปิดใช้งานอยู่
+      enable: เปิดใช้งาน
+      enabled: เปิดใช้งานอยู่
+      inbox_url: URL รีเลย์
+      save_and_enable: บันทึกแล้วเปิดใช้งาน
+      status: สถานะ
+      title: รีเลย์
+    report_notes:
+      created_msg: สร้างหมายเหตุรายงานสำเร็จ!
+      destroyed_msg: ลบหมายเหตุรายงานสำเร็จ!
     reports:
+      account:
+        note: หมายเหตุ
+        report: รายงาน
+      are_you_sure: คุณแน่ใจหรือไม่?
+      assign_to_self: มอบหมายให้ฉัน
       comment:
-        none: None
-      mark_as_resolved: ทำเครื่องหมายว่าจัดการแล้ว
-      report: 'Report #%{id}'
-      reported_account: รายงานแอคเคาท์
+        none: ไม่มี
+      created_at: รายงานเมื่อ
+      mark_as_resolved: ทำเครื่องหมายว่าแก้ปัญหาแล้ว
+      mark_as_unresolved: ทำเครื่องหมายว่ายังไม่ได้แก้ปัญหา
+      notes:
+        create: เพิ่มหมายเหตุ
+        delete: ลบ
+      report: 'รายงาน #%{id}'
+      reported_account: บัญชีที่ได้รับการรายงาน
       reported_by: รายงานโดย
-      resolved: จัดการแล้ว
+      resolved: แก้ปัญหาแล้ว
+      resolved_msg: แก้ปัญหารายงานสำเร็จ!
       status: สถานะ
       title: รายงาน
-      unresolved: Unresolved
+      unassign: เลิกมอบหมาย
+      unresolved: ยังไม่ได้แก้ปัญหา
+      updated_at: อัปเดตเมื่อ
     settings:
       contact_information:
-        email: กรอกที่อยู่อีเมล์สาธารณะ
-        username: กรอกชื่อผู้ใช้
+        email: อีเมลธุรกิจ
+        username: ชื่อผู้ใช้ในการติดต่อ
+      custom_css:
+        title: CSS ที่กำหนดเอง
+      profile_directory:
+        title: เปิดใช้งานไดเรกทอรีโปรไฟล์
       registrations:
         closed_message:
-          desc_html: Displayed on frontpage when registrations are closed<br> ใช้ HTML tags ได้
-          title: ปิดข้อความลงทะเบียน
-        open:
-          title: เปิดรับลงทะเบียน
+          desc_html: แสดงในหน้าแรกเมื่อปิดการลงทะเบียน คุณสามารถใช้แท็ก HTML
+          title: ข้อความการปิดการลงทะเบียน
+        deletion:
+          desc_html: อนุญาตให้ใครก็ตามลบบัญชีของเขา
+          title: เปิดการลบบัญชี
+        min_invite_role:
+          disabled: ไม่มีใคร
+          title: อนุญาตคำเชิญโดย
+      registrations_mode:
+        modes:
+          none: ไม่มีใครสามารถลงทะเบียน
+          open: ใครก็ตามสามารถลงทะเบียน
+        title: โหมดการลงทะเบียน
+      show_staff_badge:
+        desc_html: แสดงป้ายพนักงานในหน้าผู้ใช้
+        title: แสดงป้ายพนักงาน
       site_description:
-        desc_html: Displayed as a paragraph on the frontpage and used as a meta tag.<br> ใช้ HTML tags ได้, in particular <code>&lt;a&gt;</code> และ <code>&lt;em&gt;</code>.
-        title: คำอธิบายไซต์
+        desc_html: ย่อหน้าเกริ่นนำใน API อธิบายถึงสิ่งที่ทำให้เซิร์ฟเวอร์ Mastodon นี้พิเศษและสิ่งอื่นใดที่สำคัญ คุณสามารถใช้แท็ก HTML โดยเฉพาะอย่างยิ่ง <code>&lt;a&gt;</code> และ <code>&lt;em&gt;</code>
+        title: คำอธิบายเซิร์ฟเวอร์
       site_description_extended:
-        desc_html: Displayed on extended information page<br>You can use HTML tags
-        title: คำอธิบายไซต์เพิ่มเติม
-      site_title: ชื่อไซต์
-      title: ตั้งค่าไซต์
+        desc_html: สถานที่ที่ดีสำหรับแนวทางปฏิบัติ, กฎ, หลักเกณฑ์ และสิ่งอื่น ๆ ของคุณที่ทำให้เซิร์ฟเวอร์ของคุณแตกต่าง คุณสามารถใช้แท็ก HTML
+        title: ข้อมูลแบบขยายที่กำหนดเอง
+      site_short_description:
+        title: คำอธิบายเซิร์ฟเวอร์แบบสั้น
+      site_title: ชื่อเซิร์ฟเวอร์
+      timeline_preview:
+        desc_html: แสดงเส้นเวลาสาธารณะในหน้าเริ่มต้น
+        title: ตัวอย่างเส้นเวลา
+      title: การตั้งค่าไซต์
+    statuses:
+      back_to_account: กลับไปที่หน้าบัญชี
+      batch:
+        delete: ลบ
+        nsfw_off: ทำเครื่องหมายว่าไม่ละเอียดอ่อน
+        nsfw_on: ทำเครื่องหมายว่าละเอียดอ่อน
+      media:
+        title: สื่อ
+      no_media: ไม่มีสื่อ
+      title: สถานะบัญชี
     subscriptions:
-      callback_url: Callback URL
-      confirmed: ยืนยัน
+      callback_url: URL เรียกกลับ
+      confirmed: ยืนยันแล้ว
       expires_in: หมดอายุภายใน
-      last_delivery: จัดส่งครั้งล่าสุด
+      last_delivery: ส่งล่าสุด
       title: WebSub
-      topic: ชื่อเรื่อง
-    title: แอดมิน
+      topic: หัวข้อ
+    tags:
+      accounts: บัญชี
+      hidden: ซ่อนอยู่
+      hide: ซ่อนจากไดเรกทอรี
+      name: แฮชแท็ก
+      title: แฮชแท็ก
+      unhide: แสดงในไดเรกทอรี
+      visible: มองเห็น
+    title: การดูแล
+    warning_presets:
+      add_new: เพิ่มใหม่
+      delete: ลบ
+      edit: แก้ไข
+      edit_preset: แก้ไขคำเตือนที่ตั้งไว้ล่วงหน้า
+      title: จัดการคำเตือนที่ตั้งไว้ล่วงหน้า
+  appearance:
+    advanced_web_interface: ส่วนติดต่อเว็บขั้นสูง
+    animations_and_accessibility: ภาพเคลื่อนไหวและการช่วยการเข้าถึง
+    sensitive_content: เนื้อหาที่ละเอียดอ่อน
   application_mailer:
-    settings: 'เปลี่ยนอีเมล์ preferences: %{link}'
-    view: 'วิว:'
+    notification_preferences: เปลี่ยนการกำหนดลักษณะอีเมล
+    settings: 'เปลี่ยนการกำหนดลักษณะอีเมล: %{link}'
+    view: 'มุมมอง:'
+    view_profile: ดูโปรไฟล์
+    view_status: ดูสถานะ
   applications:
-    invalid_url: URL ที่ระบุไม่ถูกตั้ง
+    invalid_url: URL ที่ระบุไม่ถูกต้อง
   auth:
-    didnt_get_confirmation: Didn't receive confirmation instructions?
-    forgot_password: คุณลืมพาสเวริ์ดใช่ัม้ย?
-    login: ล๊อคอิน
-    logout: ล๊อคเอาท์
-    register: สมัคร
+    apply_for_account: ขอคำเชิญ
+    change_password: รหัสผ่าน
+    confirm_email: ยืนยันอีเมล
+    delete_account: ลบบัญชี
+    forgot_password: ลืมรหัสผ่านของคุณ?
+    login: เข้าสู่ระบบ
+    logout: ออกจากระบบ
+    migrate_account: ย้ายไปยังบัญชีอื่น
+    or_log_in_with: หรือเข้าสู่ระบบด้วย
+    providers:
+      cas: CAS
+      saml: SAML
+    register: ลงทะเบียน
     resend_confirmation: ส่งขั้นตอนวิธีการยืนยันใหม่อีกครั้ง
-    reset_password: เปลี่ยนรหัสผ่าน
-    security: Credentials
+    reset_password: ตั้งรหัสผ่านใหม่
+    security: ความปลอดภัย
     set_new_password: ตั้งรหัสผ่านใหม่
+    trouble_logging_in: มีปัญหาในการเข้าสู่ระบบ?
   authorize_follow:
-    error: Unfortunately, there was an error looking up the remote account
+    already_following: คุณกำลังติดตามบัญชีนี้อยู่แล้ว
     follow: ติดตาม
+    follow_request: 'คุณได้ส่งคำขอติดตามไปยัง:'
+    following: 'สำเร็จ! คุณกำลังติดตาม:'
+    post_follow:
+      return: แสดงโปรไฟล์ของผู้ใช้
+      web: ไปยังเว็บ
     title: ติดตาม %{acct}
   datetime:
     distance_in_words:
-      about_x_hours: "%{count}ช"
-      about_x_months: "%{count}ด"
-      about_x_years: "%{count}ป"
-      almost_x_years: "%{count}ป"
-      half_a_minute: ครึ่งนาที
-      less_than_x_minutes: "%{count}ม"
-      less_than_x_seconds: ไม่ถึงนาที
-      over_x_years: "%{count}ป"
-      x_days: "%{count}ด"
-      x_minutes: "%{count}น"
-      x_months: "%{count}ด"
-      x_seconds: "%{count}ว"
+      about_x_hours: "%{count} ชั่วโมง"
+      about_x_months: "%{count} เดือน"
+      about_x_years: "%{count} ปี"
+      almost_x_years: "%{count} ปี"
+      half_a_minute: เมื่อกี้นี้
+      less_than_x_minutes: "%{count} นาที"
+      less_than_x_seconds: เมื่อกี้นี้
+      over_x_years: "%{count} ปี"
+      x_days: "%{count} วัน"
+      x_minutes: "%{count} นาที"
+      x_months: "%{count} เดือน"
+      x_seconds: "%{count} วินาที"
+  deletes:
+    proceed: ลบบัญชี
+    success_msg: ลบบัญชีของคุณสำเร็จ
+  directories:
+    directory: ไดเรกทอรีโปรไฟล์
+    explanation: ค้นพบผู้ใช้ตามความสนใจของเขา
+    explore_mastodon: สำรวจ %{title}
   errors:
-    '403': คุณไม่มีสิทธิ์เข้าดูหน้านี้.
-    '404': ไม่พบเพจที่คุณต้องการดู.
-    '410': เพจที่คุณต้องการดูไม่มีแล้ว.
+    '403': คุณไม่มีสิทธิอนุญาตเพื่อดูหน้านี้
+    '404': หน้าที่คุณกำลังมองหาไม่ได้อยู่ที่นี่
+    '410': หน้าที่คุณกำลังมองหาไม่มีอยู่ที่นี่อีกต่อไป
     '422':
-      content: การตรวจสอบความปลอดภัยล้มเหลว. คุณกำลังบล๊อกคุกกี้อยู่?
+      content: การตรวจสอบความปลอดภัยล้มเหลว คุณกำลังปิดกั้นคุกกี้หรือไม่?
       title: การตรวจสอบความปลอดภัยล้มเหลว
     '429': Throttled
+    '500':
+      title: หน้านี้ไม่ถูกต้อง
   exports:
-    blocks: คุณบล๊อก
+    archive_takeout:
+      date: วันที่
+      download: ดาวน์โหลดการเก็บถาวรของคุณ
+      request: ขอการเก็บถาวรของคุณ
+      size: ขนาด
+    blocks: คุณปิดกั้น
     csv: CSV
+    domain_blocks: การปิดกั้นโดเมน
     follows: คุณติดตาม
+    lists: รายการ
     mutes: คุณปิดเสียง
-    storage: ที่เก็บสื่อ
-  followers:
-    domain: โดเมน
-    explanation_html: If you want to ensure the privacy of your statuses, you must be aware of who is following you. <strong>Your private statuses are delivered to all instances where you have followers</strong>. You may wish to review them, and remove followers if you do not trust your privacy to be respected by the staff or software of those instances.
-    followers_count: จำนวนผู้ติดตาม
-    lock_link: ล๊อคแอคเค๊าท์ของคุณ
-    purge: นำผู้ติดตามออก
-    success:
-      one: In the process of soft-blocking followers from one domain...
-      other: In the process of soft-blocking followers from %{count} domains...
-    true_privacy_html: Please mind that <strong>true privacy can only be achieved with end-to-end encryption</strong>.
-    unlocked_warning_html: Anyone can follow you to immediately view your private statuses. %{lock_link} to be able to review and reject followers.
-    unlocked_warning_title: แอคเค๊าท์ของคุณไม่ได้ล๊อค
+    storage: ที่เก็บข้อมูลสื่อ
+  featured_tags:
+    add_new: เพิ่มใหม่
+  filters:
+    contexts:
+      home: เส้นเวลาหน้าแรก
+      notifications: การแจ้งเตือน
+      public: เส้นเวลาสาธารณะ
+      thread: การสนทนา
+    edit:
+      title: แก้ไขตัวกรอง
+    index:
+      delete: ลบ
+      title: ตัวกรอง
+    new:
+      title: เพิ่มตัวกรองใหม่
+  footer:
+    developers: นักพัฒนา
+    more: เพิ่มเติม…
+    resources: ทรัพยากร
   generic:
-    changes_saved_msg: บันทึกการแก้ไขแล้ว!
+    all: ทั้งหมด
+    changes_saved_msg: บันทึกการเปลี่ยนแปลงสำเร็จ!
+    copy: คัดลอก
     save_changes: บันทึกการเปลี่ยนแปลง
-    validation_errors:
-      one: Something isn't quite right yet! Please review the error below
-      other: Something isn't quite right yet! Please review %{count} errors below
+  identity_proofs:
+    authorize: ใช่ อนุญาต
   imports:
+    modes:
+      merge: ผสาน
+      overwrite: เขียนทับ
     preface: You can import certain data like all the people you are following or blocking into your account on this instance, from files created by an export on another instance.
-    success: Your data was successfully uploaded and will now be processed in due time
     types:
-      blocking: Blocking list
-      following: Following list
-      muting: Muting list
-    upload: Upload
+      blocking: รายการปิดกั้น
+      following: รายการติดตาม
+      muting: รายการปิดเสียง
+    upload: อัปโหลด
+  invites:
+    delete: ปิดใช้งาน
+    expires_in:
+      '1800': 30 นาที
+      '21600': 6 ชั่วโมง
+      '3600': 1 ชั่วโมง
+      '43200': 12 ชั่วโมง
+      '604800': 1 สัปดาห์
+      '86400': 1 วัน
+    expires_in_prompt: ไม่เลย
+    generate: สร้าง
+    max_uses_prompt: ไม่มีขีดจำกัด
+    table:
+      expires_at: หมดอายุเมื่อ
+    title: เชิญผู้คน
   media_attachments:
     validations:
-      images_and_video: Cannot attach a video to a status that already contains images
-      too_many: แนบมากกว่า 4 ไฟล์ไม่ได้
+      images_and_video: ไม่สามารถแนบวิดีโอกับสถานะที่มีภาพอยู่แล้ว
+      too_many: ไม่สามารถแนบมากกว่า 4 ไฟล์
+  migrations:
+    acct: username@domain ของบัญชีใหม่
+    proceed: บันทึก
+  moderation:
+    title: การควบคุม
   notification_mailer:
     digest:
-      body: Here is a brief summary of the messages you missed since your last visit on %{since}
-      mention: "%{name} ส่งข้อความถึงคุณ:"
+      action: ดูการแจ้งเตือนทั้งหมด
+      mention: "%{name} ได้กล่าวถึงคุณใน:"
       new_followers_summary:
-        one: ยินดีด้วยคุณได้ผู้ติดตามคนใหม่! Yay!
         other: You have gotten %{count} new followers! Amazing!
-      subject:
-        one: "1 new notification since your last visit \U0001F418"
-        other: "%{count} new notifications since your last visit \U0001F418"
+      title: เมื่อคุณไม่อยู่...
     favourite:
-      body: 'สเตตัสของคุณได้รับการกดถูกใจโดย %{name} :'
-      subject: "%{name} กดถูกใจสเตตัสของคุณ"
+      body: 'สถานะของคุณได้รับการชื่นชอบโดย %{name}:'
+      subject: "%{name} ได้ชื่นชอบสถานะของคุณ"
+      title: รายการโปรดใหม่
     follow:
-      body: "%{name} กำลังติดตามคุณ"
-      subject: "%{name} ได้ติดตามคุณแล้ว"
+      body: "%{name} กำลังติดตามคุณ!"
+      subject: "%{name} กำลังติดตามคุณ"
+      title: ผู้ติดตามใหม่
     follow_request:
+      action: จัดการคำขอติดตาม
       body: "%{name} ได้ขอติดตามคุณ"
-      subject: 'Pending follower: %{name}'
+      subject: 'ผู้ติดตามที่รอดำเนินการ: %{name}'
+      title: คำขอติดตามใหม่
     mention:
-      body: 'You were mentioned by %{name} in:'
-      subject: You were mentioned by %{name}
+      action: ตอบกลับ
+      body: 'คุณได้รับการกล่าวถึงโดย %{name} ใน:'
+      subject: คุณได้รับการกล่าวถึงโดย %{name}
+      title: การกล่าวถึงใหม่
     reblog:
-      body: 'Your status was boosted by %{name}:'
-      subject: "%{name} boosted your status"
-  number:
-    human:
-      decimal_units:
-        format: "%n%u"
-        units:
-          billion: B
-          million: M
-          quadrillion: Q
-          thousand: K
-          trillion: T
-          unit: ''
+      body: 'สถานะของคุณได้รับการดันโดย %{name}:'
+      subject: "%{name} ได้ดันสถานะของคุณ"
+      title: การดันใหม่
   pagination:
-    next: ต่อไป
-    prev: ย้อนกลับ
+    newer: ใหม่กว่า
+    next: ถัดไป
+    older: เก่ากว่า
+    prev: ก่อนหน้า
     truncate: "&hellip;"
+  preferences:
+    posting_defaults: ค่าเริ่มต้นการโพสต์
+    public_timelines: เส้นเวลาสาธารณะ
+  relationships:
+    activity: กิจกรรมบัญชี
+    last_active: ใช้งานล่าสุด
+    relationship: ความสัมพันธ์
+    remove_selected_domains: เอาผู้ติดตามทั้งหมดออกจากโดเมนที่เลือก
+    remove_selected_followers: เอาผู้ติดตามที่เลือกออก
+    remove_selected_follows: เลิกติดตามผู้ใช้ที่เลือก
+    status: สถานะบัญชี
   remote_follow:
-    acct: Enter your username@domain you want to follow from
-    missing_resource: Could not find the required redirect URL for your account
-    proceed: Proceed to follow
-    prompt: 'You are going to follow:'
+    acct: ป้อน username@domain ของคุณที่คุณต้องการกระทำจาก
+    no_account_html: ไม่มีบัญชี? คุณสามารถ <a href='%{sign_up_path}' target='_blank'>ลงทะเบียนที่นี่</a>
+    proceed: ดำเนินการต่อเพื่อติดตาม
+    prompt: 'คุณกำลังจะติดตาม:'
+  remote_interaction:
+    favourite:
+      proceed: ดำเนินการต่อเพื่อชื่นชอบ
+      prompt: 'คุณต้องการชื่นชอบโพสต์นี้:'
+    reblog:
+      proceed: ดำเนินการต่อเพื่อดัน
+      prompt: 'คุณต้องการดันโพสต์นี้:'
+    reply:
+      proceed: ดำเนินการต่อเพื่อตอบกลับ
+      prompt: 'คุณต้องการตอบกลับโพสต์นี้:'
+  remote_unfollow:
+    error: ข้อผิดพลาด
+    title: ชื่อเรื่อง
+    unfollowed: เลิกติดตามแล้ว
+  sessions:
+    activity: กิจกรรมล่าสุด
+    browser: เบราว์เซอร์
+    browsers:
+      alipay: Alipay
+      blackberry: Blackberry
+      chrome: Chrome
+      edge: Microsoft Edge
+      electron: Electron
+      firefox: Firefox
+      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: เซสชันปัจจุบัน
+    ip: IP
+    platforms:
+      adobe_air: Adobe Air
+      android: Android
+      blackberry: Blackberry
+      chrome_os: ChromeOS
+      firefox_os: Firefox OS
+      ios: iOS
+      linux: Linux
+      mac: Mac
+      windows: Windows
+      windows_mobile: Windows Mobile
+      windows_phone: Windows Phone
+    revoke: เพิกถอน
+    revoke_success: เพิกถอนเซสชันสำเร็จ
+    title: เซสชัน
   settings:
-    authorized_apps: Authorized apps
-    back: กลับไปที่แมสโทดอน
+    account: บัญชี
+    account_settings: การตั้งค่าบัญชี
+    appearance: ลักษณะที่ปรากฏ
+    authorized_apps: แอปที่ได้รับอนุญาต
+    back: กลับไปที่ Mastodon
+    delete: การลบบัญชี
+    development: การพัฒนา
     edit_profile: แก้ไขโปรไฟล์
-    export: นำข้อมูลออก
-    followers: Authorized followers
+    export: การส่งออกข้อมูล
     import: นำเข้า
-    preferences: Preferences
-    settings: ตั้งค่า
-    two_factor_authentication: Two-factor Authentication
+    import_and_export: การนำเข้าและการส่งออก
+    notifications: การแจ้งเตือน
+    preferences: การกำหนดลักษณะ
+    profile: โปรไฟล์
+    relationships: การติดตามและผู้ติดตาม
+    two_factor_authentication: การรับรองความถูกต้องด้วยสองปัจจัย
   statuses:
+    attached:
+      description: 'แนบ: %{attached}'
+      image:
+        other: "%{count} ภาพ"
+      video:
+        other: "%{count} วิดีโอ"
+    content_warning: 'คำเตือนเนื้อหา: %{warning}'
     open_in_web: เปิดในเว็บ
-    over_character_limit: character limit of %{max} exceeded
-    show_more: แสดงเพิ่มอีก
+    pin_errors:
+      reblog: ไม่สามารถปักหมุดการดัน
+    poll:
+      total_votes:
+        other: "%{count} การลงคะแนน"
+    show_more: แสดงเพิ่มเติม
+    sign_in_to_participate: ลงชื่อเข้าเพื่อเข้าร่วมการสนทนา
+    title: '%{name}: "%{quote}"'
     visibilities:
-      private: สำหรับผู้ติดตามเท่านั้น
-      private_long: ให้เห็นเฉพาะผู้ติดตาม
-      public: Public
-      public_long: เปิดให้ทุกคนเห็นได้
-      unlisted: Unlisted
-      unlisted_long: Everyone can see, but not listed on public timelines
+      private: ผู้ติดตามเท่านั้น
+      private_long: แสดงต่อผู้ติดตามเท่านั้น
+      public: สาธารณะ
+      public_long: ทุกคนสามารถเห็น
+      unlisted: ไม่อยู่ในรายการ
   stream_entries:
-    reblogged: boosted
-    sensitive_content: Sensitive content
+    pinned: โพสต์ที่ปักหมุด
+    sensitive_content: เนื้อหาที่ละเอียดอ่อน
+  themes:
+    contrast: Mastodon (ความคมชัดสูง)
+    default: Mastodon (มืด)
+    mastodon-light: Mastodon (สว่าง)
   time:
     formats:
-      default: "%b %d, %Y, %H:%M"
+      default: "%d %b %Y, %H:%M"
   two_factor_authentication:
-    code_hint: Enter the code generated by your authenticator app to confirm
-    description_html: If you enable <strong>two-factor authentication</strong>, logging in will require you to be in possession of your phone, which will generate tokens for you to enter.
-    disable: ปิด
-    enable: เปิด
-    enabled_success: Two-factor authentication successfully enabled
-    generate_recovery_codes: สร้าง Recovery Codes
-    instructions_html: "<strong>Scan this QR code into Google Authenticator or a similiar TOTP app on your phone</strong>. From now on, that app will generate tokens that you will have to enter when logging in."
-    lost_recovery_codes: Recovery codes allow you to regain access to your account if you lose your phone. If you've lost your recovery codes, you can regenerate them here. Your old recovery codes will be invalidated.
-    manual_instructions: 'If you can''t scan the QR code and need to enter it manually, here is the plain-text secret:'
-    recovery_codes_regenerated: Recovery codes successfully regenerated
+    disable: ปิดใช้งาน
+    enable: เปิดใช้งาน
+    enabled: เปิดใช้งานการรับรองความถูกต้องด้วยสองปัจจัยแล้ว
+    enabled_success: เปิดใช้งานการรับรองความถูกต้องด้วยสองปัจจัยสำเร็จ
+    generate_recovery_codes: สร้างรหัสกู้คืน
     recovery_instructions_html: If you ever lose access to your phone, you can use one of the recovery codes below to regain access to your account. Keep the recovery codes safe, for example by printing them and storing them with other important documents.
     setup: ตั้งค่า
-    wrong_code: รหัสที่กรอกไม่ถูกต้อง! Are server time and device time correct?
+    wrong_code: รหัสที่ป้อนไม่ถูกต้อง! เวลาเซิร์ฟเวอร์และเวลาอุปกรณ์ถูกต้องหรือไม่?
+  user_mailer:
+    warning:
+      title:
+        none: คำเตือน
+        silence: จำกัดบัญชีอยู่
+        suspend: ระงับบัญชีอยู่
+    welcome:
+      review_preferences_action: เปลี่ยนการกำหนดลักษณะ
+      subject: ยินดีต้อนรับสู่ Mastodon
+      tips: เคล็ดลับ
   users:
-    invalid_email: อีเมล์ไม่ถูกต้อง
-    invalid_otp_token: two-factor code ไม่ถูกต้อง
+    invalid_email: ที่อยู่อีเมลไม่ถูกต้อง
+    invalid_otp_token: รหัสสองปัจจัยไม่ถูกต้อง
+    signed_in_as: 'ลงชื่อเข้าเป็น:'
+  verification:
+    verification: การตรวจสอบ
diff --git a/config/locales/tr.yml b/config/locales/tr.yml
index c38b73f2e25152ec365175a939cab7f97ecbdea4..3113e7a08f8cae0fa540d36afce2fec20bafb039 100644
--- a/config/locales/tr.yml
+++ b/config/locales/tr.yml
@@ -1,78 +1,163 @@
 ---
 tr:
   about:
+    about_hashtag_html: Bunlar <strong>#%{hashtag}X</strong> ile etiketlenen genel paylaşımlar. Açık alanda herhangi bir yerde bir hesabınız varsa, onlarla etkileşime geçebilirsiniz.
     about_mastodon_html: Mastodon <em>ücretsiz ve açık kaynaklı</em> bir sosyal ağdır. <em>Merkezileştirilmemiş</em> yapısı sayesinde diğer ticari sosyal platformların aksine iletişimininizin tek bir firmada tutulmasının/yönetilmesinin önüne geçer. Güvendiğiniz bir sunucuyu seçerek oradaki kişilerle etkileşimde bulunabilirsiniz. Herkes kendi Mastodon sunucusunu kurabilir ve sorunsuz bir şekilde Mastodon <em>sosyal ağına</em> dahil edebilir.
     about_this: Bu sunucu hakkında
-    closed_registrations: Bu sunucu şu anda yeni kayıt almamaktadır.
+    administered_by: 'Tarafından yönetildi:'
+    apps: Mobil uygulamalar
     contact: İletişim
-    other_instances: DiÄŸer sunucular
+    contact_missing: Ayarlanmadı
+    contact_unavailable: Yok
+    documentation: Belgeler
+    extended_description_html: |
+      <h3>Kural için iyi bir yer</h3>
+      <p>Genişletilmiş açıklama henüz ayarlanmamış.</p>
+    generic_description: "%{domain} aÄŸdaki bir sunucudur"
+    hosted_on: Mastodon %{domain} üzerinde barındırılıyor
+    learn_more: Daha fazla bilgi edinin
+    privacy_policy: Gizlilik politikası
     source_code: Kaynak kodu
-    status_count_after: adet gönderi yazıldı.
+    status_count_after:
+      one: durum
+      other: durum
     status_count_before: Åžu ana kadar
-    user_count_after: kullanıcı var.
+    terms: Kullanım şartları
+    user_count_after:
+      one: kullanıcı
+      other: kullanıcı
     user_count_before: Kayıtlı
+    what_is_mastodon: Mastodon nedir?
   accounts:
+    choices_html: "%{name} seçimleri:"
     follow: Takip et
-    followers: Takipçiler
+    followers:
+      one: Takipçi
+      other: Takipçi
     following: Takip ediliyor
+    joined: "%{date} tarihinde katıldı"
+    link_verified_on: Bu bağlantının mülkiyeti %{date} tarihinde kontrol edildi
+    media: Medya
+    moved_html: "%{name}, %{new_profile_link} adresine taşındı:"
+    network_hidden: Bu bilgi mevcut deÄŸil
     nothing_here: Burada henüz hiçbir gönderi yok!
     people_followed_by: Kullanıcı %{name}'in takip ettikleri
     people_who_follow: Kullanıcı %{name}'i takip edenler
-    posts: Gönderiler
+    pin_errors:
+      following: Onaylamak istediğiniz kişiyi zaten takip ediyor olmalısınız
+    posts_tab_heading: Tootlar
+    posts_with_replies: Tootlar ve yanıtlar
+    reserved_username: Kullanıcı adı saklıdır
+    roles:
+      admin: Yönetici
+      moderator: Denetleyici
     unfollow: Takibi bırak
   admin:
+    account_actions:
+      action: Eylemi gerçekleştir
+    account_moderation_notes:
+      create: Not bırakın
+      created_msg: Denetim notu başarıyla oluşturuldu!
+      delete: Sil
+      destroyed_msg: Denetim notu başarıyla yok edildi!
     accounts:
       are_you_sure: Emin misiniz?
+      by_domain: Sunucu
+      change_email:
+        changed_msg: Hesap e-postası başarıyla değiştirildi!
+        current_email: Mevcut e-posta
+        label: E-postayı değiştir
+        new_email: Yeni e-posta
+        submit: E-postayı değiştir
+        title: "%{username} için e-postayı değiştir"
       confirm: Onayla
       confirmed: Onaylandı
       confirming: Onaylama
+      deleted: Silinen
+      disable: Devre dışı
+      disable_two_factor_authentication: 2AD kapat
+      disabled: Kapalı
       display_name: Görünen adınız
       domain: Sunucu
       edit: Düzenle
       email: E-posta
-      email_status: Email Durumu
+      email_status: E-posta durumu
+      enable: EtkinleÅŸtir
+      enabled: Etkin
       feed_url: Besleme linki
       followers: Takipçiler
+      followers_url: Takipçi bağlantısı
       follows: Takip edilen
+      header: Üstbilgi
+      inbox_url: Gelen kutusu bağlantısı
+      invited_by: Tarafından davet edildi
+      joined: Katıldı
       location:
         all: Hepsi
         local: Yerel
         remote: Uzaktan
         title: Konum
+      login_status: GiriÅŸ durumu
       media_attachments: Medya ekleri
+      memorialize: Bir hatıraya dön
       moderation:
         all: Hepsi
         silenced: Susturulanlar
         suspended: Uzaklaştırılanlar
         title: Yönetim
+      moderation_notes: Denetleme notları
       most_recent_activity: Son aktivite
       most_recent_ip: Son IP
       not_subscribed: Abone edilmedi
-      perform_full_suspension: Tamamen uzaklaştır
+      perform_full_suspension: Askıya al
       profile_url: Profil linki
+      promote: Yükselt
+      protocol: Protokol
       public: Herkese açık
       push_subscription_expires: PuSH aboneliÄŸi dolumu
+      redownload: Profili yenile
+      remove_avatar: Avatarı kaldır
+      remove_header: Üstbilgiyi kaldır
       resend_confirmation:
         already_confirmed: Bu kullanıcı zaten onaylandı
         send: Doğrulama epostasını yeniden gönder
         success: Onay e-postası başarıyla gönderildi!
+      reset: Sıfırla
       reset_password: Parolayı değiştir
+      resubscribe: Yeniden abone ol
+      role: İzinler
+      roles:
+        admin: Yönetici
+        moderator: Denetleyici
+        staff: Personel
+        user: Kullanıcı
       salmon_url: Salmon Linki
+      search: Ara
+      shared_inbox_url: Paylaşılan gelen kutusu bağlantısı
       show:
-        created_reports: Bu hesap tarafından gelen şikayetler
-        targeted_reports: Bu hesaba gelen ÅŸikayetler
+        created_reports: Yapılan şikayetler
+        targeted_reports: Başkaları tarafından şikayet edildi
       silence: Sustur
+      silenced: SusturulmuÅŸ
       statuses: Durumlar
+      subscribe: Abone ol
+      suspended: Askıya alındı
       title: Hesaplar
+      unconfirmed_email: Onaylanmamış e-posta
       undo_silenced: Susturmayı geri al
       undo_suspension: Uzaklaştırmayı geri al
+      unsubscribe: Abonelikten çık
       username: Kullanıcı adı
-      web: Web
+      warn: Uyar
+    action_logs:
+      actions:
+        confirm_user: "%{name} %{target} kullanıcısının e-posta adresini onayladı"
+        create_custom_emoji: "%{name} yeni ifade yükledi %{target}"
+        disable_2fa_user: "%{name}, %{target} kullanıcısı için iki adım gereksinimini kapattı"
     domain_blocks:
       add_new: Yeni ekle
       created_msg: Domain bloÄŸu ÅŸu an iÅŸleniyor
       destroyed_msg: Domain bloÄŸu silindi
-      domain: Domain
       new:
         create: Yeni blok oluÅŸtur
         hint: Domain bloğu, veri tabanında hesap kayıtlarının oluşturulmasını engellemez, fakat o hesapların üzerine otomatik olarak belirli yönetim metodlarını olarak uygular.
@@ -114,8 +199,6 @@ tr:
         closed_message:
           desc_html: Kayıt alımları kapatıldığında ana sayfada görüntülenecek mesajdır. <br> HTML etiketleri kullanabilirsiniz
           title: Kayıt alımları kapatılma mesajı
-        open:
-          title: Kayıt alımları
       site_description:
         desc_html: Ana sayfada paragraf olarak görüntülenecek bilgidir.<br>Özellikle <code>&lt;a&gt;</code> ve <code>&lt;em&gt;</code> olmak suretiyle HTML etiketlerini kullanabilirsiniz.
         title: Site açıklaması
@@ -129,9 +212,16 @@ tr:
       confirmed: Onaylandı
       expires_in: BitiÅŸ Tarihi
       last_delivery: Son gönderim
-      title: WebSub
       topic: Konu
+    tags:
+      accounts: Hesaplar
+      name: Etiketler
+      title: Etiketler
     title: Yönetim
+    warning_presets:
+      add_new: Yeni ekle
+      delete: Sil
+      edit: Düzenle
   application_mailer:
     settings: 'E-mail tercihlerini deÄŸiÅŸtir: %{link}'
     view: 'Görüntüle:'
@@ -172,24 +262,13 @@ tr:
     '422':
       content: Güvenlik doğrulaması başarısız oldu. Site cookie'lerini engellemiş olabilirsiniz.
       title: Güvenlik doğrulamasu başarısız
+    '429': Throttled
+    '500': 
   exports:
     blocks: Blokladıklarınız
-    csv: CSV
     follows: Takip ettikleriniz
     mutes: Susturduklarınız
     storage: Ortam deposu
-  followers:
-    domain: Domain
-    explanation_html: Eğer gönderilerinizin gizliliğini garanti altına almak istiyorsanız, sizi kimin takip ettiğinden emin olmak zorundasınız. <strong> Gizli gönderileriniz, takipçilerinizin olduğu bütün sunuculara iletilir</strong>. Gönderilerinizi gözden geçirmek isteyebilir, ve o sunuculardaki yazılımın veya ilgili çalışanın, gizliliğinizi suistimal edeceğinizi düşünüyorsanız, o sunucudaki takipçilerinizi silebilirsiniz.
-    followers_count: Takipçi sayısı
-    lock_link: Hesabımı kilitle
-    purge: Takipçilerimden çıkar
-    success:
-      one: Domaindeki takipçilerin engellenmesi sürüyor...
-      other: "%{count} domaindeki takipçilerin engellenmesi sürüyor..."
-    true_privacy_html: 'Lütfen aklınızda bulundurun: <strong>gerçek gizlilik yalnızca uçtan-uca şifreleme ile sağlanır</strong>.'
-    unlocked_warning_html: Herhangi bir kişi sizi takip edebilir ve paylaştığınız gizli gönderilerinizi görebilir. %{lock_link}'e tıklayarak takipçilerinizi gözden geçirebilir ve reddedebilirsiniz.
-    unlocked_warning_title: Hesabınız kilitlendi
   generic:
     changes_saved_msg: Değişiklikler başarıyla kaydedildi!
     save_changes: DeÄŸiÅŸiklikleri kaydet
@@ -204,6 +283,14 @@ tr:
       following: Takip edilenler listesi
       muting: Susturulanlar listesi
     upload: Yükle
+  invites:
+    expires_in:
+      '1800': 30 minutes
+      '21600': 6 hours
+      '3600': 1 hour
+      '43200': 12 hours
+      '604800': 1 week
+      '86400': 1 day
   media_attachments:
     validations:
       images_and_video: Halihazırda görsel içeren bir gönderiye video ekleyemezsiniz
@@ -233,21 +320,9 @@ tr:
     reblog:
       body: "%{name} durumunuzu boost etti:"
       subject: "%{name} durumunuzu boost etti"
-  number:
-    human:
-      decimal_units:
-        format: "%n%u"
-        units:
-          billion: B
-          million: M
-          quadrillion: Q
-          thousand: K
-          trillion: T
-          unit: ''
   pagination:
     next: Sonraki
     prev: Önceki
-    truncate: "&hellip;"
   remote_follow:
     acct: Takip edeceÄŸiniz kiÅŸiyi kullaniciadi@sunuculinki ÅŸeklinde giriniz
     missing_resource: Hesabınız için yönlendirme linki bulunamadı
@@ -258,10 +333,8 @@ tr:
     back: Mastodon'a geri dön
     edit_profile: Profili düzenle
     export: Dışa aktar
-    followers: İzin verilmiş takipçiler
     import: İçe aktar
     preferences: Tercihler
-    settings: Ayarlar
     two_factor_authentication: İki-faktörlü doğrulama
   statuses:
     open_in_web: Web sayfasında aç
@@ -277,9 +350,6 @@ tr:
   stream_entries:
     reblogged: boost edildi
     sensitive_content: Hassas içerik
-  time:
-    formats:
-      default: "%b %d, %Y, %H:%M"
   two_factor_authentication:
     code_hint: Onaylamak için kimlik doğrulama uygulamanızın oluşturduğu kodu giriniz
     description_html: Eğer <strong>iki-faktörlü kimlik doğrulamayı</strong> aktif ederseniz, giriş yaparken sizin için giriş kodu üreten telefonunuza ihtiyaç duyacaksınız.
diff --git a/config/locales/uk.yml b/config/locales/uk.yml
index 9a63854b5821a064a667315c72153a88d2956699..e027b6baee48a24f7fbd8f3d99e72e62389f6e99 100644
--- a/config/locales/uk.yml
+++ b/config/locales/uk.yml
@@ -5,8 +5,6 @@ uk:
     about_mastodon_html: Mastodon - це <em>вільна</em> соціальна мережа з <em>відкритим вихідним кодом</em>. Вона є <em>децентралізованою</em> альтернативою комерційним платформам, що дозволяє уникнути ризиків монополізації вашого спілкування однією компанією. Виберіть сервер, якому ви довіряєте &mdash; що б ви не вибрали, Ви зможете спілкуватись з усіма іншими. Будь-який користувач може запустити власну інстанцію Mastodon та без проблем брати участь в <em>соціальній мережі</em>.
     about_this: Про цю інстанцію
     administered_by: 'Адміністратор:'
-    api: API
-    closed_registrations: На даний момент реєстрація на цій інстанції закрита.
     contact: Зв'язатися
     contact_missing: Не зазначено
     contact_unavailable: Недоступно
@@ -14,30 +12,17 @@ uk:
     extended_description_html: |
       <h3>Гарне місце для правил</h3>
       <p>Детальний опис ще не налаштований.</p>
-    features:
-      humane_approach_body: Навчаючись з помилок інших соціальних мереж, Mastodon націлений на етичні рішення для боротьби з направильним використанням соціальних медіа.
-      humane_approach_title: Більш людський підхід
-      not_a_product_body: Mastodon - це некомерційна мережа. Ніякої реклами, збору даних і залізних стін. Тут немає центральної влади.
-      not_a_product_title: Ви - особистість, а не продукт
-      real_conversation_body: Висловлюйте свої думки себе у будь-який спосіб маючи в розпорядженні 500 символів з підтримкою гранульованого контенту та попереджень медіа.
-      real_conversation_title: Побудований для справжньої розмови
-      within_reach_body: Велика кількість застосунків для iOS, Android та інших платформ, завдяки дружній до розробника екосистемі дозволяє бути на звязку з друзями звідусіль.
-      within_reach_title: Завжди на звязку
     generic_description: "%{domain} є одним сервером у мережі"
     hosted_on: Mastodon розміщено на %{domain}
     learn_more: Дізнатися більше
-    other_instances: Інші інстанції
     privacy_policy: Політика приватності
     source_code: Вихідний код
-    status_count_after: статусів
     status_count_before: Опубліковано
     terms: Правила використання
-    user_count_after: користувачів
     user_count_before: Тут живе
     what_is_mastodon: Що таке Mastodon?
   accounts:
     follow: Підписатися
-    followers: Підписники
     following: Підписаний(-а)
     joined: Приєднався %{date}
     media: Медіа
@@ -46,7 +31,6 @@ uk:
     nothing_here: Тут нічого немає!
     people_followed_by: Люди, на яких підписаний(-а) %{name}
     people_who_follow: Підписники %{name}
-    posts: Пости
     posts_with_replies: Пости і відповіді
     reserved_username: Це ім'я користувача зарезервоване
     roles:
@@ -81,7 +65,6 @@ uk:
       display_name: Відображуване ім'я
       domain: Домен
       edit: Змінити
-      email: Email
       email_status: Статус e-mail
       enable: Увімкнути
       enabled: Увімкнено
@@ -90,7 +73,6 @@ uk:
       followers_url: URL підписників
       follows: Підписки
       inbox_url: Вхідний URL
-      ip: IP
       location:
         all: Усі
         local: Локальні
@@ -130,7 +112,6 @@ uk:
         moderator: Модератор
         staff: Персонал
         user: Користувач
-      salmon_url: Salmon URL
       search: Пошук
       shared_inbox_url: URL спільного вхідного кошика
       show:
@@ -331,9 +312,6 @@ uk:
         min_invite_role:
           disabled: Ніхто
           title: Дозволити запрошення від
-        open:
-          desc_html: Дозволити будь-ком створювати аккаунт
-          title: Відкрити реєстрацію
       show_known_fediverse_at_about_page:
         desc_html: Коли увімкнено, будуть показані пости з усього відомого федисвіту у передпоказі. Інакше будуть показані локальні пости.
         title: Показувати доступний федисвіт у передпоказі фіду
@@ -372,11 +350,9 @@ uk:
       title: Статуси аккаунтів
       with_media: З медіа
     subscriptions:
-      callback_url: Callback URL
       confirmed: Підтверджено
       expires_in: Спливає через
       last_delivery: Остання доставка
-      title: WebSub
       topic: Тема
     title: Адміністрування
   admin_mailer:
@@ -386,7 +362,6 @@ uk:
       subject: Нова скарга до %{instance} (#%{id})
   application_mailer:
     notification_preferences: Змінити налаштування e-mail
-    salutation: "%{name},"
     settings: 'Змінити налаштування e-mail: %{link}'
     view: 'Перегляд:'
     view_profile: Показати профіль
@@ -400,7 +375,6 @@ uk:
     warning: Будьте дуже обережні з цими даними. Ніколи не діліться ними ні з ким!
     your_token: Ваш токен доступу
   auth:
-    agreement_html: Реєструючись, ви погоджуєтеся виконувати <a href="%{rules_path}">правила інстанції</a> та <a href="%{terms_path}">наші умови використання</a>.
     change_password: Пароль
     confirm_email: Підтвердьте e-mail адресу
     delete_account: Видалити аккаунт
@@ -412,13 +386,8 @@ uk:
     logout: Вийти
     migrate_account: Переїхати до іншого аккаунту
     migrate_account_html: Якщо ви бажаєте, щоб відвідувачі цього акканту були перенаправлені до іншого, ви можете <a href="%{path}">налаштувати це тут</a>.
-    or: або
     or_log_in_with: Або увійдіть з
-    providers:
-      cas: CAS
-      saml: SAML
     register: Зареєструватися
-    register_elsewhere: Зареєструватися на іншому сервері
     resend_confirmation: Повторно відправити інструкції з підтвердження
     reset_password: Скинути пароль
     security: Зміна паролю
@@ -477,7 +446,6 @@ uk:
       request: Зробити запит на архів
       size: Розмір
     blocks: Список блокувань
-    csv: CSV
     follows: Підписки
     mutes: Список глушення
     storage: Ваш медіаконтент
@@ -497,20 +465,9 @@ uk:
       title: Фільтри
     new:
       title: Додати фільтр
-  followers:
-    domain: Домен
-    explanation_html: Якщо Ви хочете бути впевнені в приватності Ваших статусів, Ви повинні мати чітке уявлення про те, хто на Вас підписаний. <strong>Ваші приватні статусі відправляються усім сайтам, на яких у Вас є підписники</strong>. Рекомендуємо видалити з підписників користувачів інстанцій, адміністрації чи програмному забезпеченню яких Ви не довіряєте.
-    followers_count: Кількість підписників
-    lock_link: Закрийте акаунт
-    purge: Видалити з підписників
-    success: У процесі м'якого блокування підписників з %{count} доменів...
-    true_privacy_html: Будь ласка, помітьте, що <strong>справжняя конфіденційність може бути досягнена тільки за допомогою end-to-end шифрування</strong>.
-    unlocked_warning_html: Хто завгодно може підписатися на Вас та отримати доступ до перегляду Ваших приватних статусів. %{lock_link}, щоб отримати можливість роздивлятися та вручну підтверджувати запити щодо підписки.
-    unlocked_warning_title: Ваш аккаунт не закритий для підписки
   generic:
     changes_saved_msg: Зміни успішно збережені!
     save_changes: Зберегти зміни
-    validation_errors: Щось тут не так! Будь ласка, ознайомтеся з %{count} помилками нижче
   imports:
     preface: Вы можете завантажити деякі дані, наприклад, списки людей, на яких Ви підписані чи яких блокуєте, в Ваш акаунт на цій інстанції з файлів, експортованих з іншої інстанції.
     success: Ваші дані були успішно загружені та будуть оброблені в найближчий момент
@@ -533,7 +490,6 @@ uk:
     expires_in_prompt: Ніколи
     generate: Згенерувати
     invited_by: 'Вас запросив(-ла):'
-    max_uses: "%{count} використань"
     max_uses_prompt: Без обмеження
     prompt: Генеруйте та діліться посиланням з іншими для надання доступу до сайту
     table:
@@ -595,24 +551,18 @@ uk:
   number:
     human:
       decimal_units:
-        format: "%n%u"
         units:
           billion: млрд
           million: млн
           quadrillion: квдрл
           thousand: тис
           trillion: трлн
-          unit: ''
   pagination:
     newer: Новіше
     next: Далі
     prev: Назад
-    truncate: "&hellip;"
   preferences:
-    languages: Мови
     other: Інше
-    publishing: Публікація
-    web: Веб
   remote_follow:
     acct: Введіть username@domain, яким ви хочете підписатися
     missing_resource: Пошук потрібного перенаправлення URL для Вашого аккаунта закінчився невдачею
@@ -627,40 +577,12 @@ uk:
     activity: Остання активність
     browser: Браузер
     browsers:
-      alipay: Alipay
-      blackberry: Blackberry
-      chrome: Chrome
-      edge: Microsoft Edge
-      electron: Electron
-      firefox: Firefox
       generic: Невідомий браузер
-      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: Активна сесія
     description: "%{browser} на %{platform}"
     explanation: Це веб-браузери, нині авторизовані до вашого аккаунту Mastodon.
-    ip: IP
     platforms:
-      adobe_air: Adobe Air
-      android: Android
-      blackberry: Blackberry
-      chrome_os: ChromeOS
-      firefox_os: Firefox OS
-      ios: iOS
-      linux: Linux
-      mac: Mac
       other: невідома платформа
-      windows: Windows
-      windows_mobile: Windows Mobile
-      windows_phone: Windows Phone
     revoke: Закінчити
     revoke_success: Сесія успішно закінчена
     title: Сесії
@@ -671,22 +593,16 @@ uk:
     development: Розробка
     edit_profile: Редагувати профіль
     export: Експорт даних
-    followers: Авторизовані підписники
     import: Імпорт
     migrate: Міграція акаунту
     notifications: Сповіщення
     preferences: Налаштування
-    settings: Опції
     two_factor_authentication: Двофакторна авторизація
-    your_apps: Ваші затосунки
   statuses:
     attached:
       description: 'Прикріплено: %{attached}'
-      image: "%{count} картинки"
-      video: "%{count} відео"
     boosted_from_html: Просунуто від %{acct_link}
     content_warning: 'Попередження про контент: %{warning}'
-    disallowed_hashtags: 'містив заборонені хештеґи: %{tags}'
     language_detection: Автоматично визначати мову
     open_in_web: Відкрити у вебі
     over_character_limit: перевищено ліміт символів (%{max})
@@ -696,7 +612,6 @@ uk:
       private: Не можна закріпити непублічний пост
       reblog: Не можна закріпити просунутий пост
     show_more: Детальніше
-    title: '%{name}: "%{quote}"'
     visibilities:
       private: Для підписників
       private_long: Показувати тільки підписникам
@@ -714,9 +629,6 @@ uk:
     contrast: Висока контрасність
     default: Mastodon
     mastodon-light: Mastodon (світла)
-  time:
-    formats:
-      default: "%b %d, %Y, %H:%M"
   two_factor_authentication:
     code_hint: Для підтверждення введіть код, згенерований застосунком аутентифікатора
     description_html: При увімкненні <strong>двофакторної аутентифікації</strong>, вхід буде вимагати від Вас використовування Вашого телефона, який згенерує вхідний код.
diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml
index 076bdb17e26fb3e98fe4d79341edc621137833e1..0c9b291ad3d301fd27b8b41b07bff9ab9b288af3 100644
--- a/config/locales/zh-CN.yml
+++ b/config/locales/zh-CN.yml
@@ -1,56 +1,61 @@
 ---
 zh-CN:
   about:
-    about_hashtag_html: 这里展示的是带有话题标签 <strong>#%{hashtag}</strong> 的公开嘟文。如果你想与他们互动,你需要在任意一个 Mastodon 实例或与其兼容的网站上拥有一个帐户。
+    about_hashtag_html: 这里展示的是带有话题标签 <strong>#%{hashtag}</strong> 的公开嘟文。如果你想与他们互动,你需要在任意一个 Mastodon 站点或与其兼容的网站上拥有一个帐户。
     about_mastodon_html: Mastodon(长毛象)是一个建立在开放式网络协议和自由、开源软件之上的社交网络,有着类似于电子邮件的分布式设计。
-    about_this: 关于本实例
-    administered_by: 本实例的管理员:
+    about_this: 关于本站
+    active_count_after: 活跃
+    active_footnote: 每月活跃用户
+    administered_by: 本站管理员:
     api: API
     apps: 移动应用
-    closed_registrations: 这个实例目前没有开放注册。不过,你可以前往其他实例注册一个帐户,同样可以加入到这个网络中哦!
+    apps_platforms: 在 iOS、Android 和其他平台上使用 Mastodon
+    browse_directory: 浏览用户资料目录并按兴趣筛选
+    browse_public_posts: 浏览 Mastodon 上公共嘟文的实时信息流
     contact: 联系方式
     contact_missing: 未设定
     contact_unavailable: 未公开
+    discover_users: 发现用户
     documentation: 文档
     extended_description_html: |
       <h3>这里可以写一些规定</h3>
       <p>本站尚未设置详细介绍。</p>
-    features:
-      humane_approach_body: Mastodon 从其他网络的失败经验中汲取了教训,致力于在与错误的社交媒体使用方式的斗争中做出符合伦理化设计的选择。
-      humane_approach_title: 更加以人为本
-      not_a_product_body: Mastodon 绝非一个商业网络。这里既没有广告,也没有数据挖掘,更没有围墙花园。中心机构在这里不复存在。
-      not_a_product_title: 作为用户,你并非一件商品
-      real_conversation_body: Mastodon 有着高达 65535 字的字数限制,以及对内容的细化控制和媒体警告提示的支持,只为让你能够畅所欲言。
-      real_conversation_title: 为真正的交流而生
-      within_reach_body: 通过一个面向开发者友好的 API 生态系统,Mastodon 让你可以随时随地通过众多 iOS、Android 以及其他平台的应用与朋友们保持联系。
-      within_reach_title: 始终触手可及
+    federation_hint_html: 在%{instance} 上拥有账户后,你可以关注任何 Mastodon 服务器或其他服务器上的人。
     generic_description: "%{domain} 是这个庞大网络中的一台服务器"
+    get_apps: 尝试移动应用
     hosted_on: 一个在 %{domain} 上运行的 Mastodon 实例
     learn_more: 了解详情
-    other_instances: 其他实例
     privacy_policy: 隐私政策
+    see_whats_happening: 看一看现在在发生什么
+    server_stats: 服务器统计数据:
     source_code: 源代码
-    status_count_after: 条嘟文
+    status_count_after:
+      other: 条嘟文
     status_count_before: 他们共嘟出了
+    tagline: 关注朋友并发现新朋友
     terms: 使用条款
-    user_count_after: 位用户
+    user_count_after:
+      other: 位用户
     user_count_before: 这里共注册有
     what_is_mastodon: Mastodon 是什么?
   accounts:
+    choices_html: "%{name} 的推荐:"
     follow: 关注
     followers:
-      one: 关注者
       other: 关注者
     following: 正在关注
     joined: 加入于 %{date}
+    last_active: 最近活动
+    link_verified_on: 此链接的所有权已在 %{date} 检查
     media: 媒体
     moved_html: "%{name} 已经迁移到 %{new_profile_link}:"
     network_hidden: 此信息不可用
     nothing_here: 这里神马都没有!
     people_followed_by: "%{name} 关注的人"
     people_who_follow: 关注 %{name} 的人
+    pin_errors:
+      following: 您必须关注您要推荐的人
     posts:
-      one: 嘟文
       other: 嘟文
     posts_tab_heading: 嘟文
     posts_with_replies: 嘟文和回复
@@ -59,14 +64,20 @@ zh-CN:
       admin: 管理员
       bot: 机器人
       moderator: 监察员
+    unavailable: 个人资料不可用
     unfollow: 取消关注
   admin:
+    account_actions:
+      action: 执行操作
+      title: 在 %{acct} 上执行管理操作
     account_moderation_notes:
       create: 新建
       created_msg: 管理备忘建立成功!
       delete: 删除
       destroyed_msg: 管理备忘删除成功!
     accounts:
+      approve: 批准
+      approve_all: 批准全部
       are_you_sure: 你确定吗?
       avatar: 头像
       by_domain: 域名
@@ -80,6 +91,7 @@ zh-CN:
       confirm: 确认
       confirmed: 已确认
       confirming: 确认
+      deleted: 已删除
       demote: 降任
       disable: 停用
       disable_two_factor_authentication: 停用双重认证
@@ -95,8 +107,11 @@ zh-CN:
       followers: 关注者
       followers_url: 关注者(Followers)URL
       follows: 正在关注
+      header: 个人资料页横幅图片
       inbox_url: 收件箱(Inbox)URL
+      invited_by: 邀请者为
       ip: IP 地址
+      joined: 加入于
       location:
         all: 全部
         local: 本地
@@ -106,23 +121,31 @@ zh-CN:
       media_attachments: 媒体文件
       memorialize: 设置为追悼帐户
       moderation:
+        active: 活跃
         all: 全部
+        pending: 待审核
         silenced: 已隐藏
         suspended: 已封禁
         title: 帐户状态
       moderation_notes: 管理备忘
       most_recent_activity: 最后一次活跃的时间
       most_recent_ip: 最后一次活跃的 IP 地址
+      no_account_selected: 因为没有账户被选择,所以没有更改
+      no_limits_imposed: 无限制
       not_subscribed: 未订阅
       outbox_url: 发件箱(Outbox)URL
-      perform_full_suspension: 永久封禁
+      pending: 待审核
+      perform_full_suspension: 封禁
       profile_url: 个人资料页面 URL
       promote: 升任
       protocol: 协议
       public: 公开页面
       push_subscription_expires: PuSH 订阅过期时间
-      redownload: 刷新头像
+      redownload: 刷新个人资料
+      reject: 拒绝
+      reject_all: 拒绝全部
       remove_avatar: 删除头像
+      remove_header: 删除横幅图片
       resend_confirmation:
         already_confirmed: 该用户已被确认
         send: 重发确认邮件
@@ -136,31 +159,37 @@ zh-CN:
         moderator: 监察员
         staff: 管理人员
         user: 普通用户
-      salmon_url: Salmon URL
+      salmon_url: 三文鱼协议网址(Salmon URL)
       search: 搜索
       shared_inbox_url: 公用收件箱(Shared Inbox)URL
       show:
         created_reports: 这个帐户提交的举报
         targeted_reports: 针对这个帐户的举报
       silence: 隐藏
+      silenced: 已隐藏
       statuses: 嘟文
       subscribe: 订阅
+      suspended: 已封禁
+      time_in_queue: 已经等待了 %{time}
       title: 用户
       unconfirmed_email: 待验证的电子邮件地址
       undo_silenced: 解除隐藏
       undo_suspension: 解除封禁
       unsubscribe: 取消订阅
       username: 用户名
+      warn: 警告
       web: 站内页面
     action_logs:
       actions:
         assigned_to_self_report: "%{name} 接管了举报 %{target}"
         change_email_user: "%{name} 更改了用户 %{target} 的电子邮件地址"
         confirm_user: "%{name} 确认了用户 %{target} 的电子邮件地址"
+        create_account_warning: "%{name} 向 %{target} 发送了警告"
         create_custom_emoji: "%{name} 添加了新的自定义表情 %{target}"
         create_domain_block: "%{name} 屏蔽了域名 %{target}"
         create_email_domain_block: "%{name} 屏蔽了电子邮件域名 %{target}"
         demote_user: "%{name} 对用户 %{target} 进行了降任操作"
+        destroy_custom_emoji: "%{name} 销毁了自定义表情 %{target}"
         destroy_domain_block: "%{name} 解除了对域名 %{target} 的屏蔽"
         destroy_email_domain_block: "%{name} 解除了对电子邮件域名 %{target} 的屏蔽"
         destroy_status: "%{name} 删除了 %{target} 的嘟文"
@@ -206,7 +235,7 @@ zh-CN:
       shortcode_hint: 至少 2 个字符,只能使用字母、数字和下划线
       title: 自定义表情
       unlisted: 已隐藏
-      update_failed_msg: 表情更新失败!
+      update_failed_msg: 表情更新失败
       updated_msg: 表情更新成功!
       upload: 上传新表情
     dashboard:
@@ -214,8 +243,10 @@ zh-CN:
       config: 服务器配置
       feature_deletions: 帐户删除
       feature_invites: 邀请链接
+      feature_profile_directory: 用户资料目录
       feature_registrations: 公开注册
       feature_relay: 同步中继
+      feature_timeline_preview: 时间轴预览
       features: 功能
       hidden_service: 匿名服务连通性
       open_reports: 待处理举报数
@@ -231,10 +262,11 @@ zh-CN:
       week_users_active: 本周活跃用户数
       week_users_new: 本周新用户数
     domain_blocks:
-      add_new: 添加新条目
+      add_new: 添加新屏蔽域名
       created_msg: 正在进行域名屏蔽
       destroyed_msg: 域名屏蔽已撤销
       domain: 域名
+      existing_domain_block_html: 您已经对 %{name} 施加了更严格的限制,您需要先 <a href="%{unblock_url}">解封</a>。
       new:
         create: 添加屏蔽
         hint: 域名屏蔽不会阻止该域名下的帐户进入本站的数据库,但是会对来自这个域名的帐户自动进行预先设置的管理操作。
@@ -246,16 +278,22 @@ zh-CN:
         title: 添加域名屏蔽
       reject_media: 拒绝接收媒体文件
       reject_media_hint: 删除本地已缓存的媒体文件,并且不再接收来自该域名的任何媒体文件。此选项不影响封禁
+      reject_reports: 拒绝接收举报
+      reject_reports_hint: 忽略来自此域名的所有举报。这和封禁无关。
+      rejecting_media: 拒绝接收媒体文件
+      rejecting_reports: 拒绝接收举报
+      severity:
+        silence: 已隐藏
+        suspend: 已封禁
       show:
         affected_accounts:
-          one: 将会影响到数据库中的 1 个帐户
           other: 将会影响到数据库中的 %{count} 个帐户
         retroactive:
           silence: 对此域名的所有帐户解除隐藏
           suspend: 对此域名的所有帐户解除封禁
         title: 撤销对 %{domain} 的域名屏蔽
         undo: 撤销
-      undo: 撤销
+      undo: 撤销屏蔽域名
     email_domain_blocks:
       add_new: 添加新条目
       created_msg: 电子邮件域名屏蔽添加成功
@@ -266,8 +304,24 @@ zh-CN:
         create: 添加域名
         title: 添加电子邮件域名屏蔽
       title: 电子邮件域名屏蔽
+    followers:
+      back_to_account: 返回帐户
+      title: "%{acct} 的关注者"
     instances:
+      by_domain: 域名
+      delivery_available: 无法投递
+      known_accounts:
+        other: "%{count} 个已知帐户"
+      moderation:
+        all: 全部
+        limited: 受限的
+        title: 运营
       title: 已知实例
+      total_blocked_by_us: 被我方屏蔽的
+      total_followed_by_them: 被对方关注的
+      total_followed_by_us: 被我方关注的
+      total_reported: 关于对方的举报
+      total_storage: 媒体文件
     invites:
       deactivate_all: 撤销所有邀请链接
       filter:
@@ -276,10 +330,17 @@ zh-CN:
         expired: 已失效
         title: 筛选
       title: 邀请用户
+    pending_accounts:
+      title: 待处理的帐户 (%{count})
     relays:
       add_new: 添加新的中继
+      delete: 删除
       description_html: "<strong>同步中继</strong>是一种中间服务器,各实例可以通过订阅中继和向中继推送信息的方式来大量交换公开嘟文。<strong>它可以帮助中小型实例发现网络中的内容</strong>,而无需本地用户手动关注其他远程实例上的用户。"
+      disable: 禁用
+      disabled: 已禁用
+      enable: 启用
       enable_hint: 启用此功能后,你的实例会订阅此中继的所有公开嘟文,并同时向其推送本服务器的公开嘟文。
+      enabled: 已启用
       inbox_url: 中继 URL
       pending: 等待中继确认
       save_and_enable: 保存并启用
@@ -335,12 +396,18 @@ zh-CN:
       hero:
         desc_html: 用于在首页展示。推荐分辨率 600×100px 以上。未指定的情况下将默认使用本站缩略图
         title: 主题图片
+      mascot:
+        desc_html: 用于在首页展示。推荐分辨率 293×205px 以上。未指定的情况下将使用默认吉祥物。
+        title: 吉祥物图像
       peers_api_enabled:
         desc_html: 截至目前本实例在网络中已发现的域名
         title: 公开已知实例的列表
       preview_sensitive_media:
         desc_html: 始终在站外链接预览中展示缩略图,无论媒体内容是否标记为敏感
         title: 在 OpenGraph 预览中显示敏感媒体内容
+      profile_directory:
+        desc_html: 允许用户可被发现
+        title: 启用用户资料目录
       registrations:
         closed_message:
           desc_html: 本站关闭注册期间的提示信息。可以使用 HTML 标签
@@ -351,9 +418,12 @@ zh-CN:
         min_invite_role:
           disabled: 没有人
           title: 允许发送邀请的用户组
-        open:
-          desc_html: 允许所有人建立帐户
-          title: 开放注册
+      registrations_mode:
+        modes:
+          approved: 注册时需要批准
+          none: 关闭注册
+          open: 开放注册
+        title: 注册模式
       show_known_fediverse_at_about_page:
         desc_html: 启用此选项将会在预览中显示来自已知实例的嘟文,否则只会显示本站时间轴的内容.
         title: 在时间轴预览中显示已知实例
@@ -361,11 +431,14 @@ zh-CN:
         desc_html: 在个人资料页上显示管理人员标志
         title: 显示管理人员标志
       site_description:
-        desc_html: 用于首页展示以及 meta 标签中的网站简介。可以使用 HTML 标签,包括 <code>&lt;a&gt;</code> 和 <code>&lt;em&gt;</code>
+        desc_html: 首页上的介绍文字。 描述一下本 Mastodon 实例的特殊之处以及其他重要信息。可以使用 HTML 标签,包括 <code>&lt;a&gt;</code> 和 <code>&lt;em&gt;</code> 。
         title: 本站简介
       site_description_extended:
         desc_html: 可以填写行为守则、规定、指南或其他本站特有的内容。可以使用 HTML 标签
         title: 本站详细介绍
+      site_short_description:
+        desc_html: 会在在侧栏和元数据标签中显示。可以用一小段话描述 Mastodon 是什么,以及本服务器的特点。
+        title: 服务器一句话介绍
       site_terms:
         desc_html: 可以填写自己的隐私权政策、使用条款或其他法律文本。可以使用 HTML 标签
         title: 自定义使用条款
@@ -387,6 +460,7 @@ zh-CN:
       media:
         title: 媒体文件
       no_media: 不含媒体文件
+      no_status_selected: 因为没有嘟文被选中,所以没有更改
       title: 帐户嘟文
       with_media: 含有媒体文件
     subscriptions:
@@ -395,13 +469,36 @@ zh-CN:
       expires_in: 失效时间
       last_delivery: 最后一次接收数据的时间
       title: WebSub
-      topic: Topic
+      topic: 话题
+    tags:
+      accounts: 帐户
+      hidden: 隐藏
+      hide: 从目录隐藏
+      name: 话题标签
+      title: 话题标签
+      unhide: 在目录中显示
+      visible: 可见
     title: 管理
+    warning_presets:
+      add_new: 添加新条目
+      delete: 删除
+      edit: 编辑
+      edit_preset: 编辑预置警告
+      title: 管理预设警告
   admin_mailer:
+    new_pending_account:
+      body: 新帐户的详细信息如下。您可以批准或拒绝此申请。
+      subject: 在 %{instance} 上有新账户 ( %{username}) 需要审核
     new_report:
       body: "%{reporter} 举报了用户 %{target}"
       body_remote: 来自 %{domain} 的用户举报了用户 %{target}
       subject: 来自 %{instance} 的用户举报(#%{id})
+  appearance:
+    advanced_web_interface: 高级 web 界面
+    advanced_web_interface_hint: 如果你想使用整个屏幕宽度,高级 web 界面允许您配置多个不同的栏目,可以同时看到更多的信息:主页、通知、跨站时间轴、任意数量的列表和话题标签。
+    animations_and_accessibility: 动画和访问选项
+    confirmation_dialogs: 确认对话框
+    sensitive_content: 敏感内容
   application_mailer:
     notification_preferences: 更改电子邮件首选项
     salutation: "%{name}:"
@@ -418,8 +515,9 @@ zh-CN:
     warning: 一定小心,千万不要把它分享给任何人!
     your_token: 你的访问令牌
   auth:
-    agreement_html: 注册即表示你同意遵守<a href="%{rules_path}">本实例的相关规定</a>和<a href="%{terms_path}">我们的使用条款</a>。
+    apply_for_account: 请求邀请
     change_password: 密码
+    checkbox_agreement_html: 我同意 <a href="%{rules_path}" target="_blank">服务器规则</a> 和 <a href="%{terms_path}" target="_blank">服务条款</a>
     confirm_email: 确认电子邮件地址
     delete_account: 删除帐户
     delete_account_html: 如果你想删除你的帐户,请<a href="%{path}">点击这里继续</a>。你需要确认你的操作。
@@ -430,17 +528,17 @@ zh-CN:
     logout: 登出
     migrate_account: 迁移到另一个帐户
     migrate_account_html: 如果你希望引导他人关注另一个帐户,请<a href="%{path}">点击这里进行设置</a>。
-    or: 或者
     or_log_in_with: 或通过其他方式登录
     providers:
       cas: CAS
       saml: SAML
     register: 注册
-    register_elsewhere: 前往其他实例注册
+    registration_closed: "%{instance} 目前不接收新成员"
     resend_confirmation: 重新发送确认邮件
     reset_password: 重置密码
     security: 帐户安全
     set_new_password: 设置新密码
+    trouble_logging_in: 登录有问题?
   authorize_follow:
     already_following: 你已经在关注此用户了
     error: 对不起,寻找这个跨站用户时出错
@@ -472,12 +570,21 @@ zh-CN:
     description_html: 继续操作将会<strong>永久地、不可撤销地</strong>删除帐户中的所有内容,然后冻结帐户。你的用户名将会被保留,以防有人冒用你的身份。
     proceed: 删除帐户
     success_msg: 你的帐户已经成功删除
-    warning_html: 我们只能保证本实例上的内容将会被彻底删除。对于已经被广泛传播的内容,它们在本实例以外的某些地方可能仍然可见。此外,失去连接的服务器以及停止接收订阅的服务器所存储的数据亦无法删除。
+    warning_html: 我们只能保证本服务器上的内容将会被彻底删除。对于已经被广泛传播的内容,它们在本服务器以外的某些地方可能仍然可见。此外,失去连接的服务器以及停止接收订阅的服务器所存储的数据亦无法删除。
     warning_title: 关于已传播的内容的警告
+  directories:
+    directory: 用户资料目录
+    enabled: 您目前已被列入目录中。
+    enabled_but_waiting: 您已选择列入目录,但是您没有达到关注者数量下限 (%{min_followers} 名) 。
+    explanation: 根据兴趣发现用户
+    explore_mastodon: 探索 %{title}
+    how_to_enable: 您目前没有选择选择列入到目录中。您可以在下面选择列入。可以在个人简介中加上话题标签,话题标签也会显示在用户资料目录里!
+    people:
+      other: "%{count} 人"
   errors:
     '403': 你没有访问这个页面的权限。
     '404': 无法找到你所要访问的页面。
-    '410': 你所要访问的页面已被删除。
+    '410': 你所要访问的页面此处已不存在。
     '422':
       content: 无法确认登录信息。你是不是屏蔽了 Cookie?
       title: 无法确认登录信息
@@ -486,6 +593,9 @@ zh-CN:
       content: 抱歉,我们的后台出错了。
       title: 这个页面有问题
     noscript_html: 使用 Mastodon 网页版应用需要启用 JavaScript。你也可以选择适用于你的平台的 <a href="%{apps_path}">Mastodon 应用</a>。
+  existing_username_validator:
+    not_found: 在本站找不到此用户
+    not_found_multiple: 找不到 %{usernames}
   exports:
     archive_takeout:
       date: 日期
@@ -496,9 +606,15 @@ zh-CN:
       size: 大小
     blocks: 屏蔽的用户
     csv: CSV
+    domain_blocks: 域名屏蔽
     follows: 关注的用户
+    lists: 列表
     mutes: 隐藏的用户
     storage: 媒体文件存储
+  featured_tags:
+    add_new: 添加新条目
+    errors:
+      limit: 你所推荐的话题标签数已达上限
   filters:
     contexts:
       home: 主页时间轴
@@ -508,33 +624,56 @@ zh-CN:
     edit:
       title: 编辑过滤器
     errors:
+      invalid_context: 过滤器场景没有或无效
       invalid_irreversible: 此功能只适用于主页时间轴或通知
     index:
       delete: 删除
       title: 过滤器
     new:
       title: 添加新的过滤器
-  followers:
-    domain: 域名
-    explanation_html: 为保证你的嘟文的隐私安全,你应当经常检查你的关注者列表。<strong>受保护的嘟文将会发送到所有关注者所在的实例上</strong>。有些实例使用的软件代码或其管理员可能不会尊重你的隐私设置,因此你应当复查一下关注者列表,并移除那些你无法信任的关注者。
-    followers_count: 关注者数量
-    lock_link: 为你的帐户开启保护
-    purge: 从关注者中移除
-    success: 正在从 %{count} 个域名中移除关注者……
-    true_privacy_html: 请始终铭记:<strong>真正的隐私只能靠端到端加密来实现</strong>!
-    unlocked_warning_html: 任何人都可以在关注你后立即查看非公开的嘟文。只要%{lock_link},你就可以审核并拒绝关注请求。
-    unlocked_warning_title: 你的帐户未受到保护
+  footer:
+    developers: 开发者
+    more: 更多…
+    resources: 资源
   generic:
+    all: 全部
     changes_saved_msg: 更改保存成功!
+    copy: 复制
+    order_by: 排序方式
     save_changes: 保存更改
     validation_errors:
-      one: 出错啦!检查一下下面出错的地方吧
       other: 出错啦!检查一下下面 %{count} 处出错的地方吧
+  html_validator:
+    invalid_markup: '包含无效的 HTML 标记: %{error}'
+  identity_proofs:
+    active: 有效
+    authorize: 是,授权
+    authorize_connection_prompt: 授权这一密码学连接?
+    errors:
+      failed: 密码关联失败。请在 %{provider} 上重新尝试。
+      keybase:
+        invalid_token: Keybase 令牌是签名的哈希并且必须是 66 个十六进制字符
+        verification_failed: Keybase 无法将此令牌识别为 Keybase 用户 %{kb_username} 的签名。请在 Keybase 再试一次。
+      wrong_user: 无法以 %{current} 的身份创建 %{proving} 的证明。请以 %{proving} 的身份登录并再次尝试。
+    explanation_html: 在这里,你可以和你的其他身份建立密码学关联,例如 Keybase 个人资料。这可以让别人向你发送加密信息,并信任你发给他们的内容。
+    i_am_html: 我是 %{service} 上的 %{username} 。
+    identity: 身份
+    inactive: 失效
+    publicize_checkbox: 并发一条这样的嘟文:
+    publicize_toot: '证明完毕!我是 %{service} 上的 %{username}: %{url}'
+    status: 验证状态
+    view_proof: 查看证明
   imports:
+    modes:
+      merge: 合并
+      merge_long: 保留现有记录并添加新的记录
+      overwrite: 覆盖
+      overwrite_long: 将当前记录替换为新记录
     preface: 你可以在此导入你在其他实例导出的数据,比如你所关注或屏蔽的用户列表。
     success: 数据上传成功,正在处理中
     types:
       blocking: 屏蔽列表
+      domain_blocking: 域名屏蔽列表
       following: 关注列表
       muting: 隐藏列表
     upload: 上传
@@ -553,10 +692,9 @@ zh-CN:
     generate: 生成邀请链接
     invited_by: 你的邀请人是:
     max_uses:
-      one: 1 次
       other: "%{count} 次"
     max_uses_prompt: 无限制
-    prompt: 生成分享链接,邀请他人在本实例注册
+    prompt: 生成分享链接,邀请他人在本服务器注册
     table:
       expires_at: 失效时间
       uses: 已使用次数
@@ -581,9 +719,9 @@ zh-CN:
       body: 以下是自%{since}你最后一次登录以来错过的消息的摘要
       mention: "%{name} 在嘟文中提到了你:"
       new_followers_summary:
-        one: 而且,你不在的时候,有一个人关注了你!耶!
         other: 而且,你不在的时候,有 %{count} 个人关注了你!好棒!
-      subject: "自从你最后一次登录以来,你错过了 %{count} 条新通知 \U0001F418"
+      subject:
+        other: "自从上次访问后,有 %{count} 条新通知 \U0001F418"
       title: 在你不在的这段时间……
     favourite:
       body: 你的嘟文被 %{name} 收藏了:
@@ -595,7 +733,7 @@ zh-CN:
       title: 新的关注者
     follow_request:
       action: 处理关注请求
-      body: "%{name} 向你发送了关注请求!"
+      body: "%{name} 向你发送了关注请求"
       subject: 来自 %{name} 的关注请求
       title: 新的关注请求
     mention:
@@ -610,50 +748,84 @@ zh-CN:
   number:
     human:
       decimal_units:
-        format: "%n%u"
         units:
           billion: B
           million: M
           quadrillion: Q
           thousand: K
           trillion: T
-          unit: ''
   pagination:
     newer: æ›´æ–°
     next: 下一页
     older: æ›´æ—©
     prev: 上一页
-    truncate: "…"
+  polls:
+    errors:
+      already_voted: 你已经在这里投过票了
+      duplicate_options: 包含重复的项目
+      duration_too_long: 持续时间过长
+      duration_too_short: 持续时间过短
+      expired: 投票已经结束
+      over_character_limit: 每条不能超过 %{max} 个字符
+      too_few_options: 至少需要两个选项
+      too_many_options: 不能超过 %{max} 项
   preferences:
-    languages: 语言
     other: å…¶ä»–
-    publishing: 发布
-    web: 站内
+    posting_defaults: 发布默认值
+    public_timelines: 公共时间轴
+  relationships:
+    activity: 账户活动
+    dormant: 休眠
+    last_active: 最近活动
+    most_recent: 最近的
+    moved: 已迁移
+    mutual: 互相关注
+    primary: 主要
+    relationship: 关系
+    remove_selected_domains: 从选定的域名中删除所有关注者
+    remove_selected_followers: 移除选中的关注者
+    remove_selected_follows: 取消关注所选用户
+    status: 帐户状态
   remote_follow:
     acct: 请输入你的“用户名@实例域名”
     missing_resource: 无法确定你的帐户的跳转 URL
     no_account_html: 还没有帐号?你可以<a href='%{sign_up_path}' target='_blank'>注册一个</a>
     proceed: 确认关注
     prompt: 你正准备关注:
+    reason_html: "<strong>为什么需要这个步骤?</strong> <code>%{instance}</code> 可能不是您所注册的服务器,所以我们需要先重定向到您所在的服务器。"
+  remote_interaction:
+    favourite:
+      proceed: 确认收藏
+      prompt: 您想要收藏此嘟文:
+    reblog:
+      proceed: 确认转嘟
+      prompt: 您想要转嘟此条:
+    reply:
+      proceed: 确认回复
+      prompt: 您想要回复此嘟文:
   remote_unfollow:
     error: 错误
     title: 标题
     unfollowed: 已取消关注
+  scheduled_statuses:
+    over_daily_limit: 您已超出每日定时嘟文的上限(%{limit} 条)
+    over_total_limit: 您已超出定时嘟文的上限(%{limit} 条)
+    too_soon: 所定的时间必须在未来
   sessions:
     activity: 最后一次活跃的时间
     browser: 浏览器
     browsers:
       alipay: 支付宝
-      blackberry: Blackberry
+      blackberry: 黑莓
       chrome: Chrome
-      edge: Microsoft Edge
+      edge: 微软 Edge
       electron: Electron
-      firefox: Firefox
+      firefox: 火狐
       generic: 未知浏览器
-      ie: Internet Explorer
+      ie: IE 浏览器
       micro_messenger: 微信
       nokia: Nokia S40 Ovi 浏览器
-      opera: Opera
+      opera: 欧朋浏览器
       otter: Otter
       phantom_js: PhantomJS
       qq: QQ浏览器
@@ -667,7 +839,7 @@ zh-CN:
     platforms:
       adobe_air: Adobe Air
       android: Android
-      blackberry: Blackberry
+      blackberry: 黑莓
       chrome_os: ChromeOS
       firefox_os: Firefox OS
       ios: iOS
@@ -681,33 +853,35 @@ zh-CN:
     revoke_success: 会话注销成功
     title: 会话
   settings:
+    account: 账户
+    account_settings: 帐户设置
+    appearance: 外观
     authorized_apps: 已授权的应用
     back: 返回 Mastodon
     delete: 删除帐户
     development: 开发
     edit_profile: 更改个人资料
     export: 导出
-    followers: 已授权的关注者
+    featured_tags: 推荐的话题标签
+    identity_proofs: 身份证明
     import: 导入
+    import_and_export: 导入和导出
     migrate: 帐户迁移
     notifications: 通知
     preferences: 首选项
-    settings: 设置
+    profile: 个人资料
+    relationships: 正在关注以及关注者
     two_factor_authentication: 双重认证
-    your_apps: 你的应用
   statuses:
     attached:
       description: 附加媒体:%{attached}
       image:
-        one: "%{count} 张图片"
         other: "%{count} 张图片"
       video:
-        one: "%{count} 段视频"
         other: "%{count} 段视频"
     boosted_from_html: 转嘟自 %{acct_link}
     content_warning: 内容警告:%{warning}
     disallowed_hashtags:
-      one: 包含了一个禁止的话题标签:%{tags}
       other: 包含了这些禁止的话题标签:%{tags}
     language_detection: 自动检测语言
     open_in_web: 在站内打开
@@ -717,7 +891,12 @@ zh-CN:
       ownership: 不能置顶他人的嘟文
       private: 不能置顶非公开的嘟文
       reblog: 不能置顶转嘟
+    poll:
+      total_votes:
+        other: "%{count} 票"
+      vote: 投票
     show_more: 显示更多
+    sign_in_to_participate: 登录以加入对话
     title: "%{name}:“%{quote}”"
     visibilities:
       private: 仅关注者
@@ -733,12 +912,13 @@ zh-CN:
   terms:
     title: "%{instance} 使用条款和隐私权政策"
   themes:
-    contrast: 高对比度
-    default: Mastodon
+    contrast: Mastodon(高对比度)
+    default: Mastodon(暗色主题)
     mastodon-light: Mastodon(亮色主题)
   time:
     formats:
       default: "%Y年%-m月%d日 %H:%M"
+      month: "%Y å¹´ %B"
   two_factor_authentication:
     code_hint: 输入认证器生成的代码以确认操作
     description_html: 启用<strong>双重认证</strong>后,你需要输入手机认证器生成的代码才能登录.
@@ -754,12 +934,28 @@ zh-CN:
     recovery_codes_regenerated: 恢复代码重新生成成功
     recovery_instructions_html: 如果你的手机无法使用,你可以使用下列任意一个恢复代码来重新获得对帐户的访问权。<strong>请妥善保管好你的恢复代码</strong>(例如,你可以将它们打印出来,然后和其他重要的文件放在一起)。
     setup: 设置
-    wrong_code: 输入的认证码无效!请核对一下你的设备显示的时间,如果正确,你可能需要联系一下实例的管理员,让他们校准服务器的时间。
+    wrong_code: 输入的认证码无效!请确认服务器时间与设备时间是否正确?
   user_mailer:
     backup_ready:
       explanation: 你请求了一份 Mastodon 帐户的完整备份。现在你可以下载了!
       subject: 你的存档已经准备完毕
       title: 存档导出
+    warning:
+      explanation:
+        disable: 虽然您的帐户被冻结,您的帐户数据仍然完整;但是您无法在解锁前执行任何操作。
+        silence: 当您的帐户受限时,只有已经关注过你的人才会这台服务器上看到你的嘟文,并且您会被排除在各种公共列表之外。但是,其他人仍然可以手动关注你。
+        suspend: 您的帐户已被封禁,所有的嘟文和您上传的媒体文件都已经从该服务器和您的关注者的服务器上删除并且不可恢复。
+      review_server_policies: 审阅服务器条款
+      subject:
+        disable: 您的帐户 %{acct} 已被冻结
+        none: 对 %{acct} 的警告
+        silence: 您的帐户 %{acct} 已经受限
+        suspend: 您的帐户 %{acct} 已被封禁。
+      title:
+        disable: 账户已冻结
+        none: 警示
+        silence: 帐户受限
+        suspend: 账户被封禁
     welcome:
       edit_profile_action: 设置个人资料
       edit_profile_step: 你可以自定义你的个人资料,包括上传头像、横幅图片、更改昵称等等。如果你想在新的关注者关注你之前对他们进行审核,你也可以选择为你的帐户开启保护。
@@ -767,19 +963,23 @@ zh-CN:
       final_action: 开始嘟嘟
       final_step: '开始嘟嘟吧!即便你现在没有关注者,其他人仍然能在本站时间轴或者话题标签等地方看到你的公开嘟文。试着用 #introductions 这个话题标签介绍一下自己吧。'
       full_handle: 你的完整用户地址
-      full_handle_hint: 你需要把这个告诉你的朋友们,这样他们就能从另一个实例向你发送信息或者关注你。
+      full_handle_hint: 你需要把这个告诉你的朋友们,这样他们就能从另一台服务器向你发送信息或者关注你。
       review_preferences_action: 更改首选项
       review_preferences_step: 记得调整你的偏好设置,比如你想接收什么类型的邮件,或者你想把你的嘟文可见范围默认设置为什么级别。如果你没有晕动病的话,考虑一下启用“自动播放 GIF 动画”这个选项吧。
       subject: 欢迎来到 Mastodon
       tip_federated_timeline: 跨站公共时间轴可以让你一窥更广阔的 Mastodon 网络。不过,由于它只显示你的邻居们所订阅的内容,所以并不是全部。
-      tip_following: 默认情况下,你会自动关注你所在实例的管理员。想结交更多有趣的人的话,记得多逛逛本站时间轴和跨站公共时间轴哦。
+      tip_following: 默认情况下,你会自动关注你所在服务器的管理员。想结交更多有趣的人的话,记得多逛逛本站时间轴和跨站公共时间轴哦。
       tip_local_timeline: 本站时间轴可以让你一窥 %{instance} 上的用户。他们就是离你最近的邻居!
       tip_mobile_webapp: 如果你的移动设备浏览器允许你将 Mastodon 添加到主屏幕,你就能够接收推送消息。它就像本地应用一样好使!
       tips: 小贴士
       title: "%{name},欢迎你的加入!"
   users:
+    follow_limit_reached: 您不能关注超过 %{limit} 个人
     invalid_email: 输入的电子邮件地址无效
     invalid_otp_token: 输入的双重认证代码无效
     otp_lost_help_html: 如果你不慎丢失了所有的代码,请联系 %{email} 寻求帮助
     seamless_external_login: 因为你是通过外部服务登录的,所以密码和电子邮件地址设置都不可用。
     signed_in_as: 当前登录的帐户:
+  verification:
+    explanation_html: 您可以 <strong>验证自己是个人资料元数据中的某个链接的所有者</strong>。 为此,被链接网站必须包含一个到您的 Mastodon 主页的链接。链接中 <strong>必须</strong> 包括 <code>rel="me"</code> 属性。链接的文本内容可以随意填写。例如:
+    verification: 验证
diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml
index 97adfe84d3625baa9ba149146286faaba252831b..25e7475a88d5ec5e584f4b90af7ffe643c48212b 100644
--- a/config/locales/zh-HK.yml
+++ b/config/locales/zh-HK.yml
@@ -5,35 +5,24 @@ zh-HK:
     about_mastodon_html: Mastodon(萬象)是<em>自由、開源</em>的社交網絡。服務站<em>各自獨立而互連</em>,避免單一商業機構壟斷。找你所信任的服務站,建立帳號,你即可與任何服務站上的用戶溝通,享受無縫的<em>網絡交流</em>。
     about_this: 關於本服務站
     administered_by: 管理者:
-    closed_registrations: 本服務站暫時停止接受登記。
     contact: 聯絡
     contact_missing: 未設定
     contact_unavailable: 未公開
     extended_description_html: |
       <h3>這裡可以寫一些網站規則</h3>
       <p>本站未有詳細介紹</p>
-    features:
-      humane_approach_body: Mastodon 從其他網絡的失敗經驗中汲取教訓,以合乎道德的設計對抗社交媒體的濫用問題。
-      humane_approach_title: 以人為本
-      not_a_product_body: Mastodon 不是商業網絡。沒有廣告,沒有數據挖掘,也沒有中央機構操控。平台完全開放。
-      not_a_product_title: 你是用戶,不是商品
-      real_conversation_body: Mastodon 的字數限制高達 65535 字,並支援仔細的媒體警告選項,令你暢所欲言。
-      real_conversation_title: 為真正的交流而生
-      within_reach_body: 簡易的 API 系統,令用戶可以透過不同的 iOS、Android 及其他平台的應用軟件,與朋友保持聯繫。
-      within_reach_title: 無處不在
     generic_description: "%{domain} 是 Mastodon 網絡中其中一個服務站"
     hosted_on: 在 %{domain} 運作的 Mastodon 服務站
     learn_more: 了解更多
-    other_instances: 其他服務站
     source_code: 源代碼
-    status_count_after: 篇文章
     status_count_before: 他們共發佈了
-    user_count_after: 位使用者
+    tagline: 關注朋友並探索新朋友
     user_count_before: 這裏共註冊有
     what_is_mastodon: Mastodon 是甚麼?
   accounts:
     follow: 關注
-    followers: 關注者
+    followers:
+      other: 關注者
     following: 正在關注
     media: 媒體
     moved_html: "%{name} 已經轉移到 %{new_profile_link}:"
@@ -41,7 +30,6 @@ zh-HK:
     nothing_here: 暫時未有內容可以顯示。
     people_followed_by: "%{name} 關注的人"
     people_who_follow: 關注 %{name} 的人
-    posts: 文章
     posts_with_replies: 文章和回覆
     reserved_username: 此用戶名已被保留
     roles:
@@ -214,7 +202,6 @@ zh-HK:
       reject_media: 拒絕媒體檔案
       reject_media_hint: 刪除本地緩存的媒體檔案,再也不在未來下載這個站點的檔案。和自動刪除無關
       show:
-        affected_accounts: 資料庫中有%{count}個用戶受影響
         retroactive:
           silence: 對此域名的所有用戶取消靜音
           suspend: 對此域名的所有用戶取消除名
@@ -231,8 +218,12 @@ zh-HK:
         create: 新增網域
         title: 新增電郵網域阻隔
       title: 電郵網域阻隔
+    followers:
+      back_to_account: 返回帳戶
+      title: "%{acct} 的關注者"
     instances:
       title: 已知服務站
+      total_followed_by_us: 開始關注你
     invites:
       filter:
         all: 全部
@@ -240,6 +231,8 @@ zh-HK:
         expired: 已失效
         title: 篩選
       title: 邀請用戶
+    relays:
+      description_html: "<strong>聯邦中繼站</strong> 是種中繼伺服器,會在訂閱並推送至此中繼站的伺服器之間交換大量的公開嘟文。<strong>中繼站也能協助小型或中型伺服器從聯邦中探索內容</strong>,而無須本地使用者手動關注遠端伺服器的其他使用者。"
     report_notes:
       created_msg: 舉報筆記已建立。
       destroyed_msg: 舉報筆記已刪除。
@@ -299,9 +292,6 @@ zh-HK:
         min_invite_role:
           disabled: 沒有人
           title: 允許發送邀請的身份
-        open:
-          desc_html: 允許所有人建立帳戶
-          title: 開放註冊
       show_known_fediverse_at_about_page:
         desc_html: 如果開啟,就會在時間軸預覽顯示跨站文章,否則就只會顯示本站文章。
         title: 在時間軸預覽顯示跨站文章
@@ -366,7 +356,6 @@ zh-HK:
     warning: 警告,不要把它分享給任何人!
     your_token: token
   auth:
-    agreement_html: 登記即表示你同意遵守<a href="%{rules_path}">本服務站的規則</a>和<a href="%{terms_path}">使用條款</a>。
     change_password: 密碼
     confirm_email: 確認電郵
     delete_account: 刪除帳戶
@@ -378,13 +367,8 @@ zh-HK:
     logout: 登出
     migrate_account: 轉移到另一個帳號
     migrate_account_html: 想要將這個帳號指向另一個帳號可<a href="%{path}">到這裡設定</a>。
-    or: 或
     or_log_in_with: 或登入於
-    providers:
-      cas: CAS
-      saml: SAML
     register: 登記
-    register_elsewhere: 在其他服務站登記
     resend_confirmation: 重發確認指示電郵
     reset_password: 重設密碼
     security: 登入資訊
@@ -443,27 +427,13 @@ zh-HK:
       request: 下載檔案
       size: 檔案大小
     blocks: 被你封鎖的用戶
-    csv: CSV
     follows: 你所關注的用戶
     mutes: 你所靜音的用戶
     storage: 媒體容量大小
-  followers:
-    domain: 網域
-    explanation_html: 如果你想確保你的私隱,請留意是甚麼用戶在關注你。<strong>即使你的將文章設定「私人文章」,它仍為會被遞送至你所有關注者的服務站</strong>。如果你不信任某些用戶、或其服務站的管理者會尊重你私隱,請將他們自關注者名單私除。
-    followers_count: 關注者數目
-    lock_link: 將用戶轉為「私人」
-    purge: 私除關注者
-    success:
-      one: 正準備軟性阻擋 1 個網域的關注者……
-      other: 正準備軟性阻擋 %{count} 個網域的關注者……
-    true_privacy_html: 請謹記,唯有<strong>點對點加密方可以真正確保你的私隱</strong>。
-    unlocked_warning_html: 目前任何人都可以看到你的私人文章,若%{lock_link}的話,你將可以審批關注者。
-    unlocked_warning_title: 你的用戶目前為「公共」
   generic:
     changes_saved_msg: 已成功儲存修改。
     save_changes: 儲存修改
     validation_errors:
-      one: 提交的資料有問題
       other: 提交的資料有 %{count} 項問題
   imports:
     preface: 你可以在此匯入你在其他服務站所匯出的資料檔,包括︰你所關注的用戶,被你封鎖的用戶。
@@ -488,7 +458,6 @@ zh-HK:
     generate: 生成邀請連結
     invited_by: 你的邀請人是:
     max_uses:
-      one: 1 次
       other: "%{count} 次"
     max_uses_prompt: 無限制
     prompt: 生成分享連結,邀請他人在本服務站註冊
@@ -516,10 +485,8 @@ zh-HK:
       body: 這是自從你在%{since}使用以後,你錯失了的訊息︰
       mention: "%{name} 在此提及了你︰"
       new_followers_summary:
-        one: 你新獲得了 1 位關注者了!恭喜!
         other: 你新獲得了 %{count} 位關注者了!好厲害!
       subject:
-        one: "自從上次登入以來,你收到 1 則新的通知 \U0001F418"
         other: "自從上次登入以來,你收到 %{count} 則新的通知 \U0001F418"
       title: 在你不在的這段時間……
     favourite:
@@ -544,27 +511,14 @@ zh-HK:
       body: 您的文章被 %{name} 轉推:
       subject: "%{name} 轉推了你的文章"
       title: 新的轉推
-  number:
-    human:
-      decimal_units:
-        format: "%n%u"
-        units:
-          billion: B
-          million: M
-          quadrillion: Q
-          thousand: K
-          trillion: T
   pagination:
     newer: 較新
     next: 下一頁
     older: 較舊
     prev: 上一頁
     truncate: "……"
-  preferences:
-    languages: 語言
-    other: å…¶ä»–
-    publishing: 發佈
-    web: 站内
+  relationships:
+    remove_selected_followers: 刪除所選選項
   remote_follow:
     acct: 請輸入你的︰用戶名稱@服務點域名
     missing_resource: 無法找到你用戶的轉接網址
@@ -579,7 +533,6 @@ zh-HK:
     browser: 瀏覽器
     browsers:
       alipay: 支付寶
-      blackberry: Blackberry
       chrome: Chrome 瀏覽器
       edge: Microsoft Edge 瀏覽器
       electron: Electron 瀏覽器
@@ -588,30 +541,14 @@ zh-HK:
       ie: Internet Explorer 瀏覽器
       micro_messenger: 微信
       nokia: Nokia S40 Ovi 瀏覽器
-      opera: Opera
       otter: Otter 瀏覽器
-      phantom_js: PhantomJS
       qq: QQ瀏覽器
-      safari: Safari
       uc_browser: UC瀏覽器
       weibo: 新浪微博
     current_session: 目前的作業階段
     description: "%{platform} 上的 %{browser}"
     explanation: 這些是現在正登入於你的 Mastodon 帳號的瀏覽器。
     ip: IP 位址
-    platforms:
-      adobe_air: Adobe Air
-      android: Android
-      blackberry: Blackberry
-      chrome_os: ChromeOS
-      firefox_os: Firefox OS
-      ios: iOS
-      linux: Linux
-      mac: Mac
-      other: 未知平台
-      windows: Windows
-      windows_mobile: Windows Mobile
-      windows_phone: Windows Phone
     revoke: 取消
     revoke_success: 作業階段成功取消
     title: 作業階段
@@ -622,27 +559,21 @@ zh-HK:
     development: 開發
     edit_profile: 修改個人資料
     export: 匯出
-    followers: 授權關注
     import: 匯入
     migrate: 帳戶遷移
     notifications: 通知
     preferences: 偏好設定
-    settings: 設定
     two_factor_authentication: 雙重認證
-    your_apps: 你的應用程式
   statuses:
     attached:
       description: 附件: %{attached}
       image:
-        one: "%{count} 幅圖片"
         other: "%{count} 幅圖片"
       video:
-        one: "%{count} 段影片"
         other: "%{count} 段影片"
     boosted_from_html: 轉推自 %{acct_link}
     content_warning: 內容警告: %{warning}
     disallowed_hashtags:
-      one: 包含不允許的標籤: %{tags}
       other: 包含不允許的標籤: %{tags}
     language_detection: 自動偵測語言
     open_in_web: 開啟網頁
diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml
index f4bda0f348fb12dbfef7333bc5222ee5967f6e62..d3dcf5133f5f4203aa923456606298784f6dcd16 100644
--- a/config/locales/zh-TW.yml
+++ b/config/locales/zh-TW.yml
@@ -2,95 +2,110 @@
 zh-TW:
   about:
     about_hashtag_html: 這些是包含「<strong>#%{hashtag}</strong>」標籤的公開文章。只要你有任何 Mastodon 站點、或者其他站點的使用者,便可以與他們互動。
-    about_mastodon_html: Mastodon (長毛象)是一個<em>自由、開放原始碼</em>的社群網站。它是一個分散式的服務,避免您的通訊被單一商業機構壟斷操控。請您選擇一家您信任的 Mastodon 站點,在上面建立帳號,然後您就可以和任一 Mastodon 站點上的使用者互通,享受無縫的<em>社群網路</em>交流。
+    about_mastodon_html: Mastodon (長毛象)是一個<em>自由、開放原始碼</em>的社群網站。它是一個分散式的服務,避免您的通訊被單一商業機構壟斷操控。請您選擇一家您信任的 Mastodon 站點,在上面建立帳戶,然後您就可以和任一 Mastodon 站點上的使用者互通,享受無縫的<em>社群網路</em>交流。
     about_this: 關於本站
+    active_count_after: 活躍
+    active_footnote: 每月活躍使用者 (MAU)
     administered_by: 管理者:
-    api: API
-    apps: Mobile apps
-    closed_registrations: 本站暫時停止接受註冊。
+    apps: 行動應用程式
+    apps_platforms: 在 iOS、Android 和其他平台使用 Mastodon
+    browse_directory: 依興趣瀏覽個人資料目錄和過濾器
+    browse_public_posts: 在 Mastodon 瀏覽公開嘟文的即時串流
     contact: 聯絡我們
     contact_missing: 未設定
     contact_unavailable: 未公開
+    discover_users: 探索使用者
     documentation: 文件
     extended_description_html: |
       <h3>這裡可以寫一些網站規則</h3>
       <p>本站點未有詳細介紹</p>
-    features:
-      humane_approach_body: Mastodon 從其他網路的失敗經驗中汲取教訓,以合乎道德的設計對抗社交媒體的濫用問題。
-      humane_approach_title: 以人為本
-      not_a_product_body: Mastodon 不是商業網站。沒有廣告,沒有數據挖掘,也沒有中央機構操控。平台完全開放。
-      not_a_product_title: 你是用戶,不是商品
-      real_conversation_body: Mastodon 的字數限制高達 500 字,並支援仔細的媒體警告選項,令你暢所欲言。
-      real_conversation_title: 為真正的交流而生
-      within_reach_body: 簡易的 API 系統,令用戶可以透過不同的 iOS、Android 及其他平台的應用軟體,與朋友保持聯繫。
-      within_reach_title: 始終觸手可及
     generic_description: "%{domain} 是 Mastodon 網路中其中一個站點"
+    get_apps: 嘗試行動應用程式
     hosted_on: 在 %{domain} 運作的 Mastodon 站點
     learn_more: 了解詳細
-    other_instances: 其他站點
+    privacy_policy: 隱私權政策
+    see_whats_happening: 看看發生什麼事
+    server_stats: 伺服器統計:
     source_code: 原始碼
-    status_count_after: 狀態
+    status_count_after:
+      other: 條嘟文
     status_count_before: 他們共嘟出了
+    tagline: 關注朋友並探索新朋友
     terms: 使用條款
-    user_count_after: 使用者
-    user_count_before: 這裡共註冊有
+    user_count_after:
+      other: 位使用者
+    user_count_before: 註冊使用者數
     what_is_mastodon: 什麼是 Mastodon?
   accounts:
+    choices_html: "%{name} 的選擇:"
     follow: 關注
-    followers: 關注者
+    followers:
+      other: 關注者
     following: 正在關注
+    joined: 加入於 %{date}
+    last_active: 上次活躍時間
+    link_verified_on: 此連結的所有權已在 %{date} 檢查過
     media: 媒體
     moved_html: "%{name} 已經搬遷到 %{new_profile_link}:"
     network_hidden: 此訊息不可用
     nothing_here: 暫時沒有內容可供顯示!
     people_followed_by: "%{name} 關注的人"
     people_who_follow: 關注 %{name} 的人
-    posts: 嘟文
+    posts:
+      other: 嘟文
     posts_tab_heading: 嘟文
     posts_with_replies: 嘟文與回覆
-    reserved_username: 此用戶名已被保留
+    reserved_username: 此使用者名稱已被保留
     roles:
       admin: 管理員
       bot: 機器人
       moderator: 版主
     unfollow: 取消關注
   admin:
+    account_actions:
+      action: 執行動作
+      title: 在 %{acct} 執行管理員動作
     account_moderation_notes:
       create: 記錄
       created_msg: 已新增管理備忘!
       delete: 刪除
       destroyed_msg: 成功刪除管理備忘!
     accounts:
+      approve: 核准
       are_you_sure: 您確定嗎?
       avatar: 頭像
-      by_domain: 網域
+      by_domain: 站點
       change_email:
-        changed_msg: E-mail更改成功!
-        current_email: 目前的E-mail
-        label: 更改E-mail
-        new_email: 新的E-mail
-        submit: 更改E-mail
-        title: 為 %{username} 更改E-mail
+        changed_msg: 已成功變更帳戶電子信箱位址!
+        current_email: 目前的電子信箱位址
+        label: 變更電子信箱位址
+        new_email: 新的電子信箱位址
+        submit: 變更電子信箱位址
+        title: 為 %{username} 變更電子信箱位址
       confirm: 確定
       confirmed: 已確定
       confirming: 確定
+      deleted: 已刪除
       demote: 降級
       disable: 停用
       disable_two_factor_authentication: 停用兩階段認證
       disabled: 已停用
       display_name: 暱稱
-      domain: 網域
+      domain: 站點
       edit: 編輯
-      email: E-mail
-      email_status: E-mail狀態
+      email: 電子信箱位址
+      email_status: 電子信箱狀態
       enable: 啟用
       enabled: 已啟用
       feed_url: 訂閱 URL
       followers: 關注者
       followers_url: 關注者(Followers)URL
       follows: 正在關注
+      header: é–‹é ­
       inbox_url: æ”¶ä»¶ç®± (Inbox) URL
+      invited_by: 邀請者
       ip: IP 位址
+      joined: 已加入
       location:
         all: 全部
         local: 本站
@@ -100,25 +115,31 @@ zh-TW:
       media_attachments: 多媒體附件
       memorialize: 設定為追悼帳戶
       moderation:
+        active: 活躍
         all: 全部
+        pending: 等待中
         silenced: 已靜音
         suspended: 已停權
         title: 版務
       moderation_notes: 管理備忘
       most_recent_activity: 最近活動
       most_recent_ip: 最近 IP 位址
+      no_limits_imposed: 未受限制
       not_subscribed: 未訂閱
       outbox_url: 寄件箱 (Outbox) URL
-      perform_full_suspension: 進行停權
+      pending: 等待審核中
+      perform_full_suspension: 停權
       profile_url: 個人檔案 URL
       promote: 晉級
       protocol: 協議
       public: 公開
       push_subscription_expires: PuSH 訂閱過期
-      redownload: 更新頭像
+      redownload: 重新整理個人資料
+      reject: 拒絕
       remove_avatar: 取消頭像
+      remove_header: 移除開頭
       resend_confirmation:
-        already_confirmed: 此用戶已被確認
+        already_confirmed: 此使用者已被確認
         send: 重新發送驗證信
         success: 驗證信發送成功!
       reset: 重設
@@ -129,34 +150,39 @@ zh-TW:
         admin: 管理員
         moderator: 版主
         staff: 管理人員
-        user: 普通用戶
+        user: 普通使用者
       salmon_url: Salmon 網址
       search: 搜尋
-      shared_inbox_url: 公共收件箱 (Shared Inbox) URL
+      shared_inbox_url: 共享收件箱網址
       show:
-        created_reports: 這個使用者提交的檢舉
-        targeted_reports: 針對這個使用者的檢舉
+        created_reports: 建立檢舉
+        targeted_reports: 由其他人檢舉
       silence: 靜音
+      silenced: 已靜音
       statuses: 嘟文
       subscribe: 訂閱
+      suspended: 已停權
       title: 帳戶
-      unconfirmed_email: 等待驗證的E-mail
+      unconfirmed_email: 未確認的電子信箱位址
       undo_silenced: 取消靜音
       undo_suspension: 取消停權
       unsubscribe: 取消訂閱
       username: 使用者名稱
+      warn: 警告
       web: 頁面
     action_logs:
       actions:
         assigned_to_self_report: "%{name} 接受了檢舉 %{target}"
-        change_email_user: "%{name} 更改了使用者 %{target} 的E-mail"
-        confirm_user: "%{name} 確認了使用者 %{target} 的E-mail"
+        change_email_user: "%{name} 變更了使用者 %{target} 的電子信箱位址"
+        confirm_user: "%{name} 確認了使用者 %{target} 的電子信箱位址"
+        create_account_warning: "%{name} 已對 %{target} 送出警告"
         create_custom_emoji: "%{name} 加入自訂表情符號 %{target}"
-        create_domain_block: "%{name} 封鎖了網域 %{target}"
-        create_email_domain_block: "%{name} 封鎖了E-mail %{target}"
+        create_domain_block: "%{name} 封鎖了站點 %{target}"
+        create_email_domain_block: "%{name} 封鎖了電子信箱網域 %{target}"
         demote_user: "%{name} 把使用者 %{target} 降級"
-        destroy_domain_block: "%{name} 取消了對網域 %{target} 的封鎖"
-        destroy_email_domain_block: "%{name} 取消了對E-mail %{target} 的封鎖"
+        destroy_custom_emoji: "%{name} 破壞了 %{target} 表情符號"
+        destroy_domain_block: "%{name} 取消了對站點 %{target} 的封鎖"
+        destroy_email_domain_block: "%{name} 取消了對電子信箱網域 %{target} 的封鎖"
         destroy_status: "%{name} 刪除了 %{target} 的嘟文"
         disable_2fa_user: "%{name} 停用了使用者 %{target} 的兩階段認證"
         disable_custom_emoji: "%{name} 停用了自訂表情符號 %{target}"
@@ -176,9 +202,10 @@ zh-TW:
         unsuspend_account: "%{name} 取消了使用者 %{target} 的停權狀態"
         update_custom_emoji: "%{name} 更新了自訂表情符號 %{target}"
         update_status: "%{name} 重整了 %{target} 的嘟文"
+      deleted_status: "(已刪除嘟文)"
       title: 營運日誌
     custom_emojis:
-      by_domain: 網域
+      by_domain: 站點
       copied_msg: 成功將表情複製到本地
       copy: 複製
       copy_failed_msg: 無法將表情複製到本地
@@ -202,42 +229,75 @@ zh-TW:
       update_failed_msg: 無法更新表情符號
       updated_msg: 已更新表情符號!
       upload: 上傳新的表情符號
+    dashboard:
+      backlog: 未處理工作數
+      config: 設定
+      feature_deletions: 帳戶刪除
+      feature_invites: 邀請連結
+      feature_profile_directory: 個人資料目錄
+      feature_registrations: 註冊
+      feature_relay: 聯邦中繼站
+      features: 功能
+      hidden_service: 與隱密服務互連
+      open_reports: 待處理檢舉數
+      recent_users: 最近加入的使用者
+      search: 全文搜尋
+      single_user_mode: 單一使用者模式
+      software: 軟體
+      space: 儲存空間用量
+      title: 儀表板
+      total_users: 總使用者數
+      trends: 趨勢
+      week_interactions: 本週互動次數
+      week_users_active: 本週活躍使用者數
+      week_users_new: 本週新使用者數
     domain_blocks:
-      add_new: 新增
-      created_msg: 正在進行網域封鎖
-      destroyed_msg: 已撤銷網域封鎖
-      domain: 網域
+      add_new: 新增欲封鎖域名
+      created_msg: 正在進行站點封鎖
+      destroyed_msg: 已撤銷站點封鎖
+      domain: 站點
       new:
         create: 新增封鎖
-        hint: 網域封鎖動作並不會阻止帳戶紀錄被新增至資料庫,但會自動回溯性地對那些帳戶套用特定管理設定。
+        hint: 站點封鎖動作並不會阻止帳戶紀錄被新增至資料庫,但會自動回溯性地對那些帳戶套用特定管理設定。
         severity:
-          desc_html: "「<strong>自動靜音</strong>」令該網域下使用者的嘟文,設定為只對關注者顯示,沒有關注的人會看不到。 「<strong>自動刪除</strong>」會刪除將該網域下使用者的嘟文、媒體檔案和個人資料。「<strong>無</strong>」則會拒絕接收來自該網域的媒體檔案。"
+          desc_html: "「<strong>靜音</strong>」令該站點下使用者的嘟文,設定為只對關注者顯示,沒有關注的人會看不到。「<strong>停權</strong>」會刪除將該站點下使用者的嘟文、媒體檔案和個人資料。「<strong>無</strong>」則會拒絕接收來自該站點的媒體檔案。"
           noop: ç„¡
-          silence: 自動靜音
+          silence: 靜音
           suspend: 停權
-        title: 新增封鎖網域
+        title: 新增封鎖站點
       reject_media: 拒絕媒體檔案
-      reject_media_hint: 刪除本地緩存的媒體檔案,並且不再接收來自該網域的任何媒體檔案。與自動封鎖無關
+      reject_media_hint: 刪除本地快取的媒體檔案,並且不再接收來自該站點的任何媒體檔案。與停權無關
+      reject_reports: 拒絕檢舉
+      reject_reports_hint: 忽略所有來自此站點的檢舉。與停權無關
+      rejecting_media: 拒絕媒體檔案
+      rejecting_reports: 拒絕檢舉中
+      severity:
+        silence: 已靜音
+        suspend: 已停權
       show:
-        affected_accounts: 資料庫中有%{count}個使用者受影響
+        affected_accounts:
+          other: 將影響到資料庫中的 %{count} 個帳戶
         retroactive:
-          silence: 對此網域的所有使用者取消靜音
-          suspend: 對此網域的所有使用者取消封鎖
-        title: 撤銷 %{domain} 的網域封鎖
+          silence: 對此站點的所有使用者取消靜音
+          suspend: 對此站點的所有使用者取消停權
+        title: 撤銷 %{domain} 的站點封鎖
         undo: 撤銷
-      undo: 撤銷
+      undo: 復原欲封鎖域名
     email_domain_blocks:
       add_new: 加入新項目
-      created_msg: 已新增E-mail封鎖
+      created_msg: 已成功將電子信箱網域加入黑名單
       delete: 刪除
-      destroyed_msg: 已刪除E-mail封鎖
-      domain: 網域
+      destroyed_msg: 已成功從黑名單刪除電子信箱網域
+      domain: 站點
       new:
-        create: 新增網域
-        title: 新增E-mail封鎖
-      title: E-mail封鎖
+        create: 新增站點
+        title: 新增電子信箱黑名單項目
+      title: 電子信箱黑名單
+    followers:
+      back_to_account: 返回帳戶
+      title: "%{acct} 的關注者"
     instances:
-      title: 已知站點
+      title: 聯邦
     invites:
       filter:
         all: 全部
@@ -245,6 +305,8 @@ zh-TW:
         expired: 已失效
         title: 篩選
       title: 邀請使用者
+    relays:
+      description_html: "<strong>聯邦中繼站</strong> 是種中繼伺服器,會在訂閱並推送至此中繼站的伺服器之間交換大量的公開嘟文。<strong>中繼站也能協助小型或中型伺服器從聯邦中探索內容</strong>,而無須本地使用者手動關注遠端伺服器的其他使用者。"
     report_notes:
       created_msg: 檢舉記錄建立成功!
       destroyed_msg: 檢舉記錄刪除成功!
@@ -273,7 +335,7 @@ zh-TW:
       reported_by: 檢舉人
       resolved: 已解決
       resolved_msg: 檢舉已處理!
-      status: 狀態
+      status: 嘟文
       title: 檢舉
       unassign: 取消指派
       unresolved: 未解決
@@ -283,17 +345,17 @@ zh-TW:
         desc_html: 本站使用者發佈的嘟文數量,以及本站的活躍使用者與一週內新使用者數量
         title: 公開使用者活躍度的統計數據
       bootstrap_timeline_accounts:
-        desc_html: 以半形逗號分隔多個使用者名。只能加入來自本站且未開啟保護的帳號。如果留空,則預設關注本站所有管理員。
+        desc_html: 以半形逗號分隔多個使用者名。只能加入來自本站且未開啟保護的帳戶。如果留空,則預設關注本站所有管理員。
         title: 新使用者預設關注
       contact_information:
-        email: 請輸入一個公開E-mail
+        email: 用於聯絡的公開電子信箱位址
         username: 請輸入使用者名稱
       hero:
-        desc_html: 在首頁顯示。推薦最小 600x100px。如果留空,就會預設為站點預覽圖
+        desc_html: 在首頁顯示。推薦最小 600x100px。如果留空,就會重設回伺服器預覽圖
         title: 主題圖片
       peers_api_enabled:
-        desc_html: 現在本站點在網路中已發現的網域
-        title: 公開已知站點的列表
+        desc_html: 本伺服器在聯邦中發現的站點
+        title: 發布已知伺服器的列表
       registrations:
         closed_message:
           desc_html: 關閉註冊時顯示在首頁的內容,可使用 HTML 標籤
@@ -304,9 +366,6 @@ zh-TW:
         min_invite_role:
           disabled: 沒有人
           title: 允許發送邀請的身份
-        open:
-          desc_html: 允許所有人建立帳戶
-          title: 開放註冊
       show_known_fediverse_at_about_page:
         desc_html: 如果開啟,就會在時間軸預覽顯示其他站點嘟文,否則就只會顯示本站點嘟文。
         title: 在時間軸預覽顯示其他站點嘟文
@@ -314,18 +373,18 @@ zh-TW:
         desc_html: 在個人資料頁面上顯示管理人員標誌
         title: 顯示管理人員標誌
       site_description:
-        desc_html: "</code>在首頁顯示,及在 meta 標籤中的站點簡介。可以使用 HTML 標籤,包括 <code> 1&lt; 2a&gt; 3</code> 4 and <code> 5&lt; 6em&gt; 7</code> 8."
-        title: 站點描述
+        desc_html: 首頁上的介紹文字,描述此 Mastodon 伺服器的特別之處和其他重要資訊。可使用 HTML 標籤,包括 <code>&lt;a&gt;</code> 和 <code>&lt;em&gt;</code>。
+        title: 伺服器描述
       site_description_extended:
-        desc_html: 顯示在資訊頁的長版描述,可使用 HTML 標籤
+        desc_html: 可放置行為準則、規定以及其他此伺服器特有的內容。可使用 HTML 標籤
         title: 本站詳細資訊
       site_terms:
         desc_html: 可以填寫自己的隱私權政策、使用條款或其他法律文本。可以使用 HTML 標籤
         title: 自訂使用條款
-      site_title: 站點名稱
+      site_title: 伺服器名稱
       thumbnail:
         desc_html: 用於在 OpenGraph 和 API 中顯示預覽圖。推薦大小 1200×630px
-        title: 本站縮圖
+        title: 伺服器縮圖
       timeline_preview:
         desc_html: 在主頁顯示本站時間軸
         title: 時間軸預覽
@@ -356,9 +415,9 @@ zh-TW:
       body_remote: 來自 %{domain} 的使用者檢舉了使用者 %{target}
       subject: 來自 %{instance} 的使用者檢舉(#%{id})
   application_mailer:
-    notification_preferences: 更改E-mail設定
-    salutation: "%{name},"
-    settings: 修改E-mail設定︰ %{link}
+    notification_preferences: 變更電子信件設定
+    salutation: "%{name}、"
+    settings: 變更電子信箱設定︰%{link}
     view: '進入瀏覽:'
     view_profile: 檢視個人資料頁
     view_status: 檢視嘟文
@@ -371,9 +430,8 @@ zh-TW:
     warning: 警告,不要把它分享給任何人!
     your_token: ä½ çš„ token
   auth:
-    agreement_html: 註冊即表示你同意遵守<a href="%{rules_path}">本站點的規則</a>和<a href="%{terms_path}">使用條款</a>。
     change_password: 密碼
-    confirm_email: 確認E-mail
+    confirm_email: 確認電子信箱位址
     delete_account: 刪除帳戶
     delete_account_html: 如果你想刪除你的帳戶,請<a href="%{path}">點擊這裡繼續</a>。你需要確認你的操作。
     didnt_get_confirmation: 沒有收到驗證信?
@@ -381,16 +439,11 @@ zh-TW:
     invalid_reset_password_token: 密碼重設 token 無效或已過期。請重新設定密碼。
     login: 登入
     logout: 登出
-    migrate_account: 轉移到另一個帳號
+    migrate_account: 轉移到另一個帳戶
     migrate_account_html: 如果你希望引導他人關注另一個帳戶,請<a href="%{path}">到這裡設定</a>。
-    or: 或
     or_log_in_with: 或透過其他方式登入
-    providers:
-      cas: CAS
-      saml: SAML
     register: 註冊
-    register_elsewhere: 在其他站點註冊
-    resend_confirmation: 重新寄送E-mail
+    resend_confirmation: 重新寄送確認指引
     reset_password: 重設密碼
     security: 登入資訊
     set_new_password: 設定新密碼
@@ -422,15 +475,15 @@ zh-TW:
   deletes:
     bad_password_msg: 想得美,駭客! 密碼輸入錯誤
     confirm_password: 輸入你現在的密碼來驗證身份
-    description_html: 繼續操作將會<strong>永久地、不可還原地</strong>刪除帳戶中的所有內容,然後凍結帳戶。你的用戶名將會被保留,以防有人冒用你的身份。
+    description_html: 繼續操作將會<strong>永久地、不可還原地</strong>刪除帳戶中的所有內容,然後凍結帳戶。你的使用者名稱將會被保留,以防有人冒用你的身份。
     proceed: 刪除帳戶
     success_msg: 你的帳戶已經成功刪除
-    warning_html: 我們只能保證本站點上的內容將會被徹底刪除。對於已經被廣泛傳播的內容,它們在本站點以外的某些地方可能仍然可見。此外,失去連接的站點以及停止接收訂閱的站點所儲存的數據亦無法刪除。
+    warning_html: 我們只能保證本伺服器上的內容將會被徹底刪除。對於已經被廣泛傳播的內容,它們在本伺服器以外的某些地方可能仍然可見。此外,離線伺服器以及停止接收訂閱的伺服器所儲存的資料亦無法刪除。
     warning_title: 關於已傳播的內容警告
   errors:
     '403': 你沒有觀看這個頁面的權限。
     '404': 您所尋找的網頁不存在。
-    '410': 您所尋找的網頁已不存在。
+    '410': 您所尋找的網頁此處已不存在。
     '422':
       content: 安全驗證失敗。請確定有開啟瀏覽器 Cookies 功能?
       title: 安全驗證失敗
@@ -448,26 +501,14 @@ zh-TW:
       request: 下載存檔
       size: 大小
     blocks: 您封鎖的使用者
-    csv: CSV
     follows: 您關注的使用者
     mutes: 您靜音的使用者
     storage: 儲存空間大小
-  followers:
-    domain: 網域
-    explanation_html: 為確保個人隱私,您必須知道有哪些使用者正關注你。<strong>您的私密內容會被發送到所有您有被關注的站點上</strong>。如果您不信任這些站點的管理者,您可以選擇檢查或刪除您的關注者。
-    followers_count: 關注者數量
-    lock_link: 將你的帳戶設定為私人
-    purge: 移除關注者
-    success: 正準備軟性封鎖 %{count} 個網域的關注者……
-    true_privacy_html: 請謹記,唯有<strong>點對點加密方可以真正確保你的隱私</strong>。
-    unlocked_warning_html: 任何人都可以在關注你後立即查看非公開的嘟文。只要%{lock_link},你就可以審核並拒絕關注請求。
-    unlocked_warning_title: 你的帳戶是公開的
   generic:
     changes_saved_msg: 已成功儲存修改!
     save_changes: 儲存修改
-    validation_errors: 送出的資料有 %{count} 個問題
   imports:
-    preface: 您可以在此匯入您在其他站點所匯出的資料檔,包括關注的使用者、封鎖的使用者名單。
+    preface: 您可以在此匯入您在其他伺服器所匯出的資料檔,包括關注的使用者、封鎖的使用者名單。
     success: 資料檔上傳成功,正在匯入,請稍候
     types:
       blocking: 您封鎖的使用者名單
@@ -488,9 +529,8 @@ zh-TW:
     expires_in_prompt: 永不過期
     generate: 建立邀請連結
     invited_by: 你的邀請人是:
-    max_uses: "%{count} 次"
     max_uses_prompt: 無限制
-    prompt: 建立分享連結,邀請他人在本站點註冊
+    prompt: 建立分享連結,邀請他人在本伺服器註冊
     table:
       expires_at: 失效時間
       uses: 已使用次數
@@ -514,8 +554,6 @@ zh-TW:
       action: 閱覽所有通知
       body: 以下是自%{since}你最後一次登入以來錯過的訊息摘要
       mention: "%{name} 在此提及了你:"
-      new_followers_summary: 而且,你不在的時候,有 %{count} 個人關注你了! 好棒!
-      subject: "自從上次登入以來,你收到 %{count} 則新的通知 \U0001F418"
       title: 你不在的時候...
     favourite:
       body: '你的嘟文被 %{name} 加入了最愛:'
@@ -539,30 +577,13 @@ zh-TW:
       body: '你的嘟文被 %{name} 轉嘟:'
       subject: "%{name} 轉嘟了你的嘟文"
       title: 新的轉嘟
-  number:
-    human:
-      decimal_units:
-        format: "%n%u"
-        units:
-          billion: B
-          million: M
-          quadrillion: Q
-          thousand: K
-          trillion: T
-          unit: ''
   pagination:
     newer: 較新
     next: 下一頁
     older: 較舊
     prev: 上一頁
-    truncate: ''
-  preferences:
-    languages: 語言
-    other: å…¶ä»–
-    publishing: 發佈
-    web: 站內
   remote_follow:
-    acct: 請輸入您的︰使用者名稱@站點網域
+    acct: 請輸入您的使用者名稱@站點網域
     missing_resource: 無法找到資源
     proceed: 下一步
     prompt: '您希望關注:'
@@ -593,13 +614,8 @@ zh-TW:
       weibo: 新浪微博
     current_session: 目前的 session
     description: "%{platform} 上的 %{browser}"
-    explanation: 這些是現在正登入於你的 Mastodon 帳號的瀏覽器。
+    explanation: 這些是現在正登入於你的 Mastodon 帳戶的瀏覽器。
     ip: IP 位址
-    platforms:
-      adobe_air: ''
-      linux: ''
-      mac: ''
-      other: 未知平台
     revoke: 取消
     revoke_success: Session 取消成功
     title: 作業階段
@@ -610,22 +626,16 @@ zh-TW:
     development: 開發
     edit_profile: 編輯使用者資訊
     export: 匯出
-    followers: 授權關注者
     import: 匯入
     migrate: 帳戶搬遷
     notifications: 通知
     preferences: 偏好設定
-    settings: 設定
     two_factor_authentication: 兩階段認證
-    your_apps: 你的應用程式
   statuses:
     attached:
       description: 附件: %{attached}
-      image: "%{count} 幅圖片"
-      video: "%{count} 段影片"
     boosted_from_html: 轉嘟自 %{acct_link}
     content_warning: 內容警告: %{warning}
-    disallowed_hashtags: 包含不允許的標籤: %{tags}
     language_detection: 自動偵測語言
     open_in_web: 以網頁開啟
     over_character_limit: 超過了 %{max} 字的限制
@@ -635,7 +645,6 @@ zh-TW:
       private: 不能置頂非公開的嘟文
       reblog: 不能置頂轉嘟
     show_more: 顯示更多
-    title: '%{name}: "%{quote}"'
     visibilities:
       private: 僅關注者
       private_long: 只有關注你的人能看到
@@ -650,8 +659,8 @@ zh-TW:
   terms:
     title: "%{instance} 使用條款和隱私權政策"
   themes:
-    contrast: 高對比
-    mastodon-light: Mastodon (亮色主題)
+    contrast: Mastodon(高對比)
+    mastodon-light: Mastodon(亮色主題)
   time:
     formats:
       default: "%Y年%-m月%d日 %H:%M"
@@ -673,18 +682,18 @@ zh-TW:
     wrong_code: 您輸入的認證碼無效! 請確認伺服器時間與設備時間是否正確?
   user_mailer:
     backup_ready:
-      explanation: 你要求的 Mastodon 帳號完整備份檔案現已就緒,可供下載!
+      explanation: 你要求的 Mastodon 帳戶完整備份檔案現已就緒,可供下載!
       subject: 你的備份檔已可供下載
       title: 檔案匯出
     welcome:
       edit_profile_action: 設定個人資料
-      edit_profile_step: 你可以設定你的個人資料,包括上傳頭像、橫幅圖片、更改顯示名稱等等。如果你想在新的關注者關注你之前對他們進行審核,你也可以選擇為你的帳戶設為「私人」。
+      edit_profile_step: 你可以設定你的個人資料,包括上傳頭像、橫幅圖片、變更顯示名稱等等。如果你想在新的關注者關注你之前對他們進行審核,你也可以選擇為你的帳戶設為「私人」。
       explanation: 下面是幾個小幫助,希望它們能幫到你
       final_action: 開始嘟嘟
       final_step: '開始嘟嘟吧! 即使你現在沒有關注者,其他人仍然能在本站時間軸或著話題標籤等地方看到你的公開嘟文。試著用 #introductions 這個話題標籤介紹一下自己吧。'
       full_handle: 你的完整帳戶名稱
-      full_handle_hint: 你需要把這個告訴你的朋友們,這樣他們就能從另一個站點向你發送訊息或著關注你。
-      review_preferences_action: 更改偏好設定
+      full_handle_hint: 你需要把這告訴你的朋友們,這樣他們就能從另一個伺服器向你發送訊息或著關注你。
+      review_preferences_action: 變更偏好設定
       review_preferences_step: 記得調整你的偏好設定,比如你想接收什麼類型的電子郵件,或著你想把你的嘟文可見範圍預設設定什麼級別。如果你沒有暈車的話,考慮一下啟用「自動播放 GIF 動畫」這個選項吧。
       subject: 歡迎來到 Mastodon
       tip_federated_timeline: 跨站公共時間軸可以讓你一窺更廣闊的 Mastodon 網路。不過,由於它們只顯示你的鄰居們所訂閱的內容,所以並不是全部。
@@ -694,7 +703,7 @@ zh-TW:
       tips: 小幫手
       title: "%{name} 歡迎你的加入!"
   users:
-    invalid_email: E-mail格式不正確
+    invalid_email: 電子信箱位址不正確
     invalid_otp_token: 兩階段認證碼不正確
     otp_lost_help_html: 如果你無法訪問這兩者,可以通過 %{email} 與我們聯繫
     seamless_external_login: 由於你是從外部系統登入,所以不能設定密碼與電子郵件。
diff --git a/config/navigation.rb b/config/navigation.rb
index a9521f956d0293433b9a19084dd79d6f74db76a9..df10241892997bfde20f25ac999d5e8ac7b8ae0a 100644
--- a/config/navigation.rb
+++ b/config/navigation.rb
@@ -1,48 +1,58 @@
 # frozen_string_literal: true
 
 SimpleNavigation::Configuration.run do |navigation|
-  navigation.items do |primary|
-    primary.item :web, safe_join([fa_icon('chevron-left fw'), t('settings.back')]), root_url
-
-    primary.item :settings, safe_join([fa_icon('cog fw'), t('settings.settings')]), settings_profile_url do |settings|
-      settings.item :profile, safe_join([fa_icon('user fw'), t('settings.edit_profile')]), settings_profile_url, highlights_on: %r{/settings/profile|/settings/migration}
-      settings.item :preferences, safe_join([fa_icon('sliders fw'), t('settings.preferences')]), settings_preferences_url
-      settings.item :notifications, safe_join([fa_icon('bell fw'), t('settings.notifications')]), settings_notifications_url
-      settings.item :password, safe_join([fa_icon('lock fw'), t('auth.security')]), edit_user_registration_url, highlights_on: %r{/auth/edit|/settings/delete}
-      settings.item :two_factor_authentication, safe_join([fa_icon('mobile fw'), t('settings.two_factor_authentication')]), settings_two_factor_authentication_url, highlights_on: %r{/settings/two_factor_authentication}
-      settings.item :import, safe_join([fa_icon('cloud-upload fw'), t('settings.import')]), settings_import_url
-      settings.item :export, safe_join([fa_icon('cloud-download fw'), t('settings.export')]), settings_export_url
-      settings.item :authorized_apps, safe_join([fa_icon('list fw'), t('settings.authorized_apps')]), oauth_authorized_applications_url
-      settings.item :follower_domains, safe_join([fa_icon('users fw'), t('settings.followers')]), settings_follower_domains_url
+  navigation.items do |n|
+    n.item :web, safe_join([fa_icon('chevron-left fw'), t('settings.back')]), root_url
+
+    n.item :profile, safe_join([fa_icon('user fw'), t('settings.profile')]), settings_profile_url do |s|
+      s.item :profile, safe_join([fa_icon('pencil fw'), t('settings.appearance')]), settings_profile_url, highlights_on: %r{/settings/profile|/settings/migration}
+      s.item :featured_tags, safe_join([fa_icon('hashtag fw'), t('settings.featured_tags')]), settings_featured_tags_url
+      s.item :identity_proofs, safe_join([fa_icon('key fw'), t('settings.identity_proofs')]), settings_identity_proofs_path, highlights_on: %r{/settings/identity_proofs*}, if: proc { current_account.identity_proofs.exists? }
+    end
+
+    n.item :preferences, safe_join([fa_icon('cog fw'), t('settings.preferences')]), settings_preferences_url do |s|
+      s.item :appearance, safe_join([fa_icon('desktop fw'), t('settings.appearance')]), settings_preferences_appearance_url
+      s.item :notifications, safe_join([fa_icon('bell fw'), t('settings.notifications')]), settings_preferences_notifications_url
+      s.item :other, safe_join([fa_icon('cog fw'), t('preferences.other')]), settings_preferences_other_url
     end
 
-    primary.item :filters, safe_join([fa_icon('filter fw'), t('filters.index.title')]), filters_path, highlights_on: %r{/filters}
-    primary.item :invites, safe_join([fa_icon('user-plus fw'), t('invites.title')]), invites_path, if: proc { Setting.min_invite_role == 'user' }
+    n.item :relationships, safe_join([fa_icon('users fw'), t('settings.relationships')]), relationships_url
+    n.item :filters, safe_join([fa_icon('filter fw'), t('filters.index.title')]), filters_path, highlights_on: %r{/filters}
 
-    primary.item :development, safe_join([fa_icon('code fw'), t('settings.development')]), settings_applications_url do |development|
-      development.item :your_apps, safe_join([fa_icon('list fw'), t('settings.your_apps')]), settings_applications_url, highlights_on: %r{/settings/applications}
+    n.item :security, safe_join([fa_icon('lock fw'), t('settings.account')]), edit_user_registration_url do |s|
+      s.item :password, safe_join([fa_icon('lock fw'), t('settings.account_settings')]), edit_user_registration_url, highlights_on: %r{/auth/edit|/settings/delete}
+      s.item :two_factor_authentication, safe_join([fa_icon('mobile fw'), t('settings.two_factor_authentication')]), settings_two_factor_authentication_url, highlights_on: %r{/settings/two_factor_authentication}
+      s.item :authorized_apps, safe_join([fa_icon('list fw'), t('settings.authorized_apps')]), oauth_authorized_applications_url
     end
 
-    primary.item :moderation, safe_join([fa_icon('gavel fw'), t('moderation.title')]), admin_reports_url, if: proc { current_user.staff? } do |admin|
-      admin.item :action_logs, safe_join([fa_icon('bars fw'), t('admin.action_logs.title')]), admin_action_logs_url
-      admin.item :reports, safe_join([fa_icon('flag fw'), t('admin.reports.title')]), admin_reports_url, highlights_on: %r{/admin/reports}
-      admin.item :accounts, safe_join([fa_icon('users fw'), t('admin.accounts.title')]), admin_accounts_url, highlights_on: %r{/admin/accounts}
-      admin.item :invites, safe_join([fa_icon('user-plus fw'), t('admin.invites.title')]), admin_invites_path
-      admin.item :tags, safe_join([fa_icon('tag fw'), t('admin.tags.title')]), admin_tags_path
-      admin.item :instances, safe_join([fa_icon('cloud fw'), t('admin.instances.title')]), admin_instances_url(limited: '1'), highlights_on: %r{/admin/instances|/admin/domain_blocks}, if: -> { current_user.admin? }
-      admin.item :email_domain_blocks, safe_join([fa_icon('envelope fw'), t('admin.email_domain_blocks.title')]), admin_email_domain_blocks_url, highlights_on: %r{/admin/email_domain_blocks}, if: -> { current_user.admin? }
+    n.item :data, safe_join([fa_icon('cloud-download fw'), t('settings.import_and_export')]), settings_export_url do |s|
+      s.item :import, safe_join([fa_icon('cloud-upload fw'), t('settings.import')]), settings_import_url
+      s.item :export, safe_join([fa_icon('cloud-download fw'), t('settings.export')]), settings_export_url
+    end
+
+    n.item :invites, safe_join([fa_icon('user-plus fw'), t('invites.title')]), invites_path, if: proc { Setting.min_invite_role == 'user' }
+    n.item :development, safe_join([fa_icon('code fw'), t('settings.development')]), settings_applications_url
+
+    n.item :moderation, safe_join([fa_icon('gavel fw'), t('moderation.title')]), admin_reports_url, if: proc { current_user.staff? } do |s|
+      s.item :action_logs, safe_join([fa_icon('bars fw'), t('admin.action_logs.title')]), admin_action_logs_url
+      s.item :reports, safe_join([fa_icon('flag fw'), t('admin.reports.title')]), admin_reports_url, highlights_on: %r{/admin/reports}
+      s.item :accounts, safe_join([fa_icon('users fw'), t('admin.accounts.title')]), admin_accounts_url, highlights_on: %r{/admin/accounts|/admin/pending_accounts}
+      s.item :invites, safe_join([fa_icon('user-plus fw'), t('admin.invites.title')]), admin_invites_path
+      s.item :tags, safe_join([fa_icon('tag fw'), t('admin.tags.title')]), admin_tags_path
+      s.item :instances, safe_join([fa_icon('cloud fw'), t('admin.instances.title')]), admin_instances_url(limited: '1'), highlights_on: %r{/admin/instances|/admin/domain_blocks}, if: -> { current_user.admin? }
+      s.item :email_domain_blocks, safe_join([fa_icon('envelope fw'), t('admin.email_domain_blocks.title')]), admin_email_domain_blocks_url, highlights_on: %r{/admin/email_domain_blocks}, if: -> { current_user.admin? }
     end
 
-    primary.item :admin, safe_join([fa_icon('cogs fw'), t('admin.title')]), admin_dashboard_url, if: proc { current_user.staff? } do |admin|
-      admin.item :dashboard, safe_join([fa_icon('tachometer fw'), t('admin.dashboard.title')]), admin_dashboard_url
-      admin.item :settings, safe_join([fa_icon('cogs fw'), t('admin.settings.title')]), edit_admin_settings_url, if: -> { current_user.admin? }
-      admin.item :custom_emojis, safe_join([fa_icon('smile-o fw'), t('admin.custom_emojis.title')]), admin_custom_emojis_url, highlights_on: %r{/admin/custom_emojis}
-      admin.item :relays, safe_join([fa_icon('exchange fw'), t('admin.relays.title')]), admin_relays_url, if: -> { current_user.admin? }, highlights_on: %r{/admin/relays}
-      admin.item :subscriptions, safe_join([fa_icon('paper-plane-o fw'), t('admin.subscriptions.title')]), admin_subscriptions_url, if: -> { current_user.admin? }
-      admin.item :sidekiq, safe_join([fa_icon('diamond fw'), 'Sidekiq']), sidekiq_url, link_html: { target: 'sidekiq' }, if: -> { current_user.admin? }
-      admin.item :pghero, safe_join([fa_icon('database fw'), 'PgHero']), pghero_url, link_html: { target: 'pghero' }, if: -> { current_user.admin? }
+    n.item :admin, safe_join([fa_icon('cogs fw'), t('admin.title')]), admin_dashboard_url, if: proc { current_user.staff? } do |s|
+      s.item :dashboard, safe_join([fa_icon('tachometer fw'), t('admin.dashboard.title')]), admin_dashboard_url
+      s.item :settings, safe_join([fa_icon('cogs fw'), t('admin.settings.title')]), edit_admin_settings_url, if: -> { current_user.admin? }, highlights_on: %r{/admin/settings}
+      s.item :custom_emojis, safe_join([fa_icon('smile-o fw'), t('admin.custom_emojis.title')]), admin_custom_emojis_url, highlights_on: %r{/admin/custom_emojis}
+      s.item :relays, safe_join([fa_icon('exchange fw'), t('admin.relays.title')]), admin_relays_url, if: -> { current_user.admin? }, highlights_on: %r{/admin/relays}
+      s.item :subscriptions, safe_join([fa_icon('paper-plane-o fw'), t('admin.subscriptions.title')]), admin_subscriptions_url, if: -> { current_user.admin? }
+      s.item :sidekiq, safe_join([fa_icon('diamond fw'), 'Sidekiq']), sidekiq_url, link_html: { target: 'sidekiq' }, if: -> { current_user.admin? }
+      s.item :pghero, safe_join([fa_icon('database fw'), 'PgHero']), pghero_url, link_html: { target: 'pghero' }, if: -> { current_user.admin? }
     end
 
-    primary.item :logout, safe_join([fa_icon('sign-out fw'), t('auth.logout')]), destroy_user_session_url, link_html: { 'data-method' => 'delete' }
+    n.item :logout, safe_join([fa_icon('sign-out fw'), t('auth.logout')]), destroy_user_session_url, link_html: { 'data-method' => 'delete' }
   end
 end
diff --git a/config/puma.rb b/config/puma.rb
index 1afdb1c6dfbc0900051690c33a2013482398132a..6a96867d54d27e04f2090bc4191131da39b8a76c 100644
--- a/config/puma.rb
+++ b/config/puma.rb
@@ -2,9 +2,9 @@ threads_count = ENV.fetch('MAX_THREADS') { 5 }.to_i
 threads threads_count, threads_count
 
 if ENV['SOCKET']
-  bind 'unix://' + ENV['SOCKET']
+  bind "unix://#{ENV['SOCKET']}"
 else
-  port ENV.fetch('PORT') { 3000 }
+  bind "tcp://#{ENV.fetch('BIND', '127.0.0.1')}:#{ENV.fetch('PORT', 3000)}"
 end
 
 environment ENV.fetch('RAILS_ENV') { 'development' }
diff --git a/config/routes.rb b/config/routes.rb
index af49845ccbe77e3abc501abb4fb45eb98f56029b..764db8db2e61882d1dc2507de5a50fa04beb2f58 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -22,6 +22,8 @@ Rails.application.routes.draw do
   get '.well-known/host-meta', to: 'well_known/host_meta#show', as: :host_meta, defaults: { format: 'xml' }
   get '.well-known/webfinger', to: 'well_known/webfinger#show', as: :webfinger
   get '.well-known/change-password', to: redirect('/auth/edit')
+  get '.well-known/keybase-proof-config', to: 'well_known/keybase_proof_config#show'
+
   get 'manifest', to: 'manifests#show', defaults: { format: 'json' }
   get 'intent', to: 'intents#show'
   get 'custom.css', to: 'custom_css#show', as: :custom_css
@@ -56,6 +58,7 @@ Rails.application.routes.draw do
       member do
         get :activity
         get :embed
+        get :replies
       end
     end
 
@@ -74,6 +77,7 @@ Rails.application.routes.draw do
   get '/@:username', to: 'accounts#show', as: :short_account
   get '/@:username/with_replies', to: 'accounts#show', as: :short_account_with_replies
   get '/@:username/media', to: 'accounts#show', as: :short_account_media
+  get '/@:username/tagged/:tag', to: 'accounts#show', as: :short_account_tag
   get '/@:account_username/:id', to: 'statuses#show', as: :short_account_status
   get '/@:account_username/:id/embed', to: 'statuses#embed', as: :embed_short_account_status
 
@@ -83,13 +87,22 @@ Rails.application.routes.draw do
   get '/explore', to: 'directories#index', as: :explore
   get '/explore/:id', to: 'directories#show', as: :explore_hashtag
 
+  get '/settings', to: redirect('/settings/profile')
+
   namespace :settings do
     resource :profile, only: [:show, :update]
-    resource :preferences, only: [:show, :update]
-    resource :notifications, only: [:show, :update]
-    resource :import, only: [:show, :create]
 
+    get :preferences, to: redirect('/settings/preferences/appearance')
+
+    namespace :preferences do
+      resource :appearance, only: [:show, :update], controller: :appearance
+      resource :notifications, only: [:show, :update]
+      resource :other, only: [:show, :update], controller: :other
+    end
+
+    resource :import, only: [:show, :create]
     resource :export, only: [:show, :create]
+
     namespace :exports, constraints: { format: :csv } do
       resources :follows, only: :index, controller: :following_accounts
       resources :blocks, only: :index, controller: :blocked_accounts
@@ -99,12 +112,13 @@ Rails.application.routes.draw do
     end
 
     resource :two_factor_authentication, only: [:show, :create, :destroy]
+
     namespace :two_factor_authentication do
       resources :recovery_codes, only: [:create]
       resource :confirmation, only: [:new, :create]
     end
 
-    resource :follower_domains, only: [:show, :update]
+    resources :identity_proofs, only: [:index, :show, :new, :create, :update]
 
     resources :applications, except: [:edit] do
       member do
@@ -116,6 +130,7 @@ Rails.application.routes.draw do
     resource :migration, only: [:show, :update]
 
     resources :sessions, only: [:destroy]
+    resources :featured_tags, only: [:index, :create, :destroy]
   end
 
   resources :media, only: [:show] do
@@ -126,7 +141,9 @@ Rails.application.routes.draw do
   resources :emojis, only: [:show]
   resources :invites, only: [:index, :create, :destroy]
   resources :filters, except: [:show]
+  resource :relationships, only: [:show, :update]
 
+  get '/public', to: 'public_timelines#show', as: :public_timeline
   get '/media_proxy/:id/(*any)', to: 'media_proxy#show', as: :media_proxy
 
   # Remote follow
@@ -183,6 +200,8 @@ Rails.application.routes.draw do
         post :remove_avatar
         post :remove_header
         post :memorialize
+        post :approve
+        post :reject
       end
 
       resource :change_email, only: [:show, :update]
@@ -205,6 +224,14 @@ Rails.application.routes.draw do
       end
     end
 
+    resources :pending_accounts, only: [:index] do
+      collection do
+        post :approve_all
+        post :reject_all
+        post :batch
+      end
+    end
+
     resources :users, only: [] do
       resource :two_factor_authentication, only: [:destroy]
     end
@@ -243,6 +270,9 @@ Rails.application.routes.draw do
     # OEmbed
     get '/oembed', to: 'oembed#show', as: :oembed
 
+    # Identity proofs
+    get :proofs, to: 'proofs#index'
+
     # JSON / REST API
     namespace :v1 do
       resources :statuses, only: [:create, :show, :destroy] do
@@ -280,6 +310,7 @@ Rails.application.routes.draw do
       resources :custom_emojis, only: [:index]
       resources :suggestions, only: [:index, :destroy]
       resources :scheduled_statuses, only: [:index, :show, :update, :destroy]
+      resources :preferences, only: [:index]
 
       resources :conversations, only: [:index, :destroy] do
         member do
@@ -341,6 +372,7 @@ Rails.application.routes.draw do
         resources :followers, only: :index, controller: 'accounts/follower_accounts'
         resources :following, only: :index, controller: 'accounts/following_accounts'
         resources :lists, only: :index, controller: 'accounts/lists'
+        resources :identity_proofs, only: :index, controller: 'accounts/identity_proofs'
 
         member do
           post :follow
@@ -359,9 +391,36 @@ Rails.application.routes.draw do
         resource :accounts, only: [:show, :create, :destroy], controller: 'lists/accounts'
       end
 
+      resources :polls, only: [:create, :show] do
+        resources :votes, only: :create, controller: 'polls/votes'
+      end
+
       namespace :push do
         resource :subscription, only: [:create, :show, :update, :destroy]
       end
+
+      namespace :admin do
+        resources :accounts, only: [:index, :show] do
+          member do
+            post :enable
+            post :unsilence
+            post :unsuspend
+            post :approve
+            post :reject
+          end
+
+          resource :action, only: [:create], controller: 'account_actions'
+        end
+
+        resources :reports, only: [:index, :show] do
+          member do
+            post :assign_to_self
+            post :unassign
+            post :reopen
+            post :resolve
+          end
+        end
+      end
     end
 
     namespace :v2 do
diff --git a/config/settings.yml b/config/settings.yml
index 4f7c2c8f32cc04348d89ec056a091b9b3eace7bf..805624d3e1e165593ca7952d038f7e8119c8aa97 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -9,7 +9,7 @@ defaults: &defaults
   site_terms: ''
   site_contact_username: ''
   site_contact_email: ''
-  open_registrations: true
+  registrations_mode: 'open'
   profile_directory: true
   closed_registrations_message: ''
   open_deletion: true
@@ -26,10 +26,12 @@ defaults: &defaults
   expand_spoilers: false
   preview_sensitive_media: false
   reduce_motion: false
+  show_application: true
   system_font_ui: false
   noindex: false
   theme: 'default'
   aggregate_reblogs: true
+  advanced_layout: false
   notification_emails:
     follow: false
     reblog: false
@@ -38,6 +40,7 @@ defaults: &defaults
     follow_request: true
     digest: true
     report: true
+    pending_account: true
   interactions:
     must_be_follower: false
     must_be_following: false
diff --git a/config/webpack/configuration.js b/config/webpack/configuration.js
index 4d325a82877197bc37aa1e61606866f7c7766c48..80a094c724e6a1986f23bc874150e2a697651685 100644
--- a/config/webpack/configuration.js
+++ b/config/webpack/configuration.js
@@ -1,12 +1,11 @@
 // Common configuration for webpacker loaded from config/webpacker.yml
 
-const { join, resolve } = require('path');
+const { resolve } = require('path');
 const { env } = require('process');
 const { safeLoad } = require('js-yaml');
 const { readFileSync } = require('fs');
 
 const configPath = resolve('config', 'webpacker.yml');
-const loadersDir = join(__dirname, 'loaders');
 const settings = safeLoad(readFileSync(configPath), 'utf8')[env.RAILS_ENV || env.NODE_ENV];
 
 const themePath = resolve('config', 'themes.yml');
@@ -37,6 +36,5 @@ module.exports = {
     CDN_HOST: env.CDN_HOST,
     NODE_ENV: env.NODE_ENV,
   },
-  loadersDir,
   output,
 };
diff --git a/config/webpack/development.js b/config/webpack/development.js
index d54d919eca59ca5e79a48cc34e5a70c66b0b60d7..1e50a4f468efb19a792f13abc0c6f294b3be6c2b 100644
--- a/config/webpack/development.js
+++ b/config/webpack/development.js
@@ -1,12 +1,10 @@
 // Note: You must restart bin/webpack-dev-server for changes to take effect
 
 const merge = require('webpack-merge');
-const sharedConfig = require('./shared.js');
-const { settings, output } = require('./configuration.js');
+const sharedConfig = require('./shared');
+const { settings, output } = require('./configuration');
 
-const watchOptions = {
-  ignored: /node_modules/,
-};
+const watchOptions = {};
 
 if (process.env.VAGRANT) {
   // If we are in Vagrant, we can't rely on inotify to update us with changed
@@ -17,7 +15,7 @@ if (process.env.VAGRANT) {
 
 module.exports = merge(sharedConfig, {
   mode: 'development',
-
+  cache: true,
   devtool: 'cheap-module-eval-source-map',
 
   stats: {
@@ -30,15 +28,33 @@ module.exports = merge(sharedConfig, {
 
   devServer: {
     clientLogLevel: 'none',
-    https: settings.dev_server.https,
+    compress: settings.dev_server.compress,
+    quiet: settings.dev_server.quiet,
+    disableHostCheck: settings.dev_server.disable_host_check,
     host: settings.dev_server.host,
     port: settings.dev_server.port,
+    https: settings.dev_server.https,
+    hot: settings.dev_server.hmr,
     contentBase: output.path,
+    inline: settings.dev_server.inline,
+    useLocalIp: settings.dev_server.use_local_ip,
+    public: settings.dev_server.public,
     publicPath: output.publicPath,
-    compress: true,
-    headers: { 'Access-Control-Allow-Origin': '*' },
-    historyApiFallback: true,
-    disableHostCheck: true,
-    watchOptions: watchOptions,
+    historyApiFallback: {
+      disableDotRule: true,
+    },
+    headers: settings.dev_server.headers,
+    overlay: settings.dev_server.overlay,
+    stats: {
+      entrypoints: false,
+      errorDetails: false,
+      modules: false,
+      moduleTrace: false,
+    },
+    watchOptions: Object.assign(
+      {},
+      settings.dev_server.watch_options,
+      watchOptions
+    ),
   },
 });
diff --git a/config/webpack/loaders/assets.js b/config/webpack/loaders/assets.js
deleted file mode 100644
index 643b3eeb0a8ad65d54f413c7bc626aef54593da5..0000000000000000000000000000000000000000
--- a/config/webpack/loaders/assets.js
+++ /dev/null
@@ -1,12 +0,0 @@
-const { env, publicPath } = require('../configuration.js');
-
-module.exports = {
-  test: /\.(jpg|jpeg|png|gif|svg|eot|ttf|woff|woff2)$/i,
-  use: [{
-    loader: 'file-loader',
-    options: {
-      publicPath,
-      name: env.NODE_ENV === 'production' ? '[name]-[hash].[ext]' : '[name].[ext]',
-    },
-  }],
-};
diff --git a/config/webpack/loaders/babel.js b/config/webpack/loaders/babel.js
deleted file mode 100644
index 7509617fdaa2a9e86d4b3bced21b7215f45dbffd..0000000000000000000000000000000000000000
--- a/config/webpack/loaders/babel.js
+++ /dev/null
@@ -1,12 +0,0 @@
-const { resolve } = require('path');
-
-const env = process.env.NODE_ENV || 'development';
-
-module.exports = {
-  test: /\.js$/,
-  exclude: /node_modules/,
-  loader: 'babel-loader',
-  options: {
-    cacheDirectory: env === 'development' ? false : resolve(__dirname, '..', '..', '..', 'tmp', 'cache', 'babel-loader'),
-  },
-};
diff --git a/config/webpack/loaders/babel_external.js b/config/webpack/loaders/babel_external.js
deleted file mode 100644
index 39e74ed90a5eec9ed4ef17c45a2557ff93e81380..0000000000000000000000000000000000000000
--- a/config/webpack/loaders/babel_external.js
+++ /dev/null
@@ -1,21 +0,0 @@
-const { resolve } = require('path');
-
-const env = process.env.NODE_ENV || 'development';
-
-if (env === 'development') {
-  module.exports = {};
-} else {
-  // babel options to apply only to external libraries, e.g. remove-prop-types
-  module.exports = {
-    test: /\.js$/,
-    include: /node_modules/,
-    loader: 'babel-loader',
-    options: {
-      babelrc: false,
-      plugins: [
-        'transform-react-remove-prop-types',
-      ],
-      cacheDirectory: env === 'development' ? false : resolve(__dirname, '..', '..', '..', 'tmp', 'cache', 'babel-loader-external'),
-    },
-  };
-}
diff --git a/config/webpack/production.js b/config/webpack/production.js
index d37e11792b5b5fb2da800175b50ddd0b3a67e938..bceffaf5c18e17c2d5b83f004c10bbedd5d8f452 100644
--- a/config/webpack/production.js
+++ b/config/webpack/production.js
@@ -1,15 +1,14 @@
 // Note: You must restart bin/webpack-dev-server for changes to take effect
 
-const merge = require('webpack-merge');
-const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
-const CompressionPlugin = require('compression-webpack-plugin');
-const zopfli = require('@gfx/zopfli');
-const sharedConfig = require('./shared.js');
-const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
-const OfflinePlugin = require('offline-plugin');
-const { publicPath } = require('./configuration.js');
 const path = require('path');
 const { URL } = require('url');
+const merge = require('webpack-merge');
+const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
+const OfflinePlugin = require('offline-plugin');
+const TerserPlugin = require('terser-webpack-plugin');
+const CompressionPlugin = require('compression-webpack-plugin');
+const { output } = require('./configuration');
+const sharedConfig = require('./shared');
 
 let attachmentHost;
 
@@ -28,55 +27,34 @@ if (process.env.S3_ENABLED === 'true') {
 
 module.exports = merge(sharedConfig, {
   mode: 'production',
-
-  output: {
-    filename: '[name]-[chunkhash].js',
-    chunkFilename: '[name]-[chunkhash].js',
-  },
-
-  devtool: 'source-map', // separate sourcemap file, suitable for production
+  devtool: 'source-map',
   stats: 'normal',
-
+  bail: true,
   optimization: {
     minimize: true,
     minimizer: [
-      new UglifyJsPlugin({
+      new TerserPlugin({
         cache: true,
         parallel: true,
         sourceMap: true,
-
-        uglifyOptions: {
-          compress: {
-            warnings: false,
-          },
-
-          output: {
-            comments: false,
-          },
-        },
       }),
     ],
   },
 
   plugins: [
     new CompressionPlugin({
-      algorithm(input, compressionOptions, callback) {
-        return zopfli.gzip(input, compressionOptions, callback);
-      },
-      test: /\.(js|css|html|json|ico|svg|eot|otf|ttf)$/,
+      filename: '[path].gz[query]',
+      cache: true,
+      test: /\.(js|css|html|json|ico|svg|eot|otf|ttf|map)$/,
     }),
-    new BundleAnalyzerPlugin({ // generates report.html and stats.json
+    new BundleAnalyzerPlugin({ // generates report.html
       analyzerMode: 'static',
-      generateStatsFile: true,
-      statsOptions: {
-        // allows usage with http://chrisbateman.github.io/webpack-visualizer/
-        chunkModules: true,
-      },
       openAnalyzer: false,
       logLevel: 'silent', // do not bother Webpacker, who runs with --json and parses stdout
     }),
     new OfflinePlugin({
-      publicPath: publicPath, // sw.js must be served from the root to avoid scope issues
+      publicPath: output.publicPath, // sw.js must be served from the root to avoid scope issues
+      safeToUseOptionalCaches: true,
       caches: {
         main: [':rest:'],
         additional: [':externals:'],
diff --git a/config/webpack/rules/babel.js b/config/webpack/rules/babel.js
new file mode 100644
index 0000000000000000000000000000000000000000..2fc245c432f6b93eb9b8890ccd7a92e4c81b0744
--- /dev/null
+++ b/config/webpack/rules/babel.js
@@ -0,0 +1,21 @@
+const { join, resolve } = require('path');
+const { env, settings } = require('../configuration');
+
+module.exports = {
+  test: /\.(js|jsx|mjs)$/,
+  include: [
+    settings.source_path,
+    ...settings.resolved_paths,
+  ].map(p => resolve(p)),
+  exclude: /node_modules/,
+  use: [
+    {
+      loader: 'babel-loader',
+      options: {
+        cacheDirectory: join(settings.cache_path, 'babel-loader'),
+        cacheCompression: env.NODE_ENV === 'production',
+        compact: env.NODE_ENV === 'production',
+      },
+    },
+  ],
+};
diff --git a/config/webpack/loaders/sass.js b/config/webpack/rules/css.js
similarity index 68%
rename from config/webpack/loaders/sass.js
rename to config/webpack/rules/css.js
index 67a1890b8f822117ff21d304f90494118a10ae4f..3b5b51232029fdfbda34b49a4408c11e073e4d70 100644
--- a/config/webpack/loaders/sass.js
+++ b/config/webpack/rules/css.js
@@ -4,7 +4,14 @@ module.exports = {
   test: /\.s?css$/i,
   use: [
     MiniCssExtractPlugin.loader,
-    'css-loader',
+    {
+      loader: 'css-loader',
+      options: {
+        sourceMap: true,
+        importLoaders: 2,
+        localIdentName: '[name]__[local]___[hash:base64:5]',
+      },
+    },
     {
       loader: 'postcss-loader',
       options: {
@@ -14,7 +21,6 @@ module.exports = {
     {
       loader: 'sass-loader',
       options: {
-        fiber: require('fibers'),
         implementation: require('sass'),
         sourceMap: true,
       },
diff --git a/config/webpack/rules/file.js b/config/webpack/rules/file.js
new file mode 100644
index 0000000000000000000000000000000000000000..f2fb58780103f96193efafa75738a7b495b70717
--- /dev/null
+++ b/config/webpack/rules/file.js
@@ -0,0 +1,20 @@
+const { join } = require('path');
+const { settings } = require('../configuration');
+
+module.exports = {
+  test: new RegExp(`(${settings.static_assets_extensions.join('|')})$`, 'i'),
+  use: [
+    {
+      loader: 'file-loader',
+      options: {
+        name(file) {
+          if (file.includes(settings.source_path)) {
+            return 'media/[path][name]-[hash].[ext]';
+          }
+          return 'media/[folder]/[name]-[hash:8].[ext]';
+        },
+        context: join(settings.source_path),
+      },
+    },
+  ],
+};
diff --git a/config/webpack/rules/index.js b/config/webpack/rules/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..bbf6b0187b173ff92f326a99ccfe412973dddadc
--- /dev/null
+++ b/config/webpack/rules/index.js
@@ -0,0 +1,14 @@
+const babel = require('./babel');
+const css = require('./css');
+const file = require('./file');
+const nodeModules = require('./node_modules');
+
+// Webpack loaders are processed in reverse order
+// https://webpack.js.org/concepts/loaders/#loader-features
+// Lastly, process static files using file loader
+module.exports = {
+  file,
+  css,
+  nodeModules,
+  babel,
+};
diff --git a/config/webpack/loaders/mark.js b/config/webpack/rules/mark.js
similarity index 100%
rename from config/webpack/loaders/mark.js
rename to config/webpack/rules/mark.js
diff --git a/config/webpack/rules/node_modules.js b/config/webpack/rules/node_modules.js
new file mode 100644
index 0000000000000000000000000000000000000000..7ed05504bf3d29fcdfccaab9171031b61da2d111
--- /dev/null
+++ b/config/webpack/rules/node_modules.js
@@ -0,0 +1,23 @@
+const { join } = require('path');
+const { settings, env } = require('../configuration');
+
+module.exports = {
+  test: /\.(js|mjs)$/,
+  include: /node_modules/,
+  exclude: /@babel(?:\/|\\{1,2})runtime/,
+  use: [
+    {
+      loader: 'babel-loader',
+      options: {
+        babelrc: false,
+        plugins: [
+          'transform-react-remove-prop-types',
+        ],
+        cacheDirectory: join(settings.cache_path, 'babel-loader-node-modules'),
+        cacheCompression: env.NODE_ENV === 'production',
+        compact: false,
+        sourceMaps: false,
+      },
+    },
+  ],
+};
diff --git a/config/webpack/shared.js b/config/webpack/shared.js
index d6199373b8458c9086e0a90dbbe261e145d76612..cb4e5a85f0e70eba3376c64a78a9fc8609961ca7 100644
--- a/config/webpack/shared.js
+++ b/config/webpack/shared.js
@@ -6,7 +6,8 @@ const { sync } = require('glob');
 const MiniCssExtractPlugin = require('mini-css-extract-plugin');
 const AssetsManifestPlugin = require('webpack-assets-manifest');
 const extname = require('path-complete-extname');
-const { env, settings, themes, output, loadersDir } = require('./configuration.js');
+const { env, settings, themes, output } = require('./configuration');
+const rules = require('./rules');
 const localePackPaths = require('./generateLocalePacks');
 
 const extensionGlob = `**/*{${settings.extensions.join(',')}}*`;
@@ -33,8 +34,9 @@ module.exports = {
   ),
 
   output: {
-    filename: '[name].js',
-    chunkFilename: '[name].js',
+    filename: 'js/[name]-[chunkhash].js',
+    chunkFilename: 'js/[name]-[chunkhash].chunk.js',
+    hotUpdateChunkFilename: 'js/[id]-[hash].hot-update.js',
     path: output.path,
     publicPath: output.publicPath,
   },
@@ -60,7 +62,7 @@ module.exports = {
   },
 
   module: {
-    rules: sync(join(loadersDir, '*.js')).map(loader => require(loader)),
+    rules: Object.keys(rules).map(key => rules[key]),
   },
 
   plugins: [
@@ -73,11 +75,14 @@ module.exports = {
       }
     ),
     new MiniCssExtractPlugin({
-      filename: env.NODE_ENV === 'production' ? '[name]-[contenthash].css' : '[name].css',
+      filename: 'css/[name]-[contenthash:8].css',
+      chunkFilename: 'css/[name]-[contenthash:8].chunk.css',
     }),
     new AssetsManifestPlugin({
-      publicPath: true,
+      integrity: false,
+      entrypoints: true,
       writeToDisk: true,
+      publicPath: true,
     }),
   ],
 
diff --git a/config/webpack/translationRunner.js b/config/webpack/translationRunner.js
index e6543fbb7f7b9a2e55566ee9d1210bb32eceb467..38050baf8d1550e31bc93e7f9b5ff9d5609b7b80 100644
--- a/config/webpack/translationRunner.js
+++ b/config/webpack/translationRunner.js
@@ -48,8 +48,7 @@ Use yarn "manage:translations -- --help" for usage information
   }
 };
 
-const { argv } = require('yargs')
-  .usage(`Usage: yarn manage:translations -- [OPTIONS] [LANGUAGES]
+const usage = `Usage: yarn manage:translations [OPTIONS] [LANGUAGES]
 
 Manage JavaScript translation files in Mastodon. Generates and update translations in translationsDirectory: ${translationsDirectory}
 
@@ -58,16 +57,15 @@ The RFC5646 language tag for the language you want to test or fix. If you want t
 
 Available languages:
 ${availableLanguages.join(', ')}
-`)
-  .help('h', 'show this message')
-  .alias('h', 'help')
-  .options({
-    f: {
-      alias: 'force',
-      default: false,
-      describe: 'force using the provided languages. create files if not exists.',
-      type: 'boolean',
-    },
+`;
+
+const { argv } = require('yargs')
+  .usage(usage)
+  .option('f', {
+    alias: 'force',
+    default: false,
+    describe: 'force using the provided languages. create files if not exists.',
+    type: 'boolean',
   });
 
 // check if message directory exists
diff --git a/config/webpacker.yml b/config/webpacker.yml
index ea814a0e65f6156c250551d3174205b2a5243689..4ad78a190ec4989d20a9d768a89d7834da1c5993 100644
--- a/config/webpacker.yml
+++ b/config/webpacker.yml
@@ -3,8 +3,11 @@
 default: &default
   source_path: app/javascript
   source_entry_path: packs
+  public_root_path: public
   public_output_path: packs
   cache_path: tmp/cache/webpacker
+  check_yarn_integrity: false
+  webpack_compile_output: false
 
   # Additional paths webpack should lookup modules
   # ['app/assets', 'engine/foo/app/assets']
@@ -13,11 +16,31 @@ default: &default
   # Reload manifest.json on all requests so we reload latest compiled packs
   cache_manifest: false
 
+  # Extract and emit a css file
+  extract_css: true
+
+  static_assets_extensions:
+    - .jpg
+    - .jpeg
+    - .png
+    - .tiff
+    - .ico
+    - .svg
+    - .eot
+    - .otf
+    - .ttf
+    - .woff
+    - .woff2
+
   extensions:
+    - .mjs
     - .js
     - .sass
     - .scss
     - .css
+    - .module.sass
+    - .module.scss
+    - .module.css
     - .png
     - .svg
     - .gif
@@ -26,24 +49,38 @@ default: &default
 
 development:
   <<: *default
+
   compile: true
 
+  # Reference: https://webpack.js.org/configuration/dev-server/
   dev_server:
+    https: false
     host: localhost
     port: 3035
+    public: localhost:3035
     hmr: false
-    https: false
+    # Inline should be set to true if using HMR
+    inline: true
+    overlay: true
+    compress: true
+    disable_host_check: true
+    use_local_ip: false
+    quiet: false
+    headers:
+      'Access-Control-Allow-Origin': '*'
+    watch_options:
+      ignored: '**/node_modules/**'
 
 test:
   <<: *default
 
-  # Compile test packs to a separate directory
-  public_output_path: packs-test
-
   # CircleCI precompiles packs prior to running the tests.
   # Also avoids race conditions in parallel_tests.
   compile: false
 
+  # Compile test packs to a separate directory
+  public_output_path: packs-test
+
 production:
   <<: *default
 
diff --git a/crowdin.yml b/crowdin.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f94417f2ed7b776f30cc4e90f01812319120fd2b
--- /dev/null
+++ b/crowdin.yml
@@ -0,0 +1,20 @@
+commit_message: "[ci skip]"
+files:
+  - source: /app/javascript/mastodon/locales/en.json
+    translation: /app/javascript/mastodon/locales/%two_letters_code%.json
+    update_option: update_as_unapproved
+  - source: /config/locales/en.yml
+    translation: /config/locales/%two_letters_code%.yml
+    update_option: update_as_unapproved
+  - source: /config/locales/simple_form.en.yml
+    translation: /config/locales/simple_form.%two_letters_code%.yml
+    update_option: update_as_unapproved
+  - source: /config/locales/activerecord.en.yml
+    translation: /config/locales/activerecord.%two_letters_code%.yml
+    update_option: update_as_unapproved
+  - source: /config/locales/devise.en.yml
+    translation: /config/locales/devise.%two_letters_code%.yml
+    update_option: update_as_unapproved
+  - source: /config/locales/doorkeeper.en.yml
+    translation: /config/locales/doorkeeper.%two_letters_code%.yml
+    update_option: update_as_unapproved
diff --git a/db/migrate/20171005102658_create_account_moderation_notes.rb b/db/migrate/20171005102658_create_account_moderation_notes.rb
index d1802b5b3c6d405e4128660529d7c0f63d5e9e32..010b94586e163ca5229d4b3323c6086ed76e0029 100644
--- a/db/migrate/20171005102658_create_account_moderation_notes.rb
+++ b/db/migrate/20171005102658_create_account_moderation_notes.rb
@@ -7,6 +7,7 @@ class CreateAccountModerationNotes < ActiveRecord::Migration[5.1]
 
       t.timestamps
     end
-    add_foreign_key :account_moderation_notes, :accounts, column: :target_account_id
+
+    safety_assured { add_foreign_key :account_moderation_notes, :accounts, column: :target_account_id }
   end
 end
diff --git a/db/migrate/20171010023049_add_foreign_key_to_account_moderation_notes.rb b/db/migrate/20171010023049_add_foreign_key_to_account_moderation_notes.rb
index fc1e1ab912594b7997e6da13c7679d13b9fcdb7c..cdcd159349895508142bcc936394d903ea4774bd 100644
--- a/db/migrate/20171010023049_add_foreign_key_to_account_moderation_notes.rb
+++ b/db/migrate/20171010023049_add_foreign_key_to_account_moderation_notes.rb
@@ -1,5 +1,5 @@
 class AddForeignKeyToAccountModerationNotes < ActiveRecord::Migration[5.1]
   def change
-    add_foreign_key :account_moderation_notes, :accounts
+    safety_assured { add_foreign_key :account_moderation_notes, :accounts }
   end
 end
diff --git a/db/migrate/20171118012443_add_moved_to_account_id_to_accounts.rb b/db/migrate/20171118012443_add_moved_to_account_id_to_accounts.rb
index 0c8a894cca27c9105e4561f00f31032e454fb62d..586ef6f02d26dc92a7cc012bf98074585843a9cd 100644
--- a/db/migrate/20171118012443_add_moved_to_account_id_to_accounts.rb
+++ b/db/migrate/20171118012443_add_moved_to_account_id_to_accounts.rb
@@ -1,6 +1,6 @@
 class AddMovedToAccountIdToAccounts < ActiveRecord::Migration[5.1]
   def change
     add_column :accounts, :moved_to_account_id, :bigint, null: true, default: nil
-    add_foreign_key :accounts, :accounts, column: :moved_to_account_id, on_delete: :nullify
+    safety_assured { add_foreign_key :accounts, :accounts, column: :moved_to_account_id, on_delete: :nullify }
   end
 end
diff --git a/db/migrate/20180402040909_create_report_notes.rb b/db/migrate/20180402040909_create_report_notes.rb
index 732ddf8259cb8d1168a8ac8ee6cc32a6b91b5c92..429cb453495d015e84074f74b165d9b06b30a0ac 100644
--- a/db/migrate/20180402040909_create_report_notes.rb
+++ b/db/migrate/20180402040909_create_report_notes.rb
@@ -8,7 +8,7 @@ class CreateReportNotes < ActiveRecord::Migration[5.1]
       t.timestamps
     end
 
-    add_foreign_key :report_notes, :reports, column: :report_id, on_delete: :cascade
-    add_foreign_key :report_notes, :accounts, column: :account_id, on_delete: :cascade
+    safety_assured { add_foreign_key :report_notes, :reports, column: :report_id, on_delete: :cascade }
+    safety_assured { add_foreign_key :report_notes, :accounts, column: :account_id, on_delete: :cascade }
   end
 end
diff --git a/db/migrate/20181116173541_copy_account_stats.rb b/db/migrate/20181116173541_copy_account_stats.rb
index bb523fbbd31c3fadab0d3d5241100d0437391d02..8e27eb11b57d71372256c6d3ba00883b07627f3d 100644
--- a/db/migrate/20181116173541_copy_account_stats.rb
+++ b/db/migrate/20181116173541_copy_account_stats.rb
@@ -44,7 +44,7 @@ class CopyAccountStats < ActiveRecord::Migration[5.2]
     # uniqueness violations that we need to skip over
     Account.unscoped.select('id, statuses_count, following_count, followers_count, created_at, updated_at').find_each do |account|
       begin
-        params = [[nil, account.id], [nil, account.statuses_count], [nil, account.following_count], [nil, account.followers_count], [nil, account.created_at], [nil, account.updated_at]]
+        params = [[nil, account.id], [nil, account[:statuses_count]], [nil, account[:following_count]], [nil, account[:followers_count]], [nil, account.created_at], [nil, account.updated_at]]
         exec_insert('INSERT INTO account_stats (account_id, statuses_count, following_count, followers_count, created_at, updated_at) VALUES ($1, $2, $3, $4, $5, $6)', nil, params)
       rescue ActiveRecord::RecordNotUnique
         next
diff --git a/db/migrate/20190201012802_add_overwrite_to_imports.rb b/db/migrate/20190201012802_add_overwrite_to_imports.rb
new file mode 100644
index 0000000000000000000000000000000000000000..89b262cc72363266dfd38860ac833a635ae995a9
--- /dev/null
+++ b/db/migrate/20190201012802_add_overwrite_to_imports.rb
@@ -0,0 +1,17 @@
+require Rails.root.join('lib', 'mastodon', 'migration_helpers')
+
+class AddOverwriteToImports < ActiveRecord::Migration[5.2]
+  include Mastodon::MigrationHelpers
+
+  disable_ddl_transaction!
+
+  def up
+    safety_assured do
+      add_column_with_default :imports, :overwrite, :boolean, default: false, allow_null: false
+    end
+  end
+
+  def down
+    remove_column :imports, :overwrite, :boolean
+  end
+end
diff --git a/db/migrate/20190203180359_create_featured_tags.rb b/db/migrate/20190203180359_create_featured_tags.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b08410a3a7d983f2832ef02f299f454bc49b0488
--- /dev/null
+++ b/db/migrate/20190203180359_create_featured_tags.rb
@@ -0,0 +1,12 @@
+class CreateFeaturedTags < ActiveRecord::Migration[5.2]
+  def change
+    create_table :featured_tags do |t|
+      t.references :account, foreign_key: { on_delete: :cascade }
+      t.references :tag, foreign_key: { on_delete: :cascade }
+      t.bigint :statuses_count, default: 0, null: false
+      t.datetime :last_status_at
+
+      t.timestamps
+    end
+  end
+end
diff --git a/db/migrate/20190225031541_create_polls.rb b/db/migrate/20190225031541_create_polls.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ea9ad0425fcdd086a8f3544028145c0d07e3de28
--- /dev/null
+++ b/db/migrate/20190225031541_create_polls.rb
@@ -0,0 +1,17 @@
+class CreatePolls < ActiveRecord::Migration[5.2]
+  def change
+    create_table :polls do |t|
+      t.belongs_to :account, foreign_key: { on_delete: :cascade }
+      t.belongs_to :status, foreign_key: { on_delete: :cascade }
+      t.datetime :expires_at
+      t.string :options, null: false, array: true, default: []
+      t.bigint :cached_tallies, null: false, array: true, default: []
+      t.boolean :multiple, null: false, default: false
+      t.boolean :hide_totals, null: false, default: false
+      t.bigint :votes_count, null: false, default: 0
+      t.datetime :last_fetched_at
+
+      t.timestamps
+    end
+  end
+end
diff --git a/db/migrate/20190225031625_create_poll_votes.rb b/db/migrate/20190225031625_create_poll_votes.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a0849d3a555ec72b5086c7b11b257f72af488ea5
--- /dev/null
+++ b/db/migrate/20190225031625_create_poll_votes.rb
@@ -0,0 +1,11 @@
+class CreatePollVotes < ActiveRecord::Migration[5.2]
+  def change
+    create_table :poll_votes do |t|
+      t.belongs_to :account, foreign_key: { on_delete: :cascade }
+      t.belongs_to :poll, foreign_key: { on_delete: :cascade }
+      t.integer :choice, null: false, default: 0
+
+      t.timestamps
+    end
+  end
+end
diff --git a/db/migrate/20190226003449_add_poll_id_to_statuses.rb b/db/migrate/20190226003449_add_poll_id_to_statuses.rb
new file mode 100644
index 0000000000000000000000000000000000000000..692e8f814fc5d0b501422ff3787b9610e08b6be2
--- /dev/null
+++ b/db/migrate/20190226003449_add_poll_id_to_statuses.rb
@@ -0,0 +1,5 @@
+class AddPollIdToStatuses < ActiveRecord::Migration[5.2]
+  def change
+    add_column :statuses, :poll_id, :bigint
+  end
+end
diff --git a/db/migrate/20190304152020_add_uri_to_poll_votes.rb b/db/migrate/20190304152020_add_uri_to_poll_votes.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f6b81f1ba33a2535546f136da9b080af053c77f2
--- /dev/null
+++ b/db/migrate/20190304152020_add_uri_to_poll_votes.rb
@@ -0,0 +1,5 @@
+class AddUriToPollVotes < ActiveRecord::Migration[5.2]
+  def change
+    add_column :poll_votes, :uri, :string
+  end
+end
diff --git a/db/migrate/20190306145741_add_lock_version_to_polls.rb b/db/migrate/20190306145741_add_lock_version_to_polls.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5bb8cd3b48d717db9affac2c067a5bd7774f779e
--- /dev/null
+++ b/db/migrate/20190306145741_add_lock_version_to_polls.rb
@@ -0,0 +1,24 @@
+require Rails.root.join('lib', 'mastodon', 'migration_helpers')
+
+class AddLockVersionToPolls < ActiveRecord::Migration[5.2]
+  include Mastodon::MigrationHelpers
+
+  disable_ddl_transaction!
+
+  def up
+    safety_assured do
+      add_column_with_default(
+        :polls,
+        :lock_version,
+        :integer,
+        allow_null: false,
+        default: 0
+      )
+    end
+  end
+
+  def down
+    remove_column :polls, :lock_version
+  end
+end
+
diff --git a/db/migrate/20190307234537_add_approved_to_users.rb b/db/migrate/20190307234537_add_approved_to_users.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c57a66dbc3cb2e11503f97e44ef931689357487b
--- /dev/null
+++ b/db/migrate/20190307234537_add_approved_to_users.rb
@@ -0,0 +1,23 @@
+require Rails.root.join('lib', 'mastodon', 'migration_helpers')
+
+class AddApprovedToUsers < ActiveRecord::Migration[5.2]
+  include Mastodon::MigrationHelpers
+
+  disable_ddl_transaction!
+
+  def up
+    safety_assured do
+      add_column_with_default(
+        :users,
+        :approved,
+        :bool,
+        allow_null: false,
+        default: true
+      )
+    end
+  end
+
+  def down
+    remove_column :users, :approved
+  end
+end
diff --git a/db/migrate/20190314181829_migrate_open_registrations_setting.rb b/db/migrate/20190314181829_migrate_open_registrations_setting.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e5fe95009ec3f192a7e72d08c4e30a51af642cec
--- /dev/null
+++ b/db/migrate/20190314181829_migrate_open_registrations_setting.rb
@@ -0,0 +1,15 @@
+class MigrateOpenRegistrationsSetting < ActiveRecord::Migration[5.2]
+  def up
+    open_registrations = Setting.find_by(var: 'open_registrations')
+    return if open_registrations.nil? || open_registrations.value
+    setting = Setting.where(var: 'registrations_mode').first_or_initialize(var: 'registrations_mode')
+    setting.update(value: 'none')
+  end
+
+  def down
+    registrations_mode = Setting.find_by(var: 'registrations_mode')
+    return if registrations_mode.nil?
+    setting = Setting.where(var: 'open_registrations').first_or_initialize(var: 'open_registrations')
+    setting.update(value: registrations_mode.value == 'open')
+  end
+end
diff --git a/db/migrate/20190316190352_create_account_identity_proofs.rb b/db/migrate/20190316190352_create_account_identity_proofs.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ddcbce3f369be86927726f2ee6e91095f3da5e39
--- /dev/null
+++ b/db/migrate/20190316190352_create_account_identity_proofs.rb
@@ -0,0 +1,16 @@
+class CreateAccountIdentityProofs < ActiveRecord::Migration[5.2]
+  def change
+    create_table :account_identity_proofs do |t|
+      t.belongs_to :account, foreign_key: { on_delete: :cascade }
+      t.string :provider, null: false, default: ''
+      t.string :provider_username, null: false, default: ''
+      t.text :token, null: false, default: ''
+      t.boolean :verified, null: false, default: false
+      t.boolean :live, null: false, default: false
+
+      t.timestamps null: false
+    end
+
+    add_index :account_identity_proofs, [:account_id, :provider, :provider_username], unique: true, name: :index_account_proofs_on_account_and_provider_and_username
+  end
+end
diff --git a/db/migrate/20190317135723_add_uri_to_reports.rb b/db/migrate/20190317135723_add_uri_to_reports.rb
new file mode 100644
index 0000000000000000000000000000000000000000..47c0f2a21d36c6a2048aa488dc9de9842a5f17ce
--- /dev/null
+++ b/db/migrate/20190317135723_add_uri_to_reports.rb
@@ -0,0 +1,5 @@
+class AddUriToReports < ActiveRecord::Migration[5.2]
+  def change
+    add_column :reports, :uri, :string
+  end
+end
diff --git a/db/migrate/20190409054914_create_user_invite_requests.rb b/db/migrate/20190409054914_create_user_invite_requests.rb
new file mode 100644
index 0000000000000000000000000000000000000000..974e0f69feb4e70c530dfff1c4766c31208061f4
--- /dev/null
+++ b/db/migrate/20190409054914_create_user_invite_requests.rb
@@ -0,0 +1,10 @@
+class CreateUserInviteRequests < ActiveRecord::Migration[5.2]
+  def change
+    create_table :user_invite_requests do |t|
+      t.belongs_to :user, foreign_key: { on_delete: :cascade }
+      t.text :text
+
+      t.timestamps
+    end
+  end
+end
diff --git a/db/migrate/20190420025523_add_blurhash_to_media_attachments.rb b/db/migrate/20190420025523_add_blurhash_to_media_attachments.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f2bbe0a856c18cb11d8247ac006dc425f69ec6c9
--- /dev/null
+++ b/db/migrate/20190420025523_add_blurhash_to_media_attachments.rb
@@ -0,0 +1,5 @@
+class AddBlurhashToMediaAttachments < ActiveRecord::Migration[5.2]
+  def change
+    add_column :media_attachments, :blurhash, :string
+  end
+end
diff --git a/db/migrate/20190509164208_add_by_moderator_to_tombstone.rb b/db/migrate/20190509164208_add_by_moderator_to_tombstone.rb
new file mode 100644
index 0000000000000000000000000000000000000000..80c2448428f4388821ac156e7e3e2d042a41b4d2
--- /dev/null
+++ b/db/migrate/20190509164208_add_by_moderator_to_tombstone.rb
@@ -0,0 +1,5 @@
+class AddByModeratorToTombstone < ActiveRecord::Migration[5.2]
+  def change
+    add_column :tombstones, :by_moderator, :boolean
+  end
+end
diff --git a/db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb b/db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1e5cd669c34bdc9d9829fe398bfa1558c6077603
--- /dev/null
+++ b/db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb
@@ -0,0 +1,41 @@
+class AddSilencedAtSuspendedAtToAccounts < ActiveRecord::Migration[5.2]
+  class Account < ApplicationRecord
+    # Dummy class, to make migration possible across version changes
+  end
+
+  class DomainBlock < ApplicationRecord
+    # Dummy class, to make migration possible across version changes
+    enum severity: [:silence, :suspend, :noop]
+
+    has_many :accounts, foreign_key: :domain, primary_key: :domain
+  end
+
+  def up
+    add_column :accounts, :silenced_at, :datetime
+    add_column :accounts, :suspended_at, :datetime
+
+    # Record suspend date of blocks and silences for users whose limitations match
+    # a domain block
+    DomainBlock.where(severity: [:silence, :suspend]).find_each do |block|
+      scope = block.accounts
+      if block.suspend?
+        block.accounts.where(suspended: true).in_batches.update_all(suspended_at: block.created_at)
+      else
+        block.accounts.where(silenced: true).in_batches.update_all(silenced_at: block.created_at)
+      end
+    end
+
+    # Set dates for accounts which have limitations not related to a domain block
+    Account.where(suspended: true, suspended_at: nil).in_batches.update_all(suspended_at: Time.now.utc)
+    Account.where(silenced: true, silenced_at: nil).in_batches.update_all(silenced_at: Time.now.utc)
+  end
+
+  def down
+    # Block or silence accounts that have a date set
+    Account.where(suspended: false).where.not(suspended_at: nil).in_batches.update_all(suspended: true)
+    Account.where(silenced: false).where.not(silenced_at: nil).in_batches.update_all(silenced: true)
+
+    remove_column :accounts, :silenced_at
+    remove_column :accounts, :suspended_at
+  end
+end
diff --git a/db/migrate/20190529143559_preserve_old_layout_for_existing_users.rb b/db/migrate/20190529143559_preserve_old_layout_for_existing_users.rb
new file mode 100644
index 0000000000000000000000000000000000000000..72b7c609d17acf08d67c88218dca7d0b599a2580
--- /dev/null
+++ b/db/migrate/20190529143559_preserve_old_layout_for_existing_users.rb
@@ -0,0 +1,17 @@
+class PreserveOldLayoutForExistingUsers < ActiveRecord::Migration[5.2]
+  disable_ddl_transaction!
+
+  def up
+    # Assume that currently active users are already using the layout that they
+    # want to use, therefore ensure that it is saved explicitly and not based
+    # on the to-be-changed default
+
+    User.where(User.arel_table[:current_sign_in_at].gteq(1.month.ago)).find_each do |user|
+      next if Setting.unscoped.where(thing_type: 'User', thing_id: user.id, var: 'advanced_layout').exists?
+      user.settings.advanced_layout = true
+    end
+  end
+
+  def down
+  end
+end
diff --git a/db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb b/db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a46349cb73aa11f4998054931b6322b864b14a7e
--- /dev/null
+++ b/db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+class RemoveSuspendedSilencedAccountFields < ActiveRecord::Migration[5.2]
+  class Account < ApplicationRecord
+    # Dummy class, to make migration possible across version changes
+  end
+
+  class DomainBlock < ApplicationRecord
+    # Dummy class, to make migration possible across version changes
+    enum severity: [:silence, :suspend, :noop]
+
+    has_many :accounts, foreign_key: :domain, primary_key: :domain
+  end
+
+  disable_ddl_transaction!
+
+  def up
+    # Record suspend date of blocks and silences for users whose limitations match
+    # a domain block
+    DomainBlock.where(severity: [:silence, :suspend]).find_each do |block|
+      scope = block.accounts
+      if block.suspend?
+        block.accounts.where(suspended: true).in_batches.update_all(suspended_at: block.created_at)
+      else
+        block.accounts.where(silenced: true).in_batches.update_all(silenced_at: block.created_at)
+      end
+    end
+
+    # Set dates for accounts which have limitations not related to a domain block
+    Account.where(suspended: true, suspended_at: nil).in_batches.update_all(suspended_at: Time.now.utc)
+    Account.where(silenced: true, silenced_at: nil).in_batches.update_all(silenced_at: Time.now.utc)
+
+    safety_assured do
+      remove_column :accounts, :suspended, :boolean, null: false, default: false
+      remove_column :accounts, :silenced, :boolean, null: false, default: false
+    end
+  end
+
+  def down
+    safety_assured do
+      add_column :accounts, :suspended, :boolean, null: false, default: false
+      add_column :accounts, :silenced, :boolean, null: false, default: false
+    end
+  end
+end
diff --git a/db/post_migrate/20190519130537_remove_boosts_widening_audience.rb b/db/post_migrate/20190519130537_remove_boosts_widening_audience.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d2d924239229d3ce68afd9d794748528c92ce000
--- /dev/null
+++ b/db/post_migrate/20190519130537_remove_boosts_widening_audience.rb
@@ -0,0 +1,23 @@
+class RemoveBoostsWideningAudience < ActiveRecord::Migration[5.2]
+  disable_ddl_transaction!
+
+  def up
+    public_boosts = Status.find_by_sql(<<-SQL)
+      SELECT boost.id
+      FROM statuses AS boost
+      LEFT JOIN statuses AS boosted ON boost.reblog_of_id = boosted.id
+      WHERE
+        boost.id > 101746055577600000
+        AND (boost.local = TRUE OR boost.uri IS NULL)
+        AND boost.visibility IN (0, 1)
+        AND boost.reblog_of_id IS NOT NULL
+        AND boosted.visibility = 2
+    SQL
+
+    RemovalWorker.push_bulk(public_boosts.pluck(:id))
+  end
+
+  def down
+    raise ActiveRecord::IrreversibleMigration
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 3487adf08852c02983c7408dbff3d84356aae99d..f633f4e3fb7df7dcff0ad5a01a629e32593dd2ae 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 2019_01_17_114553) do
+ActiveRecord::Schema.define(version: 2019_05_29_143559) do
 
   # These are extensions that must be enabled in order to support this database
   enable_extension "plpgsql"
@@ -36,6 +36,19 @@ ActiveRecord::Schema.define(version: 2019_01_17_114553) do
     t.index ["account_id", "domain"], name: "index_account_domain_blocks_on_account_id_and_domain", unique: true
   end
 
+  create_table "account_identity_proofs", force: :cascade do |t|
+    t.bigint "account_id"
+    t.string "provider", default: "", null: false
+    t.string "provider_username", default: "", null: false
+    t.text "token", default: "", null: false
+    t.boolean "verified", default: false, null: false
+    t.boolean "live", default: false, null: false
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+    t.index ["account_id", "provider", "provider_username"], name: "index_account_proofs_on_account_and_provider_and_username", unique: true
+    t.index ["account_id"], name: "index_account_identity_proofs_on_account_id"
+  end
+
   create_table "account_moderation_notes", force: :cascade do |t|
     t.text "content", null: false
     t.bigint "account_id", null: false
@@ -118,8 +131,6 @@ ActiveRecord::Schema.define(version: 2019_01_17_114553) do
     t.datetime "header_updated_at"
     t.string "avatar_remote_url"
     t.datetime "subscription_expires_at"
-    t.boolean "silenced", default: false, null: false
-    t.boolean "suspended", default: false, null: false
     t.boolean "locked", default: false, null: false
     t.string "header_remote_url", default: "", null: false
     t.datetime "last_webfingered_at"
@@ -135,6 +146,8 @@ ActiveRecord::Schema.define(version: 2019_01_17_114553) do
     t.string "actor_type"
     t.boolean "discoverable"
     t.string "also_known_as", array: true
+    t.datetime "silenced_at"
+    t.datetime "suspended_at"
     t.index "(((setweight(to_tsvector('simple'::regconfig, (display_name)::text), 'A'::\"char\") || setweight(to_tsvector('simple'::regconfig, (username)::text), 'B'::\"char\")) || setweight(to_tsvector('simple'::regconfig, (COALESCE(domain, ''::character varying))::text), 'C'::\"char\")))", name: "search_index", using: :gin
     t.index "lower((username)::text), lower((domain)::text)", name: "index_accounts_on_username_and_domain_lower", unique: true
     t.index ["moved_to_account_id"], name: "index_accounts_on_moved_to_account_id"
@@ -250,6 +263,17 @@ ActiveRecord::Schema.define(version: 2019_01_17_114553) do
     t.index ["status_id"], name: "index_favourites_on_status_id"
   end
 
+  create_table "featured_tags", force: :cascade do |t|
+    t.bigint "account_id"
+    t.bigint "tag_id"
+    t.bigint "statuses_count", default: 0, null: false
+    t.datetime "last_status_at"
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+    t.index ["account_id"], name: "index_featured_tags_on_account_id"
+    t.index ["tag_id"], name: "index_featured_tags_on_tag_id"
+  end
+
   create_table "follow_requests", force: :cascade do |t|
     t.datetime "created_at", null: false
     t.datetime "updated_at", null: false
@@ -290,6 +314,7 @@ ActiveRecord::Schema.define(version: 2019_01_17_114553) do
     t.integer "data_file_size"
     t.datetime "data_updated_at"
     t.bigint "account_id", null: false
+    t.boolean "overwrite", default: false, null: false
   end
 
   create_table "invites", force: :cascade do |t|
@@ -337,6 +362,7 @@ ActiveRecord::Schema.define(version: 2019_01_17_114553) do
     t.bigint "account_id"
     t.text "description"
     t.bigint "scheduled_status_id"
+    t.string "blurhash"
     t.index ["account_id"], name: "index_media_attachments_on_account_id"
     t.index ["scheduled_status_id"], name: "index_media_attachments_on_scheduled_status_id"
     t.index ["shortcode"], name: "index_media_attachments_on_shortcode", unique: true
@@ -356,9 +382,9 @@ ActiveRecord::Schema.define(version: 2019_01_17_114553) do
   create_table "mutes", force: :cascade do |t|
     t.datetime "created_at", null: false
     t.datetime "updated_at", null: false
+    t.boolean "hide_notifications", default: true, null: false
     t.bigint "account_id", null: false
     t.bigint "target_account_id", null: false
-    t.boolean "hide_notifications", default: true, null: false
     t.index ["account_id", "target_account_id"], name: "index_mutes_on_account_id_and_target_account_id", unique: true
     t.index ["target_account_id"], name: "index_mutes_on_target_account_id"
   end
@@ -429,6 +455,34 @@ ActiveRecord::Schema.define(version: 2019_01_17_114553) do
     t.index ["database", "captured_at"], name: "index_pghero_space_stats_on_database_and_captured_at"
   end
 
+  create_table "poll_votes", force: :cascade do |t|
+    t.bigint "account_id"
+    t.bigint "poll_id"
+    t.integer "choice", default: 0, null: false
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+    t.string "uri"
+    t.index ["account_id"], name: "index_poll_votes_on_account_id"
+    t.index ["poll_id"], name: "index_poll_votes_on_poll_id"
+  end
+
+  create_table "polls", force: :cascade do |t|
+    t.bigint "account_id"
+    t.bigint "status_id"
+    t.datetime "expires_at"
+    t.string "options", default: [], null: false, array: true
+    t.bigint "cached_tallies", default: [], null: false, array: true
+    t.boolean "multiple", default: false, null: false
+    t.boolean "hide_totals", default: false, null: false
+    t.bigint "votes_count", default: 0, null: false
+    t.datetime "last_fetched_at"
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+    t.integer "lock_version", default: 0, null: false
+    t.index ["account_id"], name: "index_polls_on_account_id"
+    t.index ["status_id"], name: "index_polls_on_status_id"
+  end
+
   create_table "preview_cards", force: :cascade do |t|
     t.string "url", default: "", null: false
     t.string "title", default: "", null: false
@@ -485,6 +539,7 @@ ActiveRecord::Schema.define(version: 2019_01_17_114553) do
     t.bigint "action_taken_by_account_id"
     t.bigint "target_account_id", null: false
     t.bigint "assigned_account_id"
+    t.string "uri"
     t.index ["account_id"], name: "index_reports_on_account_id"
     t.index ["target_account_id"], name: "index_reports_on_target_account_id"
   end
@@ -569,6 +624,7 @@ ActiveRecord::Schema.define(version: 2019_01_17_114553) do
     t.bigint "account_id", null: false
     t.bigint "application_id"
     t.bigint "in_reply_to_account_id"
+    t.bigint "poll_id"
     t.index ["account_id", "id", "visibility", "updated_at"], name: "index_statuses_20180106", order: { id: :desc }
     t.index ["in_reply_to_account_id"], name: "index_statuses_on_in_reply_to_account_id"
     t.index ["in_reply_to_id"], name: "index_statuses_on_in_reply_to_id"
@@ -620,10 +676,19 @@ ActiveRecord::Schema.define(version: 2019_01_17_114553) do
     t.string "uri", null: false
     t.datetime "created_at", null: false
     t.datetime "updated_at", null: false
+    t.boolean "by_moderator"
     t.index ["account_id"], name: "index_tombstones_on_account_id"
     t.index ["uri"], name: "index_tombstones_on_uri"
   end
 
+  create_table "user_invite_requests", force: :cascade do |t|
+    t.bigint "user_id"
+    t.text "text"
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+    t.index ["user_id"], name: "index_user_invite_requests_on_user_id"
+  end
+
   create_table "users", force: :cascade do |t|
     t.string "email", default: "", null: false
     t.datetime "created_at", null: false
@@ -658,6 +723,7 @@ ActiveRecord::Schema.define(version: 2019_01_17_114553) do
     t.string "remember_token"
     t.string "chosen_languages", array: true
     t.bigint "created_by_application_id"
+    t.boolean "approved", default: true, null: false
     t.index ["account_id"], name: "index_users_on_account_id"
     t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
     t.index ["created_by_application_id"], name: "index_users_on_created_by_application_id"
@@ -689,6 +755,7 @@ ActiveRecord::Schema.define(version: 2019_01_17_114553) do
   add_foreign_key "account_conversations", "accounts", on_delete: :cascade
   add_foreign_key "account_conversations", "conversations", on_delete: :cascade
   add_foreign_key "account_domain_blocks", "accounts", name: "fk_206c6029bd", on_delete: :cascade
+  add_foreign_key "account_identity_proofs", "accounts", on_delete: :cascade
   add_foreign_key "account_moderation_notes", "accounts"
   add_foreign_key "account_moderation_notes", "accounts", column: "target_account_id"
   add_foreign_key "account_pins", "accounts", column: "target_account_id", on_delete: :cascade
@@ -707,6 +774,8 @@ ActiveRecord::Schema.define(version: 2019_01_17_114553) do
   add_foreign_key "custom_filters", "accounts", on_delete: :cascade
   add_foreign_key "favourites", "accounts", name: "fk_5eb6c2b873", on_delete: :cascade
   add_foreign_key "favourites", "statuses", name: "fk_b0e856845e", on_delete: :cascade
+  add_foreign_key "featured_tags", "accounts", on_delete: :cascade
+  add_foreign_key "featured_tags", "tags", on_delete: :cascade
   add_foreign_key "follow_requests", "accounts", column: "target_account_id", name: "fk_9291ec025d", on_delete: :cascade
   add_foreign_key "follow_requests", "accounts", name: "fk_76d644b0e7", on_delete: :cascade
   add_foreign_key "follows", "accounts", column: "target_account_id", name: "fk_745ca29eac", on_delete: :cascade
@@ -732,6 +801,10 @@ ActiveRecord::Schema.define(version: 2019_01_17_114553) do
   add_foreign_key "oauth_access_tokens", "oauth_applications", column: "application_id", name: "fk_f5fc4c1ee3", on_delete: :cascade
   add_foreign_key "oauth_access_tokens", "users", column: "resource_owner_id", name: "fk_e84df68546", on_delete: :cascade
   add_foreign_key "oauth_applications", "users", column: "owner_id", name: "fk_b0988c7c0a", on_delete: :cascade
+  add_foreign_key "poll_votes", "accounts", on_delete: :cascade
+  add_foreign_key "poll_votes", "polls", on_delete: :cascade
+  add_foreign_key "polls", "accounts", on_delete: :cascade
+  add_foreign_key "polls", "statuses", on_delete: :cascade
   add_foreign_key "report_notes", "accounts", on_delete: :cascade
   add_foreign_key "report_notes", "reports", on_delete: :cascade
   add_foreign_key "reports", "accounts", column: "action_taken_by_account_id", name: "fk_bca45b75fd", on_delete: :nullify
@@ -753,6 +826,7 @@ ActiveRecord::Schema.define(version: 2019_01_17_114553) do
   add_foreign_key "stream_entries", "accounts", name: "fk_5659b17554", on_delete: :cascade
   add_foreign_key "subscriptions", "accounts", name: "fk_9847d1cbb5", on_delete: :cascade
   add_foreign_key "tombstones", "accounts", on_delete: :cascade
+  add_foreign_key "user_invite_requests", "users", on_delete: :cascade
   add_foreign_key "users", "accounts", name: "fk_50500f500d", on_delete: :cascade
   add_foreign_key "users", "invites", on_delete: :nullify
   add_foreign_key "users", "oauth_applications", column: "created_by_application_id", on_delete: :nullify
diff --git a/db/seeds.rb b/db/seeds.rb
index cf62ebf39ad562f88247682f069c37f47bbb724d..9a6e9dd78ed1edf0e061ff29b91670181eb469ab 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -4,5 +4,5 @@ if Rails.env.development?
   domain = ENV['LOCAL_DOMAIN'] || Rails.configuration.x.local_domain
   admin  = Account.where(username: 'admin').first_or_initialize(username: 'admin')
   admin.save(validate: false)
-  User.where(email: "admin@#{domain}").first_or_initialize(email: "admin@#{domain}", password: 'mastodonadmin', password_confirmation: 'mastodonadmin', confirmed_at: Time.now.utc, admin: true, account: admin, agreement: true).save!
+  User.where(email: "admin@#{domain}").first_or_initialize(email: "admin@#{domain}", password: 'mastodonadmin', password_confirmation: 'mastodonadmin', confirmed_at: Time.now.utc, admin: true, account: admin, agreement: true, approved: true).save!
 end
diff --git a/dist/mastodon-streaming.service b/dist/mastodon-streaming.service
index 5d7c129dfbbff5d17e7535f25982e351259fca01..c324fccf467aab18aed0ccad3f9d017045730b66 100644
--- a/dist/mastodon-streaming.service
+++ b/dist/mastodon-streaming.service
@@ -9,7 +9,7 @@ WorkingDirectory=/home/mastodon/live
 Environment="NODE_ENV=production"
 Environment="PORT=4000"
 Environment="STREAMING_CLUSTER_NUM=1"
-ExecStart=/usr/bin/npm run start
+ExecStart=/usr/bin/node ./streaming
 TimeoutSec=15
 Restart=always
 
diff --git a/dist/nginx.conf b/dist/nginx.conf
index 3d57417657002af4d722ee3cfa11d82b0afc03d6..7c429bad42e5b25127db73d487968dd66e4e62e8 100644
--- a/dist/nginx.conf
+++ b/dist/nginx.conf
@@ -78,6 +78,7 @@ server {
 
     proxy_cache CACHE;
     proxy_cache_valid 200 7d;
+    proxy_cache_valid 410 24h;
     proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
     add_header X-Cached $upstream_cache_status;
     add_header Strict-Transport-Security "max-age=31536000";
diff --git a/docker-compose.yml b/docker-compose.yml
index faa066149baf7938e027773ad8cab15e2146e203..7406849663e61280d44fcbfda16176692eaaee65 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -13,7 +13,7 @@ services:
 
   redis:
     restart: always
-    image: redis:4.0-alpine
+    image: redis:5.0-alpine
     networks:
       - internal_network
     healthcheck:
@@ -38,12 +38,12 @@ services:
     image: tootsuite/mastodon
     restart: always
     env_file: .env.production
-    command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000 -b '0.0.0.0'"
+    command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
     networks:
       - external_network
       - internal_network
     healthcheck:
-      test: ["CMD-SHELL", "wget -q --spider --header 'x-forwarded-proto: https' --proxy off localhost:3000/api/v1/instance || exit 1"]
+      test: ["CMD-SHELL", "wget -q --spider --header 'x-forwarded-proto: https' --proxy=off localhost:3000/api/v1/instance || exit 1"]
     ports:
       - "127.0.0.1:3000:3000"
     depends_on:
@@ -58,12 +58,12 @@ services:
     image: tootsuite/mastodon
     restart: always
     env_file: .env.production
-    command: yarn start
+    command: node ./streaming
     networks:
       - external_network
       - internal_network
     healthcheck:
-      test: ["CMD-SHELL", "wget -q --spider --header 'x-forwarded-proto: https' --proxy off localhost:4000/api/v1/streaming/health || exit 1"]
+      test: ["CMD-SHELL", "wget -q --spider --header 'x-forwarded-proto: https' --proxy=off localhost:4000/api/v1/streaming/health || exit 1"]
     ports:
       - "127.0.0.1:4000:4000"
     depends_on:
diff --git a/jest.config.js b/jest.config.js
deleted file mode 100644
index 50bde57e65fbb252f3ed1b021dbbd9bc6ea9fee0..0000000000000000000000000000000000000000
--- a/jest.config.js
+++ /dev/null
@@ -1,25 +0,0 @@
-module.exports = {
-  projects: [
-    '<rootDir>/app/javascript/mastodon',
-  ],
-  testPathIgnorePatterns: [
-    '<rootDir>/node_modules/',
-    '<rootDir>/vendor/',
-    '<rootDir>/config/',
-    '<rootDir>/log/',
-    '<rootDir>/public/',
-    '<rootDir>/tmp/',
-  ],
-  setupFiles: [
-    'raf/polyfill',
-  ],
-  setupTestFrameworkScriptFile: '<rootDir>/app/javascript/mastodon/test_setup.js',
-  collectCoverageFrom: [
-    'app/javascript/mastodon/**/*.js',
-    '!app/javascript/mastodon/features/emoji/emoji_compressed.js',
-    '!app/javascript/mastodon/locales/locale-data/*.js',
-    '!app/javascript/mastodon/service_worker/entry.js',
-    '!app/javascript/mastodon/test_setup.js',
-  ],
-  coverageDirectory: '<rootDir>/coverage',
-};
diff --git a/lib/cli.rb b/lib/cli.rb
index 6036adfbed7e03b1f9943d44793d2a15dca96138..be276583d22568659eaa77aabfaf313875f1867b 100644
--- a/lib/cli.rb
+++ b/lib/cli.rb
@@ -5,8 +5,11 @@ require_relative 'mastodon/media_cli'
 require_relative 'mastodon/emoji_cli'
 require_relative 'mastodon/accounts_cli'
 require_relative 'mastodon/feeds_cli'
+require_relative 'mastodon/search_cli'
 require_relative 'mastodon/settings_cli'
+require_relative 'mastodon/statuses_cli'
 require_relative 'mastodon/domains_cli'
+require_relative 'mastodon/cache_cli'
 require_relative 'mastodon/version'
 
 module Mastodon
@@ -27,12 +30,94 @@ module Mastodon
     desc 'feeds SUBCOMMAND ...ARGS', 'Manage feeds'
     subcommand 'feeds', Mastodon::FeedsCLI
 
+    desc 'search SUBCOMMAND ...ARGS', 'Manage the search engine'
+    subcommand 'search', Mastodon::SearchCLI
+
     desc 'settings SUBCOMMAND ...ARGS', 'Manage dynamic settings'
     subcommand 'settings', Mastodon::SettingsCLI
 
+    desc 'statuses SUBCOMMAND ...ARGS', 'Manage statuses'
+    subcommand 'statuses', Mastodon::StatusesCLI
+
     desc 'domains SUBCOMMAND ...ARGS', 'Manage account domains'
     subcommand 'domains', Mastodon::DomainsCLI
 
+    desc 'cache SUBCOMMAND ...ARGS', 'Manage cache'
+    subcommand 'cache', Mastodon::CacheCLI
+
+    option :dry_run, type: :boolean
+    desc 'self-destruct', 'Erase the server from the federation'
+    long_desc <<~LONG_DESC
+      Erase the server from the federation by broadcasting account delete
+      activities to all known other servers. This allows a "clean exit" from
+      running a Mastodon server, as it leaves next to no cache behind on
+      other servers.
+
+      This command is always interactive and requires confirmation twice.
+
+      No local data is actually deleted, because emptying the
+      database or removing files is much faster through other, external
+      means, such as e.g. deleting the entire VPS. However, because other
+      servers will delete data about local users, but no local data will be
+      updated (such as e.g. followers), there will be a state mismatch
+      that will lead to glitches and issues if you then continue to run and use
+      the server.
+
+      So either you know exactly what you are doing, or you are starting
+      from a blank slate afterwards by manually clearing out all the local
+      data!
+    LONG_DESC
+    def self_destruct
+      require 'tty-prompt'
+
+      prompt = TTY::Prompt.new
+
+      exit(1) unless prompt.ask('Type in the domain of the server to confirm:', required: true) == Rails.configuration.x.local_domain
+
+      prompt.warn('This operation WILL NOT be reversible. It can also take a long time.')
+      prompt.warn('While the data won\'t be erased locally, the server will be in a BROKEN STATE afterwards.')
+      prompt.warn('A running Sidekiq process is required. Do not shut it down until queues clear.')
+
+      exit(1) if prompt.no?('Are you sure you want to proceed?')
+
+      inboxes   = Account.inboxes
+      processed = 0
+      dry_run   = options[:dry_run] ? ' (DRY RUN)' : ''
+
+      if inboxes.empty?
+        prompt.ok('It seems like your server has not federated with anything')
+        prompt.ok('You can shut it down and delete it any time')
+        return
+      end
+
+      prompt.warn('Do NOT interrupt this process...')
+
+      Account.local.without_suspended.find_each do |account|
+        payload = ActiveModelSerializers::SerializableResource.new(
+          account,
+          serializer: ActivityPub::DeleteActorSerializer,
+          adapter: ActivityPub::Adapter
+        ).as_json
+
+        json = Oj.dump(ActivityPub::LinkedDataSignature.new(payload).sign!(account))
+
+        unless options[:dry_run]
+          ActivityPub::DeliveryWorker.push_bulk(inboxes) do |inbox_url|
+            [json, account.id, inbox_url]
+          end
+
+          account.suspend!
+        end
+
+        processed += 1
+      end
+
+      prompt.ok("Queued #{inboxes.size * processed} items into Sidekiq for #{processed} accounts#{dry_run}")
+      prompt.ok('Wait until Sidekiq processes all items, then you can shut everything down and delete the data')
+    rescue TTY::Reader::InputInterrupt
+      exit(1)
+    end
+
     map %w(--version -v) => :version
 
     desc 'version', 'Show version'
diff --git a/lib/mastodon/accounts_cli.rb b/lib/mastodon/accounts_cli.rb
index dca31cdca3e7bf4840ddb955662de4b0c578e8bd..7d02153131c89682fb062dfe239bdf8b2b661d73 100644
--- a/lib/mastodon/accounts_cli.rb
+++ b/lib/mastodon/accounts_cli.rb
@@ -73,7 +73,7 @@ module Mastodon
     def create(username)
       account  = Account.new(username: username)
       password = SecureRandom.hex
-      user     = User.new(email: options[:email], password: password, agreement: true, admin: options[:role] == 'admin', moderator: options[:role] == 'moderator', confirmed_at: options[:confirmed] ? Time.now.utc : nil)
+      user     = User.new(email: options[:email], password: password, agreement: true, approved: true, admin: options[:role] == 'admin', moderator: options[:role] == 'moderator', confirmed_at: options[:confirmed] ? Time.now.utc : nil)
 
       if options[:reattach]
         account = Account.find_local(username) || Account.new(username: username)
@@ -87,8 +87,8 @@ module Mastodon
         end
       end
 
-      account.suspended = false
-      user.account      = account
+      account.suspended_at = nil
+      user.account         = account
 
       if user.save
         if options[:confirmed]
@@ -115,6 +115,7 @@ module Mastodon
     option :enable, type: :boolean
     option :disable, type: :boolean
     option :disable_2fa, type: :boolean
+    option :approve, type: :boolean
     desc 'modify USERNAME', 'Modify a user'
     long_desc <<-LONG_DESC
       Modify a user account.
@@ -128,6 +129,9 @@ module Mastodon
       With the --disable option, lock the user out of their account. The
       --enable option is the opposite.
 
+      With the --approve option, the account will be approved, if it was
+      previously not due to not having open registrations.
+
       With the --disable-2fa option, the two-factor authentication
       requirement for the user can be removed.
     LONG_DESC
@@ -147,6 +151,7 @@ module Mastodon
       user.email = options[:email] if options[:email]
       user.disabled = false if options[:enable]
       user.disabled = true if options[:disable]
+      user.approved = true if options[:approve]
       user.otp_required_for_login = false if options[:disable_2fa]
       user.confirm if options[:confirm]
 
@@ -219,12 +224,14 @@ module Mastodon
     def cull
       skip_threshold = 7.days.ago
       culled         = 0
+      dry_run_culled = []
       skip_domains   = Set.new
       dry_run        = options[:dry_run] ? ' (DRY RUN)' : ''
 
       Account.remote.where(protocol: :activitypub).partitioned.find_each do |account|
         next if account.updated_at >= skip_threshold || (account.last_webfingered_at.present? && account.last_webfingered_at >= skip_threshold)
 
+        code = 0
         unless skip_domains.include?(account.domain)
           begin
             code = Request.new(:head, account.uri).perform(&:code)
@@ -236,11 +243,11 @@ module Mastodon
         end
 
         if [404, 410].include?(code)
-          unless options[:dry_run]
-            SuspendAccountService.new.call(account)
-            account.destroy
+          if options[:dry_run]
+            dry_run_culled << account.acct
+          else
+            SuspendAccountService.new.call(account, destroy: true)
           end
-
           culled += 1
           say('+', :green, false)
         else
@@ -256,6 +263,11 @@ module Mastodon
         say('The following servers were not available during the check:', :yellow)
         skip_domains.each { |domain| say('    ' + domain) }
       end
+
+      unless dry_run_culled.empty?
+        say('The following accounts would have been deleted:', :green)
+        dry_run_culled.each { |account| say('    ' + account) }
+      end
     end
 
     option :all, type: :boolean
@@ -360,6 +372,104 @@ module Mastodon
       say("OK, unfollowed target from #{processed} accounts, skipped #{failed}", :green)
     end
 
+    option :follows, type: :boolean, default: false
+    option :followers, type: :boolean, default: false
+    desc 'reset-relationships USERNAME', 'Reset all follows and/or followers for a user'
+    long_desc <<-LONG_DESC
+      Reset all follows and/or followers for a user specified by USERNAME.
+
+      With the --follows option, the command unfollows everyone that the account follows,
+      and then re-follows the users that would be followed by a brand new account.
+
+      With the --followers option, the command removes all followers of the account.
+    LONG_DESC
+    def reset_relationships(username)
+      unless options[:follows] || options[:followers]
+        say('Please specify either --follows or --followers, or both', :red)
+        exit(1)
+      end
+
+      account = Account.find_local(username)
+
+      if account.nil?
+        say('No user with such username', :red)
+        exit(1)
+      end
+
+      if options[:follows]
+        processed = 0
+        failed    = 0
+
+        say("Unfollowing #{account.username}'s followees, this might take a while...")
+
+        Account.where(id: ::Follow.where(account: account).select(:target_account_id)).find_each do |target_account|
+          begin
+            UnfollowService.new.call(account, target_account)
+            processed += 1
+            say('.', :green, false)
+          rescue StandardError
+            failed += 1
+            say('.', :red, false)
+          end
+        end
+
+        BootstrapTimelineWorker.perform_async(account.id)
+
+        say("OK, unfollowed #{processed} followees, skipped #{failed}", :green)
+      end
+
+      if options[:followers]
+        processed = 0
+        failed    = 0
+
+        say("Removing #{account.username}'s followers, this might take a while...")
+
+        Account.where(id: ::Follow.where(target_account: account).select(:account_id)).find_each do |target_account|
+          begin
+            UnfollowService.new.call(target_account, account)
+            processed += 1
+            say('.', :green, false)
+          rescue StandardError
+            failed += 1
+            say('.', :red, false)
+          end
+        end
+
+        say("OK, removed #{processed} followers, skipped #{failed}", :green)
+      end
+    end
+
+    option :number, type: :numeric, aliases: [:n]
+    option :all, type: :boolean
+    desc 'approve [USERNAME]', 'Approve pending accounts'
+    long_desc <<~LONG_DESC
+      When registrations require review from staff, approve pending accounts,
+      either all of them with the --all option, or a specific number of them
+      specified with the --number (-n) option, or only a single specific
+      account identified by its username.
+    LONG_DESC
+    def approve(username = nil)
+      if options[:all]
+        User.pending.find_each(&:approve!)
+        say('OK', :green)
+      elsif options[:number]
+        User.pending.limit(options[:number]).each(&:approve!)
+        say('OK', :green)
+      elsif username.present?
+        account = Account.find_local(username)
+
+        if account.nil?
+          say('No such account', :red)
+          exit(1)
+        end
+
+        account.user&.approve!
+        say('OK', :green)
+      else
+        exit(1)
+      end
+    end
+
     private
 
     def rotate_keys_for_account(account, delay = 0)
diff --git a/lib/mastodon/cache_cli.rb b/lib/mastodon/cache_cli.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e9b6667b3b610a5a0bbb4169a35a8c93e1698421
--- /dev/null
+++ b/lib/mastodon/cache_cli.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require_relative '../../config/boot'
+require_relative '../../config/environment'
+require_relative 'cli_helper'
+
+module Mastodon
+  class CacheCLI < Thor
+    def self.exit_on_failure?
+      true
+    end
+
+    desc 'clear', 'Clear out the cache storage'
+    def clear
+      Rails.cache.clear
+      say('OK', :green)
+    end
+  end
+end
diff --git a/lib/mastodon/domains_cli.rb b/lib/mastodon/domains_cli.rb
index 303b8a94a0f0be6cf5eaaed54dcb2421375152fb..b081581fe5797089d3e2a2f00c85209c33a303c8 100644
--- a/lib/mastodon/domains_cli.rb
+++ b/lib/mastodon/domains_cli.rb
@@ -28,10 +28,15 @@ module Mastodon
         say('.', :green, false)
       end
 
-      DomainBlock.where(domain: domain).destroy_all
+      DomainBlock.where(domain: domain).destroy_all unless options[:dry_run]
 
       say
       say("Removed #{removed} accounts#{dry_run}", :green)
+
+      custom_emojis = CustomEmoji.where(domain: domain)
+      custom_emojis_count = custom_emojis.count
+      custom_emojis.destroy_all unless options[:dry_run]
+      say("Removed #{custom_emojis_count} custom emojis", :green)
     end
 
     option :concurrency, type: :numeric, default: 50, aliases: [:c]
diff --git a/lib/mastodon/emoji_cli.rb b/lib/mastodon/emoji_cli.rb
index 2262040d49cbb0f0e3f8c0fc8e1a07e36497da3e..97a822e4558dead73b7f38948230477c8d1d17c5 100644
--- a/lib/mastodon/emoji_cli.rb
+++ b/lib/mastodon/emoji_cli.rb
@@ -15,9 +15,9 @@ module Mastodon
     option :suffix
     option :overwrite, type: :boolean
     option :unlisted, type: :boolean
-    desc 'import PATH', 'Import emoji from a TAR archive at PATH'
+    desc 'import PATH', 'Import emoji from a TAR GZIP archive at PATH'
     long_desc <<-LONG_DESC
-      Imports custom emoji from a TAR archive specified by PATH.
+      Imports custom emoji from a TAR GZIP archive specified by PATH.
 
       Existing emoji will be skipped unless the --overwrite option
       is provided, in which case they will be overwritten.
@@ -66,6 +66,12 @@ module Mastodon
       say("Imported #{imported}, skipped #{skipped}, failed to import #{failed}", color(imported, skipped, failed))
     end
 
+    desc 'purge', 'Remove all custom emoji'
+    def purge
+      CustomEmoji.in_batches.destroy_all
+      say('OK', :green)
+    end
+
     private
 
     def color(green, _yellow, red)
diff --git a/lib/mastodon/migration_helpers.rb b/lib/mastodon/migration_helpers.rb
index f5dc7e1c6ec15c3613a36212bf2f99f303077614..146eba8ec66e19af0e301de5e6ca2a0265954f7d 100644
--- a/lib/mastodon/migration_helpers.rb
+++ b/lib/mastodon/migration_helpers.rb
@@ -889,7 +889,7 @@ table #{table}.
 If you are using PostgreSQL you can solve this by logging in to the GitLab
 database (#{dbname}) using a super user and running:
 
-    ALTER #{user} WITH SUPERUSER
+    ALTER USER #{user} WITH SUPERUSER
 
 For MySQL you instead need to run:
 
diff --git a/lib/mastodon/search_cli.rb b/lib/mastodon/search_cli.rb
new file mode 100644
index 0000000000000000000000000000000000000000..42ad93f1edbfa271a7a9cd091a4848adcbc1165a
--- /dev/null
+++ b/lib/mastodon/search_cli.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require_relative '../../config/boot'
+require_relative '../../config/environment'
+require_relative 'cli_helper'
+
+module Mastodon
+  class SearchCLI < Thor
+    desc 'deploy', 'Create or update an ElasticSearch index and populate it'
+    long_desc <<~LONG_DESC
+      If ElasticSearch is empty, this command will create the necessary indices
+      and then import data from the database into those indices.
+
+      This command will also upgrade indices if the underlying schema has been
+      changed since the last run.
+    LONG_DESC
+    def deploy
+      processed = Chewy::RakeHelper.upgrade
+      Chewy::RakeHelper.sync(except: processed)
+    end
+  end
+end
diff --git a/lib/mastodon/settings_cli.rb b/lib/mastodon/settings_cli.rb
index c81cfbe520148ba0a3e91973555511ed5595577d..061650a80bb6f7a6203c5ac1f03fc646dd99e535 100644
--- a/lib/mastodon/settings_cli.rb
+++ b/lib/mastodon/settings_cli.rb
@@ -12,13 +12,13 @@ module Mastodon
 
     desc 'open', 'Open registrations'
     def open
-      Setting.open_registrations = true
+      Setting.registrations_mode = 'open'
       say('OK', :green)
     end
 
     desc 'close', 'Close registrations'
     def close
-      Setting.open_registrations = false
+      Setting.registrations_mode = 'none'
       say('OK', :green)
     end
   end
diff --git a/lib/mastodon/statuses_cli.rb b/lib/mastodon/statuses_cli.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7f2fbfa85d438f560c36ca282798de4ca9236234
--- /dev/null
+++ b/lib/mastodon/statuses_cli.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+require_relative '../../config/boot'
+require_relative '../../config/environment'
+require_relative 'cli_helper'
+
+module Mastodon
+  class StatusesCLI < Thor
+    include ActionView::Helpers::NumberHelper
+
+    def self.exit_on_failure?
+      true
+    end
+
+    option :days, type: :numeric, default: 90
+    desc 'remove', 'Remove unreferenced statuses'
+    long_desc <<~LONG_DESC
+      Remove statuses that are not referenced by local user activity, such as
+      ones that came from relays, or belonging to users that were once followed
+      by someone locally but no longer are.
+
+      This is a computationally heavy procedure that creates extra database
+      indicides before commencing, and removes them afterward.
+    LONG_DESC
+    def remove
+      say('Creating temporary database indices...')
+
+      ActiveRecord::Base.connection.add_index(:accounts, :id, name: :index_accounts_local, where: 'domain is null', algorithm: :concurrently) unless ActiveRecord::Base.connection.index_name_exists?(:accounts, :index_accounts_local)
+      ActiveRecord::Base.connection.add_index(:status_pins, :status_id, name: :index_status_pins_status_id, algorithm: :concurrently) unless ActiveRecord::Base.connection.index_name_exists?(:status_pins, :index_status_pins_status_id)
+      ActiveRecord::Base.connection.add_index(:media_attachments, :remote_url, name: :index_media_attachments_remote_url, where: 'remote_url is not null', algorithm: :concurrently) unless ActiveRecord::Base.connection.index_name_exists?(:media_attachments, :index_media_attachments_remote_url)
+
+      max_id   = Mastodon::Snowflake.id_at(options[:days].days.ago)
+      start_at = Time.now.to_f
+
+      say('Beginning removal... This might take a while...')
+
+      Status.remote
+            .where('id < ?', max_id)
+            .where(reblog_of_id: nil)                                                                                                                                                                                              # Skip reblogs
+            .where(in_reply_to_id: nil)                                                                                                                                                                                            # Skip replies
+            .where('id NOT IN (SELECT status_pins.status_id FROM status_pins WHERE statuses.id = status_id)')                                                                                                                      # Skip statuses that are pinned on profiles
+            .where('id NOT IN (SELECT mentions.status_id FROM mentions WHERE statuses.id = mentions.status_id AND mentions.account_id IN (SELECT accounts.id FROM accounts WHERE domain IS NULL))')                                # Skip statuses that mention local accounts
+            .where('id NOT IN (SELECT statuses1.in_reply_to_id FROM statuses AS statuses1 WHERE statuses.id = statuses1.in_reply_to_id)')                                                                                          # Skip statuses favourited by local accounts
+            .where('id NOT IN (SELECT statuses1.reblog_of_id FROM statuses AS statuses1 WHERE statuses.id = statuses1.reblog_of_id AND statuses1.account_id IN (SELECT accounts.id FROM accounts WHERE accounts.domain IS NULL))') # Skip statuses reblogged by local accounts
+            .where('account_id NOT IN (SELECT follows.target_account_id FROM follows WHERE statuses.account_id = follows.target_account_id)')                                                                                      # Skip accounts followed by local accounts
+            .in_batches
+            .delete_all
+
+      say('Beginning removal of now-orphaned media attachments to free up disk space...')
+
+      Scheduler::MediaCleanupScheduler.new.perform
+
+      say("Done after #{Time.now.to_f - start_at}s", :green)
+    ensure
+      say('Removing temporary database indices to restore write performance...')
+
+      ActiveRecord::Base.connection.remove_index(:accounts, name: :index_accounts_local) if ActiveRecord::Base.connection.index_name_exists?(:accounts, :index_accounts_local)
+      ActiveRecord::Base.connection.remove_index(:status_pins, name: :index_status_pins_status_id) if ActiveRecord::Base.connection.index_name_exists?(:status_pins, :index_status_pins_status_id)
+      ActiveRecord::Base.connection.remove_index(:media_attachments, name: :index_media_attachments_remote_url) if ActiveRecord::Base.connection.index_name_exists?(:media_attachments, :index_media_attachments_remote_url)
+    end
+  end
+end
diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb
index abbc31178d2d5770a994720bbd1031eec23cc961..99d709c980da5b516829314b91c727e0181c4de1 100644
--- a/lib/mastodon/version.rb
+++ b/lib/mastodon/version.rb
@@ -9,40 +9,40 @@ module Mastodon
     end
 
     def minor
-      7
+      9
     end
 
     def patch
-      0
+      3
     end
 
-    def pre
-      nil
+    def flags
+      ''
     end
 
-    def flags
+    def suffix
       ''
     end
 
     def to_a
-      [major, minor, patch, pre].compact
+      [major, minor, patch].compact
     end
 
     def to_s
-      [to_a.join('.'), flags].join
+      [to_a.join('.'), flags, suffix].join
     end
 
     def repository
-      'tootsuite/mastodon'
+      ENV.fetch('GITHUB_REPOSITORY') { 'tootsuite/mastodon' }
     end
 
     def source_base_url
-      "https://github.com/#{repository}"
+      ENV.fetch('SOURCE_BASE_URL') { "https://github.com/#{repository}" }
     end
 
     # specify git tag or commit hash here
     def source_tag
-      nil
+      ENV.fetch('SOURCE_TAG') { nil }
     end
 
     def source_url
diff --git a/lib/paperclip/blurhash_transcoder.rb b/lib/paperclip/blurhash_transcoder.rb
new file mode 100644
index 0000000000000000000000000000000000000000..08925a6dde01fd77fb27526ee2ae4278b88860fe
--- /dev/null
+++ b/lib/paperclip/blurhash_transcoder.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Paperclip
+  class BlurhashTranscoder < Paperclip::Processor
+    def make
+      return @file unless options[:style] == :small
+
+      pixels   = convert(':source RGB:-', source: File.expand_path(@file.path)).unpack('C*')
+      geometry = options.fetch(:file_geometry_parser).from_file(@file)
+
+      attachment.instance.blurhash = Blurhash.encode(geometry.width, geometry.height, pixels, options[:blurhash] || {})
+
+      @file
+    end
+  end
+end
diff --git a/lib/paperclip/type_corrector.rb b/lib/paperclip/type_corrector.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0b0c10a56e9965658599c9d8c4b5dfa5077c1c0e
--- /dev/null
+++ b/lib/paperclip/type_corrector.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'mime/types/columnar'
+
+module Paperclip
+  class TypeCorrector < Paperclip::Processor
+    def make
+      target_extension = options[:format]
+      extension        = File.extname(attachment.instance.file_file_name)
+
+      return @file unless options[:style] == :original && target_extension && extension != target_extension
+
+      attachment.instance.file_content_type = options[:content_type] || attachment.instance.file_content_type
+      attachment.instance.file_file_name    = File.basename(attachment.instance.file_file_name, '.*') + '.' + target_extension
+
+      @file
+    end
+  end
+end
diff --git a/nanobox/nginx-local.conf b/nanobox/nginx-local.conf
index c0e883603d2b0026ffb4e3b1b13226ac50786c75..37c8a451a35d58c3ddd5ba8330e24eea7d6e3291 100644
--- a/nanobox/nginx-local.conf
+++ b/nanobox/nginx-local.conf
@@ -10,10 +10,13 @@ http {
     sendfile on;
 
     gzip on;
-    gzip_http_version 1.0;
+    gzip_disable "MSIE [1-6]\.";
+    gzip_vary on;
     gzip_proxied any;
+    gzip_comp_level 6;
+    gzip_buffers 16 8k;
     gzip_min_length 500;
-    gzip_disable "MSIE [1-6]\.";
+    gzip_http_version 1.1;
     gzip_types text/plain text/xml text/javascript text/css text/comma-separated-values application/xml+rss application/xml application/x-javascript application/json application/javascript application/atom+xml;
 
     # Proxy upstream to the puma process
@@ -36,9 +39,12 @@ http {
         # Listen on port 8080
         listen 8080;
 
+        keepalive_timeout    70;
+        client_max_body_size 80M;
+
         root /app/public;
 
-        client_max_body_size 80M;
+        add_header Strict-Transport-Security "max-age=31536000";
 
         location / {
             try_files $uri @rails;
@@ -47,6 +53,10 @@ http {
         # Proxy connections to rails
         location @rails {
             proxy_set_header Host $host;
+            proxy_set_header X-Real-IP $remote_addr;
+            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+            proxy_set_header X-Forwarded-Proto https;
+            proxy_set_header Proxy "";
             proxy_pass_header Server;
 
             proxy_pass http://rails;
@@ -62,6 +72,10 @@ http {
         # Proxy connections to node
         location /api/v1/streaming {
             proxy_set_header Host $host;
+            proxy_set_header X-Real-IP $remote_addr;
+            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+            proxy_set_header X-Forwarded-Proto https;
+            proxy_set_header Proxy "";
 
             proxy_pass http://node;
             proxy_buffering off;
diff --git a/nanobox/nginx-stream.conf.erb b/nanobox/nginx-stream.conf.erb
index 12bcc8ca53ab5ba63074e797790753505af797bb..4ea6e30fc9aa044444c0c40cbcec5291d018f6fa 100644
--- a/nanobox/nginx-stream.conf.erb
+++ b/nanobox/nginx-stream.conf.erb
@@ -10,10 +10,13 @@ http {
     sendfile on;
 
     gzip on;
-    gzip_http_version 1.1;
+    gzip_disable "MSIE [1-6]\.";
+    gzip_vary on;
     gzip_proxied any;
+    gzip_comp_level 6;
+    gzip_buffers 16 8k;
     gzip_min_length 500;
-    gzip_disable "MSIE [1-6]\.";
+    gzip_http_version 1.1;
     gzip_types text/plain text/xml text/javascript text/css text/comma-separated-values application/xml+rss application/xml application/x-javascript application/json application/javascript application/atom+xml;
 
     # Proxy upstream to the node process
@@ -31,11 +34,13 @@ http {
         # Listen on port 8080
         listen 8080;
 
-        add_header Strict-Transport-Security "max-age=31536000";
-        # add_header Content-Security-Policy "style-src 'self' 'unsafe-inline'; script-src 'self'; object-src 'self'; img-src data: https:; media-src data: https:; connect-src 'self' wss://<%= ENV["LOCAL_DOMAIN"] %>; upgrade-insecure-requests";
+        keepalive_timeout    70;
+        client_max_body_size 80M;
 
         root /app/public;
 
+        add_header Strict-Transport-Security "max-age=31536000";
+
         location / {
             try_files $uri @node;
         }
@@ -43,6 +48,10 @@ http {
         # Proxy connections to node
         location @node {
             proxy_set_header Host $host;
+            proxy_set_header X-Real-IP $remote_addr;
+            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+            proxy_set_header X-Forwarded-Proto https;
+            proxy_set_header Proxy "";
 
             proxy_pass http://node;
             proxy_buffering off;
diff --git a/nanobox/nginx-web.conf.erb b/nanobox/nginx-web.conf.erb
index d96f1bfc7a740cfe90b60bb769b24e4f1eeb9968..182d9920993dcb5667e838e14f758f2254060cdc 100644
--- a/nanobox/nginx-web.conf.erb
+++ b/nanobox/nginx-web.conf.erb
@@ -10,10 +10,13 @@ http {
     sendfile on;
 
     gzip on;
-    gzip_http_version 1.0;
+    gzip_disable "MSIE [1-6]\.";
+    gzip_vary on;
     gzip_proxied any;
+    gzip_comp_level 6;
+    gzip_buffers 16 8k;
     gzip_min_length 500;
-    gzip_disable "MSIE [1-6]\.";
+    gzip_http_version 1.1;
     gzip_types text/plain text/xml text/javascript text/css text/comma-separated-values application/xml+rss application/xml application/x-javascript application/json application/javascript application/atom+xml;
 
     # Proxy upstream to the puma process
@@ -31,12 +34,12 @@ http {
         # Listen on port 8080
         listen 8080;
 
-        add_header Strict-Transport-Security "max-age=31536000";
-        # add_header Content-Security-Policy "style-src 'self' 'unsafe-inline'; script-src 'self'; object-src 'self'; img-src data: https:; media-src data: https:; connect-src 'self' wss://<%= ENV["LOCAL_DOMAIN"] %>; upgrade-insecure-requests";
+        keepalive_timeout    70;
+        client_max_body_size 80M;
 
         root /app/public;
 
-        client_max_body_size 80M;
+        add_header Strict-Transport-Security "max-age=31536000";
 
         location / {
             try_files $uri @rails;
@@ -44,17 +47,23 @@ http {
 
         location /sw.js {
             add_header Cache-Control "public, max-age=0";
+            add_header Strict-Transport-Security "max-age=31536000";
             try_files $uri @rails;
         }
 
         location ~ ^/(emoji|packs|system/media_attachments/files|system/accounts/avatars) {
             add_header Cache-Control "public, max-age=31536000, immutable";
+            add_header Strict-Transport-Security "max-age=31536000";
             try_files $uri @rails;
         }
 
         # Proxy connections to rails
         location @rails {
             proxy_set_header Host $host;
+            proxy_set_header X-Real-IP $remote_addr;
+            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+            proxy_set_header X-Forwarded-Proto https;
+            proxy_set_header Proxy "";
             proxy_pass_header Server;
 
             proxy_pass http://rails;
@@ -66,7 +75,10 @@ http {
 
             proxy_cache CACHE;
             proxy_cache_valid 200 7d;
+            proxy_cache_valid 410 24h;
             proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
+            add_header Strict-Transport-Security "max-age=31536000";
+            add_header X-Cached $upstream_cache_status;
 
             tcp_nodelay on;
         }
diff --git a/package.json b/package.json
index 5fa6fa8b7641700ae299f0b2ace36c3f4352dfad..c691d8e4345c5c1220a307461f933fb674a0a83d 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "name": "mastodon",
   "license": "AGPL-3.0-or-later",
   "engines": {
-    "node": ">=8 <11"
+    "node": ">=8.12 <12"
   },
   "scripts": {
     "postversion": "git push --tags",
@@ -10,8 +10,10 @@
     "build:production": "cross-env RAILS_ENV=production NODE_ENV=production ./bin/webpack",
     "manage:translations": "node ./config/webpack/translationRunner.js",
     "start": "node ./streaming/index.js",
-    "test": "${npm_execpath} run test:lint && ${npm_execpath} run test:jest",
-    "test:lint": "eslint --ext=js .",
+    "test": "${npm_execpath} run test:lint:js && ${npm_execpath} run test:jest",
+    "test:lint": "${npm_execpath} run test:lint:js && ${npm_execpath} run test:lint:sass",
+    "test:lint:js": "eslint --ext=js .",
+    "test:lint:sass": "sass-lint -v",
     "test:jest": "cross-env NODE_ENV=test jest --coverage"
   },
   "repository": {
@@ -24,57 +26,86 @@
     "iOS >= 9",
     "not dead"
   ],
+  "jest": {
+    "projects": [
+      "<rootDir>/app/javascript/mastodon"
+    ],
+    "testPathIgnorePatterns": [
+      "<rootDir>/node_modules/",
+      "<rootDir>/vendor/",
+      "<rootDir>/config/",
+      "<rootDir>/log/",
+      "<rootDir>/public/",
+      "<rootDir>/tmp/"
+    ],
+    "setupFiles": [
+      "raf/polyfill"
+    ],
+    "setupFilesAfterEnv": [
+      "<rootDir>/app/javascript/mastodon/test_setup.js"
+    ],
+    "collectCoverageFrom": [
+      "app/javascript/mastodon/**/*.js",
+      "!app/javascript/mastodon/features/emoji/emoji_compressed.js",
+      "!app/javascript/mastodon/locales/locale-data/*.js",
+      "!app/javascript/mastodon/service_worker/entry.js",
+      "!app/javascript/mastodon/test_setup.js"
+    ],
+    "coverageDirectory": "<rootDir>/coverage",
+    "moduleDirectories": [
+      "<rootDir>/node_modules",
+      "<rootDir>/app/javascript"
+    ]
+  },
   "private": true,
   "dependencies": {
-    "@babel/core": "^7.2.2",
-    "@babel/plugin-proposal-class-properties": "^7.2.3",
-    "@babel/plugin-proposal-decorators": "^7.2.3",
-    "@babel/plugin-proposal-object-rest-spread": "^7.2.0",
+    "@babel/core": "^7.4.5",
+    "@babel/plugin-proposal-class-properties": "^7.4.4",
+    "@babel/plugin-proposal-decorators": "^7.4.4",
+    "@babel/plugin-proposal-object-rest-spread": "^7.4.4",
     "@babel/plugin-syntax-dynamic-import": "^7.2.0",
     "@babel/plugin-transform-react-inline-elements": "^7.2.0",
     "@babel/plugin-transform-react-jsx-self": "^7.2.0",
     "@babel/plugin-transform-react-jsx-source": "^7.2.0",
-    "@babel/plugin-transform-runtime": "^7.2.0",
-    "@babel/preset-env": "^7.2.3",
+    "@babel/plugin-transform-runtime": "^7.4.4",
+    "@babel/preset-env": "^7.4.5",
     "@babel/preset-react": "^7.0.0",
-    "@babel/runtime": "^7.2.0",
-    "@gfx/zopfli": "^1.0.10",
+    "@babel/runtime": "^7.4.5",
+    "@clusterws/cws": "^0.14.0",
     "array-includes": "^3.0.3",
-    "autoprefixer": "^9.4.3",
-    "axios": "^0.18.0",
-    "babel-core": "^7.0.0-bridge.0",
-    "babel-loader": "^8.0.4",
+    "autoprefixer": "^9.6.0",
+    "axios": "^0.19.0",
+    "babel-loader": "^8.0.5",
     "babel-plugin-lodash": "^3.3.4",
     "babel-plugin-preval": "^3.0.1",
-    "babel-plugin-react-intl": "^3.0.1",
-    "babel-plugin-transform-react-remove-prop-types": "^0.4.21",
+    "babel-plugin-react-intl": "^3.1.3",
+    "babel-plugin-transform-react-remove-prop-types": "^0.4.24",
     "babel-runtime": "^6.26.0",
+    "blurhash": "^1.0.0",
     "classnames": "^2.2.5",
     "compression-webpack-plugin": "^2.0.0",
     "cross-env": "^5.1.4",
-    "css-loader": "^2.1.0",
-    "cssnano": "^4.1.8",
+    "css-loader": "^2.1.1",
+    "cssnano": "^4.1.10",
     "detect-passive-events": "^1.0.2",
-    "dotenv": "^6.2.0",
+    "dotenv": "^8.0.0",
     "emoji-mart": "Gargron/emoji-mart#build",
     "es6-symbol": "^3.1.1",
     "escape-html": "^1.0.3",
     "exif-js": "^2.3.0",
-    "express": "^4.16.4",
-    "fibers": "^3.1.1",
-    "file-loader": "^3.0.1",
+    "express": "^4.17.1",
+    "file-loader": "^4.0.0",
     "font-awesome": "^4.7.0",
     "glob": "^7.1.1",
-    "history": "^4.7.2",
     "http-link-header": "^1.0.2",
     "immutable": "^3.8.2",
     "imports-loader": "^0.8.0",
-    "intersection-observer": "^0.5.1",
+    "intersection-observer": "^0.7.0",
     "intl": "^1.2.5",
     "intl-messageformat": "^2.2.0",
-    "intl-relativeformat": "^2.1.0",
+    "intl-relativeformat": "^2.2.0",
     "is-nan": "^1.2.1",
-    "js-yaml": "^3.11.0",
+    "js-yaml": "^3.13.1",
     "lodash": "^4.7.11",
     "mark-loader": "^0.1.6",
     "marky": "^1.2.1",
@@ -83,77 +114,73 @@
     "npmlog": "^4.1.2",
     "object-assign": "^4.1.1",
     "object-fit-images": "^3.2.3",
-    "object.values": "^1.0.4",
-    "offline-plugin": "^5.0.6",
+    "object.values": "^1.1.0",
+    "offline-plugin": "^5.0.7",
     "path-complete-extname": "^1.0.0",
     "pg": "^6.4.0",
     "postcss-loader": "^3.0.0",
     "postcss-object-fit-images": "^1.1.2",
     "prop-types": "^15.5.10",
     "punycode": "^2.1.0",
-    "rails-ujs": "^5.2.2",
-    "react": "^16.7.0",
-    "react-dom": "^16.7.0",
+    "rails-ujs": "^5.2.3",
+    "react": "^16.8.6",
+    "react-dom": "^16.8.6",
     "react-hotkeys": "^1.1.4",
     "react-immutable-proptypes": "^2.1.0",
     "react-immutable-pure-component": "^1.1.1",
-    "react-intl": "^2.7.2",
+    "react-intl": "^2.9.0",
     "react-masonry-infinite": "^1.2.2",
     "react-motion": "^0.5.2",
     "react-notification": "^6.8.4",
     "react-overlays": "^0.8.3",
-    "react-redux": "^6.0.0",
+    "react-redux": "^6.0.1",
     "react-redux-loading-bar": "^4.0.8",
     "react-router-dom": "^4.1.1",
     "react-router-scroll-4": "^1.0.0-beta.1",
-    "react-select": "^2.2.0",
+    "react-select": "^2.4.4",
     "react-sparklines": "^1.7.0",
-    "react-swipeable-views": "^0.13.0",
+    "react-swipeable-views": "^0.13.3",
     "react-textarea-autosize": "^7.1.0",
     "react-toggle": "^4.0.1",
     "redis": "^2.7.1",
     "redux": "^4.0.1",
     "redux-immutable": "^4.0.0",
     "redux-thunk": "^2.2.0",
-    "rellax": "^1.7.1",
+    "rellax": "^1.10.0",
     "requestidlecallback": "^0.3.0",
     "reselect": "^4.0.0",
-    "rimraf": "^2.6.1",
-    "sass": "^1.15.2",
+    "rimraf": "^2.6.3",
+    "sass": "^1.20.3",
     "sass-loader": "^7.0.3",
     "stringz": "^1.0.0",
-    "style-loader": "0.23.1",
     "substring-trie": "^1.0.2",
+    "terser-webpack-plugin": "^1.3.0",
     "throng": "^4.0.0",
     "tiny-queue": "^0.2.1",
-    "uglifyjs-webpack-plugin": "^2.1.1",
     "uuid": "^3.1.0",
-    "uws": "10.148.0",
-    "webpack": "^4.28.3",
+    "webpack": "^4.34.0",
     "webpack-assets-manifest": "^3.1.1",
-    "webpack-bundle-analyzer": "^3.0.3",
-    "webpack-cli": "^3.1.2",
-    "webpack-merge": "^4.1.5",
+    "webpack-bundle-analyzer": "^3.3.2",
+    "webpack-cli": "^3.3.4",
+    "webpack-merge": "^4.2.1",
     "websocket.js": "^0.1.12"
   },
   "devDependencies": {
     "babel-eslint": "^10.0.1",
-    "babel-jest": "^23.6.0",
-    "enzyme": "^3.8.0",
-    "enzyme-adapter-react-16": "^1.7.1",
+    "babel-jest": "^24.8.0",
+    "enzyme": "^3.10.0",
+    "enzyme-adapter-react-16": "^1.14.0",
     "eslint": "^5.11.1",
-    "eslint-plugin-import": "~2.14.0",
-    "eslint-plugin-jsx-a11y": "~6.1.2",
-    "eslint-plugin-promise": "~4.0.1",
+    "eslint-plugin-import": "~2.17.3",
+    "eslint-plugin-jsx-a11y": "~6.2.1",
+    "eslint-plugin-promise": "~4.1.1",
     "eslint-plugin-react": "~7.12.1",
-    "jest": "^23.6.0",
+    "jest": "^24.8.0",
     "raf": "^3.4.1",
     "react-intl-translations-manager": "^5.0.3",
-    "react-test-renderer": "^16.7.0",
-    "webpack-dev-server": "^3.1.14",
-    "yargs": "^8.0.2"
-  },
-  "optionalDependencies": {
-    "fsevents": "*"
+    "react-test-renderer": "^16.8.6",
+    "sass-lint": "^1.13.1",
+    "webpack-dev-server": "^3.5.1",
+    "yargs": "^12.0.5"
   }
 }
diff --git a/public/oops.png b/public/oops.png
new file mode 100644
index 0000000000000000000000000000000000000000..1ac779f2551c4997c06851b0b41d0fb4ad24dee0
Binary files /dev/null and b/public/oops.png differ
diff --git a/public/robots.txt b/public/robots.txt
index 3c9c7c01f30b90e009de2d15952ae83230f8e37a..771bf2160b4e3bdc65981d3680ef1ae78925f79d 100644
--- a/public/robots.txt
+++ b/public/robots.txt
@@ -1,5 +1,5 @@
 # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
-#
-# To ban all spiders from the entire site uncomment the next two lines:
-# User-agent: *
-# Disallow: /
+
+User-agent: *
+Disallow: /media_proxy/
+Disallow: /interact/
diff --git a/spec/controllers/accounts_controller_spec.rb b/spec/controllers/accounts_controller_spec.rb
index 3ba5d8aec2d92bd6cc4b5fdd7b3edae1616e6348..b728d719f9dea829be2294a2a24d3e7fcbe91f3e 100644
--- a/spec/controllers/accounts_controller_spec.rb
+++ b/spec/controllers/accounts_controller_spec.rb
@@ -3,7 +3,7 @@ require 'rails_helper'
 RSpec.describe AccountsController, type: :controller do
   render_views
 
-  let(:alice) { Fabricate(:account, username: 'alice') }
+  let(:alice) { Fabricate(:account, username: 'alice', user: Fabricate(:user)) }
   let(:eve) { Fabricate(:user) }
 
   describe 'GET #show' do
diff --git a/spec/controllers/activitypub/inboxes_controller_spec.rb b/spec/controllers/activitypub/inboxes_controller_spec.rb
index 4055d93424c2682b983632c31e895ab99152ff8d..eab4b8c3e65c2d04ee4d1c89b8aef3e7e71410d6 100644
--- a/spec/controllers/activitypub/inboxes_controller_spec.rb
+++ b/spec/controllers/activitypub/inboxes_controller_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe ActivityPub::InboxesController, type: :controller do
           Fabricate(:account)
         end
 
-        post :create
+        post :create, body: '{}'
         expect(response).to have_http_status(202)
       end
     end
@@ -21,7 +21,7 @@ RSpec.describe ActivityPub::InboxesController, type: :controller do
           false
         end
 
-        post :create
+        post :create, body: '{}'
         expect(response).to have_http_status(401)
       end
     end
diff --git a/spec/controllers/admin/domain_blocks_controller_spec.rb b/spec/controllers/admin/domain_blocks_controller_spec.rb
index 129bf888370020bc10789f6c5e251dd0a72e377d..fb23658c017b719587d36a819cc9458d9f2ce448 100644
--- a/spec/controllers/admin/domain_blocks_controller_spec.rb
+++ b/spec/controllers/admin/domain_blocks_controller_spec.rb
@@ -37,7 +37,7 @@ RSpec.describe Admin::DomainBlocksController, type: :controller do
     end
 
     it 'renders new when failed to save' do
-      Fabricate(:domain_block, domain: 'example.com')
+      Fabricate(:domain_block, domain: 'example.com', severity: 'suspend')
       allow(DomainBlockWorker).to receive(:perform_async).and_return(true)
 
       post :create, params: { domain_block: { domain: 'example.com', severity: 'silence' } }
@@ -45,6 +45,17 @@ RSpec.describe Admin::DomainBlocksController, type: :controller do
       expect(DomainBlockWorker).not_to have_received(:perform_async)
       expect(response).to render_template :new
     end
+
+    it 'allows upgrading a block' do
+      Fabricate(:domain_block, domain: 'example.com', severity: 'silence')
+      allow(DomainBlockWorker).to receive(:perform_async).and_return(true)
+
+      post :create, params: { domain_block: { domain: 'example.com', severity: 'silence', reject_media: true, reject_reports: true } }
+
+      expect(DomainBlockWorker).to have_received(:perform_async)
+      expect(flash[:notice]).to eq I18n.t('admin.domain_blocks.created_msg')
+      expect(response).to redirect_to(admin_instances_path(limited: '1'))
+    end
   end
 
   describe 'DELETE #destroy' do
@@ -52,9 +63,9 @@ RSpec.describe Admin::DomainBlocksController, type: :controller do
       service = double(call: true)
       allow(UnblockDomainService).to receive(:new).and_return(service)
       domain_block = Fabricate(:domain_block)
-      delete :destroy, params: { id: domain_block.id, domain_block: { retroactive: '1' } }
+      delete :destroy, params: { id: domain_block.id }
 
-      expect(service).to have_received(:call).with(domain_block, true)
+      expect(service).to have_received(:call).with(domain_block)
       expect(flash[:notice]).to eq I18n.t('admin.domain_blocks.destroyed_msg')
       expect(response).to redirect_to(admin_instances_path(limited: '1'))
     end
diff --git a/spec/controllers/admin/settings_controller_spec.rb b/spec/controllers/admin/settings_controller_spec.rb
index eaf99679a17ad40cea1ebd1ba18343a3092c7fac..6cf0ee20a61d8d6c3c09b8baa4b1c06ecc242f89 100644
--- a/spec/controllers/admin/settings_controller_spec.rb
+++ b/spec/controllers/admin/settings_controller_spec.rb
@@ -19,6 +19,10 @@ RSpec.describe Admin::SettingsController, type: :controller do
     end
 
     describe 'PUT #update' do
+      before do
+        allow_any_instance_of(Form::AdminSettings).to receive(:valid?).and_return(true)
+      end
+
       describe 'for a record that doesnt exist' do
         around do |example|
           before = Setting.site_extended_description
@@ -62,22 +66,6 @@ RSpec.describe Admin::SettingsController, type: :controller do
           expect(Setting.site_title).to eq 'New title'
         end
       end
-
-      context do
-        around do |example|
-          open_registrations = Setting.open_registrations
-          example.run
-          Setting.open_registrations = open_registrations
-        end
-
-        it 'typecasts open_registrations to boolean' do
-          Setting.open_registrations = false
-          patch :update, params: { form_admin_settings: { open_registrations: '1' } }
-
-          expect(response).to redirect_to(edit_admin_settings_path)
-          expect(Setting.open_registrations).to eq true
-        end
-      end
     end
   end
 end
diff --git a/spec/controllers/api/proofs_controller_spec.rb b/spec/controllers/api/proofs_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..dbde4927f1484d63eaa6ea3436c423fe0b9158a1
--- /dev/null
+++ b/spec/controllers/api/proofs_controller_spec.rb
@@ -0,0 +1,96 @@
+require 'rails_helper'
+
+describe Api::ProofsController do
+  let(:alice) { Fabricate(:account, username: 'alice') }
+
+  before do
+    stub_request(:get, 'https://keybase.io/_/api/1.0/sig/proof_valid.json?domain=cb6e6126.ngrok.io&kb_username=crypto_alice&sig_hash=111111111111111111111111111111111111111111111111111111111111111111&username=alice').to_return(status: 200, body: '{"proof_valid":true,"proof_live":false}')
+    stub_request(:get, 'https://keybase.io/_/api/1.0/sig/proof_live.json?domain=cb6e6126.ngrok.io&kb_username=crypto_alice&sig_hash=111111111111111111111111111111111111111111111111111111111111111111&username=alice').to_return(status: 200, body: '{"proof_valid":true,"proof_live":true}')
+    stub_request(:get, 'https://keybase.io/_/api/1.0/sig/proof_valid.json?domain=cb6e6126.ngrok.io&kb_username=hidden_alice&sig_hash=222222222222222222222222222222222222222222222222222222222222222222&username=alice').to_return(status: 200, body: '{"proof_valid":true,"proof_live":true}')
+    stub_request(:get, 'https://keybase.io/_/api/1.0/sig/proof_live.json?domain=cb6e6126.ngrok.io&kb_username=hidden_alice&sig_hash=222222222222222222222222222222222222222222222222222222222222222222&username=alice').to_return(status: 200, body: '{"proof_valid":true,"proof_live":true}')
+  end
+
+  describe 'GET #index' do
+    describe 'with a non-existent username' do
+      it '404s' do
+        get :index, params: { username: 'nonexistent', provider: 'keybase' }
+
+        expect(response).to have_http_status(:not_found)
+      end
+    end
+
+    describe 'with a user that has no proofs' do
+      it 'is an empty list of signatures' do
+        get :index, params: { username: alice.username, provider: 'keybase' }
+
+        expect(body_as_json[:signatures]).to eq []
+      end
+    end
+
+    describe 'with a user that has a live, valid proof' do
+      let(:token1) { '111111111111111111111111111111111111111111111111111111111111111111' }
+      let(:kb_name1) { 'crypto_alice' }
+
+      before do
+        Fabricate(:account_identity_proof, account: alice, verified: true, live: true, token: token1, provider_username: kb_name1)
+      end
+
+      it 'is a list with that proof in it' do
+        get :index, params: { username: alice.username, provider: 'keybase' }
+
+        expect(body_as_json[:signatures]).to eq [
+          { kb_username: kb_name1, sig_hash: token1 },
+        ]
+      end
+
+      describe 'add one that is neither live nor valid' do
+        let(:token2) { '222222222222222222222222222222222222222222222222222222222222222222' }
+        let(:kb_name2) { 'hidden_alice' }
+
+        before do
+          Fabricate(:account_identity_proof, account: alice, verified: false, live: false, token: token2, provider_username: kb_name2)
+        end
+
+        it 'is a list with both proofs' do
+          get :index, params: { username: alice.username, provider: 'keybase' }
+
+          expect(body_as_json[:signatures]).to eq [
+            { kb_username: kb_name1, sig_hash: token1 },
+            { kb_username: kb_name2, sig_hash: token2 },
+          ]
+        end
+      end
+    end
+
+    describe 'a user that has an avatar' do
+      let(:alice) { Fabricate(:account, username: 'alice', avatar: attachment_fixture('avatar.gif')) }
+
+      context 'and a proof' do
+        let(:token1) { '111111111111111111111111111111111111111111111111111111111111111111' }
+        let(:kb_name1) { 'crypto_alice' }
+
+        before do
+          Fabricate(:account_identity_proof, account: alice, verified: true, live: true, token: token1, provider_username: kb_name1)
+          get :index, params: { username: alice.username, provider: 'keybase' }
+        end
+
+        it 'has two keys: signatures and avatar' do
+          expect(body_as_json.keys).to match_array [:signatures, :avatar]
+        end
+
+        it 'has the correct signatures' do
+          expect(body_as_json[:signatures]).to eq [
+            { kb_username: kb_name1, sig_hash: token1 },
+          ]
+        end
+
+        it 'has the correct avatar url' do
+          first_part = 'https://cb6e6126.ngrok.io/system/accounts/avatars/'
+          last_part  = 'original/avatar.gif'
+
+          expect(body_as_json[:avatar]).to match /#{Regexp.quote(first_part)}(?:\d{3,5}\/){3}#{Regexp.quote(last_part)}/
+        end
+      end
+    end
+  end
+end
diff --git a/spec/controllers/api/v1/accounts/credentials_controller_spec.rb b/spec/controllers/api/v1/accounts/credentials_controller_spec.rb
index 72766988635a23db3545b8926352b190bad7bb87..19ac32612858962721baa4edd7ee3132f1ff50c7 100644
--- a/spec/controllers/api/v1/accounts/credentials_controller_spec.rb
+++ b/spec/controllers/api/v1/accounts/credentials_controller_spec.rb
@@ -61,7 +61,7 @@ describe Api::V1::Accounts::CredentialsController do
 
       describe 'with invalid data' do
         before do
-          patch :update, params: { note: 'This is too long. ' * 10 }
+          patch :update, params: { note: 'This is too long. ' * 30 }
         end
 
         it 'returns http unprocessable entity' do
diff --git a/spec/controllers/api/v1/admin/account_actions_controller_spec.rb b/spec/controllers/api/v1/admin/account_actions_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a5a8f4bb0d3b64f85cda638a3f94c650ac9a7dac
--- /dev/null
+++ b/spec/controllers/api/v1/admin/account_actions_controller_spec.rb
@@ -0,0 +1,57 @@
+require 'rails_helper'
+
+RSpec.describe Api::V1::Admin::AccountActionsController, type: :controller do
+  render_views
+
+  let(:role)   { 'moderator' }
+  let(:user)   { Fabricate(:user, role: role, account: Fabricate(:account, username: 'alice')) }
+  let(:scopes) { 'admin:read admin:write' }
+  let(:token)  { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
+  let(:account) { Fabricate(:user).account }
+
+  before do
+    allow(controller).to receive(:doorkeeper_token) { token }
+  end
+
+  shared_examples 'forbidden for wrong scope' do |wrong_scope|
+    let(:scopes) { wrong_scope }
+
+    it 'returns http forbidden' do
+      expect(response).to have_http_status(403)
+    end
+  end
+
+  shared_examples 'forbidden for wrong role' do |wrong_role|
+    let(:role) { wrong_role }
+
+    it 'returns http forbidden' do
+      expect(response).to have_http_status(403)
+    end
+  end
+
+  describe 'POST #create' do
+    before do
+      post :create, params: { account_id: account.id, type: 'disable' }
+    end
+
+    it_behaves_like 'forbidden for wrong scope', 'write:statuses'
+    it_behaves_like 'forbidden for wrong role', 'user'
+
+    it 'returns http success' do
+      expect(response).to have_http_status(200)
+    end
+
+    it 'performs action against account' do
+      expect(account.reload.user_disabled?).to be true
+    end
+
+    it 'logs action' do
+      log_item = Admin::ActionLog.last
+
+      expect(log_item).to_not be_nil
+      expect(log_item.action).to eq :disable
+      expect(log_item.account_id).to eq user.account_id
+      expect(log_item.target_id).to eq account.user.id
+    end
+  end
+end
diff --git a/spec/controllers/api/v1/admin/accounts_controller_spec.rb b/spec/controllers/api/v1/admin/accounts_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f3f9946baac2dbb197586350c93ccc891d0a7710
--- /dev/null
+++ b/spec/controllers/api/v1/admin/accounts_controller_spec.rb
@@ -0,0 +1,147 @@
+require 'rails_helper'
+
+RSpec.describe Api::V1::Admin::AccountsController, type: :controller do
+  render_views
+
+  let(:role)   { 'moderator' }
+  let(:user)   { Fabricate(:user, role: role, account: Fabricate(:account, username: 'alice')) }
+  let(:scopes) { 'admin:read admin:write' }
+  let(:token)  { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
+  let(:account) { Fabricate(:user).account }
+
+  before do
+    allow(controller).to receive(:doorkeeper_token) { token }
+  end
+
+  shared_examples 'forbidden for wrong scope' do |wrong_scope|
+    let(:scopes) { wrong_scope }
+
+    it 'returns http forbidden' do
+      expect(response).to have_http_status(403)
+    end
+  end
+
+  shared_examples 'forbidden for wrong role' do |wrong_role|
+    let(:role) { wrong_role }
+
+    it 'returns http forbidden' do
+      expect(response).to have_http_status(403)
+    end
+  end
+
+  describe 'GET #index' do
+    before do
+      get :index
+    end
+
+    it_behaves_like 'forbidden for wrong scope', 'write:statuses'
+    it_behaves_like 'forbidden for wrong role', 'user'
+
+    it 'returns http success' do
+      expect(response).to have_http_status(200)
+    end
+  end
+
+  describe 'GET #show' do
+    before do
+      get :show, params: { id: account.id }
+    end
+
+    it_behaves_like 'forbidden for wrong scope', 'write:statuses'
+    it_behaves_like 'forbidden for wrong role', 'user'
+
+    it 'returns http success' do
+      expect(response).to have_http_status(200)
+    end
+  end
+
+  describe 'POST #approve' do
+    before do
+      account.user.update(approved: false)
+      post :approve, params: { id: account.id }
+    end
+
+    it_behaves_like 'forbidden for wrong scope', 'write:statuses'
+    it_behaves_like 'forbidden for wrong role', 'user'
+
+    it 'returns http success' do
+      expect(response).to have_http_status(200)
+    end
+
+    it 'approves user' do
+      expect(account.reload.user_approved?).to be true
+    end
+  end
+
+  describe 'POST #reject' do
+    before do
+      account.user.update(approved: false)
+      post :reject, params: { id: account.id }
+    end
+
+    it_behaves_like 'forbidden for wrong scope', 'write:statuses'
+    it_behaves_like 'forbidden for wrong role', 'user'
+
+    it 'returns http success' do
+      expect(response).to have_http_status(200)
+    end
+
+    it 'removes user' do
+      expect(User.where(id: account.user.id).count).to eq 0
+    end
+  end
+
+  describe 'POST #enable' do
+    before do
+      account.user.update(disabled: true)
+      post :enable, params: { id: account.id }
+    end
+
+    it_behaves_like 'forbidden for wrong scope', 'write:statuses'
+    it_behaves_like 'forbidden for wrong role', 'user'
+
+    it 'returns http success' do
+      expect(response).to have_http_status(200)
+    end
+
+    it 'enables user' do
+      expect(account.reload.user_disabled?).to be false
+    end
+  end
+
+  describe 'POST #unsuspend' do
+    before do
+      account.touch(:suspended_at)
+      post :unsuspend, params: { id: account.id }
+    end
+
+    it_behaves_like 'forbidden for wrong scope', 'write:statuses'
+    it_behaves_like 'forbidden for wrong role', 'user'
+
+    it 'returns http success' do
+      expect(response).to have_http_status(200)
+    end
+
+    it 'unsuspends account' do
+      expect(account.reload.suspended?).to be false
+    end
+  end
+
+  describe 'POST #unsilence' do
+    before do
+      account.touch(:silenced_at)
+      post :unsilence, params: { id: account.id }
+    end
+
+    it_behaves_like 'forbidden for wrong scope', 'write:statuses'
+    it_behaves_like 'forbidden for wrong role', 'user'
+
+    it 'returns http success' do
+      expect(response).to have_http_status(200)
+    end
+
+    it 'unsilences account' do
+      expect(account.reload.silenced?).to be false
+    end
+  end
+end
diff --git a/spec/controllers/api/v1/admin/reports_controller_spec.rb b/spec/controllers/api/v1/admin/reports_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4ed3c5dc4c456f53f85aeab1bf06994bdaabca0d
--- /dev/null
+++ b/spec/controllers/api/v1/admin/reports_controller_spec.rb
@@ -0,0 +1,109 @@
+require 'rails_helper'
+
+RSpec.describe Api::V1::Admin::ReportsController, type: :controller do
+  render_views
+
+  let(:role)   { 'moderator' }
+  let(:user)   { Fabricate(:user, role: role, account: Fabricate(:account, username: 'alice')) }
+  let(:scopes) { 'admin:read admin:write' }
+  let(:token)  { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
+  let(:report) { Fabricate(:report) }
+
+  before do
+    allow(controller).to receive(:doorkeeper_token) { token }
+  end
+
+  shared_examples 'forbidden for wrong scope' do |wrong_scope|
+    let(:scopes) { wrong_scope }
+
+    it 'returns http forbidden' do
+      expect(response).to have_http_status(403)
+    end
+  end
+
+  shared_examples 'forbidden for wrong role' do |wrong_role|
+    let(:role) { wrong_role }
+
+    it 'returns http forbidden' do
+      expect(response).to have_http_status(403)
+    end
+  end
+
+  describe 'GET #index' do
+    before do
+      get :index
+    end
+
+    it_behaves_like 'forbidden for wrong scope', 'write:statuses'
+    it_behaves_like 'forbidden for wrong role', 'user'
+
+    it 'returns http success' do
+      expect(response).to have_http_status(200)
+    end
+  end
+
+  describe 'GET #show' do
+    before do
+      get :show, params: { id: report.id }
+    end
+
+    it_behaves_like 'forbidden for wrong scope', 'write:statuses'
+    it_behaves_like 'forbidden for wrong role', 'user'
+
+    it 'returns http success' do
+      expect(response).to have_http_status(200)
+    end
+  end
+
+  describe 'POST #resolve' do
+    before do
+      post :resolve, params: { id: report.id }
+    end
+
+    it_behaves_like 'forbidden for wrong scope', 'write:statuses'
+    it_behaves_like 'forbidden for wrong role', 'user'
+
+    it 'returns http success' do
+      expect(response).to have_http_status(200)
+    end
+  end
+
+  describe 'POST #reopen' do
+    before do
+      post :reopen, params: { id: report.id }
+    end
+
+    it_behaves_like 'forbidden for wrong scope', 'write:statuses'
+    it_behaves_like 'forbidden for wrong role', 'user'
+
+    it 'returns http success' do
+      expect(response).to have_http_status(200)
+    end
+  end
+
+  describe 'POST #assign_to_self' do
+    before do
+      post :assign_to_self, params: { id: report.id }
+    end
+
+    it_behaves_like 'forbidden for wrong scope', 'write:statuses'
+    it_behaves_like 'forbidden for wrong role', 'user'
+
+    it 'returns http success' do
+      expect(response).to have_http_status(200)
+    end
+  end
+
+  describe 'POST #unassign' do
+    before do
+      post :unassign, params: { id: report.id }
+    end
+
+    it_behaves_like 'forbidden for wrong scope', 'write:statuses'
+    it_behaves_like 'forbidden for wrong role', 'user'
+
+    it 'returns http success' do
+      expect(response).to have_http_status(200)
+    end
+  end
+end
diff --git a/spec/controllers/api/v1/filter_controller_spec.rb b/spec/controllers/api/v1/filters_controller_spec.rb
similarity index 100%
rename from spec/controllers/api/v1/filter_controller_spec.rb
rename to spec/controllers/api/v1/filters_controller_spec.rb
diff --git a/spec/controllers/api/v1/notifications_controller_spec.rb b/spec/controllers/api/v1/notifications_controller_spec.rb
index d0f82e79febbc85cbf5b053cc8878b3b89628946..db3f4b782be842445be286dde5b623cf12e1625b 100644
--- a/spec/controllers/api/v1/notifications_controller_spec.rb
+++ b/spec/controllers/api/v1/notifications_controller_spec.rb
@@ -6,6 +6,7 @@ RSpec.describe Api::V1::NotificationsController, type: :controller do
   let(:user)  { Fabricate(:user, account: Fabricate(:account, username: 'alice')) }
   let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
   let(:other) { Fabricate(:user, account: Fabricate(:account, username: 'bob')) }
+  let(:third) { Fabricate(:user, account: Fabricate(:account, username: 'carol')) }
 
   before do
     allow(controller).to receive(:doorkeeper_token) { token }
@@ -55,6 +56,7 @@ RSpec.describe Api::V1::NotificationsController, type: :controller do
       mentioning_status = PostStatusService.new.call(other.account, text: 'Hello @alice')
       @mention_from_status = mentioning_status.mentions.first
       @favourite = FavouriteService.new.call(other.account, first_status)
+      @second_favourite = FavouriteService.new.call(third.account, first_status)
       @follow = FollowService.new.call(other.account, 'alice')
     end
 
@@ -84,6 +86,66 @@ RSpec.describe Api::V1::NotificationsController, type: :controller do
       end
     end
 
+    describe 'from specified user' do
+      before do
+        get :index, params: { account_id: third.account.id }
+      end
+
+      it 'returns http success' do
+        expect(response).to have_http_status(200)
+      end
+
+      it 'includes favourite' do
+        expect(assigns(:notifications).map(&:activity)).to include(@second_favourite)
+      end
+
+      it 'excludes favourite' do
+        expect(assigns(:notifications).map(&:activity)).to_not include(@favourite)
+      end
+
+      it 'excludes mention' do
+        expect(assigns(:notifications).map(&:activity)).to_not include(@mention_from_status)
+      end
+
+      it 'excludes reblog' do
+        expect(assigns(:notifications).map(&:activity)).to_not include(@reblog_of_first_status)
+      end
+
+      it 'excludes follow' do
+        expect(assigns(:notifications).map(&:activity)).to_not include(@follow)
+      end
+    end
+
+    describe 'from nonexistent user' do
+      before do
+        get :index, params: { account_id: 'foo' }
+      end
+
+      it 'returns http success' do
+        expect(response).to have_http_status(200)
+      end
+
+      it 'excludes favourite' do
+        expect(assigns(:notifications).map(&:activity)).to_not include(@favourite)
+      end
+
+      it 'excludes second favourite' do
+        expect(assigns(:notifications).map(&:activity)).to_not include(@second_favourite)
+      end
+
+      it 'excludes mention' do
+        expect(assigns(:notifications).map(&:activity)).to_not include(@mention_from_status)
+      end
+
+      it 'excludes reblog' do
+        expect(assigns(:notifications).map(&:activity)).to_not include(@reblog_of_first_status)
+      end
+
+      it 'excludes follow' do
+        expect(assigns(:notifications).map(&:activity)).to_not include(@follow)
+      end
+    end
+
     describe 'with excluded mentions' do
       before do
         get :index, params: { exclude_types: ['mention'] }
@@ -105,6 +167,10 @@ RSpec.describe Api::V1::NotificationsController, type: :controller do
         expect(assigns(:notifications).map(&:activity)).to include(@favourite)
       end
 
+      it 'includes third favourite' do
+        expect(assigns(:notifications).map(&:activity)).to include(@second_favourite)
+      end
+
       it 'includes follow' do
         expect(assigns(:notifications).map(&:activity)).to include(@follow)
       end
diff --git a/spec/controllers/api/v1/polls/votes_controller_spec.rb b/spec/controllers/api/v1/polls/votes_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0ee3aa040c49418e03ccc04c8dc0ba6e1d7b5c6c
--- /dev/null
+++ b/spec/controllers/api/v1/polls/votes_controller_spec.rb
@@ -0,0 +1,34 @@
+require 'rails_helper'
+
+RSpec.describe Api::V1::Polls::VotesController, type: :controller do
+  render_views
+
+  let(:user)   { Fabricate(:user, account: Fabricate(:account, username: 'alice')) }
+  let(:scopes) { 'write:statuses' }
+  let(:token)  { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
+
+  before { allow(controller).to receive(:doorkeeper_token) { token } }
+
+  describe 'POST #create' do
+    let(:poll) { Fabricate(:poll) }
+
+    before do
+      post :create, params: { poll_id: poll.id, choices: %w(1) }
+    end
+
+    it 'returns http success' do
+      expect(response).to have_http_status(200)
+    end
+
+    it 'creates a vote' do
+      vote = poll.votes.where(account: user.account).first
+
+      expect(vote).to_not be_nil
+      expect(vote.choice).to eq 1
+    end
+
+    it 'updates poll tallies' do
+      expect(poll.reload.cached_tallies).to eq [0, 1]
+    end
+  end
+end
diff --git a/spec/controllers/api/v1/polls_controller_spec.rb b/spec/controllers/api/v1/polls_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..851bccb7e2dce400ade477eb9caad1bf47ad609b
--- /dev/null
+++ b/spec/controllers/api/v1/polls_controller_spec.rb
@@ -0,0 +1,35 @@
+require 'rails_helper'
+
+RSpec.describe Api::V1::PollsController, type: :controller do
+  render_views
+
+  let(:user)   { Fabricate(:user, account: Fabricate(:account, username: 'alice')) }
+  let(:scopes) { 'read:statuses' }
+  let(:token)  { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
+
+  before { allow(controller).to receive(:doorkeeper_token) { token } }
+
+  describe 'GET #show' do
+    let(:poll) { Fabricate(:poll, status: Fabricate(:status, visibility: visibility)) }
+
+    before do
+      get :show, params: { id: poll.id }
+    end
+
+    context 'when parent status is public' do
+      let(:visibility) { 'public' }
+
+      it 'returns http success' do
+        expect(response).to have_http_status(200)
+      end
+    end
+
+    context 'when parent status is private' do
+      let(:visibility) { 'private' }
+
+      it 'returns http not found' do
+        expect(response).to have_http_status(404)
+      end
+    end
+  end
+end
diff --git a/spec/controllers/auth/registrations_controller_spec.rb b/spec/controllers/auth/registrations_controller_spec.rb
index eeb01d5ada51a631a58ef0c754408051c71e436e..a4337039e154f6c7993a9c6535f646dc7616abc5 100644
--- a/spec/controllers/auth/registrations_controller_spec.rb
+++ b/spec/controllers/auth/registrations_controller_spec.rb
@@ -5,14 +5,14 @@ RSpec.describe Auth::RegistrationsController, type: :controller do
 
   shared_examples 'checks for enabled registrations' do |path|
     around do |example|
-      open_registrations = Setting.open_registrations
+      registrations_mode = Setting.registrations_mode
       example.run
-      Setting.open_registrations = open_registrations
+      Setting.registrations_mode = registrations_mode
     end
 
     it 'redirects if it is in single user mode while it is open for registration' do
       Fabricate(:account)
-      Setting.open_registrations = true
+      Setting.registrations_mode = 'open'
       expect(Rails.configuration.x).to receive(:single_user_mode).and_return(true)
 
       get path
@@ -21,7 +21,7 @@ RSpec.describe Auth::RegistrationsController, type: :controller do
     end
 
     it 'redirects if it is not open for registration while it is not in single user mode' do
-      Setting.open_registrations = false
+      Setting.registrations_mode = 'none'
       expect(Rails.configuration.x).to receive(:single_user_mode).and_return(false)
 
       get path
@@ -55,13 +55,13 @@ RSpec.describe Auth::RegistrationsController, type: :controller do
 
     context do
       around do |example|
-        open_registrations = Setting.open_registrations
+        registrations_mode = Setting.registrations_mode
         example.run
-        Setting.open_registrations = open_registrations
+        Setting.registrations_mode = registrations_mode
       end
 
       it 'returns http success' do
-        Setting.open_registrations = true
+        Setting.registrations_mode = 'open'
         get :new
         expect(response).to have_http_status(200)
       end
@@ -83,13 +83,13 @@ RSpec.describe Auth::RegistrationsController, type: :controller do
 
     context do
       around do |example|
-        open_registrations = Setting.open_registrations
+        registrations_mode = Setting.registrations_mode
         example.run
-        Setting.open_registrations = open_registrations
+        Setting.registrations_mode = registrations_mode
       end
 
       subject do
-        Setting.open_registrations = true
+        Setting.registrations_mode = 'open'
         request.headers["Accept-Language"] = accept_language
         post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678' } }
       end
@@ -107,6 +107,89 @@ RSpec.describe Auth::RegistrationsController, type: :controller do
       end
     end
 
+    context 'approval-based registrations without invite' do
+      around do |example|
+        registrations_mode = Setting.registrations_mode
+        example.run
+        Setting.registrations_mode = registrations_mode
+      end
+
+      subject do
+        Setting.registrations_mode = 'approved'
+        request.headers["Accept-Language"] = accept_language
+        post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678' } }
+      end
+
+      it 'redirects to login page' do
+        subject
+        expect(response).to redirect_to new_user_session_path
+      end
+
+      it 'creates user' do
+        subject
+        user = User.find_by(email: 'test@example.com')
+        expect(user).to_not be_nil
+        expect(user.locale).to eq(accept_language)
+        expect(user.approved).to eq(false)
+      end
+    end
+
+    context 'approval-based registrations with expired invite' do
+      around do |example|
+        registrations_mode = Setting.registrations_mode
+        example.run
+        Setting.registrations_mode = registrations_mode
+      end
+
+      subject do
+        Setting.registrations_mode = 'approved'
+        request.headers["Accept-Language"] = accept_language
+        invite = Fabricate(:invite, max_uses: nil, expires_at: 1.hour.ago)
+        post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', 'invite_code': invite.code } }
+      end
+
+      it 'redirects to login page' do
+        subject
+        expect(response).to redirect_to new_user_session_path
+      end
+
+      it 'creates user' do
+        subject
+        user = User.find_by(email: 'test@example.com')
+        expect(user).to_not be_nil
+        expect(user.locale).to eq(accept_language)
+        expect(user.approved).to eq(false)
+      end
+    end
+
+    context 'approval-based registrations with valid invite' do
+      around do |example|
+        registrations_mode = Setting.registrations_mode
+        example.run
+        Setting.registrations_mode = registrations_mode
+      end
+
+      subject do
+        Setting.registrations_mode = 'approved'
+        request.headers["Accept-Language"] = accept_language
+        invite = Fabricate(:invite, max_uses: nil, expires_at: 1.hour.from_now)
+        post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', 'invite_code': invite.code } }
+      end
+
+      it 'redirects to login page' do
+        subject
+        expect(response).to redirect_to new_user_session_path
+      end
+
+      it 'creates user' do
+        subject
+        user = User.find_by(email: 'test@example.com')
+        expect(user).to_not be_nil
+        expect(user.locale).to eq(accept_language)
+        expect(user.approved).to eq(true)
+      end
+    end
+
     it 'does nothing if user already exists' do
       Fabricate(:user, account: Fabricate(:account, username: 'test'))
       subject
diff --git a/spec/controllers/concerns/account_controller_concern_spec.rb b/spec/controllers/concerns/account_controller_concern_spec.rb
index 93685103fcbbeb3e311f83b14b2db2f0b84a825b..ea2b4a2a1deb1d62da709029b1a6ae95d48bc806 100644
--- a/spec/controllers/concerns/account_controller_concern_spec.rb
+++ b/spec/controllers/concerns/account_controller_concern_spec.rb
@@ -17,7 +17,15 @@ describe ApplicationController, type: :controller do
 
   context 'when account is suspended' do
     it 'returns http gone' do
-      account = Fabricate(:account, suspended: true)
+      account = Fabricate(:account, suspended: true, user: Fabricate(:user))
+      get 'success', params: { account_username: account.username }
+      expect(response).to have_http_status(410)
+    end
+  end
+
+  context 'when account is deleted by owner' do
+    it 'returns http gone' do
+      account = Fabricate(:account, suspended: true, user: nil)
       get 'success', params: { account_username: account.username }
       expect(response).to have_http_status(410)
     end
@@ -25,19 +33,19 @@ describe ApplicationController, type: :controller do
 
   context 'when account is not suspended' do
     it 'assigns @account' do
-      account = Fabricate(:account)
+      account = Fabricate(:account, user: Fabricate(:user))
       get 'success', params: { account_username: account.username }
       expect(assigns(:account)).to eq account
     end
 
     it 'sets link headers' do
-      account = Fabricate(:account, username: 'username')
+      account = Fabricate(:account, username: 'username', user: Fabricate(:user))
       get 'success', params: { account_username: 'username' }
       expect(response.headers['Link'].to_s).to eq '<http://test.host/.well-known/webfinger?resource=acct%3Ausername%40cb6e6126.ngrok.io>; rel="lrdd"; type="application/xrd+xml", <http://test.host/users/username.atom>; rel="alternate"; type="application/atom+xml", <https://cb6e6126.ngrok.io/users/username>; rel="alternate"; type="application/activity+json"'
     end
 
     it 'returns http success' do
-      account = Fabricate(:account)
+      account = Fabricate(:account, user: Fabricate(:user))
       get 'success', params: { account_username: account.username }
       expect(response).to have_http_status(200)
     end
diff --git a/spec/controllers/concerns/localized_spec.rb b/spec/controllers/concerns/localized_spec.rb
index 76c3de1183d430093dc76038e9e728392c8c4fda..7635d10e19f9dc384d2d922e7b731e070dee0f52 100644
--- a/spec/controllers/concerns/localized_spec.rb
+++ b/spec/controllers/concerns/localized_spec.rb
@@ -7,16 +7,10 @@ describe ApplicationController, type: :controller do
     include Localized
 
     def success
-      head 200
+      render plain: I18n.locale, status: 200
     end
   end
 
-  around do |example|
-    current_locale = I18n.locale
-    example.run
-    I18n.locale = current_locale
-  end
-
   before do
     routes.draw { get 'success' => 'anonymous#success' }
   end
@@ -25,19 +19,19 @@ describe ApplicationController, type: :controller do
     it 'sets available and preferred language' do
       request.headers['Accept-Language'] = 'ca-ES, fa'
       get 'success'
-      expect(I18n.locale).to eq :fa
+      expect(response.body).to eq 'fa'
     end
 
     it 'sets available and compatible language if none of available languages are preferred' do
       request.headers['Accept-Language'] = 'fa-IR'
       get 'success'
-      expect(I18n.locale).to eq :fa
+      expect(response.body).to eq 'fa'
     end
 
     it 'sets default locale if none of available languages are compatible' do
       request.headers['Accept-Language'] = ''
       get 'success'
-      expect(I18n.locale).to eq :en
+      expect(response.body).to eq 'en'
     end
   end
 
@@ -48,7 +42,7 @@ describe ApplicationController, type: :controller do
       sign_in(user)
       get 'success'
 
-      expect(I18n.locale).to eq :ca
+      expect(response.body).to eq 'ca'
     end
   end
 
diff --git a/spec/controllers/settings/follower_domains_controller_spec.rb b/spec/controllers/relationships_controller_spec.rb
similarity index 64%
rename from spec/controllers/settings/follower_domains_controller_spec.rb
rename to spec/controllers/relationships_controller_spec.rb
index 6d415a654962ea5ee7fdaa9866326245635c90c4..16e255afe118ea210dd06989a6bff7f2fced54e8 100644
--- a/spec/controllers/settings/follower_domains_controller_spec.rb
+++ b/spec/controllers/relationships_controller_spec.rb
@@ -1,6 +1,6 @@
 require 'rails_helper'
 
-describe Settings::FollowerDomainsController do
+describe RelationshipsController do
   render_views
 
   let(:user) { Fabricate(:user) }
@@ -12,24 +12,17 @@ describe Settings::FollowerDomainsController do
   end
 
   describe 'GET #show' do
-    subject { get :show, params: { page: 2 } }
+    subject { get :show, params: { page: 2, relationship: 'followed_by' } }
 
-    it 'assigns @account' do
-      sign_in user, scope: :user
-      subject
-      expect(assigns(:account)).to eq user.account
-    end
-
-    it 'assigns @domains' do
+    it 'assigns @accounts' do
       Fabricate(:account, domain: 'old').follow!(user.account)
       Fabricate(:account, domain: 'recent').follow!(user.account)
 
       sign_in user, scope: :user
       subject
 
-      assigned = assigns(:domains).per(1).to_a
+      assigned = assigns(:accounts).per(1).to_a
       expect(assigned.size).to eq 1
-      expect(assigned[0].accounts_from_domain).to eq 1
       expect(assigned[0].domain).to eq 'old'
     end
 
@@ -49,25 +42,24 @@ describe Settings::FollowerDomainsController do
       stub_request(:post, 'http://example.com/salmon').to_return(status: 200)
     end
 
-    shared_examples 'redirects back to followers page' do |notice|
+    shared_examples 'redirects back to followers page' do
       it 'redirects back to followers page' do
         poopfeast.follow!(user.account)
 
         sign_in user, scope: :user
         subject
 
-        expect(flash[:notice]).to eq notice
-        expect(response).to redirect_to(settings_follower_domains_path)
+        expect(response).to redirect_to(relationships_path)
       end
     end
 
     context 'when select parameter is not provided' do
       subject { patch :update }
-      include_examples 'redirects back to followers page', 'In the process of soft-blocking followers from 0 domains...'
+      include_examples 'redirects back to followers page'
     end
 
     context 'when select parameter is provided' do
-      subject { patch :update, params: { select: ['example.com'] } }
+      subject { patch :update, params: { form_account_batch: { account_ids: [poopfeast.id] }, block_domains: '' } }
 
       it 'soft-blocks followers from selected domains' do
         poopfeast.follow!(user.account)
@@ -79,7 +71,7 @@ describe Settings::FollowerDomainsController do
       end
 
       include_examples 'authenticate user'
-      include_examples 'redirects back to followers page', 'In the process of soft-blocking followers from one domain...'
+      include_examples 'redirects back to followers page'
     end
   end
 end
diff --git a/spec/controllers/settings/exports/following_accounts_controller_spec.rb b/spec/controllers/settings/exports/following_accounts_controller_spec.rb
index 786769d2459e6d0d9f69af427a7ec46117c01615..78858e7725b8933b7912878eaa45215e21a49db1 100644
--- a/spec/controllers/settings/exports/following_accounts_controller_spec.rb
+++ b/spec/controllers/settings/exports/following_accounts_controller_spec.rb
@@ -11,7 +11,7 @@ describe Settings::Exports::FollowingAccountsController do
       sign_in user, scope: :user
       get :index, format: :csv
 
-      expect(response.body).to eq "username@domain\n"
+      expect(response.body).to eq "Account address,Show boosts\nusername@domain,true\n"
     end
   end
 end
diff --git a/spec/controllers/settings/exports/muted_accounts_controller_spec.rb b/spec/controllers/settings/exports/muted_accounts_controller_spec.rb
index f42d7881ed95bbb0fa01241680adbc57570da8fa..642f0a9b8f0ae049481b2f4286a5b3c78add8e78 100644
--- a/spec/controllers/settings/exports/muted_accounts_controller_spec.rb
+++ b/spec/controllers/settings/exports/muted_accounts_controller_spec.rb
@@ -11,7 +11,7 @@ describe Settings::Exports::MutedAccountsController do
       sign_in user, scope: :user
       get :index, format: :csv
 
-      expect(response.body).to eq "username@domain\n"
+      expect(response.body).to eq "Account address,Hide notifications\nusername@domain,true\n"
     end
   end
 end
diff --git a/spec/controllers/settings/identity_proofs_controller_spec.rb b/spec/controllers/settings/identity_proofs_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2a0f91088a9bbc9df92f0cb9774ae3b71367c6b6
--- /dev/null
+++ b/spec/controllers/settings/identity_proofs_controller_spec.rb
@@ -0,0 +1,168 @@
+require 'rails_helper'
+
+describe Settings::IdentityProofsController do
+  include RoutingHelper
+  render_views
+
+  let(:user) { Fabricate(:user) }
+  let(:valid_token) { '1'*66 }
+  let(:kbname) { 'kbuser' }
+  let(:provider) { 'keybase' }
+  let(:findable_id) { Faker::Number.number(5) }
+  let(:unfindable_id) { Faker::Number.number(5) }
+  let(:new_proof_params) do
+    { provider: provider, provider_username: kbname, token: valid_token, username: user.account.username }
+  end
+  let(:status_text) { "i just proved that i am also #{kbname} on #{provider}." }
+  let(:status_posting_params) do
+    { post_status: '0', status_text: status_text }
+  end
+  let(:postable_params) do
+    { account_identity_proof: new_proof_params.merge(status_posting_params) }
+  end
+
+  before do
+    allow_any_instance_of(ProofProvider::Keybase::Verifier).to receive(:status) { { 'proof_valid' => true, 'proof_live' => true } }
+    sign_in user, scope: :user
+  end
+
+  describe 'new proof creation' do
+    context 'GET #new' do
+      before do
+        allow_any_instance_of(ProofProvider::Keybase::Badge).to receive(:avatar_url) { full_pack_url('media/images/void.png') }
+      end
+
+      context 'with all of the correct params' do
+        it 'renders the template' do
+          get :new, params: new_proof_params
+          expect(response).to render_template(:new)
+        end
+      end
+
+      context 'without any params' do
+        it 'redirects to :index' do
+          get :new, params: {}
+          expect(response).to redirect_to settings_identity_proofs_path
+        end
+      end
+
+      context 'with params to prove a different, not logged-in user' do
+        let(:wrong_user_params) { new_proof_params.merge(username: 'someone_else') }
+
+        it 'shows a helpful alert' do
+          get :new, params: wrong_user_params
+          expect(flash[:alert]).to eq I18n.t('identity_proofs.errors.wrong_user', proving: 'someone_else', current: user.account.username)
+        end
+      end
+
+      context 'with params to prove the same username cased differently' do
+        let(:capitalized_username) { new_proof_params.merge(username: user.account.username.upcase) }
+
+        it 'renders the new template' do
+          get :new, params: capitalized_username
+          expect(response).to render_template(:new)
+        end
+      end
+    end
+
+    context 'POST #create' do
+      context 'when saving works' do
+        before do
+          allow(ProofProvider::Keybase::Worker).to receive(:perform_async)
+          allow_any_instance_of(ProofProvider::Keybase::Verifier).to receive(:valid?) { true }
+          allow_any_instance_of(AccountIdentityProof).to receive(:on_success_path) { root_url }
+        end
+
+        it 'serializes a ProofProvider::Keybase::Worker' do
+          expect(ProofProvider::Keybase::Worker).to receive(:perform_async)
+          post :create, params: postable_params
+        end
+
+        it 'delegates redirection to the proof provider' do
+          expect_any_instance_of(AccountIdentityProof).to receive(:on_success_path)
+          post :create, params: postable_params
+          expect(response).to redirect_to root_url
+        end
+
+        it 'does not post a status' do
+          expect(PostStatusService).not_to receive(:new)
+          post :create, params: postable_params
+        end
+
+        context 'and the user has requested to post a status' do
+          let(:postable_params_with_status) do
+            postable_params.tap { |p| p[:account_identity_proof][:post_status] = '1' }
+          end
+
+          it 'posts a status' do
+            expect_any_instance_of(PostStatusService).to receive(:call).with(user.account, text: status_text)
+
+            post :create, params: postable_params_with_status
+          end
+        end
+      end
+
+      context 'when saving fails' do
+        before do
+          allow_any_instance_of(ProofProvider::Keybase::Verifier).to receive(:valid?) { false }
+        end
+
+        it 'redirects to :index' do
+          post :create, params: postable_params
+          expect(response).to redirect_to settings_identity_proofs_path
+        end
+
+        it 'flashes a helpful message' do
+          post :create, params: postable_params
+          expect(flash[:alert]).to eq I18n.t('identity_proofs.errors.failed', provider: 'Keybase')
+        end
+      end
+
+      context 'it can also do an update if the provider and username match an existing proof' do
+        before do
+          allow_any_instance_of(ProofProvider::Keybase::Verifier).to receive(:valid?) { true }
+          allow(ProofProvider::Keybase::Worker).to receive(:perform_async)
+          Fabricate(:account_identity_proof, account: user.account, provider: provider, provider_username: kbname)
+          allow_any_instance_of(AccountIdentityProof).to receive(:on_success_path) { root_url }
+        end
+
+        it 'calls update with the new token' do
+          expect_any_instance_of(AccountIdentityProof).to receive(:save) do |proof|
+            expect(proof.token).to eq valid_token
+          end
+
+          post :create, params: postable_params
+        end
+      end
+    end
+  end
+
+  describe 'GET #index' do
+    context 'with no existing proofs' do
+      it 'shows the helpful explanation' do
+        get :index
+        expect(response.body).to match I18n.t('identity_proofs.explanation_html')
+      end
+    end
+
+    context 'with two proofs' do
+      before do
+        allow_any_instance_of(ProofProvider::Keybase::Verifier).to receive(:valid?) { true }
+        @proof1 = Fabricate(:account_identity_proof, account: user.account)
+        @proof2 = Fabricate(:account_identity_proof, account: user.account)
+        allow_any_instance_of(AccountIdentityProof).to receive(:badge) { double(avatar_url: '', profile_url: '', proof_url: '') }
+        allow_any_instance_of(AccountIdentityProof).to receive(:refresh!) { }
+      end
+
+      it 'has the first proof username on the page' do
+        get :index
+        expect(response.body).to match /#{Regexp.quote(@proof1.provider_username)}/
+      end
+
+      it 'has the second proof username on the page' do
+        get :index
+        expect(response.body).to match /#{Regexp.quote(@proof2.provider_username)}/
+      end
+    end
+  end
+end
diff --git a/spec/controllers/settings/notifications_controller_spec.rb b/spec/controllers/settings/preferences/notifications_controller_spec.rb
similarity index 86%
rename from spec/controllers/settings/notifications_controller_spec.rb
rename to spec/controllers/settings/preferences/notifications_controller_spec.rb
index 981ef674ec0b453d941bd1f1bea63498b634d9b4..02180b383216f4190784e587324facd1eda53d4c 100644
--- a/spec/controllers/settings/notifications_controller_spec.rb
+++ b/spec/controllers/settings/preferences/notifications_controller_spec.rb
@@ -1,6 +1,6 @@
 require 'rails_helper'
 
-describe Settings::NotificationsController do
+describe Settings::Preferences::NotificationsController do
   render_views
 
   let(:user) { Fabricate(:user) }
@@ -28,7 +28,7 @@ describe Settings::NotificationsController do
         }
       }
 
-      expect(response).to redirect_to(settings_notifications_path)
+      expect(response).to redirect_to(settings_preferences_notifications_path)
       user.reload
       expect(user.settings['notification_emails']['follow']).to be true
       expect(user.settings['interactions']['must_be_follower']).to be false
diff --git a/spec/controllers/settings/preferences_controller_spec.rb b/spec/controllers/settings/preferences/other_controller_spec.rb
similarity index 83%
rename from spec/controllers/settings/preferences_controller_spec.rb
rename to spec/controllers/settings/preferences/other_controller_spec.rb
index f2028cf39b4f0f15cb4b755cfbc3a94892f735b8..1b556ac7f7ba268a6cc34678aa130fa4a5ac7079 100644
--- a/spec/controllers/settings/preferences_controller_spec.rb
+++ b/spec/controllers/settings/preferences/other_controller_spec.rb
@@ -1,6 +1,6 @@
 require 'rails_helper'
 
-describe Settings::PreferencesController do
+describe Settings::Preferences::OtherController do
   render_views
 
   let(:user) { Fabricate(:user, filtered_languages: []) }
@@ -20,7 +20,7 @@ describe Settings::PreferencesController do
     it 'updates the user record' do
       put :update, params: { user: { locale: 'en', chosen_languages: ['es', 'fr', ''] } }
 
-      expect(response).to redirect_to(settings_preferences_path)
+      expect(response).to redirect_to(settings_preferences_other_path)
       user.reload
       expect(user.locale).to eq 'en'
       expect(user.chosen_languages).to eq ['es', 'fr']
@@ -37,7 +37,7 @@ describe Settings::PreferencesController do
         }
       }
 
-      expect(response).to redirect_to(settings_preferences_path)
+      expect(response).to redirect_to(settings_preferences_other_path)
       user.reload
       expect(user.settings['boost_modal']).to be true
       expect(user.settings['delete_modal']).to be false
diff --git a/spec/controllers/well_known/keybase_proof_config_controller_spec.rb b/spec/controllers/well_known/keybase_proof_config_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9067e676debda270ca22c3f0208657eaa1004d5d
--- /dev/null
+++ b/spec/controllers/well_known/keybase_proof_config_controller_spec.rb
@@ -0,0 +1,15 @@
+require 'rails_helper'
+
+describe WellKnown::KeybaseProofConfigController, type: :controller do
+  render_views
+
+  describe 'GET #show' do
+    it 'renders json' do
+      get :show
+
+      expect(response).to have_http_status(200)
+      expect(response.content_type).to eq 'application/json'
+      expect { JSON.parse(response.body) }.not_to raise_exception
+    end
+  end
+end
diff --git a/spec/fabricators/account_fabricator.rb b/spec/fabricators/account_fabricator.rb
index e092e6c0993d4a0e98f1b3d335e512e59dc92090..f12464ef3e675a6728d867d4c41735f09c9f0128 100644
--- a/spec/fabricators/account_fabricator.rb
+++ b/spec/fabricators/account_fabricator.rb
@@ -3,8 +3,11 @@ public_key  = keypair.public_key.to_pem
 private_key = keypair.to_pem
 
 Fabricator(:account) do
+  transient :suspended, :silenced
   username            { sequence(:username) { |i| "#{Faker::Internet.user_name(nil, %w(_))}#{i}" } }
   last_webfingered_at { Time.now.utc }
   public_key          { public_key }
   private_key         { private_key }
+  suspended_at        { |attrs| attrs[:suspended] ? Time.now.utc : nil }
+  silenced_at         { |attrs| attrs[:silenced] ? Time.now.utc : nil }
 end
diff --git a/spec/fabricators/account_identity_proof_fabricator.rb b/spec/fabricators/account_identity_proof_fabricator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..94f40dfd6b7cdf31f4e7e88c8df51588cc980a4b
--- /dev/null
+++ b/spec/fabricators/account_identity_proof_fabricator.rb
@@ -0,0 +1,8 @@
+Fabricator(:account_identity_proof) do
+  account
+  provider 'keybase'
+  provider_username { sequence(:provider_username) { |i| "#{Faker::Lorem.characters(15)}" } }
+  token { sequence(:token) { |i| "#{i}#{Faker::Crypto.sha1()*2}"[0..65] } }
+  verified false
+  live false
+end
diff --git a/spec/fabricators/assets/TEAPOT b/spec/fabricators/assets/TEAPOT
new file mode 100644
index 0000000000000000000000000000000000000000..e624ecb4cc87a58076dfa94bf578d875dd327446
--- /dev/null
+++ b/spec/fabricators/assets/TEAPOT
@@ -0,0 +1,6 @@
+This "Utah teapot" photograph is licensed under the Creative Commons
+Attribution-Share Alike 3.0 Unported license:
+  https://creativecommons.org/licenses/by-sa/3.0/deed.en
+
+Original source of work:
+  https://commons.wikimedia.org/wiki/File:Utah_teapot_simple_2.png
diff --git a/spec/fabricators/assets/utah_teapot.png b/spec/fabricators/assets/utah_teapot.png
new file mode 100644
index 0000000000000000000000000000000000000000..6708361e5aceffc71c344a5266486b707bc6a1d2
Binary files /dev/null and b/spec/fabricators/assets/utah_teapot.png differ
diff --git a/spec/fabricators/featured_tag_fabricator.rb b/spec/fabricators/featured_tag_fabricator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..25cbdaac0bc1395f1c51b2899c66b44b05df7f91
--- /dev/null
+++ b/spec/fabricators/featured_tag_fabricator.rb
@@ -0,0 +1,6 @@
+Fabricator(:featured_tag) do
+  account
+  tag
+  statuses_count 1_337
+  last_status_at Time.now.utc
+end
diff --git a/spec/fabricators/poll_fabricator.rb b/spec/fabricators/poll_fabricator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..746610f7c6613d1a9fe5aedcbb59f635b5b3de63
--- /dev/null
+++ b/spec/fabricators/poll_fabricator.rb
@@ -0,0 +1,8 @@
+Fabricator(:poll) do
+  account
+  status
+  expires_at  { 7.days.from_now }
+  options     %w(Foo Bar)
+  multiple    false
+  hide_totals false
+end
diff --git a/spec/fabricators/poll_vote_fabricator.rb b/spec/fabricators/poll_vote_fabricator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..51f9b006e6011f6d4ade159ec5e7248125c0c951
--- /dev/null
+++ b/spec/fabricators/poll_vote_fabricator.rb
@@ -0,0 +1,5 @@
+Fabricator(:poll_vote) do
+  account
+  poll
+  choice  0
+end
diff --git a/spec/fabricators/site_upload_fabricator.rb b/spec/fabricators/site_upload_fabricator.rb
index 4a171486f67029d59e1503e63a3163118abfa713..2efc57e2803010f4f247d80dc41e4460794992e4 100644
--- a/spec/fabricators/site_upload_fabricator.rb
+++ b/spec/fabricators/site_upload_fabricator.rb
@@ -1,2 +1,3 @@
 Fabricator(:site_upload) do
+  file { File.open(File.join(Rails.root, 'spec', 'fabricators', 'assets', 'utah_teapot.png')) }
 end
diff --git a/spec/fabricators/user_invite_request_fabricator.rb b/spec/fabricators/user_invite_request_fabricator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5cc6ae56fec71de4979d46b55dc7277cfd064d31
--- /dev/null
+++ b/spec/fabricators/user_invite_request_fabricator.rb
@@ -0,0 +1,4 @@
+Fabricator(:user_invite_request) do
+  user
+  text { Faker::Lorem.sentence }
+end
diff --git a/spec/fixtures/files/mute-imports.txt b/spec/fixtures/files/mute-imports.txt
new file mode 100644
index 0000000000000000000000000000000000000000..125cbd384b1b973142a793a69903934508248ecf
--- /dev/null
+++ b/spec/fixtures/files/mute-imports.txt
@@ -0,0 +1,4 @@
+bob
+
+eve@example.com
+
diff --git a/spec/fixtures/files/new-following-imports.txt b/spec/fixtures/files/new-following-imports.txt
new file mode 100644
index 0000000000000000000000000000000000000000..5ea6c73466f8df4f96f6e3d28532f347c15b8b13
--- /dev/null
+++ b/spec/fixtures/files/new-following-imports.txt
@@ -0,0 +1,4 @@
+Account address,Show boosts
+bob,true
+eve@example.com,false
+
diff --git a/spec/fixtures/files/new-mute-imports.txt b/spec/fixtures/files/new-mute-imports.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c1c9bca9bfdafb76efa3813ed0b1bce2a42cfdb4
--- /dev/null
+++ b/spec/fixtures/files/new-mute-imports.txt
@@ -0,0 +1,4 @@
+Account address,Hide notifications
+bob,true
+eve@example.com,false
+
diff --git a/spec/helpers/admin/action_log_helper_spec.rb b/spec/helpers/admin/action_log_helper_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d7af6b939e6ae3d1d6b837b42685033635d4c5de
--- /dev/null
+++ b/spec/helpers/admin/action_log_helper_spec.rb
@@ -0,0 +1,272 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe Admin::ActionLogsHelper, type: :helper do
+  klass = Class.new do
+    include ActionView::Helpers
+    include Admin::ActionLogsHelper
+  end
+
+  let(:hoge) { klass.new }
+
+  describe '#log_target' do
+    after do
+      hoge.log_target(log)
+    end
+
+    context 'log.target' do
+      let(:log) { double(target: true) }
+
+      it 'calls linkable_log_target' do
+        expect(hoge).to receive(:linkable_log_target).with(log.target)
+      end
+    end
+
+    context '!log.target' do
+      let(:log) { double(target: false, target_type: :type, recorded_changes: :change) }
+
+      it 'calls log_target_from_history' do
+        expect(hoge).to receive(:log_target_from_history).with(log.target_type, log.recorded_changes)
+      end
+    end
+  end
+
+  describe '#relevant_log_changes' do
+    let(:log) { double(target_type: target_type, action: log_action, recorded_changes: recorded_changes) }
+    let(:recorded_changes) { double }
+
+    after do
+      hoge.relevant_log_changes(log)
+    end
+
+    context "log.target_type == 'CustomEmoji' && [:enable, :disable, :destroy].include?(log.action)" do
+      let(:target_type) { 'CustomEmoji' }
+      let(:log_action)  { :enable }
+
+      it "calls log.recorded_changes.slice('domain')" do
+        expect(recorded_changes).to receive(:slice).with('domain')
+      end
+    end
+
+    context "log.target_type == 'CustomEmoji' && log.action == :update" do
+      let(:target_type) { 'CustomEmoji' }
+      let(:log_action)  { :update }
+
+      it "calls log.recorded_changes.slice('domain', 'visible_in_picker')" do
+        expect(recorded_changes).to receive(:slice).with('domain', 'visible_in_picker')
+      end
+    end
+
+    context "log.target_type == 'User' && [:promote, :demote].include?(log.action)" do
+      let(:target_type) { 'User' }
+      let(:log_action)  { :promote }
+
+      it "calls log.recorded_changes.slice('moderator', 'admin')" do
+        expect(recorded_changes).to receive(:slice).with('moderator', 'admin')
+      end
+    end
+
+    context "log.target_type == 'User' && [:change_email].include?(log.action)" do
+      let(:target_type) { 'User' }
+      let(:log_action)  { :change_email }
+
+      it "calls log.recorded_changes.slice('email', 'unconfirmed_email')" do
+        expect(recorded_changes).to receive(:slice).with('email', 'unconfirmed_email')
+      end
+    end
+
+    context "log.target_type == 'DomainBlock'" do
+      let(:target_type) { 'DomainBlock' }
+      let(:log_action)  { nil }
+
+      it "calls log.recorded_changes.slice('severity', 'reject_media')" do
+        expect(recorded_changes).to receive(:slice).with('severity', 'reject_media')
+      end
+    end
+
+    context "log.target_type == 'Status' && log.action == :update" do
+      let(:target_type) { 'Status' }
+      let(:log_action)  { :update }
+
+      it "log.recorded_changes.slice('sensitive')" do
+        expect(recorded_changes).to receive(:slice).with('sensitive')
+      end
+    end
+  end
+
+  describe '#log_extra_attributes' do
+    after do
+      hoge.log_extra_attributes(hoge: 'hoge')
+    end
+
+    it "calls content_tag(:span, key, class: 'diff-key')" do
+      allow(hoge).to receive(:log_change).with(anything)
+      expect(hoge).to receive(:content_tag).with(:span, :hoge, class: 'diff-key')
+    end
+
+    it 'calls safe_join twice' do
+      expect(hoge).to receive(:safe_join).with(
+        ['<span class="diff-key">hoge</span>',
+         '=',
+         '<span class="diff-neutral">hoge</span>']
+      )
+
+      expect(hoge).to receive(:safe_join).with([nil], ' ')
+    end
+  end
+
+  describe '#log_change' do
+    after do
+      hoge.log_change(val)
+    end
+
+    context '!val.is_a?(Array)' do
+      let(:val) { 'hoge' }
+
+      it "calls content_tag(:span, val, class: 'diff-neutral')" do
+        expect(hoge).to receive(:content_tag).with(:span, val, class: 'diff-neutral')
+      end
+    end
+
+    context 'val.is_a?(Array)' do
+      let(:val) { %w(foo bar) }
+
+      it 'calls #content_tag twice and #safe_join' do
+        expect(hoge).to receive(:content_tag).with(:span, 'foo', class: 'diff-old')
+        expect(hoge).to receive(:content_tag).with(:span, 'bar', class: 'diff-new')
+        expect(hoge).to receive(:safe_join).with([nil, nil], '→')
+      end
+    end
+  end
+
+  describe '#icon_for_log' do
+    subject   { hoge.icon_for_log(log) }
+
+    context "log.target_type == 'Account'" do
+      let(:log) { double(target_type: 'Account') }
+
+      it 'returns "user"' do
+        expect(subject).to be 'user'
+      end
+    end
+
+    context "log.target_type == 'User'" do
+      let(:log) { double(target_type: 'User') }
+
+      it 'returns "user"' do
+        expect(subject).to be 'user'
+      end
+    end
+
+    context "log.target_type == 'CustomEmoji'" do
+      let(:log) { double(target_type: 'CustomEmoji') }
+
+      it 'returns "file"' do
+        expect(subject).to be 'file'
+      end
+    end
+
+    context "log.target_type == 'Report'" do
+      let(:log) { double(target_type: 'Report') }
+
+      it 'returns "flag"' do
+        expect(subject).to be 'flag'
+      end
+    end
+
+    context "log.target_type == 'DomainBlock'" do
+      let(:log) { double(target_type: 'DomainBlock') }
+
+      it 'returns "lock"' do
+        expect(subject).to be 'lock'
+      end
+    end
+
+    context "log.target_type == 'EmailDomainBlock'" do
+      let(:log) { double(target_type: 'EmailDomainBlock') }
+
+      it 'returns "envelope"' do
+        expect(subject).to be 'envelope'
+      end
+    end
+
+    context "log.target_type == 'Status'" do
+      let(:log) { double(target_type: 'Status') }
+
+      it 'returns "pencil"' do
+        expect(subject).to be 'pencil'
+      end
+    end
+  end
+
+  describe '#class_for_log_icon' do
+    subject   { hoge.class_for_log_icon(log) }
+
+    %i(enable unsuspend unsilence confirm promote resolve).each do |action|
+      context "log.action == #{action}" do
+        let(:log) { double(action: action) }
+
+        it 'returns "positive"' do
+          expect(subject).to be 'positive'
+        end
+      end
+    end
+
+    context 'log.action == :create' do
+      context 'opposite_verbs?(log)' do
+        let(:log) { double(action: :create, target_type: 'DomainBlock') }
+
+        it 'returns "negative"' do
+          expect(subject).to be 'negative'
+        end
+      end
+
+      context '!opposite_verbs?(log)' do
+        let(:log) { double(action: :create, target_type: '') }
+
+        it 'returns "positive"' do
+          expect(subject).to be 'positive'
+        end
+      end
+    end
+
+    %i(update reset_password disable_2fa memorialize change_email).each do |action|
+      context "log.action == #{action}" do
+        let(:log) { double(action: action) }
+
+        it 'returns "neutral"' do
+          expect(subject).to be 'neutral'
+        end
+      end
+    end
+
+    %i(demote silence disable suspend remove_avatar remove_header reopen).each do |action|
+      context "log.action == #{action}" do
+        let(:log) { double(action: action) }
+
+        it 'returns "negative"' do
+          expect(subject).to be 'negative'
+        end
+      end
+    end
+
+    context 'log.action == :destroy' do
+      context 'opposite_verbs?(log)' do
+        let(:log) { double(action: :destroy, target_type: 'DomainBlock') }
+
+        it 'returns "positive"' do
+          expect(subject).to be 'positive'
+        end
+      end
+
+      context '!opposite_verbs?(log)' do
+        let(:log) { double(action: :destroy, target_type: '') }
+
+        it 'returns "negative"' do
+          expect(subject).to be 'negative'
+        end
+      end
+    end
+  end
+end
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index 61780b46b929ef26ad2cb1625e41b5b85104f9ef..f09e32ecc2bd1b69dbfd49da111440f171d52a16 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -69,7 +69,7 @@ describe ApplicationHelper do
   describe 'open_registrations?' do
     it 'returns true when open for registrations' do
       without_partial_double_verification do
-        expect(Setting).to receive(:open_registrations).and_return(true)
+        expect(Setting).to receive(:registrations_mode).and_return('open')
       end
 
       expect(helper.open_registrations?).to eq true
@@ -77,7 +77,7 @@ describe ApplicationHelper do
 
     it 'returns false when closed for registrations' do
       without_partial_double_verification do
-        expect(Setting).to receive(:open_registrations).and_return(false)
+        expect(Setting).to receive(:registrations_mode).and_return('none')
       end
 
       expect(helper.open_registrations?).to eq false
diff --git a/spec/lib/activitypub/activity/announce_spec.rb b/spec/lib/activitypub/activity/announce_spec.rb
index 54dd52a60490a1d72ce207a9e544f5212c67c3ee..60fd96a18ac69d2687698bf0ed756d1af5bdd4f3 100644
--- a/spec/lib/activitypub/activity/announce_spec.rb
+++ b/spec/lib/activitypub/activity/announce_spec.rb
@@ -1,7 +1,7 @@
 require 'rails_helper'
 
 RSpec.describe ActivityPub::Activity::Announce do
-  let(:sender)    { Fabricate(:account) }
+  let(:sender)    { Fabricate(:account, followers_url: 'http://example.com/followers', uri: 'https://example.com/actor') }
   let(:recipient) { Fabricate(:account) }
   let(:status)    { Fabricate(:status, account: recipient) }
 
@@ -10,20 +10,151 @@ RSpec.describe ActivityPub::Activity::Announce do
       '@context': 'https://www.w3.org/ns/activitystreams',
       id: 'foo',
       type: 'Announce',
-      actor: ActivityPub::TagManager.instance.uri_for(sender),
-      object: ActivityPub::TagManager.instance.uri_for(status),
+      actor: 'https://example.com/actor',
+      object: object_json,
+      to: 'http://example.com/followers',
     }.with_indifferent_access
   end
 
+  let(:unknown_object_json) do
+    {
+      '@context': 'https://www.w3.org/ns/activitystreams',
+      id: 'https://example.com/actor/hello-world',
+      type: 'Note',
+      attributedTo: 'https://example.com/actor',
+      content: 'Hello world',
+      to: 'http://example.com/followers',
+    }
+  end
+
+  subject { described_class.new(json, sender) }
+
   describe '#perform' do
-    subject { described_class.new(json, sender) }
+    context 'when sender is followed by a local account' do
+      before do
+        Fabricate(:account).follow!(sender)
+        stub_request(:get, 'https://example.com/actor/hello-world').to_return(body: Oj.dump(unknown_object_json))
+        subject.perform
+      end
+
+      context 'a known status' do
+        let(:object_json) do
+          ActivityPub::TagManager.instance.uri_for(status)
+        end
+
+        it 'creates a reblog by sender of status' do
+          expect(sender.reblogged?(status)).to be true
+        end
+      end
+
+      context 'an unknown status' do
+        let(:object_json) { 'https://example.com/actor/hello-world' }
+
+        it 'creates a reblog by sender of status' do
+          reblog = sender.statuses.first
+
+          expect(reblog).to_not be_nil
+          expect(reblog.reblog.text).to eq 'Hello world'
+        end
+      end
+
+      context 'self-boost of a previously unknown status with correct attributedTo' do
+        let(:object_json) do
+          {
+            id: 'https://example.com/actor#bar',
+            type: 'Note',
+            content: 'Lorem ipsum',
+            attributedTo: 'https://example.com/actor',
+            to: 'http://example.com/followers',
+          }
+        end
+
+        it 'creates a reblog by sender of status' do
+          expect(sender.reblogged?(sender.statuses.first)).to be true
+        end
+      end
+    end
 
-    before do
-      subject.perform
+    context 'when the status belongs to a local user' do
+      before do
+        subject.perform
+      end
+
+      let(:object_json) do
+        ActivityPub::TagManager.instance.uri_for(status)
+      end
+
+      it 'creates a reblog by sender of status' do
+        expect(sender.reblogged?(status)).to be true
+      end
     end
 
-    it 'creates a reblog by sender of status' do
-      expect(sender.reblogged?(status)).to be true
+    context 'when the sender is relayed' do
+      let!(:relay_account) { Fabricate(:account, inbox_url: 'https://relay.example.com/inbox') }
+      let!(:relay) { Fabricate(:relay, inbox_url: 'https://relay.example.com/inbox') }
+
+      subject { described_class.new(json, sender, relayed_through_account: relay_account) }
+
+      context 'and the relay is enabled' do
+        before do
+          relay.update(state: :accepted)
+          subject.perform
+        end
+
+        let(:object_json) do
+          {
+            id: 'https://example.com/actor#bar',
+            type: 'Note',
+            content: 'Lorem ipsum',
+            to: 'http://example.com/followers',
+            attributedTo: 'https://example.com/actor',
+          }
+        end
+
+        it 'creates a reblog by sender of status' do
+          expect(sender.statuses.count).to eq 2
+        end
+      end
+
+      context 'and the relay is disabled' do
+        before do
+          subject.perform
+        end
+
+        let(:object_json) do
+          {
+            id: 'https://example.com/actor#bar',
+            type: 'Note',
+            content: 'Lorem ipsum',
+            to: 'http://example.com/followers',
+            attributedTo: 'https://example.com/actor',
+          }
+        end
+
+        it 'does not create anything' do
+          expect(sender.statuses.count).to eq 0
+        end
+      end
+    end
+
+    context 'when the sender has no relevance to local activity' do
+      before do
+        subject.perform
+      end
+
+      let(:object_json) do
+        {
+          id: 'https://example.com/actor#bar',
+          type: 'Note',
+          content: 'Lorem ipsum',
+          to: 'http://example.com/followers',
+          attributedTo: 'https://example.com/actor',
+        }
+      end
+
+      it 'does not create anything' do
+        expect(sender.statuses.count).to eq 0
+      end
     end
   end
 end
diff --git a/spec/lib/activitypub/activity/create_spec.rb b/spec/lib/activitypub/activity/create_spec.rb
index cd20b7c7cb006982ee1247dd099938c436a3c5eb..412609de408d0125397d44bfdd33027ce34ec296 100644
--- a/spec/lib/activitypub/activity/create_spec.rb
+++ b/spec/lib/activitypub/activity/create_spec.rb
@@ -1,7 +1,7 @@
 require 'rails_helper'
 
 RSpec.describe ActivityPub::Activity::Create do
-  let(:sender) { Fabricate(:account, followers_url: 'http://example.com/followers') }
+  let(:sender) { Fabricate(:account, followers_url: 'http://example.com/followers', domain: 'example.com', uri: 'https://example.com/actor') }
 
   let(:json) do
     {
@@ -13,8 +13,6 @@ RSpec.describe ActivityPub::Activity::Create do
     }.with_indifferent_access
   end
 
-  subject { described_class.new(json, sender) }
-
   before do
     sender.update(uri: ActivityPub::TagManager.instance.uri_for(sender))
 
@@ -23,77 +21,504 @@ RSpec.describe ActivityPub::Activity::Create do
   end
 
   describe '#perform' do
-    before do
-      subject.perform
-    end
-
-    context 'standalone' do
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum',
-        }
-      end
-
-      it 'creates status' do
-        status = sender.statuses.first
+    context 'when fetching' do
+      subject { described_class.new(json, sender) }
 
-        expect(status).to_not be_nil
-        expect(status.text).to eq 'Lorem ipsum'
-      end
-
-      it 'missing to/cc defaults to direct privacy' do
-        status = sender.statuses.first
-
-        expect(status).to_not be_nil
-        expect(status.visibility).to eq 'direct'
-      end
-    end
-
-    context 'public' do
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum',
-          to: 'https://www.w3.org/ns/activitystreams#Public',
-        }
-      end
-
-      it 'creates status' do
-        status = sender.statuses.first
-
-        expect(status).to_not be_nil
-        expect(status.visibility).to eq 'public'
+      before do
+        subject.perform
+      end
+
+      context 'unknown object type' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Banana',
+            content: 'Lorem ipsum',
+          }
+        end
+
+        it 'does not create a status' do
+          expect(sender.statuses.count).to be_zero
+        end
+      end
+
+      context 'standalone' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.text).to eq 'Lorem ipsum'
+        end
+
+        it 'missing to/cc defaults to direct privacy' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.visibility).to eq 'direct'
+        end
+      end
+
+      context 'public' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            to: 'https://www.w3.org/ns/activitystreams#Public',
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.visibility).to eq 'public'
+        end
+      end
+
+      context 'unlisted' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            cc: 'https://www.w3.org/ns/activitystreams#Public',
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.visibility).to eq 'unlisted'
+        end
+      end
+
+      context 'private' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            to: 'http://example.com/followers',
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.visibility).to eq 'private'
+        end
+      end
+
+      context 'limited' do
+        let(:recipient) { Fabricate(:account) }
+
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            to: ActivityPub::TagManager.instance.uri_for(recipient),
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.visibility).to eq 'limited'
+        end
+
+        it 'creates silent mention' do
+          status = sender.statuses.first
+          expect(status.mentions.first).to be_silent
+        end
+      end
+
+      context 'direct' do
+        let(:recipient) { Fabricate(:account) }
+
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            to: ActivityPub::TagManager.instance.uri_for(recipient),
+            tag: {
+              type: 'Mention',
+              href: ActivityPub::TagManager.instance.uri_for(recipient),
+            },
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.visibility).to eq 'direct'
+        end
+      end
+
+      context 'as a reply' do
+        let(:original_status) { Fabricate(:status) }
+
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            inReplyTo: ActivityPub::TagManager.instance.uri_for(original_status),
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.thread).to eq original_status
+          expect(status.reply?).to be true
+          expect(status.in_reply_to_account).to eq original_status.account
+          expect(status.conversation).to eq original_status.conversation
+        end
+      end
+
+      context 'with mentions' do
+        let(:recipient) { Fabricate(:account) }
+
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            tag: [
+              {
+                type: 'Mention',
+                href: ActivityPub::TagManager.instance.uri_for(recipient),
+              },
+            ],
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.mentions.map(&:account)).to include(recipient)
+        end
+      end
+
+      context 'with mentions missing href' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            tag: [
+              {
+                type: 'Mention',
+              },
+            ],
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+          expect(status).to_not be_nil
+        end
+      end
+
+      context 'with media attachments' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            attachment: [
+              {
+                type: 'Document',
+                mediaType: 'image/png',
+                url: 'http://example.com/attachment.png',
+              },
+            ],
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.media_attachments.map(&:remote_url)).to include('http://example.com/attachment.png')
+        end
+      end
+
+      context 'with media attachments with focal points' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            attachment: [
+              {
+                type: 'Document',
+                mediaType: 'image/png',
+                url: 'http://example.com/attachment.png',
+                focalPoint: [0.5, -0.7],
+              },
+            ],
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.media_attachments.map(&:focus)).to include('0.5,-0.7')
+        end
+      end
+
+      context 'with media attachments missing url' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            attachment: [
+              {
+                type: 'Document',
+                mediaType: 'image/png',
+              },
+            ],
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+          expect(status).to_not be_nil
+        end
+      end
+
+      context 'with hashtags' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            tag: [
+              {
+                type: 'Hashtag',
+                href: 'http://example.com/blah',
+                name: '#test',
+              },
+            ],
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.tags.map(&:name)).to include('test')
+        end
+      end
+
+      context 'with hashtags missing name' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            tag: [
+              {
+                type: 'Hashtag',
+                href: 'http://example.com/blah',
+              },
+            ],
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+          expect(status).to_not be_nil
+        end
+      end
+
+      context 'with emojis' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum :tinking:',
+            tag: [
+              {
+                type: 'Emoji',
+                icon: {
+                  url: 'http://example.com/emoji.png',
+                },
+                name: 'tinking',
+              },
+            ],
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.emojis.map(&:shortcode)).to include('tinking')
+        end
+      end
+
+      context 'with emojis missing name' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum :tinking:',
+            tag: [
+              {
+                type: 'Emoji',
+                icon: {
+                  url: 'http://example.com/emoji.png',
+                },
+              },
+            ],
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+          expect(status).to_not be_nil
+        end
+      end
+
+      context 'with emojis missing icon' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum :tinking:',
+            tag: [
+              {
+                type: 'Emoji',
+                name: 'tinking',
+              },
+            ],
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+          expect(status).to_not be_nil
+        end
+      end
+
+      context 'with poll' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Question',
+            content: 'Which color was the submarine?',
+            oneOf: [
+              {
+                name: 'Yellow',
+                replies: {
+                  type: 'Collection',
+                  totalItems: 10,
+                },
+              },
+              {
+                name: 'Blue',
+                replies: {
+                  type: 'Collection',
+                  totalItems: 3,
+                }
+              },
+            ],
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+          expect(status).to_not be_nil
+          expect(status.poll).to_not be_nil
+        end
+
+        it 'creates a poll' do
+          poll = sender.polls.first
+          expect(poll).to_not be_nil
+          expect(poll.status).to_not be_nil
+          expect(poll.options).to eq %w(Yellow Blue)
+          expect(poll.cached_tallies).to eq [10, 3]
+        end
+      end
+
+      context 'when a vote to a local poll' do
+        let(:poll) { Fabricate(:poll, options: %w(Yellow Blue)) }
+        let!(:local_status) { Fabricate(:status, poll: poll) }
+
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            name: 'Yellow',
+            inReplyTo: ActivityPub::TagManager.instance.uri_for(local_status)
+          }
+        end
+
+        it 'adds a vote to the poll with correct uri' do
+          vote = poll.votes.first
+          expect(vote).to_not be_nil
+          expect(vote.uri).to eq object_json[:id]
+          expect(poll.reload.cached_tallies).to eq [1, 0]
+        end
+      end
+
+      context 'when a vote to an expired local poll' do
+        let(:poll) do
+          poll = Fabricate.build(:poll, options: %w(Yellow Blue), expires_at: 1.day.ago)
+          poll.save(validate: false)
+          poll
+        end
+        let!(:local_status) { Fabricate(:status, poll: poll) }
+
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            name: 'Yellow',
+            inReplyTo: ActivityPub::TagManager.instance.uri_for(local_status)
+          }
+        end
+
+        it 'does not add a vote to the poll' do
+          expect(poll.votes.first).to be_nil
+        end
       end
     end
 
-    context 'unlisted' do
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum',
-          cc: 'https://www.w3.org/ns/activitystreams#Public',
-        }
-      end
-
-      it 'creates status' do
-        status = sender.statuses.first
+    context 'when sender is followed by local users' do
+      subject { described_class.new(json, sender, delivery: true) }
 
-        expect(status).to_not be_nil
-        expect(status.visibility).to eq 'unlisted'
+      before do
+        Fabricate(:account).follow!(sender)
+        subject.perform
       end
-    end
 
-    context 'private' do
       let(:object_json) do
         {
           id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
           type: 'Note',
           content: 'Lorem ipsum',
-          to: 'http://example.com/followers',
         }
       end
 
@@ -101,48 +526,25 @@ RSpec.describe ActivityPub::Activity::Create do
         status = sender.statuses.first
 
         expect(status).to_not be_nil
-        expect(status.visibility).to eq 'private'
+        expect(status.text).to eq 'Lorem ipsum'
       end
     end
 
-    context 'limited' do
-      let(:recipient) { Fabricate(:account) }
-
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum',
-          to: ActivityPub::TagManager.instance.uri_for(recipient),
-        }
-      end
+    context 'when sender replies to local status' do
+      let!(:local_status) { Fabricate(:status) }
 
-      it 'creates status' do
-        status = sender.statuses.first
+      subject { described_class.new(json, sender, delivery: true) }
 
-        expect(status).to_not be_nil
-        expect(status.visibility).to eq 'limited'
+      before do
+        subject.perform
       end
 
-      it 'creates silent mention' do
-        status = sender.statuses.first
-        expect(status.mentions.first).to be_silent
-      end
-    end
-
-    context 'direct' do
-      let(:recipient) { Fabricate(:account) }
-
       let(:object_json) do
         {
           id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
           type: 'Note',
           content: 'Lorem ipsum',
-          to: ActivityPub::TagManager.instance.uri_for(recipient),
-          tag: {
-            type: 'Mention',
-            href: ActivityPub::TagManager.instance.uri_for(recipient),
-          },
+          inReplyTo: ActivityPub::TagManager.instance.uri_for(local_status),
         }
       end
 
@@ -150,47 +552,25 @@ RSpec.describe ActivityPub::Activity::Create do
         status = sender.statuses.first
 
         expect(status).to_not be_nil
-        expect(status.visibility).to eq 'direct'
+        expect(status.text).to eq 'Lorem ipsum'
       end
     end
 
-    context 'as a reply' do
-      let(:original_status) { Fabricate(:status) }
+    context 'when sender targets a local user' do
+      let!(:local_account) { Fabricate(:account) }
 
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum',
-          inReplyTo: ActivityPub::TagManager.instance.uri_for(original_status),
-        }
-      end
-
-      it 'creates status' do
-        status = sender.statuses.first
+      subject { described_class.new(json, sender, delivery: true) }
 
-        expect(status).to_not be_nil
-        expect(status.thread).to eq original_status
-        expect(status.reply?).to be true
-        expect(status.in_reply_to_account).to eq original_status.account
-        expect(status.conversation).to eq original_status.conversation
+      before do
+        subject.perform
       end
-    end
-
-    context 'with mentions' do
-      let(:recipient) { Fabricate(:account) }
 
       let(:object_json) do
         {
           id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
           type: 'Note',
           content: 'Lorem ipsum',
-          tag: [
-            {
-              type: 'Mention',
-              href: ActivityPub::TagManager.instance.uri_for(recipient),
-            },
-          ],
+          to: ActivityPub::TagManager.instance.uri_for(local_account),
         }
       end
 
@@ -198,68 +578,25 @@ RSpec.describe ActivityPub::Activity::Create do
         status = sender.statuses.first
 
         expect(status).to_not be_nil
-        expect(status.mentions.map(&:account)).to include(recipient)
-      end
-    end
-
-    context 'with mentions missing href' do
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum',
-          tag: [
-            {
-              type: 'Mention',
-            },
-          ],
-        }
-      end
-
-      it 'creates status' do
-        status = sender.statuses.first
-        expect(status).to_not be_nil
+        expect(status.text).to eq 'Lorem ipsum'
       end
     end
 
-    context 'with media attachments' do
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum',
-          attachment: [
-            {
-              type: 'Document',
-              mediaType: 'image/png',
-              url: 'http://example.com/attachment.png',
-            },
-          ],
-        }
-      end
+    context 'when sender cc\'s a local user' do
+      let!(:local_account) { Fabricate(:account) }
 
-      it 'creates status' do
-        status = sender.statuses.first
+      subject { described_class.new(json, sender, delivery: true) }
 
-        expect(status).to_not be_nil
-        expect(status.media_attachments.map(&:remote_url)).to include('http://example.com/attachment.png')
+      before do
+        subject.perform
       end
-    end
 
-    context 'with media attachments with focal points' do
       let(:object_json) do
         {
           id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
           type: 'Note',
           content: 'Lorem ipsum',
-          attachment: [
-            {
-              type: 'Document',
-              mediaType: 'image/png',
-              url: 'http://example.com/attachment.png',
-              focalPoint: [0.5, -0.7],
-            },
-          ],
+          cc: ActivityPub::TagManager.instance.uri_for(local_account),
         }
       end
 
@@ -267,143 +604,27 @@ RSpec.describe ActivityPub::Activity::Create do
         status = sender.statuses.first
 
         expect(status).to_not be_nil
-        expect(status.media_attachments.map(&:focus)).to include('0.5,-0.7')
-      end
-    end
-
-    context 'with media attachments missing url' do
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum',
-          attachment: [
-            {
-              type: 'Document',
-              mediaType: 'image/png',
-            },
-          ],
-        }
-      end
-
-      it 'creates status' do
-        status = sender.statuses.first
-        expect(status).to_not be_nil
+        expect(status.text).to eq 'Lorem ipsum'
       end
     end
 
-    context 'with hashtags' do
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum',
-          tag: [
-            {
-              type: 'Hashtag',
-              href: 'http://example.com/blah',
-              name: '#test',
-            },
-          ],
-        }
-      end
-
-      it 'creates status' do
-        status = sender.statuses.first
+    context 'when the sender has no relevance to local activity' do
+      subject { described_class.new(json, sender, delivery: true) }
 
-        expect(status).to_not be_nil
-        expect(status.tags.map(&:name)).to include('test')
+      before do
+        subject.perform
       end
-    end
 
-    context 'with hashtags missing name' do
       let(:object_json) do
         {
           id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
           type: 'Note',
           content: 'Lorem ipsum',
-          tag: [
-            {
-              type: 'Hashtag',
-              href: 'http://example.com/blah',
-            },
-          ],
-        }
-      end
-
-      it 'creates status' do
-        status = sender.statuses.first
-        expect(status).to_not be_nil
-      end
-    end
-
-    context 'with emojis' do
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum :tinking:',
-          tag: [
-            {
-              type: 'Emoji',
-              icon: {
-                url: 'http://example.com/emoji.png',
-              },
-              name: 'tinking',
-            },
-          ],
         }
       end
 
-      it 'creates status' do
-        status = sender.statuses.first
-
-        expect(status).to_not be_nil
-        expect(status.emojis.map(&:shortcode)).to include('tinking')
-      end
-    end
-
-    context 'with emojis missing name' do
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum :tinking:',
-          tag: [
-            {
-              type: 'Emoji',
-              icon: {
-                url: 'http://example.com/emoji.png',
-              },
-            },
-          ],
-        }
-      end
-
-      it 'creates status' do
-        status = sender.statuses.first
-        expect(status).to_not be_nil
-      end
-    end
-
-    context 'with emojis missing icon' do
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum :tinking:',
-          tag: [
-            {
-              type: 'Emoji',
-              name: 'tinking',
-            },
-          ],
-        }
-      end
-
-      it 'creates status' do
-        status = sender.statuses.first
-        expect(status).to_not be_nil
+      it 'does not create anything' do
+        expect(sender.statuses.count).to eq 0
       end
     end
   end
diff --git a/spec/lib/activitypub/activity/flag_spec.rb b/spec/lib/activitypub/activity/flag_spec.rb
index 3f082a813750b30d23ad3b9ad24b39195fd7d062..ec7359f2fe00bdeeded19ce10403d4959aa5b4d2 100644
--- a/spec/lib/activitypub/activity/flag_spec.rb
+++ b/spec/lib/activitypub/activity/flag_spec.rb
@@ -1,14 +1,15 @@
 require 'rails_helper'
 
 RSpec.describe ActivityPub::Activity::Flag do
-  let(:sender)  { Fabricate(:account, domain: 'example.com') }
+  let(:sender)  { Fabricate(:account, domain: 'example.com', uri: 'http://example.com/account') }
   let(:flagged) { Fabricate(:account) }
   let(:status)  { Fabricate(:status, account: flagged, uri: 'foobar') }
+  let(:flag_id) { nil }
 
   let(:json) do
     {
       '@context': 'https://www.w3.org/ns/activitystreams',
-      id: nil,
+      id: flag_id,
       type: 'Flag',
       content: 'Boo!!',
       actor: ActivityPub::TagManager.instance.uri_for(sender),
@@ -34,4 +35,22 @@ RSpec.describe ActivityPub::Activity::Flag do
       expect(report.status_ids).to eq [status.id]
     end
   end
+
+  describe '#perform with a defined uri' do
+    subject { described_class.new(json, sender) }
+    let (:flag_id) { 'http://example.com/reports/1' }
+
+    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]
+      expect(report.uri).to eq flag_id
+    end
+  end
 end
diff --git a/spec/lib/activitypub/adapter_spec.rb b/spec/lib/activitypub/adapter_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ea03797aab2819a7a5da31456ae7928150cc9d1a
--- /dev/null
+++ b/spec/lib/activitypub/adapter_spec.rb
@@ -0,0 +1,88 @@
+require 'rails_helper'
+
+RSpec.describe ActivityPub::Adapter do
+  class TestObject < ActiveModelSerializers::Model
+    attributes :foo
+  end
+
+  class TestWithBasicContextSerializer < ActivityPub::Serializer
+    attributes :foo
+  end
+
+  class TestWithNamedContextSerializer < ActivityPub::Serializer
+    context :security
+    attributes :foo
+  end
+
+  class TestWithNestedNamedContextSerializer < ActivityPub::Serializer
+    attributes :foo
+
+    has_one :virtual_object, key: :baz, serializer: TestWithNamedContextSerializer
+
+    def virtual_object
+      object
+    end
+  end
+
+  class TestWithContextExtensionSerializer < ActivityPub::Serializer
+    context_extensions :sensitive
+    attributes :foo
+  end
+
+  class TestWithNestedContextExtensionSerializer < ActivityPub::Serializer
+    context_extensions :manually_approves_followers
+    attributes :foo
+
+    has_one :virtual_object, key: :baz, serializer: TestWithContextExtensionSerializer
+
+    def virtual_object
+      object
+    end
+  end
+
+  describe '#serializable_hash' do
+    let(:serializer_class) {}
+
+    subject { ActiveModelSerializers::SerializableResource.new(TestObject.new(foo: 'bar'), serializer: serializer_class, adapter: described_class).as_json }
+
+    context 'when serializer defines no context' do
+      let(:serializer_class) { TestWithBasicContextSerializer }
+
+      it 'renders a basic @context' do
+        expect(subject).to include({ '@context' => 'https://www.w3.org/ns/activitystreams' })
+      end
+    end
+
+    context 'when serializer defines a named context' do
+      let(:serializer_class) { TestWithNamedContextSerializer }
+
+      it 'renders a @context with both items' do
+        expect(subject).to include({ '@context' => ['https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/v1'] })
+      end
+    end
+
+    context 'when serializer has children that define a named context' do
+      let(:serializer_class) { TestWithNestedNamedContextSerializer }
+
+      it 'renders a @context with both items' do
+        expect(subject).to include({ '@context' => ['https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/v1'] })
+      end
+    end
+
+    context 'when serializer defines context extensions' do
+      let(:serializer_class) { TestWithContextExtensionSerializer }
+
+      it 'renders a @context with the extension' do
+        expect(subject).to include({ '@context' => ['https://www.w3.org/ns/activitystreams', { 'sensitive' => 'as:sensitive' }] })
+      end
+    end
+
+    context 'when serializer has children that define context extensions' do
+      let(:serializer_class) { TestWithNestedContextExtensionSerializer }
+
+      it 'renders a @context with both extensions' do
+        expect(subject).to include({ '@context' => ['https://www.w3.org/ns/activitystreams', { 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers', 'sensitive' => 'as:sensitive' }] })
+      end
+    end
+  end
+end
diff --git a/spec/lib/activitypub/tag_manager_spec.rb b/spec/lib/activitypub/tag_manager_spec.rb
index 0d16652169dfbdc8248edae23de5eec216653590..6d246629e786d3b6dfacc407af4f5bb602ce55bb 100644
--- a/spec/lib/activitypub/tag_manager_spec.rb
+++ b/spec/lib/activitypub/tag_manager_spec.rb
@@ -41,6 +41,22 @@ RSpec.describe ActivityPub::TagManager do
       status.mentions.create(account: mentioned)
       expect(subject.to(status)).to eq [subject.uri_for(mentioned)]
     end
+
+    it "returns URIs of mentions for direct silenced author's status only if they are followers or requesting to be" do
+      bob    = Fabricate(:account, username: 'bob')
+      alice  = Fabricate(:account, username: 'alice')
+      foo    = Fabricate(:account)
+      author = Fabricate(:account, username: 'author', silenced: true)
+      status = Fabricate(:status, visibility: :direct, account: author)
+      bob.follow!(author)
+      FollowRequest.create!(account: foo, target_account: author)
+      status.mentions.create(account: alice)
+      status.mentions.create(account: bob)
+      status.mentions.create(account: foo)
+      expect(subject.to(status)).to include(subject.uri_for(bob))
+      expect(subject.to(status)).to include(subject.uri_for(foo))
+      expect(subject.to(status)).to_not include(subject.uri_for(alice))
+    end
   end
 
   describe '#cc' do
@@ -70,6 +86,22 @@ RSpec.describe ActivityPub::TagManager do
       status.mentions.create(account: mentioned)
       expect(subject.cc(status)).to include(subject.uri_for(mentioned))
     end
+
+    it "returns URIs of mentions for silenced author's non-direct status only if they are followers or requesting to be" do
+      bob    = Fabricate(:account, username: 'bob')
+      alice  = Fabricate(:account, username: 'alice')
+      foo    = Fabricate(:account)
+      author = Fabricate(:account, username: 'author', silenced: true)
+      status = Fabricate(:status, visibility: :public, account: author)
+      bob.follow!(author)
+      FollowRequest.create!(account: foo, target_account: author)
+      status.mentions.create(account: alice)
+      status.mentions.create(account: bob)
+      status.mentions.create(account: foo)
+      expect(subject.cc(status)).to include(subject.uri_for(bob))
+      expect(subject.cc(status)).to include(subject.uri_for(foo))
+      expect(subject.cc(status)).to_not include(subject.uri_for(alice))
+    end
   end
 
   describe '#local_uri?' do
diff --git a/spec/lib/feed_manager_spec.rb b/spec/lib/feed_manager_spec.rb
index c506cd87f171db43229ea4e2dec1fee8e0d1b6d9..b996997b1367e51bff7b83bfc15ea47085122772 100644
--- a/spec/lib/feed_manager_spec.rb
+++ b/spec/lib/feed_manager_spec.rb
@@ -149,6 +149,14 @@ RSpec.describe FeedManager do
           status = Fabricate(:status, text: 'shiitake', account: jeff)
           expect(FeedManager.instance.filter?(:home, status, alice.id)).to be true
         end
+
+        it 'returns true if phrase is contained in a poll option' do
+          alice.custom_filters.create!(phrase: 'farts', context: %w(home public), irreversible: true)
+          alice.custom_filters.create!(phrase: 'pop tarts', context: %w(home), irreversible: true)
+          alice.follow!(jeff)
+          status = Fabricate(:status, text: 'what do you prefer', poll: Fabricate(:poll, options: %w(farts POP TARts)), account: jeff)
+          expect(FeedManager.instance.filter?(:home, status, alice.id)).to be true
+        end
       end
     end
 
@@ -168,13 +176,13 @@ RSpec.describe FeedManager do
 
       it 'returns true for status by silenced account who recipient is not following' do
         status = Fabricate(:status, text: 'Hello world', account: alice)
-        alice.update(silenced: true)
+        alice.silence!
         expect(FeedManager.instance.filter?(:mentions, status, bob.id)).to be true
       end
 
       it 'returns false for status by followed silenced account' do
         status = Fabricate(:status, text: 'Hello world', account: alice)
-        alice.update(silenced: true)
+        alice.silence!
         bob.follow!(alice)
         expect(FeedManager.instance.filter?(:mentions, status, bob.id)).to be false
       end
@@ -239,6 +247,23 @@ RSpec.describe FeedManager do
         expect(FeedManager.instance.push_to_home(account, reblogs.last)).to be false
       end
 
+      it 'saves a new reblog of a recently-reblogged status when previous reblog has been deleted' do
+        account = Fabricate(:account)
+        reblogged = Fabricate(:status)
+        old_reblog = Fabricate(:status, reblog: reblogged)
+
+        # The first reblog should be accepted
+        expect(FeedManager.instance.push_to_home(account, old_reblog)).to be true
+
+        # The first reblog should be successfully removed
+        expect(FeedManager.instance.unpush_from_home(account, old_reblog)).to be true
+
+        reblog = Fabricate(:status, reblog: reblogged)
+
+        # The second reblog should be accepted
+        expect(FeedManager.instance.push_to_home(account, reblog)).to be true
+      end
+
       it 'does not save a new reblog of a multiply-reblogged-then-unreblogged status' do
         account   = Fabricate(:account)
         reblogged = Fabricate(:status)
diff --git a/spec/lib/formatter_spec.rb b/spec/lib/formatter_spec.rb
index 0c1efe7c3cc763799e0e5c77ab1ef820f7d2d3b1..b8108a247716ced195b017e3aac3ffb2403ee37c 100644
--- a/spec/lib/formatter_spec.rb
+++ b/spec/lib/formatter_spec.rb
@@ -74,10 +74,36 @@ RSpec.describe Formatter do
     end
 
     context 'given a URL with a query string' do
-      let(:text) { 'https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&q=autolink' }
+      context 'with escaped unicode character' do
+        let(:text) { 'https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&q=autolink' }
 
-      it 'matches the full URL' do
-        is_expected.to include 'href="https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&amp;q=autolink"'
+        it 'matches the full URL' do
+          is_expected.to include 'href="https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&amp;q=autolink"'
+        end
+      end
+
+      context 'with unicode character' do
+        let(:text) { 'https://www.ruby-toolbox.com/search?utf8=✓&q=autolink' }
+
+        it 'matches the full URL' do
+          is_expected.to include 'href="https://www.ruby-toolbox.com/search?utf8=✓&amp;q=autolink"'
+        end
+      end
+
+      context 'with unicode character at the end' do
+        let(:text) { 'https://www.ruby-toolbox.com/search?utf8=✓' }
+
+        it 'matches the full URL' do
+          is_expected.to include 'href="https://www.ruby-toolbox.com/search?utf8=✓"'
+        end
+      end
+
+      context 'with escaped and not escaped unicode characters' do
+        let(:text) { 'https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&utf81=✓&q=autolink' }
+
+        it 'preserves escaped unicode characters' do
+          is_expected.to include 'href="https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&amp;utf81=✓&amp;q=autolink"'
+        end
       end
     end
 
@@ -89,6 +115,22 @@ RSpec.describe Formatter do
       end
     end
 
+    context 'given a URL in quotation marks' do
+      let(:text) { '"https://example.com/"' }
+
+      it 'does not match the quotation marks' do
+        is_expected.to include 'href="https://example.com/"'
+      end
+    end
+
+    context 'given a URL in angle brackets' do
+      let(:text) { '<https://example.com/>' }
+
+      it 'does not match the angle brackets' do
+        is_expected.to include 'href="https://example.com/"'
+      end
+    end
+
     context 'given a URL with Japanese path string' do
       let(:text) { 'https://ja.wikipedia.org/wiki/日本' }
 
@@ -105,6 +147,22 @@ RSpec.describe Formatter do
       end
     end
 
+    context 'given a URL with a full-width space' do
+      let(:text) { 'https://example.com/ abc123' }
+
+      it 'does not match the full-width space' do
+        is_expected.to include 'href="https://example.com/"'
+      end
+    end
+
+    context 'given a URL in Japanese quotation marks' do
+      let(:text) { '「[https://example.org/」' }
+
+      it 'does not match the quotation marks' do
+        is_expected.to include 'href="https://example.org/"'
+      end
+    end
+
     context 'given a URL with Simplified Chinese path string' do
       let(:text) { 'https://baike.baidu.com/item/中华人民共和国' }
 
@@ -124,7 +182,11 @@ RSpec.describe Formatter do
     context 'given a URL containing unsafe code (XSS attack, visible part)' do
       let(:text) { %q{http://example.com/b<del>b</del>} }
 
-      it 'escapes the HTML in the URL' do
+      it 'does not include the HTML in the URL' do
+        is_expected.to include '"http://example.com/b"'
+      end
+
+      it 'escapes the HTML' do
         is_expected.to include '&lt;del&gt;b&lt;/del&gt;'
       end
     end
@@ -132,7 +194,11 @@ RSpec.describe Formatter do
     context 'given a URL containing unsafe code (XSS attack, invisible part)' do
       let(:text) { %q{http://example.com/blahblahblahblah/a<script>alert("Hello")</script>} }
 
-      it 'escapes the HTML in the URL' do
+      it 'does not include the HTML in the URL' do
+        is_expected.to include '"http://example.com/blahblahblahblah/a"'
+      end
+
+      it 'escapes the HTML' do
         is_expected.to include '&lt;script&gt;alert(&quot;Hello&quot;)&lt;/script&gt;'
       end
     end
@@ -168,6 +234,14 @@ RSpec.describe Formatter do
         is_expected.to include '/tags/hashtag" class="mention hashtag" rel="tag">#<span>hashtag</span></a>'
       end
     end
+
+    context 'given text containing a hashtag with Unicode chars' do
+      let(:text)  { '#hashtagã‚¿ã‚°' }
+
+      it 'creates a hashtag link' do
+        is_expected.to include '/tags/hashtag%E3%82%BF%E3%82%B0" class="mention hashtag" rel="tag">#<span>hashtagã‚¿ã‚°</span></a>'
+      end
+    end
   end
 
   describe '#format_spoiler' do
@@ -187,7 +261,7 @@ RSpec.describe Formatter do
       let(:text) { ':coolcat: Beep boop' }
 
       it 'converts the shortcode to an image tag' do
-        is_expected.to match(/<img draggable="false" class="emojione" alt=":coolcat:"/)
+        is_expected.to match(/<img draggable="false" class="emojione custom-emoji" alt=":coolcat:"/)
       end
     end
   end
@@ -256,7 +330,7 @@ RSpec.describe Formatter do
           let(:text) { ':coolcat: Beep boop' }
 
           it 'converts the shortcode to an image tag' do
-            is_expected.to match(/<p><img draggable="false" class="emojione" alt=":coolcat:"/)
+            is_expected.to match(/<p><img draggable="false" class="emojione custom-emoji" alt=":coolcat:"/)
           end
         end
 
@@ -264,7 +338,7 @@ RSpec.describe Formatter do
           let(:text) { 'Beep :coolcat: boop' }
 
           it 'converts the shortcode to an image tag' do
-            is_expected.to match(/Beep <img draggable="false" class="emojione" alt=":coolcat:"/)
+            is_expected.to match(/Beep <img draggable="false" class="emojione custom-emoji" alt=":coolcat:"/)
           end
         end
 
@@ -280,7 +354,7 @@ RSpec.describe Formatter do
           let(:text) { 'Beep boop :coolcat:' }
 
           it 'converts the shortcode to an image tag' do
-            is_expected.to match(/boop <img draggable="false" class="emojione" alt=":coolcat:"/)
+            is_expected.to match(/boop <img draggable="false" class="emojione custom-emoji" alt=":coolcat:"/)
           end
         end
       end
@@ -303,7 +377,7 @@ RSpec.describe Formatter do
           let(:text) { '<p>:coolcat: Beep boop<br />' }
 
           it 'converts the shortcode to an image tag' do
-            is_expected.to match(/<p><img draggable="false" class="emojione" alt=":coolcat:"/)
+            is_expected.to match(/<p><img draggable="false" class="emojione custom-emoji" alt=":coolcat:"/)
           end
         end
 
@@ -311,7 +385,7 @@ RSpec.describe Formatter do
           let(:text) { '<p>Beep :coolcat: boop</p>' }
 
           it 'converts the shortcode to an image tag' do
-            is_expected.to match(/Beep <img draggable="false" class="emojione" alt=":coolcat:"/)
+            is_expected.to match(/Beep <img draggable="false" class="emojione custom-emoji" alt=":coolcat:"/)
           end
         end
 
@@ -327,7 +401,7 @@ RSpec.describe Formatter do
           let(:text) { '<p>Beep boop<br />:coolcat:</p>' }
 
           it 'converts the shortcode to an image tag' do
-            is_expected.to match(/<br><img draggable="false" class="emojione" alt=":coolcat:"/)
+            is_expected.to match(/<br><img draggable="false" class="emojione custom-emoji" alt=":coolcat:"/)
           end
         end
       end
@@ -426,7 +500,7 @@ RSpec.describe Formatter do
           let(:text) { ':coolcat: Beep boop' }
 
           it 'converts the shortcode to an image tag' do
-            is_expected.to match(/<p><img draggable="false" class="emojione" alt=":coolcat:"/)
+            is_expected.to match(/<p><img draggable="false" class="emojione custom-emoji" alt=":coolcat:"/)
           end
         end
 
@@ -434,7 +508,7 @@ RSpec.describe Formatter do
           let(:text) { 'Beep :coolcat: boop' }
 
           it 'converts the shortcode to an image tag' do
-            is_expected.to match(/Beep <img draggable="false" class="emojione" alt=":coolcat:"/)
+            is_expected.to match(/Beep <img draggable="false" class="emojione custom-emoji" alt=":coolcat:"/)
           end
         end
 
@@ -450,7 +524,7 @@ RSpec.describe Formatter do
           let(:text) { 'Beep boop :coolcat:' }
 
           it 'converts the shortcode to an image tag' do
-            is_expected.to match(/boop <img draggable="false" class="emojione" alt=":coolcat:"/)
+            is_expected.to match(/boop <img draggable="false" class="emojione custom-emoji" alt=":coolcat:"/)
           end
         end
       end
@@ -477,7 +551,7 @@ RSpec.describe Formatter do
           let(:text) { '<p>:coolcat: Beep boop<br />' }
 
           it 'converts shortcode to image tag' do
-            is_expected.to match(/<p><img draggable="false" class="emojione" alt=":coolcat:"/)
+            is_expected.to match(/<p><img draggable="false" class="emojione custom-emoji" alt=":coolcat:"/)
           end
         end
 
@@ -485,7 +559,7 @@ RSpec.describe Formatter do
           let(:text) { '<p>Beep :coolcat: boop</p>' }
 
           it 'converts shortcode to image tag' do
-            is_expected.to match(/Beep <img draggable="false" class="emojione" alt=":coolcat:"/)
+            is_expected.to match(/Beep <img draggable="false" class="emojione custom-emoji" alt=":coolcat:"/)
           end
         end
 
@@ -501,7 +575,7 @@ RSpec.describe Formatter do
           let(:text) { '<p>Beep boop<br />:coolcat:</p>' }
 
           it 'converts shortcode to image tag' do
-            is_expected.to match(/<br><img draggable="false" class="emojione" alt=":coolcat:"/)
+            is_expected.to match(/<br><img draggable="false" class="emojione custom-emoji" alt=":coolcat:"/)
           end
         end
       end
diff --git a/spec/lib/language_detector_spec.rb b/spec/lib/language_detector_spec.rb
index 0fa2a59eff9150830de9bfa4f61f6e722d2ccfd4..b7ba0f6c4f4ac9e924176b40991d8f73e7739668 100644
--- a/spec/lib/language_detector_spec.rb
+++ b/spec/lib/language_detector_spec.rb
@@ -32,11 +32,11 @@ describe LanguageDetector do
       expect(result).to eq 'Our website is and also'
     end
 
-    it 'strips #hashtags from strings before detection' do
-      string = 'Hey look at all the #animals and #fish'
+    it 'converts #hashtags back to normal text before detection' do
+      string = 'Hey look at all the #animals and #FishAndChips'
 
       result = described_class.instance.send(:prepare_text, string)
-      expect(result).to eq 'Hey look at all the and'
+      expect(result).to eq 'Hey look at all the animals and fish and chips'
     end
   end
 
@@ -106,11 +106,11 @@ describe LanguageDetector do
       end
 
       describe 'remote user' do
-        it 'nil for foreign user when language is not present' do
+        it 'detects Korean language' do
           string = '안녕하세요'
           result = described_class.instance.detect(string, account_remote)
 
-          expect(result).to eq nil
+          expect(result).to eq :ko
         end
       end
 
diff --git a/spec/lib/proof_provider/keybase/verifier_spec.rb b/spec/lib/proof_provider/keybase/verifier_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0081a735df0ca28925fbe4d2eb596c3f41afd27c
--- /dev/null
+++ b/spec/lib/proof_provider/keybase/verifier_spec.rb
@@ -0,0 +1,82 @@
+require 'rails_helper'
+
+describe ProofProvider::Keybase::Verifier do
+  let(:my_domain) { Rails.configuration.x.local_domain }
+
+  let(:keybase_proof) do
+    local_proof = AccountIdentityProof.new(
+      provider: 'Keybase',
+      provider_username: 'cryptoalice',
+      token: '11111111111111111111111111'
+    )
+
+    described_class.new('alice', 'cryptoalice', '11111111111111111111111111', my_domain)
+  end
+
+  let(:query_params) do
+    "domain=#{my_domain}&kb_username=cryptoalice&sig_hash=11111111111111111111111111&username=alice"
+  end
+
+  describe '#valid?' do
+    let(:base_url) { 'https://keybase.io/_/api/1.0/sig/proof_valid.json' }
+
+    context 'when valid' do
+      before do
+        json_response_body = '{"status":{"code":0,"name":"OK"},"proof_valid":true}'
+        stub_request(:get, "#{base_url}?#{query_params}").to_return(status: 200, body: json_response_body)
+      end
+
+      it 'calls out to keybase and returns true' do
+        expect(keybase_proof.valid?).to eq true
+      end
+    end
+
+    context 'when invalid' do
+      before do
+        json_response_body = '{"status":{"code":0,"name":"OK"},"proof_valid":false}'
+        stub_request(:get, "#{base_url}?#{query_params}").to_return(status: 200, body: json_response_body)
+      end
+
+      it 'calls out to keybase and returns false' do
+        expect(keybase_proof.valid?).to eq false
+      end
+    end
+
+    context 'with an unexpected api response' do
+      before do
+        json_response_body = '{"status":{"code":100,"desc":"wrong size hex_id","fields":{"sig_hash":"wrong size hex_id"},"name":"INPUT_ERROR"}}'
+        stub_request(:get, "#{base_url}?#{query_params}").to_return(status: 200, body: json_response_body)
+      end
+
+      it 'swallows the error and returns false' do
+        expect(keybase_proof.valid?).to eq false
+      end
+    end
+  end
+
+  describe '#status' do
+    let(:base_url) { 'https://keybase.io/_/api/1.0/sig/proof_live.json' }
+
+    context 'with a normal response' do
+      before do
+        json_response_body = '{"status":{"code":0,"name":"OK"},"proof_live":false,"proof_valid":true}'
+        stub_request(:get, "#{base_url}?#{query_params}").to_return(status: 200, body: json_response_body)
+      end
+
+      it 'calls out to keybase and returns the status fields as proof_valid and proof_live' do
+        expect(keybase_proof.status).to include({ 'proof_valid' => true, 'proof_live' => false })
+      end
+    end
+
+    context 'with an unexpected keybase response' do
+      before do
+        json_response_body = '{"status":{"code":100,"desc":"missing non-optional field sig_hash","fields":{"sig_hash":"missing non-optional field sig_hash"},"name":"INPUT_ERROR"}}'
+        stub_request(:get, "#{base_url}?#{query_params}").to_return(status: 200, body: json_response_body)
+      end
+
+      it 'raises a ProofProvider::Keybase::UnexpectedResponseError' do
+        expect { keybase_proof.status }.to raise_error ProofProvider::Keybase::UnexpectedResponseError
+      end
+    end
+  end
+end
diff --git a/spec/lib/sanitize_config_spec.rb b/spec/lib/sanitize_config_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..54bd8693cc871103b6f45026c536843701019a3f
--- /dev/null
+++ b/spec/lib/sanitize_config_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require Rails.root.join('app', 'lib', 'sanitize_config.rb')
+
+describe Sanitize::Config do
+  describe '::MASTODON_STRICT' do
+    subject { Sanitize::Config::MASTODON_STRICT }
+
+    it 'converts h1 to p' do
+      expect(Sanitize.fragment('<h1>Foo</h1>', subject)).to eq '<p>Foo</p>'
+    end
+
+    it 'converts ul to p' do
+      expect(Sanitize.fragment('<p>Check out:</p><ul><li>Foo</li><li>Bar</li></ul>', subject)).to eq '<p>Check out:</p><p>Foo<br>Bar</p>'
+    end
+
+    it 'converts p inside ul' do
+      expect(Sanitize.fragment('<ul><li><p>Foo</p><p>Bar</p></li><li>Baz</li></ul>', subject)).to eq '<p>Foo<br>Bar<br>Baz</p>'
+    end
+
+    it 'converts ul inside ul' do
+      expect(Sanitize.fragment('<ul><li>Foo</li><li><ul><li>Bar</li><li>Baz</li></ul></li></ul>', subject)).to eq '<p>Foo<br>Bar<br>Baz</p>'
+    end
+
+    it 'keep links in lists' do
+      expect(Sanitize.fragment('<p>Check out:</p><ul><li><a href="https://joinmastodon.org" rel="nofollow noopener" target="_blank">joinmastodon.org</a></li><li>Bar</li></ul>', subject)).to eq '<p>Check out:</p><p><a href="https://joinmastodon.org" rel="nofollow noopener" target="_blank">joinmastodon.org</a><br>Bar</p>'
+    end
+  end
+end
diff --git a/spec/lib/status_filter_spec.rb b/spec/lib/status_filter_spec.rb
index db2d87de204d7c5f2ca276b78dffa621b75ad011..a851014d9c025ee76b946f8fb46a3aa6a84a2aa3 100644
--- a/spec/lib/status_filter_spec.rb
+++ b/spec/lib/status_filter_spec.rb
@@ -15,7 +15,7 @@ describe StatusFilter do
 
       context 'when status account is silenced' do
         before do
-          status.account.update(silenced: true)
+          status.account.silence!
         end
 
         it { is_expected.to be_filtered }
@@ -65,7 +65,7 @@ describe StatusFilter do
 
       context 'when status account is silenced' do
         before do
-          status.account.update(silenced: true)
+          status.account.silence!
         end
 
         it { is_expected.to be_filtered }
diff --git a/spec/mailers/previews/admin_mailer_preview.rb b/spec/mailers/previews/admin_mailer_preview.rb
new file mode 100644
index 0000000000000000000000000000000000000000..561a56b7874ee5bfdd143bf7b9ed17545284c1f1
--- /dev/null
+++ b/spec/mailers/previews/admin_mailer_preview.rb
@@ -0,0 +1,8 @@
+# Preview all emails at http://localhost:3000/rails/mailers/admin_mailer
+
+class AdminMailerPreview < ActionMailer::Preview
+  # Preview this email at http://localhost:3000/rails/mailers/admin_mailer/new_pending_account
+  def new_pending_account
+    AdminMailer.new_pending_account(Account.first, User.pending.first)
+  end
+end
diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb
index 47b22719334c5de3229e4899c546a9f76ec0e93e..363bf94d6c1a5014491630ce657dca746beef273 100644
--- a/spec/models/account_spec.rb
+++ b/spec/models/account_spec.rb
@@ -558,6 +558,11 @@ RSpec.describe Account, type: :model do
       expect(account).to model_have_error_on_field(:username)
     end
 
+    it 'squishes the username before validation' do
+      account = Fabricate(:account, domain: nil, username: " \u3000bob \t \u00a0 \n ")
+      expect(account.username).to eq 'bob'
+    end
+
     context 'when is local' do
       it 'is invalid if the username is not unique in case-insensitive comparison among local accounts' do
         account_1 = Fabricate(:account, username: 'the_doctor')
@@ -682,6 +687,23 @@ RSpec.describe Account, type: :model do
       end
     end
 
+    describe 'by_domain_and_subdomains' do
+      it 'returns exact domain matches' do
+        account = Fabricate(:account, domain: 'example.com')
+        expect(Account.by_domain_and_subdomains('example.com')).to eq [account]
+      end
+
+      it 'returns subdomains' do
+        account = Fabricate(:account, domain: 'foo.example.com')
+        expect(Account.by_domain_and_subdomains('example.com')).to eq [account]
+      end
+
+      it 'does not return partially matching domains' do
+        account = Fabricate(:account, domain: 'grexample.com')
+        expect(Account.by_domain_and_subdomains('example.com')).to_not eq [account]
+      end
+    end
+
     describe 'expiring' do
       it 'returns remote accounts with followers whose subscription expiration date is past or not given' do
         local = Fabricate(:account, domain: nil)
diff --git a/spec/models/concerns/account_interactions_spec.rb b/spec/models/concerns/account_interactions_spec.rb
index 8df52b77067cd815ef3b2ac2ac36fe22b03b3d08..e8ef61f66cc1a14419259628f3bec6c81613c865 100644
--- a/spec/models/concerns/account_interactions_spec.rb
+++ b/spec/models/concerns/account_interactions_spec.rb
@@ -237,9 +237,9 @@ describe AccountInteractions do
   end
 
   describe '#block_domain!' do
-    let(:domain_block) { Fabricate(:domain_block) }
+    let(:domain) { 'example.com' }
 
-    subject { account.block_domain!(domain_block) }
+    subject { account.block_domain!(domain) }
 
     it 'creates and returns AccountDomainBlock' do
       expect do
diff --git a/spec/models/concerns/status_threading_concern_spec.rb b/spec/models/concerns/status_threading_concern_spec.rb
index 94c2d5fc2e84e95007f2e54acbabe76f2e316b92..50286ef77b9c9fb915109f39e1366d55cc6dd9e1 100644
--- a/spec/models/concerns/status_threading_concern_spec.rb
+++ b/spec/models/concerns/status_threading_concern_spec.rb
@@ -35,7 +35,7 @@ describe StatusThreadingConcern do
     end
 
     it 'does not return conversation history from silenced and not followed users' do
-      jeff.update(silenced: true)
+      jeff.silence!
       expect(reply3.ancestors(4, viewer)).to_not include(reply1)
     end
 
@@ -110,7 +110,7 @@ describe StatusThreadingConcern do
     end
 
     it 'does not return replies from silenced and not followed users' do
-      jeff.update(silenced: true)
+      jeff.silence!
       expect(status.descendants(4, viewer)).to_not include(reply3)
     end
 
diff --git a/spec/models/domain_block_spec.rb b/spec/models/domain_block_spec.rb
index 89cadccfec2b33d00a8b9c982c444f5f17b2b8a3..d98c5e11863030c11bbf694496b2d14db93335d5 100644
--- a/spec/models/domain_block_spec.rb
+++ b/spec/models/domain_block_spec.rb
@@ -21,19 +21,67 @@ RSpec.describe DomainBlock, type: :model do
     end
   end
 
-  describe 'blocked?' do
+  describe '.blocked?' do
     it 'returns true if the domain is suspended' do
-      Fabricate(:domain_block, domain: 'domain', severity: :suspend)
-      expect(DomainBlock.blocked?('domain')).to eq true
+      Fabricate(:domain_block, domain: 'example.com', severity: :suspend)
+      expect(DomainBlock.blocked?('example.com')).to eq true
     end
 
     it 'returns false even if the domain is silenced' do
-      Fabricate(:domain_block, domain: 'domain', severity: :silence)
-      expect(DomainBlock.blocked?('domain')).to eq false
+      Fabricate(:domain_block, domain: 'example.com', severity: :silence)
+      expect(DomainBlock.blocked?('example.com')).to eq false
     end
 
     it 'returns false if the domain is not suspended nor silenced' do
-      expect(DomainBlock.blocked?('domain')).to eq false
+      expect(DomainBlock.blocked?('example.com')).to eq false
+    end
+  end
+
+  describe '.rule_for' do
+    it 'returns rule matching a blocked domain' do
+      block = Fabricate(:domain_block, domain: 'example.com')
+      expect(DomainBlock.rule_for('example.com')).to eq block
+    end
+
+    it 'returns a rule matching a subdomain of a blocked domain' do
+      block = Fabricate(:domain_block, domain: 'example.com')
+      expect(DomainBlock.rule_for('sub.example.com')).to eq block
+    end
+
+    it 'returns a rule matching a blocked subdomain' do
+      block = Fabricate(:domain_block, domain: 'sub.example.com')
+      expect(DomainBlock.rule_for('sub.example.com')).to eq block
+    end
+  end
+
+  describe '#stricter_than?' do
+    it 'returns true if the new block has suspend severity while the old has lower severity' do
+      suspend = DomainBlock.new(domain: 'domain', severity: :suspend)
+      silence = DomainBlock.new(domain: 'domain', severity: :silence)
+      noop = DomainBlock.new(domain: 'domain', severity: :noop)
+      expect(suspend.stricter_than?(silence)).to be true
+      expect(suspend.stricter_than?(noop)).to be true
+    end
+
+    it 'returns false if the new block has lower severity than the old one' do
+      suspend = DomainBlock.new(domain: 'domain', severity: :suspend)
+      silence = DomainBlock.new(domain: 'domain', severity: :silence)
+      noop = DomainBlock.new(domain: 'domain', severity: :noop)
+      expect(silence.stricter_than?(suspend)).to be false
+      expect(noop.stricter_than?(suspend)).to be false
+      expect(noop.stricter_than?(silence)).to be false
+    end
+
+    it 'returns false if the new block does is less strict regarding reports' do
+      older = DomainBlock.new(domain: 'domain', severity: :silence, reject_reports: true)
+      newer = DomainBlock.new(domain: 'domain', severity: :silence, reject_reports: false)
+      expect(newer.stricter_than?(older)).to be false
+    end
+
+    it 'returns false if the new block does is less strict regarding media' do
+      older = DomainBlock.new(domain: 'domain', severity: :silence, reject_media: true)
+      newer = DomainBlock.new(domain: 'domain', severity: :silence, reject_media: false)
+      expect(newer.stricter_than?(older)).to be false
     end
   end
 end
diff --git a/spec/models/export_spec.rb b/spec/models/export_spec.rb
index 277dcc526498858f20a160bb391a5a27d541f6c2..4e6b824bbe4b164feee2314799e82e8f26d4890f 100644
--- a/spec/models/export_spec.rb
+++ b/spec/models/export_spec.rb
@@ -21,20 +21,22 @@ describe Export do
       target_accounts.each(&account.method(:mute!))
 
       export = Export.new(account).to_muted_accounts_csv
-      results = export.strip.split
+      results = export.strip.split("\n")
 
-      expect(results.size).to eq 2
-      expect(results.first).to eq 'one@local.host'
+      expect(results.size).to eq 3
+      expect(results.first).to eq 'Account address,Hide notifications'
+      expect(results.second).to eq 'one@local.host,true'
     end
 
     it 'returns a csv of the following accounts' do
       target_accounts.each(&account.method(:follow!))
 
       export = Export.new(account).to_following_accounts_csv
-      results = export.strip.split
+      results = export.strip.split("\n")
 
-      expect(results.size).to eq 2
-      expect(results.first).to eq 'one@local.host'
+      expect(results.size).to eq 3
+      expect(results.first).to eq 'Account address,Show boosts'
+      expect(results.second).to eq 'one@local.host,true'
     end
   end
 
diff --git a/spec/models/featured_tag_spec.rb b/spec/models/featured_tag_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..07533e0b90c8c267aaa389ea75eafe5058878216
--- /dev/null
+++ b/spec/models/featured_tag_spec.rb
@@ -0,0 +1,4 @@
+require 'rails_helper'
+
+RSpec.describe FeaturedTag, type: :model do
+end
diff --git a/spec/models/invite_spec.rb b/spec/models/invite_spec.rb
index 0ba1dccb33c218b892c60c76878dbccb7fe986be..30abfb86bf4d882dd13add846b47c0e4408c4676 100644
--- a/spec/models/invite_spec.rb
+++ b/spec/models/invite_spec.rb
@@ -3,27 +3,33 @@ require 'rails_helper'
 RSpec.describe Invite, type: :model do
   describe '#valid_for_use?' do
     it 'returns true when there are no limitations' do
-      invite = Invite.new(max_uses: nil, expires_at: nil)
+      invite = Fabricate(:invite, max_uses: nil, expires_at: nil)
       expect(invite.valid_for_use?).to be true
     end
 
     it 'returns true when not expired' do
-      invite = Invite.new(max_uses: nil, expires_at: 1.hour.from_now)
+      invite = Fabricate(:invite, max_uses: nil, expires_at: 1.hour.from_now)
       expect(invite.valid_for_use?).to be true
     end
 
     it 'returns false when expired' do
-      invite = Invite.new(max_uses: nil, expires_at: 1.hour.ago)
+      invite = Fabricate(:invite, max_uses: nil, expires_at: 1.hour.ago)
       expect(invite.valid_for_use?).to be false
     end
 
     it 'returns true when uses still available' do
-      invite = Invite.new(max_uses: 250, uses: 249, expires_at: nil)
+      invite = Fabricate(:invite, max_uses: 250, uses: 249, expires_at: nil)
       expect(invite.valid_for_use?).to be true
     end
 
     it 'returns false when maximum uses reached' do
-      invite = Invite.new(max_uses: 250, uses: 250, expires_at: nil)
+      invite = Fabricate(:invite, max_uses: 250, uses: 250, expires_at: nil)
+      expect(invite.valid_for_use?).to be false
+    end
+
+    it 'returns false when invite creator has been disabled' do
+      invite = Fabricate(:invite, max_uses: nil, expires_at: nil)
+      SuspendAccountService.new.call(invite.user.account)
       expect(invite.valid_for_use?).to be false
     end
   end
diff --git a/spec/models/poll_spec.rb b/spec/models/poll_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..666f8ca6832a5f1f0599059fa8fa0556b5c9cb2a
--- /dev/null
+++ b/spec/models/poll_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe Poll, type: :model do
+  pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/models/poll_vote_spec.rb b/spec/models/poll_vote_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..354afd5350bd24da958398323795ff8aaf098bb1
--- /dev/null
+++ b/spec/models/poll_vote_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe PollVote, type: :model do
+  pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/models/tag_spec.rb b/spec/models/tag_spec.rb
index 1ca50cc29f69b2d386deb5e776d18ae3371c6e00..9a30ceaa527d34e23d354b9467d1262fa5c147d0 100644
--- a/spec/models/tag_spec.rb
+++ b/spec/models/tag_spec.rb
@@ -31,7 +31,47 @@ RSpec.describe Tag, type: :model do
     end
 
     it 'matches #aesthetic' do
-      expect(subject.match('this is #aesthetic')).to_not be_nil
+      expect(subject.match('this is #aesthetic').to_s).to eq ' #aesthetic'
+    end
+
+    it 'matches digits at the start' do
+      expect(subject.match('hello #3d').to_s).to eq ' #3d'
+    end
+
+    it 'matches digits in the middle' do
+      expect(subject.match('hello #l33ts35k').to_s).to eq ' #l33ts35k'
+    end
+
+    it 'matches digits at the end' do
+      expect(subject.match('hello #world2016').to_s).to eq ' #world2016'
+    end
+
+    it 'matches underscores at the beginning' do
+      expect(subject.match('hello #_test').to_s).to eq ' #_test'
+    end
+
+    it 'matches underscores at the end' do
+      expect(subject.match('hello #test_').to_s).to eq ' #test_'
+    end
+
+    it 'matches underscores in the middle' do
+      expect(subject.match('hello #one_two_three').to_s).to eq ' #one_two_three'
+    end
+
+    it 'matches middle dots' do
+      expect(subject.match('hello #one·two·three').to_s).to eq ' #one·two·three'
+    end
+
+    it 'does not match middle dots at the start' do
+      expect(subject.match('hello #·one·two·three')).to be_nil
+    end
+
+    it 'does not match middle dots at the end' do
+      expect(subject.match('hello #one·two·three·').to_s).to eq ' #one·two·three'
+    end
+
+    it 'does not match purely-numeric hashtags' do
+      expect(subject.match('hello #0123456')).to be_nil
     end
   end
 
diff --git a/spec/models/user_invite_request_spec.rb b/spec/models/user_invite_request_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1be38d8a47784ec26340ca608b17d7e1ab1566ec
--- /dev/null
+++ b/spec/models/user_invite_request_spec.rb
@@ -0,0 +1,4 @@
+require 'rails_helper'
+
+RSpec.describe UserInviteRequest, type: :model do
+end
diff --git a/spec/presenters/instance_presenter_spec.rb b/spec/presenters/instance_presenter_spec.rb
index 0babc1b0c8a36e1e47e034acf05674a11bbf81e4..93a4e88e4136f5ac4801ec68d9505d3038612f1b 100644
--- a/spec/presenters/instance_presenter_spec.rb
+++ b/spec/presenters/instance_presenter_spec.rb
@@ -31,34 +31,6 @@ describe InstancePresenter do
     end
   end
 
-  context do
-    around do |example|
-      open_registrations = Setting.open_registrations
-      example.run
-      Setting.open_registrations = open_registrations
-    end
-
-    it "delegates open_registrations to Setting" do
-      Setting.open_registrations = false
-
-      expect(instance_presenter.open_registrations).to eq false
-    end
-  end
-
-  context do
-    around do |example|
-      closed_registrations_message = Setting.closed_registrations_message
-      example.run
-      Setting.closed_registrations_message = closed_registrations_message
-    end
-
-    it "delegates closed_registrations_message to Setting" do
-      Setting.closed_registrations_message = "Closed message"
-
-      expect(instance_presenter.closed_registrations_message).to eq "Closed message"
-    end
-  end
-
   context do
     around do |example|
       site_contact_email = Setting.site_contact_email
diff --git a/spec/requests/localization_spec.rb b/spec/requests/localization_spec.rb
index f625a93a4fe302c084b96cf473ca15255671c03e..496a885e8d9126514f080c595c01b37cba0ea264 100644
--- a/spec/requests/localization_spec.rb
+++ b/spec/requests/localization_spec.rb
@@ -11,8 +11,9 @@ describe 'Localization' do
     headers = { 'Accept-Language' => 'zh-HK' }
 
     get "/about", headers: headers
+
     expect(response.body).to include(
-      I18n.t('about.about_mastodon_html', locale: 'zh-HK')
+      I18n.t('about.tagline', locale: 'zh-HK')
     )
   end
 
@@ -20,16 +21,18 @@ describe 'Localization' do
     headers = { 'Accept-Language' => 'es-FAKE' }
 
     get "/about", headers: headers
+
     expect(response.body).to include(
-      I18n.t('about.about_mastodon_html', locale: 'es')
+      I18n.t('about.tagline', locale: 'es')
     )
   end
   it 'falls back to english when locale is missing' do
     headers = { 'Accept-Language' => '12-FAKE' }
 
     get "/about", headers: headers
+
     expect(response.body).to include(
-      I18n.t('about.about_mastodon_html', locale: 'en')
+      I18n.t('about.tagline', locale: 'en')
     )
   end
 end
diff --git a/spec/serializers/activitypub/note_spec.rb b/spec/serializers/activitypub/note_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..55bfbc16bf8815f7c4718a3ad00335008f87a337
--- /dev/null
+++ b/spec/serializers/activitypub/note_spec.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe ActivityPub::NoteSerializer do
+  let!(:account) { Fabricate(:account) }
+  let!(:other)   { Fabricate(:account) }
+  let!(:parent)  { Fabricate(:status, account: account, visibility: :public) }
+  let!(:reply1)  { Fabricate(:status, account: account, thread: parent, visibility: :public) }
+  let!(:reply2)  { Fabricate(:status, account: account, thread: parent, visibility: :public) }
+  let!(:reply3)  { Fabricate(:status, account: other, thread: parent, visibility: :public) }
+  let!(:reply4)  { Fabricate(:status, account: account, thread: parent, visibility: :public) }
+  let!(:reply5)  { Fabricate(:status, account: account, thread: parent, visibility: :direct) }
+
+  before(:each) do
+    @serialization = ActiveModelSerializers::SerializableResource.new(parent, serializer: ActivityPub::NoteSerializer, adapter: ActivityPub::Adapter)
+  end
+
+  subject { JSON.parse(@serialization.to_json) }
+
+  it 'has a Note type' do
+    expect(subject['type']).to eql('Note')
+  end
+
+  it 'has a replies collection' do
+    expect(subject['replies']['type']).to eql('Collection')
+  end
+
+  it 'has a replies collection with a first Page' do
+    expect(subject['replies']['first']['type']).to eql('CollectionPage')
+  end
+
+  it 'includes public self-replies in its replies collection' do
+    expect(subject['replies']['first']['items']).to include(reply1.uri, reply2.uri, reply4.uri)
+  end
+
+  it 'does not include replies from others in its replies collection' do
+    expect(subject['replies']['first']['items']).to_not include(reply3.uri)
+  end
+
+  it 'does not include replies with direct visibility in its replies collection' do
+    expect(subject['replies']['first']['items']).to_not include(reply5.uri)
+  end
+end
diff --git a/spec/serializers/activitypub/update_poll_spec.rb b/spec/serializers/activitypub/update_poll_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f9e035eab581aa654cf1b9c14aa3697fe9759ca7
--- /dev/null
+++ b/spec/serializers/activitypub/update_poll_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe ActivityPub::UpdatePollSerializer do
+  let(:account) { Fabricate(:account) }
+  let(:poll)    { Fabricate(:poll, account: account) }
+  let!(:status) { Fabricate(:status, account: account, poll: poll) }
+
+  before(:each) do
+    @serialization = ActiveModelSerializers::SerializableResource.new(status, serializer: ActivityPub::UpdatePollSerializer, adapter: ActivityPub::Adapter)
+  end
+
+  subject { JSON.parse(@serialization.to_json) }
+
+  it 'has a Update type' do
+    expect(subject['type']).to eql('Update')
+  end
+
+  it 'has an object with Question type' do
+    expect(subject['object']['type']).to eql('Question')
+  end
+
+  it 'has the correct actor URI set' do
+    expect(subject['actor']).to eql(ActivityPub::TagManager.instance.uri_for(account))
+  end
+end
diff --git a/spec/services/account_search_service_spec.rb b/spec/services/account_search_service_spec.rb
index c6cbdcce109d91f04ed713bd9c3aea1fe0c735aa..7b071b378e04b06fe6894ad4090205982f85e7bf 100644
--- a/spec/services/account_search_service_spec.rb
+++ b/spec/services/account_search_service_spec.rb
@@ -4,18 +4,18 @@ describe AccountSearchService, type: :service do
   describe '.call' do
     describe 'with a query to ignore' do
       it 'returns empty array for missing query' do
-        results = subject.call('', 10)
+        results = subject.call('', nil, limit: 10)
 
         expect(results).to eq []
       end
       it 'returns empty array for hashtag query' do
-        results = subject.call('#tag', 10)
+        results = subject.call('#tag', nil, limit: 10)
 
         expect(results).to eq []
       end
       it 'returns empty array for limit zero' do
         Fabricate(:account, username: 'match')
-        results = subject.call('match', 0)
+        results = subject.call('match', nil, limit: 0)
 
         expect(results).to eq []
       end
@@ -25,7 +25,7 @@ describe AccountSearchService, type: :service do
       it 'does not return a nil entry in the array for the exact match' do
         match = Fabricate(:account, username: 'matchingusername')
 
-        results = subject.call('match', 5)
+        results = subject.call('match', nil, limit: 5)
         expect(results).to eq [match]
       end
     end
@@ -35,7 +35,7 @@ describe AccountSearchService, type: :service do
         before do
           allow(Account).to receive(:find_local)
           allow(Account).to receive(:search_for)
-          subject.call('@', 10)
+          subject.call('@', nil, limit: 10)
         end
 
         it 'uses find_local with empty query to look for local accounts' do
@@ -47,7 +47,7 @@ describe AccountSearchService, type: :service do
         before do
           allow(Account).to receive(:find_local)
           allow(Account).to receive(:search_for)
-          subject.call('one', 10)
+          subject.call('one', nil, limit: 10)
         end
 
         it 'uses find_local to look for local accounts' do
@@ -55,7 +55,7 @@ describe AccountSearchService, type: :service do
         end
 
         it 'uses search_for to find matches' do
-          expect(Account).to have_received(:search_for).with('one', 10)
+          expect(Account).to have_received(:search_for).with('one', 10, 0)
         end
       end
 
@@ -65,16 +65,16 @@ describe AccountSearchService, type: :service do
         end
 
         it 'uses find_remote to look for remote accounts' do
-          subject.call('two@example.com', 10)
+          subject.call('two@example.com', nil, limit: 10)
           expect(Account).to have_received(:find_remote).with('two', 'example.com')
         end
 
         describe 'and there is no account provided' do
           it 'uses search_for to find matches' do
             allow(Account).to receive(:search_for)
-            subject.call('two@example.com', 10, nil, resolve: false)
+            subject.call('two@example.com', nil, limit: 10, resolve: false)
 
-            expect(Account).to have_received(:search_for).with('two example.com', 10)
+            expect(Account).to have_received(:search_for).with('two example.com', 10, 0)
           end
         end
 
@@ -82,9 +82,9 @@ describe AccountSearchService, type: :service do
           it 'uses advanced_search_for to find matches' do
             account = Fabricate(:account)
             allow(Account).to receive(:advanced_search_for)
-            subject.call('two@example.com', 10, account, resolve: false)
+            subject.call('two@example.com', account, limit: 10, resolve: false)
 
-            expect(Account).to have_received(:advanced_search_for).with('two example.com', account, 10, nil)
+            expect(Account).to have_received(:advanced_search_for).with('two example.com', account, 10, nil, 0)
           end
         end
       end
@@ -95,7 +95,7 @@ describe AccountSearchService, type: :service do
         partial = Fabricate(:account, username: 'exactness')
         exact = Fabricate(:account, username: 'exact')
 
-        results = subject.call('exact', 10)
+        results = subject.call('exact', nil, limit: 10)
         expect(results.size).to eq 2
         expect(results).to eq [exact, partial]
       end
@@ -114,7 +114,7 @@ describe AccountSearchService, type: :service do
         exact = Fabricate(:account, username: 'e')
         Rails.configuration.x.local_domain = 'example.com'
 
-        results = subject.call('e@example.com', 2)
+        results = subject.call('e@example.com', nil, limit: 2)
         expect(results.size).to eq 2
         expect(results).to eq([exact, remote]).or eq([exact, remote_too])
       end
@@ -125,7 +125,7 @@ describe AccountSearchService, type: :service do
         service = double(call: nil)
         allow(ResolveAccountService).to receive(:new).and_return(service)
 
-        results = subject.call('newuser@remote.com', 10, nil, resolve: true)
+        results = subject.call('newuser@remote.com', nil, limit: 10, resolve: true)
         expect(service).to have_received(:call).with('newuser@remote.com')
       end
 
@@ -133,7 +133,7 @@ describe AccountSearchService, type: :service do
         service = double(call: nil)
         allow(ResolveAccountService).to receive(:new).and_return(service)
 
-        results = subject.call('newuser@remote.com', 10, nil, resolve: false)
+        results = subject.call('newuser@remote.com', nil, limit: 10, resolve: false)
         expect(service).not_to have_received(:call)
       end
     end
@@ -143,7 +143,7 @@ describe AccountSearchService, type: :service do
         partial = Fabricate(:account, username: 'exactness')
         exact = Fabricate(:account, username: 'exact', suspended: true)
 
-        results = subject.call('exact', 10)
+        results = subject.call('exact', nil, limit: 10)
         expect(results.size).to eq 1
         expect(results).to eq [partial]
       end
@@ -151,7 +151,7 @@ describe AccountSearchService, type: :service do
       it "does not return suspended remote accounts" do
         remote = Fabricate(:account, username: 'a', domain: 'remote', display_name: 'e', suspended: true)
 
-        results = subject.call('a@example.com', 2)
+        results = subject.call('a@example.com', nil, limit: 2)
         expect(results.size).to eq 0
         expect(results).to eq []
       end
diff --git a/spec/services/activitypub/fetch_replies_service_spec.rb b/spec/services/activitypub/fetch_replies_service_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..65c453341143ee5d9c36c6503ea895a0a8810c40
--- /dev/null
+++ b/spec/services/activitypub/fetch_replies_service_spec.rb
@@ -0,0 +1,122 @@
+require 'rails_helper'
+
+RSpec.describe ActivityPub::FetchRepliesService, type: :service do
+  let(:actor)          { Fabricate(:account, domain: 'example.com', uri: 'http://example.com/account') }
+  let(:status)         { Fabricate(:status, account: actor) }
+  let(:collection_uri) { 'http://example.com/replies/1' }
+
+  let(:items) do
+    [
+      'http://example.com/self-reply-1',
+      'http://example.com/self-reply-2',
+      'http://example.com/self-reply-3',
+      'http://other.com/other-reply-1',
+      'http://other.com/other-reply-2',
+      'http://other.com/other-reply-3',
+      'http://example.com/self-reply-4',
+      'http://example.com/self-reply-5',
+      'http://example.com/self-reply-6',
+    ]
+  end
+
+  let(:payload) do
+    {
+      '@context': 'https://www.w3.org/ns/activitystreams',
+      type: 'Collection',
+      id: collection_uri,
+      items: items,
+    }.with_indifferent_access
+  end
+
+  subject { described_class.new }
+
+  describe '#call' do
+    context 'when the payload is a Collection with inlined replies' do
+      context 'when passing the collection itself' do
+        it 'spawns workers for up to 5 replies on the same server' do
+          allow(FetchReplyWorker).to receive(:push_bulk)
+          subject.call(status, payload)
+          expect(FetchReplyWorker).to have_received(:push_bulk).with(['http://example.com/self-reply-1', 'http://example.com/self-reply-2', 'http://example.com/self-reply-3', 'http://example.com/self-reply-4', 'http://example.com/self-reply-5'])
+        end
+      end
+
+      context 'when passing the URL to the collection' do
+        before do
+          stub_request(:get, collection_uri).to_return(status: 200, body: Oj.dump(payload))
+        end
+
+        it 'spawns workers for up to 5 replies on the same server' do
+          allow(FetchReplyWorker).to receive(:push_bulk)
+          subject.call(status, collection_uri)
+          expect(FetchReplyWorker).to have_received(:push_bulk).with(['http://example.com/self-reply-1', 'http://example.com/self-reply-2', 'http://example.com/self-reply-3', 'http://example.com/self-reply-4', 'http://example.com/self-reply-5'])
+        end
+      end
+    end
+
+    context 'when the payload is an OrderedCollection with inlined replies' do
+      let(:payload) do
+        {
+          '@context': 'https://www.w3.org/ns/activitystreams',
+          type: 'OrderedCollection',
+          id: collection_uri,
+          orderedItems: items,
+        }.with_indifferent_access
+      end
+
+      context 'when passing the collection itself' do
+        it 'spawns workers for up to 5 replies on the same server' do
+          allow(FetchReplyWorker).to receive(:push_bulk)
+          subject.call(status, payload)
+          expect(FetchReplyWorker).to have_received(:push_bulk).with(['http://example.com/self-reply-1', 'http://example.com/self-reply-2', 'http://example.com/self-reply-3', 'http://example.com/self-reply-4', 'http://example.com/self-reply-5'])
+        end
+      end
+
+      context 'when passing the URL to the collection' do
+        before do
+          stub_request(:get, collection_uri).to_return(status: 200, body: Oj.dump(payload))
+        end
+
+        it 'spawns workers for up to 5 replies on the same server' do
+          allow(FetchReplyWorker).to receive(:push_bulk)
+          subject.call(status, collection_uri)
+          expect(FetchReplyWorker).to have_received(:push_bulk).with(['http://example.com/self-reply-1', 'http://example.com/self-reply-2', 'http://example.com/self-reply-3', 'http://example.com/self-reply-4', 'http://example.com/self-reply-5'])
+        end
+      end
+    end
+
+    context 'when the payload is a paginated Collection with inlined replies' do
+      let(:payload) do
+        {
+          '@context': 'https://www.w3.org/ns/activitystreams',
+          type: 'Collection',
+          id: collection_uri,
+          first: {
+            type: 'CollectionPage',
+            partOf: collection_uri,
+            items: items,
+          }
+        }.with_indifferent_access
+      end
+
+      context 'when passing the collection itself' do
+        it 'spawns workers for up to 5 replies on the same server' do
+          allow(FetchReplyWorker).to receive(:push_bulk)
+          subject.call(status, payload)
+          expect(FetchReplyWorker).to have_received(:push_bulk).with(['http://example.com/self-reply-1', 'http://example.com/self-reply-2', 'http://example.com/self-reply-3', 'http://example.com/self-reply-4', 'http://example.com/self-reply-5'])
+        end
+      end
+
+      context 'when passing the URL to the collection' do
+        before do
+          stub_request(:get, collection_uri).to_return(status: 200, body: Oj.dump(payload))
+        end
+
+        it 'spawns workers for up to 5 replies on the same server' do
+          allow(FetchReplyWorker).to receive(:push_bulk)
+          subject.call(status, collection_uri)
+          expect(FetchReplyWorker).to have_received(:push_bulk).with(['http://example.com/self-reply-1', 'http://example.com/self-reply-2', 'http://example.com/self-reply-3', 'http://example.com/self-reply-4', 'http://example.com/self-reply-5'])
+        end
+      end
+    end
+  end
+end
diff --git a/spec/services/activitypub/process_account_service_spec.rb b/spec/services/activitypub/process_account_service_spec.rb
index d3318b2eddd788819834635ef68b349fdb68903c..5141e3f16568853048dc16dff00ed4f3daf75d6a 100644
--- a/spec/services/activitypub/process_account_service_spec.rb
+++ b/spec/services/activitypub/process_account_service_spec.rb
@@ -28,4 +28,49 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do
       expect(account.fields[1].value).to eq 'Unit test'
     end
   end
+
+  context 'identity proofs' do
+    let(:payload) do
+      {
+        id: 'https://foo.test',
+        type: 'Actor',
+        inbox: 'https://foo.test/inbox',
+        attachment: [
+          { type: 'IdentityProof', name: 'Alice', signatureAlgorithm: 'keybase', signatureValue: 'a' * 66 },
+        ],
+      }.with_indifferent_access
+    end
+
+    it 'parses out of attachment' do
+      allow(ProofProvider::Keybase::Worker).to receive(:perform_async)
+
+      account = subject.call('alice', 'example.com', payload)
+
+      expect(account.identity_proofs.count).to eq 1
+
+      proof = account.identity_proofs.first
+
+      expect(proof.provider).to eq 'keybase'
+      expect(proof.provider_username).to eq 'Alice'
+      expect(proof.token).to eq 'a' * 66
+    end
+
+    it 'removes no longer present proofs' do
+      allow(ProofProvider::Keybase::Worker).to receive(:perform_async)
+
+      account   = Fabricate(:account, username: 'alice', domain: 'example.com')
+      old_proof = Fabricate(:account_identity_proof, account: account, provider: 'keybase', provider_username: 'Bob', token: 'b' * 66)
+
+      subject.call('alice', 'example.com', payload)
+
+      expect(account.identity_proofs.count).to eq 1
+      expect(account.identity_proofs.find_by(id: old_proof.id)).to be_nil
+    end
+
+    it 'queues a validity check on the proof' do
+      allow(ProofProvider::Keybase::Worker).to receive(:perform_async)
+      account = subject.call('alice', 'example.com', payload)
+      expect(ProofProvider::Keybase::Worker).to have_received(:perform_async)
+    end
+  end
 end
diff --git a/spec/services/app_sign_up_service_spec.rb b/spec/services/app_sign_up_service_spec.rb
index d480df34808ce3c62a48d3109df3cca2e9e5bd18..7948bb53be10e4546129e1bd3fd6674f2f422a66 100644
--- a/spec/services/app_sign_up_service_spec.rb
+++ b/spec/services/app_sign_up_service_spec.rb
@@ -8,8 +8,10 @@ RSpec.describe AppSignUpService, type: :service do
 
   describe '#call' do
     it 'returns nil when registrations are closed' do
-      Setting.open_registrations = false
+      tmp = Setting.registrations_mode
+      Setting.registrations_mode = 'none'
       expect(subject.call(app, good_params)).to be_nil
+      Setting.registrations_mode = tmp
     end
 
     it 'raises an error when params are missing' do
diff --git a/spec/services/block_domain_service_spec.rb b/spec/services/block_domain_service_spec.rb
index 7ef9e2770e7643af28aefda9d4ce6b0761d368bb..c689b57e348c059059d533a544a1b9184f69f45f 100644
--- a/spec/services/block_domain_service_spec.rb
+++ b/spec/services/block_domain_service_spec.rb
@@ -1,20 +1,14 @@
 require 'rails_helper'
 
 RSpec.describe BlockDomainService, type: :service do
-  let(:bad_account) { Fabricate(:account, username: 'badguy666', domain: 'evil.org') }
-  let(:bad_status1) { Fabricate(:status, account: bad_account, text: 'You suck') }
-  let(:bad_status2) { Fabricate(:status, account: bad_account, text: 'Hahaha') }
-  let(:bad_attachment) { Fabricate(:media_attachment, account: bad_account, status: bad_status2, file: attachment_fixture('attachment.jpg')) }
+  let!(:bad_account) { Fabricate(:account, username: 'badguy666', domain: 'evil.org') }
+  let!(:bad_status1) { Fabricate(:status, account: bad_account, text: 'You suck') }
+  let!(:bad_status2) { Fabricate(:status, account: bad_account, text: 'Hahaha') }
+  let!(:bad_attachment) { Fabricate(:media_attachment, account: bad_account, status: bad_status2, file: attachment_fixture('attachment.jpg')) }
+  let!(:already_banned_account) { Fabricate(:account, username: 'badguy', domain: 'evil.org', suspended: true, silenced: true) }
 
   subject { BlockDomainService.new }
 
-  before do
-    bad_account
-    bad_status1
-    bad_status2
-    bad_attachment
-  end
-
   describe 'for a suspension' do
     before do
       subject.call(DomainBlock.create!(domain: 'evil.org', severity: :suspend))
@@ -28,6 +22,18 @@ RSpec.describe BlockDomainService, type: :service do
       expect(Account.find_remote('badguy666', 'evil.org').suspended?).to be true
     end
 
+    it 'records suspension date appropriately' do
+      expect(Account.find_remote('badguy666', 'evil.org').suspended_at).to eq DomainBlock.find_by(domain: 'evil.org').created_at
+    end
+
+    it 'keeps already-banned accounts banned' do
+      expect(Account.find_remote('badguy', 'evil.org').suspended?).to be true
+    end
+
+    it 'does not overwrite suspension date of already-banned accounts' do
+      expect(Account.find_remote('badguy', 'evil.org').suspended_at).to_not eq DomainBlock.find_by(domain: 'evil.org').created_at
+    end
+
     it 'removes the remote accounts\'s statuses and media attachments' do
       expect { bad_status1.reload }.to raise_exception ActiveRecord::RecordNotFound
       expect { bad_status2.reload }.to raise_exception ActiveRecord::RecordNotFound
@@ -48,6 +54,18 @@ RSpec.describe BlockDomainService, type: :service do
       expect(Account.find_remote('badguy666', 'evil.org').silenced?).to be true
     end
 
+    it 'records suspension date appropriately' do
+      expect(Account.find_remote('badguy666', 'evil.org').silenced_at).to eq DomainBlock.find_by(domain: 'evil.org').created_at
+    end
+
+    it 'keeps already-banned accounts banned' do
+      expect(Account.find_remote('badguy', 'evil.org').silenced?).to be true
+    end
+
+    it 'does not overwrite suspension date of already-banned accounts' do
+      expect(Account.find_remote('badguy', 'evil.org').silenced_at).to_not eq DomainBlock.find_by(domain: 'evil.org').created_at
+    end
+
     it 'leaves the domains status and attachements, but clears media' do
       expect { bad_status1.reload }.not_to raise_error
       expect { bad_status2.reload }.not_to raise_error
diff --git a/spec/services/import_service_spec.rb b/spec/services/import_service_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5cf2dadf06c9c22396549327a7bcbcc2671bb6a4
--- /dev/null
+++ b/spec/services/import_service_spec.rb
@@ -0,0 +1,169 @@
+require 'rails_helper'
+
+RSpec.describe ImportService, type: :service do
+  let!(:account) { Fabricate(:account, locked: false) }
+  let!(:bob)     { Fabricate(:account, username: 'bob', locked: false) }
+  let!(:eve)     { Fabricate(:account, username: 'eve', domain: 'example.com', locked: false) }
+
+  context 'import old-style list of muted users' do
+    subject { ImportService.new }
+
+    let(:csv) { attachment_fixture('mute-imports.txt') }
+
+    describe 'when no accounts are muted' do
+      let(:import) { Import.create(account: account, type: 'muting', data: csv) }
+      it 'mutes the listed accounts, including notifications' do
+        subject.call(import)
+        expect(account.muting.count).to eq 2
+        expect(Mute.find_by(account: account, target_account: bob).hide_notifications).to be true
+      end
+    end
+
+    describe 'when some accounts are muted and overwrite is not set' do
+      let(:import) { Import.create(account: account, type: 'muting', data: csv) }
+
+      it 'mutes the listed accounts, including notifications' do
+        account.mute!(bob, notifications: false)
+        subject.call(import)
+        expect(account.muting.count).to eq 2
+        expect(Mute.find_by(account: account, target_account: bob).hide_notifications).to be true
+      end
+    end
+
+    describe 'when some accounts are muted and overwrite is set' do
+      let(:import) { Import.create(account: account, type: 'muting', data: csv, overwrite: true) }
+
+      it 'mutes the listed accounts, including notifications' do
+        account.mute!(bob, notifications: false)
+        subject.call(import)
+        expect(account.muting.count).to eq 2
+        expect(Mute.find_by(account: account, target_account: bob).hide_notifications).to be true
+      end
+    end
+  end
+
+  context 'import new-style list of muted users' do
+    subject { ImportService.new }
+
+    let(:csv) { attachment_fixture('new-mute-imports.txt') }
+
+    describe 'when no accounts are muted' do
+      let(:import) { Import.create(account: account, type: 'muting', data: csv) }
+      it 'mutes the listed accounts, respecting notifications' do
+        subject.call(import)
+        expect(account.muting.count).to eq 2
+        expect(Mute.find_by(account: account, target_account: bob).hide_notifications).to be true
+        expect(Mute.find_by(account: account, target_account: eve).hide_notifications).to be false
+      end
+    end
+
+    describe 'when some accounts are muted and overwrite is not set' do
+      let(:import) { Import.create(account: account, type: 'muting', data: csv) }
+
+      it 'mutes the listed accounts, respecting notifications' do
+        account.mute!(bob, notifications: true)
+        subject.call(import)
+        expect(account.muting.count).to eq 2
+        expect(Mute.find_by(account: account, target_account: bob).hide_notifications).to be true
+        expect(Mute.find_by(account: account, target_account: eve).hide_notifications).to be false
+      end
+    end
+
+    describe 'when some accounts are muted and overwrite is set' do
+      let(:import) { Import.create(account: account, type: 'muting', data: csv, overwrite: true) }
+
+      it 'mutes the listed accounts, respecting notifications' do
+        account.mute!(bob, notifications: true)
+        subject.call(import)
+        expect(account.muting.count).to eq 2
+        expect(Mute.find_by(account: account, target_account: bob).hide_notifications).to be true
+        expect(Mute.find_by(account: account, target_account: eve).hide_notifications).to be false
+      end
+    end
+  end
+
+  context 'import old-style list of followed users' do
+    subject { ImportService.new }
+
+    let(:csv) { attachment_fixture('mute-imports.txt') }
+
+    before do
+      allow(NotificationWorker).to receive(:perform_async)
+    end
+
+    describe 'when no accounts are followed' do
+      let(:import) { Import.create(account: account, type: 'following', data: csv) }
+      it 'follows the listed accounts, including boosts' do
+        subject.call(import)
+        expect(account.following.count).to eq 2
+        expect(Follow.find_by(account: account, target_account: bob).show_reblogs).to be true
+      end
+    end
+
+    describe 'when some accounts are already followed and overwrite is not set' do
+      let(:import) { Import.create(account: account, type: 'following', data: csv) }
+
+      it 'follows the listed accounts, including notifications' do
+        account.follow!(bob, reblogs: false)
+        subject.call(import)
+        expect(account.following.count).to eq 2
+        expect(Follow.find_by(account: account, target_account: bob).show_reblogs).to be true
+      end
+    end
+
+    describe 'when some accounts are already followed and overwrite is set' do
+      let(:import) { Import.create(account: account, type: 'following', data: csv, overwrite: true) }
+
+      it 'mutes the listed accounts, including notifications' do
+        account.follow!(bob, reblogs: false)
+        subject.call(import)
+        expect(account.following.count).to eq 2
+        expect(Follow.find_by(account: account, target_account: bob).show_reblogs).to be true
+      end
+    end
+  end
+
+  context 'import new-style list of followed users' do
+    subject { ImportService.new }
+
+    let(:csv) { attachment_fixture('new-following-imports.txt') }
+
+    before do
+      allow(NotificationWorker).to receive(:perform_async)
+    end
+
+    describe 'when no accounts are followed' do
+      let(:import) { Import.create(account: account, type: 'following', data: csv) }
+      it 'follows the listed accounts, respecting boosts' do
+        subject.call(import)
+        expect(account.following.count).to eq 2
+        expect(Follow.find_by(account: account, target_account: bob).show_reblogs).to be true
+        expect(Follow.find_by(account: account, target_account: eve).show_reblogs).to be false
+      end
+    end
+
+    describe 'when some accounts are already followed and overwrite is not set' do
+      let(:import) { Import.create(account: account, type: 'following', data: csv) }
+
+      it 'mutes the listed accounts, respecting notifications' do
+        account.follow!(bob, reblogs: true)
+        subject.call(import)
+        expect(account.following.count).to eq 2
+        expect(Follow.find_by(account: account, target_account: bob).show_reblogs).to be true
+        expect(Follow.find_by(account: account, target_account: eve).show_reblogs).to be false
+      end
+    end
+
+    describe 'when some accounts are already followed and overwrite is set' do
+      let(:import) { Import.create(account: account, type: 'following', data: csv, overwrite: true) }
+
+      it 'mutes the listed accounts, respecting notifications' do
+        account.follow!(bob, reblogs: true)
+        subject.call(import)
+        expect(account.following.count).to eq 2
+        expect(Follow.find_by(account: account, target_account: bob).show_reblogs).to be true
+        expect(Follow.find_by(account: account, target_account: eve).show_reblogs).to be false
+      end
+    end
+  end
+end
diff --git a/spec/services/notify_service_spec.rb b/spec/services/notify_service_spec.rb
index 39a681abbf70381aaf2cbc69cf05b195ee7a9dd1..440018ac93d282994330367d64d28d57cd8d5373 100644
--- a/spec/services/notify_service_spec.rb
+++ b/spec/services/notify_service_spec.rb
@@ -39,12 +39,12 @@ RSpec.describe NotifyService, type: :service do
   end
 
   it 'does not notify when sender is silenced and not followed' do
-    sender.update(silenced: true)
+    sender.silence!
     is_expected.to_not change(Notification, :count)
   end
 
   it 'does not notify when recipient is suspended' do
-    recipient.update(suspended: true)
+    recipient.suspend!
     is_expected.to_not change(Notification, :count)
   end
 
@@ -105,7 +105,7 @@ RSpec.describe NotifyService, type: :service do
     end
 
     it 'shows reblogs when disabled' do
-      recipient.follow!(sender, reblogs: true)
+      recipient.follow!(sender, reblogs: false)
       is_expected.to change(Notification, :count)
     end
   end
diff --git a/spec/services/post_status_service_spec.rb b/spec/services/post_status_service_spec.rb
index 3774fed6f3e8a641e5bac4b515060ff9c2e5b5d8..facbe977f2333096f345c8b9e27ad082ae3bb63f 100644
--- a/spec/services/post_status_service_spec.rb
+++ b/spec/services/post_status_service_spec.rb
@@ -36,6 +36,20 @@ RSpec.describe PostStatusService, type: :service do
     expect(status.params['text']).to eq 'Hi future!'
   end
 
+  it 'does not immediately create a status when scheduling a status' do
+    account = Fabricate(:account)
+    media = Fabricate(:media_attachment)
+    future  = Time.now.utc + 2.hours
+
+    status = subject.call(account, text: 'Hi future!', media_ids: [media.id], scheduled_at: future)
+
+    expect(status).to be_a ScheduledStatus
+    expect(status.scheduled_at).to eq future
+    expect(status.params['text']).to eq 'Hi future!'
+    expect(media.reload.status).to be_nil
+    expect(Status.where(text: 'Hi future!').exists?).to be_falsey
+  end
+
   it 'creates response to the original status of boost' do
     boosted_status = Fabricate(:status)
     in_reply_to_status = Fabricate(:status, reblog: boosted_status)
@@ -153,7 +167,7 @@ RSpec.describe PostStatusService, type: :service do
 
   it 'attaches the given media to the created status' do
     account = Fabricate(:account)
-    media = Fabricate(:media_attachment)
+    media = Fabricate(:media_attachment, account: account)
 
     status = subject.call(
       account,
@@ -164,6 +178,19 @@ RSpec.describe PostStatusService, type: :service do
     expect(media.reload.status).to eq status
   end
 
+  it 'does not attach media from another account to the created status' do
+    account = Fabricate(:account)
+    media = Fabricate(:media_attachment, account: Fabricate(:account))
+
+    status = subject.call(
+      account,
+      text: "test status update",
+      media_ids: [media.id],
+    )
+
+    expect(media.reload.status).to eq nil
+  end
+
   it 'does not allow attaching more than 4 files' do
     account = Fabricate(:account)
 
diff --git a/spec/services/process_mentions_service_spec.rb b/spec/services/process_mentions_service_spec.rb
index 963924fa9c42a0c526e06c2bcccddc386f8e14c3..8a6bb44acaad6ba4abf6ae4aa241a125512bc8ad 100644
--- a/spec/services/process_mentions_service_spec.rb
+++ b/spec/services/process_mentions_service_spec.rb
@@ -1,10 +1,11 @@
 require 'rails_helper'
 
 RSpec.describe ProcessMentionsService, type: :service do
-  let(:account) { Fabricate(:account, username: 'alice') }
-  let(:status)  { Fabricate(:status, account: account, text: "Hello @#{remote_user.acct}") }
+  let(:account)    { Fabricate(:account, username: 'alice') }
+  let(:visibility) { :public }
+  let(:status)     { Fabricate(:status, account: account, text: "Hello @#{remote_user.acct}", visibility: visibility) }
 
-  context 'OStatus' do
+  context 'OStatus with public toot' do
     let(:remote_user) { Fabricate(:account, username: 'remote_user', protocol: :ostatus, domain: 'example.com', salmon_url: 'http://salmon.example.com') }
 
     subject { ProcessMentionsService.new }
@@ -23,6 +24,26 @@ RSpec.describe ProcessMentionsService, type: :service do
     end
   end
 
+  context 'OStatus with private toot' do
+    let(:visibility)  { :private }
+    let(:remote_user) { Fabricate(:account, username: 'remote_user', protocol: :ostatus, domain: 'example.com', salmon_url: 'http://salmon.example.com') }
+
+    subject { ProcessMentionsService.new }
+
+    before do
+      stub_request(:post, remote_user.salmon_url)
+      subject.call(status)
+    end
+
+    it 'does not create a mention' do
+      expect(remote_user.mentions.where(status: status).count).to eq 0
+    end
+
+    it 'does not post to remote user\'s Salmon end point' do
+      expect(a_request(:post, remote_user.salmon_url)).to_not have_been_made
+    end
+  end
+
   context 'ActivityPub' do
     let(:remote_user) { Fabricate(:account, username: 'remote_user', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') }
 
diff --git a/spec/services/reblog_service_spec.rb b/spec/services/reblog_service_spec.rb
index 2755da772067cbbd77598c5154d9d779dfa1bc49..9d84c41d5eaadeabf18f0180ebbf693c4c442d96 100644
--- a/spec/services/reblog_service_spec.rb
+++ b/spec/services/reblog_service_spec.rb
@@ -3,6 +3,35 @@ require 'rails_helper'
 RSpec.describe ReblogService, type: :service do
   let(:alice)  { Fabricate(:account, username: 'alice') }
 
+  context 'creates a reblog with appropriate visibility' do
+    let(:visibility)        { :public }
+    let(:reblog_visibility) { :public }
+    let(:status)            { Fabricate(:status, account: alice, visibility: visibility) }
+
+    subject { ReblogService.new }
+
+    before do
+      subject.call(alice, status, visibility: reblog_visibility)
+    end
+
+    describe 'boosting privately' do
+      let(:reblog_visibility) { :private }
+
+      it 'reblogs privately' do
+        expect(status.reblogs.first.visibility).to eq 'private'
+      end
+    end
+
+    describe 'public reblogs of private toots should remain private' do
+      let(:visibility)        { :private }
+      let(:reblog_visibility) { :public }
+
+      it 'reblogs privately' do
+        expect(status.reblogs.first.visibility).to eq 'private'
+      end
+    end
+  end
+
   context 'OStatus' do
     let(:bob)    { Fabricate(:account, username: 'bob', domain: 'example.com', salmon_url: 'http://salmon.example.com') }
     let(:status) { Fabricate(:status, account: bob, uri: 'tag:example.com;something:something') }
diff --git a/spec/services/report_service_spec.rb b/spec/services/report_service_spec.rb
index e8b094c89b2b686ca291e00537b8f11f737184c5..454e4d896fd7116da1fe3913a4cb5c86a7c76252 100644
--- a/spec/services/report_service_spec.rb
+++ b/spec/services/report_service_spec.rb
@@ -21,6 +21,11 @@ RSpec.describe ReportService, type: :service do
       subject.call(source_account, remote_account, forward: false)
       expect(a_request(:post, 'http://example.com/inbox')).to_not have_been_made
     end
+
+    it 'has an uri' do
+      report = subject.call(source_account, remote_account, forward: true)
+      expect(report.uri).to_not be_nil
+    end
   end
 
   context 'when other reports already exist for the same target' do
diff --git a/spec/services/search_service_spec.rb b/spec/services/search_service_spec.rb
index 671080f1d980e68936c3ddb9b613bf63dc8ac98f..d064cd9b85d5f682135364fbd8c674b8304d6e25 100644
--- a/spec/services/search_service_spec.rb
+++ b/spec/services/search_service_spec.rb
@@ -10,7 +10,7 @@ describe SearchService, type: :service do
       it 'returns empty results without searching' do
         allow(AccountSearchService).to receive(:new)
         allow(Tag).to receive(:search_for)
-        results = subject.call('', 10)
+        results = subject.call('', nil, 10)
 
         expect(results).to eq(empty_results)
         expect(AccountSearchService).not_to have_received(:new)
@@ -27,7 +27,7 @@ describe SearchService, type: :service do
         it 'returns the empty results' do
           service = double(call: nil)
           allow(ResolveURLService).to receive(:new).and_return(service)
-          results = subject.call(@query, 10)
+          results = subject.call(@query, nil, 10)
 
           expect(service).to have_received(:call).with(@query, on_behalf_of: nil)
           expect(results).to eq empty_results
@@ -40,7 +40,7 @@ describe SearchService, type: :service do
           service = double(call: account)
           allow(ResolveURLService).to receive(:new).and_return(service)
 
-          results = subject.call(@query, 10)
+          results = subject.call(@query, nil, 10)
           expect(service).to have_received(:call).with(@query, on_behalf_of: nil)
           expect(results).to eq empty_results.merge(accounts: [account])
         end
@@ -52,7 +52,7 @@ describe SearchService, type: :service do
           service = double(call: status)
           allow(ResolveURLService).to receive(:new).and_return(service)
 
-          results = subject.call(@query, 10)
+          results = subject.call(@query, nil, 10)
           expect(service).to have_received(:call).with(@query, on_behalf_of: nil)
           expect(results).to eq empty_results.merge(statuses: [status])
         end
@@ -67,8 +67,8 @@ describe SearchService, type: :service do
           service = double(call: [account])
           allow(AccountSearchService).to receive(:new).and_return(service)
 
-          results = subject.call(query, 10)
-          expect(service).to have_received(:call).with(query, 10, nil, resolve: false)
+          results = subject.call(query, nil, 10)
+          expect(service).to have_received(:call).with(query, nil, limit: 10, offset: 0, resolve: false)
           expect(results).to eq empty_results.merge(accounts: [account])
         end
       end
@@ -77,17 +77,17 @@ describe SearchService, type: :service do
         it 'includes the tag in the results' do
           query = '#tag'
           tag = Tag.new
-          allow(Tag).to receive(:search_for).with('tag', 10).and_return([tag])
+          allow(Tag).to receive(:search_for).with('tag', 10, 0).and_return([tag])
 
-          results = subject.call(query, 10)
-          expect(Tag).to have_received(:search_for).with('tag', 10)
+          results = subject.call(query, nil, 10)
+          expect(Tag).to have_received(:search_for).with('tag', 10, 0)
           expect(results).to eq empty_results.merge(hashtags: [tag])
         end
         it 'does not include tag when starts with @ character' do
           query = '@username'
           allow(Tag).to receive(:search_for)
 
-          results = subject.call(query, 10)
+          results = subject.call(query, nil, 10)
           expect(Tag).not_to have_received(:search_for)
           expect(results).to eq empty_results
         end
diff --git a/spec/services/suspend_account_service_spec.rb b/spec/services/suspend_account_service_spec.rb
index 8a5bd33010c2cfd90f464f542368ea236e75c10a..6f45762aa3fb6d99a2d41d20c63e331069b5bfb5 100644
--- a/spec/services/suspend_account_service_spec.rb
+++ b/spec/services/suspend_account_service_spec.rb
@@ -1,7 +1,7 @@
 require 'rails_helper'
 
 RSpec.describe SuspendAccountService, type: :service do
-  describe '#call' do
+  describe '#call on local account' do
     before do
       stub_request(:post, "https://alice.com/inbox").to_return(status: 201)
       stub_request(:post, "https://bob.com/inbox").to_return(status: 201)
@@ -43,4 +43,46 @@ RSpec.describe SuspendAccountService, type: :service do
       expect(a_request(:post, "https://bob.com/inbox")).to have_been_made.once
     end
   end
+
+  describe '#call on remote account' do
+    before do
+      stub_request(:post, "https://alice.com/inbox").to_return(status: 201)
+      stub_request(:post, "https://bob.com/inbox").to_return(status: 201)
+    end
+
+    subject do
+      -> { described_class.new.call(remote_bob) }
+    end
+
+    let!(:account) { Fabricate(:account) }
+    let!(:remote_alice) { Fabricate(:account, inbox_url: 'https://alice.com/inbox', protocol: :activitypub) }
+    let!(:remote_bob) { Fabricate(:account, inbox_url: 'https://bob.com/inbox', protocol: :activitypub) }
+    let!(:status) { Fabricate(:status, account: remote_bob) }
+    let!(:media_attachment) { Fabricate(:media_attachment, account: remote_bob) }
+    let!(:notification) { Fabricate(:notification, account: remote_bob) }
+    let!(:favourite) { Fabricate(:favourite, account: remote_bob) }
+    let!(:active_relationship) { Fabricate(:follow, account: remote_bob, target_account: account) }
+    let!(:passive_relationship) { Fabricate(:follow, target_account: remote_bob) }
+    let!(:subscription) { Fabricate(:subscription, account: remote_bob) }
+
+    it 'deletes associated records' do
+      is_expected.to change {
+        [
+          remote_bob.statuses,
+          remote_bob.media_attachments,
+          remote_bob.stream_entries,
+          remote_bob.notifications,
+          remote_bob.favourites,
+          remote_bob.active_relationships,
+          remote_bob.passive_relationships,
+          remote_bob.subscriptions
+        ].map(&:count)
+      }.from([1, 1, 1, 1, 1, 1, 1, 1]).to([0, 0, 0, 0, 0, 0, 0, 0])
+    end
+
+    it 'sends a reject follow to follwer inboxes' do
+      subject.call
+      expect(a_request(:post, remote_bob.inbox_url)).to have_been_made.once
+    end
+  end
 end
diff --git a/spec/services/unblock_domain_service_spec.rb b/spec/services/unblock_domain_service_spec.rb
index 8e8893d6354af3b88e50938e679270839fa9c6a7..619aefb5c0c535f291b09b2950a2437662419201 100644
--- a/spec/services/unblock_domain_service_spec.rb
+++ b/spec/services/unblock_domain_service_spec.rb
@@ -7,36 +7,33 @@ describe UnblockDomainService, type: :service do
 
   describe 'call' do
     before do
-      @silenced = Fabricate(:account, domain: 'example.com', silenced: true)
-      @suspended = Fabricate(:account, domain: 'example.com', suspended: true)
+      @independently_suspended = Fabricate(:account, domain: 'example.com', suspended_at: 1.hour.ago)
+      @independently_silenced = Fabricate(:account, domain: 'example.com', silenced_at: 1.hour.ago)
       @domain_block = Fabricate(:domain_block, domain: 'example.com')
+      @silenced = Fabricate(:account, domain: 'example.com', silenced_at: @domain_block.created_at)
+      @suspended = Fabricate(:account, domain: 'example.com', suspended_at: @domain_block.created_at)
     end
 
-    context 'without retroactive' do
-      it 'removes the domain block' do
-        subject.call(@domain_block, false)
-        expect_deleted_domain_block
-      end
-    end
-
-    context 'with retroactive' do
-      it 'unsilences accounts and removes block' do
-        @domain_block.update(severity: :silence)
+    it 'unsilences accounts and removes block' do
+      @domain_block.update(severity: :silence)
 
-        subject.call(@domain_block, true)
-        expect_deleted_domain_block
-        expect(@silenced.reload.silenced).to be false
-        expect(@suspended.reload.suspended).to be true
-      end
+      subject.call(@domain_block)
+      expect_deleted_domain_block
+      expect(@silenced.reload.silenced?).to be false
+      expect(@suspended.reload.suspended?).to be true
+      expect(@independently_suspended.reload.suspended?).to be true
+      expect(@independently_silenced.reload.silenced?).to be true
+    end
 
-      it 'unsuspends accounts and removes block' do
-        @domain_block.update(severity: :suspend)
+    it 'unsuspends accounts and removes block' do
+      @domain_block.update(severity: :suspend)
 
-        subject.call(@domain_block, true)
-        expect_deleted_domain_block
-        expect(@suspended.reload.suspended).to be false
-        expect(@silenced.reload.silenced).to be true
-      end
+      subject.call(@domain_block)
+      expect_deleted_domain_block
+      expect(@suspended.reload.suspended?).to be false
+      expect(@silenced.reload.silenced?).to be true
+      expect(@independently_suspended.reload.suspended?).to be true
+      expect(@independently_silenced.reload.silenced?).to be true
     end
   end
 
diff --git a/spec/validators/blacklisted_email_validator_spec.rb b/spec/validators/blacklisted_email_validator_spec.rb
index d2e442f4ab40bc71d219660053693bc9470c5f20..ccc5dc0f485050fb017d3df4b9f8270250950bad 100644
--- a/spec/validators/blacklisted_email_validator_spec.rb
+++ b/spec/validators/blacklisted_email_validator_spec.rb
@@ -8,6 +8,7 @@ RSpec.describe BlacklistedEmailValidator, type: :validator do
     let(:errors) { double(add: nil) }
 
     before do
+      allow(user).to receive(:valid_invitation?) { false }
       allow_any_instance_of(described_class).to receive(:blocked_email?) { blocked_email }
       described_class.new.validate(user)
     end
diff --git a/spec/validators/email_mx_validator_spec.rb b/spec/validators/email_mx_validator_spec.rb
index bc68f63cfbc16fa3b22eb87e5d4e0e699f177b62..48e17a4f1086efd18751bce520615a8f41264fc9 100644
--- a/spec/validators/email_mx_validator_spec.rb
+++ b/spec/validators/email_mx_validator_spec.rb
@@ -11,6 +11,7 @@ describe EmailMxValidator do
 
       allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([])
       allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([])
+      allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([])
       allow(resolver).to receive(:timeouts=).and_return(nil)
       allow(Resolv::DNS).to receive(:open).and_yield(resolver)
 
@@ -23,7 +24,9 @@ describe EmailMxValidator do
 
       allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([double(exchange: 'mail.example.com')])
       allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([])
+      allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([])
       allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::A).and_return([])
+      allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::AAAA).and_return([])
       allow(resolver).to receive(:timeouts=).and_return(nil)
       allow(Resolv::DNS).to receive(:open).and_yield(resolver)
 
@@ -37,6 +40,21 @@ describe EmailMxValidator do
 
       allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([])
       allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([double(address: '1.2.3.4')])
+      allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([])
+      allow(resolver).to receive(:timeouts=).and_return(nil)
+      allow(Resolv::DNS).to receive(:open).and_yield(resolver)
+
+      subject.validate(user)
+      expect(user.errors).to have_received(:add)
+    end
+
+    it 'adds an error if the AAAA record is blacklisted' do
+      EmailDomainBlock.create!(domain: 'fd00::1')
+      resolver = double
+
+      allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([])
+      allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([])
+      allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([double(address: 'fd00::1')])
       allow(resolver).to receive(:timeouts=).and_return(nil)
       allow(Resolv::DNS).to receive(:open).and_yield(resolver)
 
@@ -50,7 +68,25 @@ describe EmailMxValidator do
 
       allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([double(exchange: 'mail.example.com')])
       allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([])
+      allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([])
       allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::A).and_return([double(address: '2.3.4.5')])
+      allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::AAAA).and_return([])
+      allow(resolver).to receive(:timeouts=).and_return(nil)
+      allow(Resolv::DNS).to receive(:open).and_yield(resolver)
+
+      subject.validate(user)
+      expect(user.errors).to have_received(:add)
+    end
+
+    it 'adds an error if the MX IPv6 record is blacklisted' do
+      EmailDomainBlock.create!(domain: 'fd00::2')
+      resolver = double
+
+      allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([double(exchange: 'mail.example.com')])
+      allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([])
+      allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([])
+      allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::A).and_return([])
+      allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::AAAA).and_return([double(address: 'fd00::2')])
       allow(resolver).to receive(:timeouts=).and_return(nil)
       allow(Resolv::DNS).to receive(:open).and_yield(resolver)
 
@@ -64,7 +100,9 @@ describe EmailMxValidator do
 
       allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([double(exchange: 'mail.example.com')])
       allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([])
+      allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([])
       allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::A).and_return([double(address: '2.3.4.5')])
+      allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::AAAA).and_return([double(address: 'fd00::2')])
       allow(resolver).to receive(:timeouts=).and_return(nil)
       allow(Resolv::DNS).to receive(:open).and_yield(resolver)
 
diff --git a/spec/validators/poll_validator_spec.rb b/spec/validators/poll_validator_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..941b83401f5d3e0f45ef06a48818d4aef5fc3a28
--- /dev/null
+++ b/spec/validators/poll_validator_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe PollValidator, type: :validator do
+  describe '#validate' do
+    before do
+      validator.validate(poll)
+    end
+
+    let(:validator) { described_class.new }
+    let(:poll) { double(options: options, expires_at: expires_at, errors: errors) }
+    let(:errors) { double(add: nil) }
+    let(:options) { %w(foo bar) }
+    let(:expires_at) { 1.day.from_now }
+
+    it 'have no errors' do
+      expect(errors).not_to have_received(:add)
+    end
+
+    context 'expires just 5 min ago' do
+      let(:expires_at) { 5.minutes.from_now }
+      it 'not calls errors add' do
+        expect(errors).not_to have_received(:add)
+      end
+    end
+  end
+end
diff --git a/spec/views/about/show.html.haml_spec.rb b/spec/views/about/show.html.haml_spec.rb
index eb81090b5173b2452f89bfcafa1db9d9918eea95..c75c2875989fdded2dc2392815b4ab7e7b5bb542 100644
--- a/spec/views/about/show.html.haml_spec.rb
+++ b/spec/views/about/show.html.haml_spec.rb
@@ -6,23 +6,29 @@ describe 'about/show.html.haml', without_verify_partial_doubles: true do
   before do
     allow(view).to receive(:site_hostname).and_return('example.com')
     allow(view).to receive(:site_title).and_return('example site')
+    allow(view).to receive(:new_user).and_return(User.new)
+    allow(view).to receive(:use_seamless_external_login?).and_return(false)
   end
 
   it 'has valid open graph tags' do
-    instance_presenter = double(:instance_presenter,
-                                site_title: 'something',
-                                site_short_description: 'something',
-                                site_description: 'something',
-                                version_number: '1.0',
-                                source_url: 'https://github.com/tootsuite/mastodon',
-                                open_registrations: false,
-                                thumbnail: nil,
-                                hero: nil,
-                                mascot: nil,
-                                user_count: 0,
-                                status_count: 0,
-                                contact_account: nil,
-                                closed_registrations_message: 'yes')
+    instance_presenter = double(
+      :instance_presenter,
+      site_title: 'something',
+      site_short_description: 'something',
+      site_description: 'something',
+      version_number: '1.0',
+      source_url: 'https://github.com/tootsuite/mastodon',
+      open_registrations: false,
+      thumbnail: nil,
+      hero: nil,
+      mascot: nil,
+      user_count: 420,
+      status_count: 69,
+      active_user_count: 420,
+      contact_account: nil,
+      sample_accounts: []
+    )
+
     assign(:instance_presenter, instance_presenter)
     render
 
diff --git a/spec/workers/activitypub/distribute_poll_update_worker_spec.rb b/spec/workers/activitypub/distribute_poll_update_worker_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7eb6119fd8091f791729952d0450e816cf4dfa67
--- /dev/null
+++ b/spec/workers/activitypub/distribute_poll_update_worker_spec.rb
@@ -0,0 +1,22 @@
+require 'rails_helper'
+
+describe ActivityPub::DistributePollUpdateWorker do
+  subject { described_class.new }
+
+  let(:account)  { Fabricate(:account) }
+  let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com') }
+  let(:poll)     { Fabricate(:poll, account: account) }
+  let!(:status)  { Fabricate(:status, account: account, poll: poll) }
+
+  describe '#perform' do
+    before do
+      allow(ActivityPub::DeliveryWorker).to receive(:push_bulk)
+      follower.follow!(account)
+    end
+
+    it 'delivers to followers' do
+      subject.perform(status.id)
+      expect(ActivityPub::DeliveryWorker).to have_received(:push_bulk).with(['http://example.com'])
+    end
+  end
+end
diff --git a/spec/workers/activitypub/fetch_replies_worker_spec.rb b/spec/workers/activitypub/fetch_replies_worker_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..91ef3c4b928fd7b125b28d3409f9def48e264b44
--- /dev/null
+++ b/spec/workers/activitypub/fetch_replies_worker_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe ActivityPub::FetchRepliesWorker do
+  subject { described_class.new }
+
+  let(:account) { Fabricate(:account, uri: 'https://example.com/user/1') }
+  let(:status)  { Fabricate(:status, account: account) }
+
+  let(:payload) do
+    {
+      '@context': 'https://www.w3.org/ns/activitystreams',
+      id: 'https://example.com/statuses_replies/1',
+      type: 'Collection',
+      items: [],
+    }
+  end
+
+  let(:json) { Oj.dump(payload) }
+
+  describe 'perform' do
+    it 'performs a request if the collection URI is from the same host' do
+      stub_request(:get, 'https://example.com/statuses_replies/1').to_return(status: 200, body: json)
+      subject.perform(status.id, 'https://example.com/statuses_replies/1')
+      expect(a_request(:get, 'https://example.com/statuses_replies/1')).to have_been_made.once
+    end
+
+    it 'does not perform a request if the collection URI is from a different host' do
+      stub_request(:get, 'https://other.com/statuses_replies/1').to_return(status: 200)
+      subject.perform(status.id, 'https://other.com/statuses_replies/1')
+      expect(a_request(:get, 'https://other.com/statuses_replies/1')).to_not have_been_made
+    end
+
+    it 'raises when request fails' do
+      stub_request(:get, 'https://example.com/statuses_replies/1').to_return(status: 500)
+      expect { subject.perform(status.id, 'https://example.com/statuses_replies/1') }.to raise_error Mastodon::UnexpectedResponseError
+    end
+  end
+end
diff --git a/streaming/index.js b/streaming/index.js
index b4d09d0ad2c7d60b0a0c7b1d74a7404a133d9a12..0529804b1b58fe94100f6e04e2aa8e16813176dd 100644
--- a/streaming/index.js
+++ b/streaming/index.js
@@ -7,7 +7,7 @@ const redis = require('redis');
 const pg = require('pg');
 const log = require('npmlog');
 const url = require('url');
-const WebSocket = require('uws');
+const { WebSocketServer } = require('@clusterws/cws');
 const uuid = require('uuid');
 const fs = require('fs');
 
@@ -24,7 +24,7 @@ const dbUrlToConfig = (dbUrl) => {
     return {};
   }
 
-  const params = url.parse(dbUrl);
+  const params = url.parse(dbUrl, true);
   const config = {};
 
   if (params.auth) {
@@ -45,8 +45,8 @@ const dbUrlToConfig = (dbUrl) => {
 
   const ssl = params.query && params.query.ssl;
 
-  if (ssl) {
-    config.ssl = ssl === 'true' || ssl === '1';
+  if (ssl && ssl === 'true' || ssl === '1') {
+    config.ssl = true;
   }
 
   return config;
@@ -101,7 +101,12 @@ const startWorker = (workerId) => {
     },
   };
 
-  const app    = express();
+  if (!!process.env.DB_SSLMODE && process.env.DB_SSLMODE !== 'disable') {
+    pgConfigs.development.ssl = true;
+    pgConfigs.production.ssl  = true;
+  }
+
+  const app = express();
   app.set('trusted proxy', process.env.TRUSTED_PROXY_IP || 'loopback,uniquelocal');
 
   const pgPool = new pg.Pool(Object.assign(pgConfigs[env], dbUrlToConfig(process.env.DATABASE_URL)));
@@ -190,14 +195,14 @@ const startWorker = (workerId) => {
     next();
   };
 
-  const accountFromToken = (token, req, next) => {
+  const accountFromToken = (token, allowedScopes, req, next) => {
     pgPool.connect((err, client, done) => {
       if (err) {
         next(err);
         return;
       }
 
-      client.query('SELECT oauth_access_tokens.resource_owner_id, users.account_id, users.chosen_languages FROM oauth_access_tokens INNER JOIN users ON oauth_access_tokens.resource_owner_id = users.id WHERE oauth_access_tokens.token = $1 AND oauth_access_tokens.revoked_at IS NULL LIMIT 1', [token], (err, result) => {
+      client.query('SELECT oauth_access_tokens.resource_owner_id, users.account_id, users.chosen_languages, oauth_access_tokens.scopes FROM oauth_access_tokens INNER JOIN users ON oauth_access_tokens.resource_owner_id = users.id WHERE oauth_access_tokens.token = $1 AND oauth_access_tokens.revoked_at IS NULL LIMIT 1', [token], (err, result) => {
         done();
 
         if (err) {
@@ -213,18 +218,29 @@ const startWorker = (workerId) => {
           return;
         }
 
+        const scopes = result.rows[0].scopes.split(' ');
+
+        if (allowedScopes.size > 0 && !scopes.some(scope => allowedScopes.includes(scope))) {
+          err = new Error('Access token does not cover required scopes');
+          err.statusCode = 401;
+
+          next(err);
+          return;
+        }
+
         req.accountId = result.rows[0].account_id;
         req.chosenLanguages = result.rows[0].chosen_languages;
+        req.allowNotifications = scopes.some(scope => ['read', 'read:notifications'].includes(scope));
 
         next();
       });
     });
   };
 
-  const accountFromRequest = (req, next, required = true) => {
+  const accountFromRequest = (req, next, required = true, allowedScopes = ['read']) => {
     const authorization = req.headers.authorization;
     const location = url.parse(req.url, true);
-    const accessToken = location.query.access_token;
+    const accessToken = location.query.access_token || req.headers['sec-websocket-protocol'];
 
     if (!authorization && !accessToken) {
       if (required) {
@@ -241,7 +257,7 @@ const startWorker = (workerId) => {
 
     const token = authorization ? authorization.replace(/^Bearer /, '') : accessToken;
 
-    accountFromToken(token, req, next);
+    accountFromToken(token, allowedScopes, req, next);
   };
 
   const PUBLIC_STREAMS = [
@@ -256,6 +272,16 @@ const startWorker = (workerId) => {
   const wsVerifyClient = (info, cb) => {
     const location = url.parse(info.req.url, true);
     const authRequired = !PUBLIC_STREAMS.some(stream => stream === location.query.stream);
+    const allowedScopes = [];
+
+    if (authRequired) {
+      allowedScopes.push('read');
+      if (location.query.stream === 'user:notification') {
+        allowedScopes.push('read:notifications');
+      } else {
+        allowedScopes.push('read:statuses');
+      }
+    }
 
     accountFromRequest(info.req, err => {
       if (!err) {
@@ -264,7 +290,7 @@ const startWorker = (workerId) => {
         log.error(info.req.requestId, err.toString());
         cb(false, 401, 'Unauthorized');
       }
-    }, authRequired);
+    }, authRequired, allowedScopes);
   };
 
   const PUBLIC_ENDPOINTS = [
@@ -281,7 +307,18 @@ const startWorker = (workerId) => {
     }
 
     const authRequired = !PUBLIC_ENDPOINTS.some(endpoint => endpoint === req.path);
-    accountFromRequest(req, next, authRequired);
+    const allowedScopes = [];
+
+    if (authRequired) {
+      allowedScopes.push('read');
+      if (req.path === '/api/v1/streaming/user/notification') {
+        allowedScopes.push('read:notifications');
+      } else {
+        allowedScopes.push('read:statuses');
+      }
+    }
+
+    accountFromRequest(req, next, authRequired, allowedScopes);
   };
 
   const errorMiddleware = (err, req, res, {}) => {
@@ -334,6 +371,10 @@ const startWorker = (workerId) => {
         return;
       }
 
+      if (event === 'notification' && !req.allowNotifications) {
+        return;
+      }
+
       // Only messages that may require filtering are statuses, since notifications
       // are already personalized and deletes do not matter
       if (!needsFiltering || event !== 'update') {
@@ -531,20 +572,13 @@ const startWorker = (workerId) => {
     });
   });
 
-  const wss = new WebSocket.Server({ server, verifyClient: wsVerifyClient });
+  const wss = new WebSocketServer({ server, verifyClient: wsVerifyClient });
 
-  wss.on('connection', ws => {
-    const req      = ws.upgradeReq;
+  wss.on('connection', (ws, req) => {
     const location = url.parse(req.url, true);
     req.requestId  = uuid.v4();
     req.remoteAddress = ws._socket.remoteAddress;
 
-    ws.isAlive = true;
-
-    ws.on('pong', () => {
-      ws.isAlive = true;
-    });
-
     let channel;
 
     switch(location.query.stream) {
@@ -605,17 +639,7 @@ const startWorker = (workerId) => {
     }
   });
 
-  setInterval(() => {
-    wss.clients.forEach(ws => {
-      if (ws.isAlive === false) {
-        ws.terminate();
-        return;
-      }
-
-      ws.isAlive = false;
-      ws.ping('', false, true);
-    });
-  }, 30000);
+  wss.startAutoPing(30000);
 
   attachServerWithConfig(server, address => {
     log.info(`Worker ${workerId} now listening on ${address}`);
@@ -648,7 +672,7 @@ const attachServerWithConfig = (server, onSuccess) => {
       }
     });
   } else {
-    server.listen(+process.env.PORT || 4000, process.env.BIND || '0.0.0.0', () => {
+    server.listen(+process.env.PORT || 4000, process.env.BIND || '127.0.0.1', () => {
       if (onSuccess) {
         onSuccess(`${server.address().address}:${server.address().port}`);
       }
diff --git a/yarn.lock b/yarn.lock
index 9ff12a712bfa077c87d21109b719d9a09f78ccc7..b9b47c18552dd931b8e0328ade104b3a9c157853 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,41 +2,72 @@
 # yarn lockfile v1
 
 
-"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.0.0-beta.35":
+"@babel/code-frame@^7.0.0":
   version "7.0.0"
   resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8"
   integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==
   dependencies:
     "@babel/highlight" "^7.0.0"
 
-"@babel/core@^7.2.2":
-  version "7.2.2"
-  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.2.2.tgz#07adba6dde27bb5ad8d8672f15fde3e08184a687"
-  integrity sha512-59vB0RWt09cAct5EIe58+NzGP4TFSD3Bz//2/ELy3ZeTeKF6VTD1AXlH8BGGbCX0PuobZBsIzO7IAI9PH67eKw==
+"@babel/core@^7.1.0":
+  version "7.3.4"
+  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.3.4.tgz#921a5a13746c21e32445bf0798680e9d11a6530b"
+  integrity sha512-jRsuseXBo9pN197KnDwhhaaBzyZr2oIcLHHTt2oDdQrej5Qp57dCCJafWx5ivU8/alEYDpssYqv1MUqcxwQlrA==
   dependencies:
     "@babel/code-frame" "^7.0.0"
-    "@babel/generator" "^7.2.2"
+    "@babel/generator" "^7.3.4"
     "@babel/helpers" "^7.2.0"
-    "@babel/parser" "^7.2.2"
+    "@babel/parser" "^7.3.4"
     "@babel/template" "^7.2.2"
-    "@babel/traverse" "^7.2.2"
-    "@babel/types" "^7.2.2"
+    "@babel/traverse" "^7.3.4"
+    "@babel/types" "^7.3.4"
     convert-source-map "^1.1.0"
     debug "^4.1.0"
     json5 "^2.1.0"
-    lodash "^4.17.10"
+    lodash "^4.17.11"
     resolve "^1.3.2"
     semver "^5.4.1"
     source-map "^0.5.0"
 
-"@babel/generator@^7.2.2":
-  version "7.2.2"
-  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.2.2.tgz#18c816c70962640eab42fe8cae5f3947a5c65ccc"
-  integrity sha512-I4o675J/iS8k+P38dvJ3IBGqObLXyQLTxtrR4u9cSUJOURvafeEWb/pFMOTwtNrmq73mJzyF6ueTbO1BtN0Zeg==
+"@babel/core@^7.4.5":
+  version "7.4.5"
+  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.4.5.tgz#081f97e8ffca65a9b4b0fdc7e274e703f000c06a"
+  integrity sha512-OvjIh6aqXtlsA8ujtGKfC7LYWksYSX8yQcM8Ay3LuvVeQ63lcOKgoZWVqcpFwkd29aYU9rVx7jxhfhiEDV9MZA==
   dependencies:
-    "@babel/types" "^7.2.2"
+    "@babel/code-frame" "^7.0.0"
+    "@babel/generator" "^7.4.4"
+    "@babel/helpers" "^7.4.4"
+    "@babel/parser" "^7.4.5"
+    "@babel/template" "^7.4.4"
+    "@babel/traverse" "^7.4.5"
+    "@babel/types" "^7.4.4"
+    convert-source-map "^1.1.0"
+    debug "^4.1.0"
+    json5 "^2.1.0"
+    lodash "^4.17.11"
+    resolve "^1.3.2"
+    semver "^5.4.1"
+    source-map "^0.5.0"
+
+"@babel/generator@^7.0.0", "@babel/generator@^7.3.4":
+  version "7.3.4"
+  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.3.4.tgz#9aa48c1989257877a9d971296e5b73bfe72e446e"
+  integrity sha512-8EXhHRFqlVVWXPezBW5keTiQi/rJMQTg/Y9uVCEZ0CAF3PKtCCaVRnp64Ii1ujhkoDhhF1fVsImoN4yJ2uz4Wg==
+  dependencies:
+    "@babel/types" "^7.3.4"
     jsesc "^2.5.1"
-    lodash "^4.17.10"
+    lodash "^4.17.11"
+    source-map "^0.5.0"
+    trim-right "^1.0.1"
+
+"@babel/generator@^7.2.2", "@babel/generator@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.4.4.tgz#174a215eb843fc392c7edcaabeaa873de6e8f041"
+  integrity sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==
+  dependencies:
+    "@babel/types" "^7.4.4"
+    jsesc "^2.5.1"
+    lodash "^4.17.11"
     source-map "^0.5.0"
     trim-right "^1.0.1"
 
@@ -63,34 +94,35 @@
     "@babel/types" "^7.0.0"
     esutils "^2.0.0"
 
-"@babel/helper-call-delegate@^7.1.0":
-  version "7.1.0"
-  resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.1.0.tgz#6a957f105f37755e8645343d3038a22e1449cc4a"
-  integrity sha512-YEtYZrw3GUK6emQHKthltKNZwszBcHK58Ygcis+gVUrF4/FmTVr5CCqQNSfmvg2y+YDEANyYoaLz/SHsnusCwQ==
+"@babel/helper-call-delegate@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz#87c1f8ca19ad552a736a7a27b1c1fcf8b1ff1f43"
+  integrity sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ==
   dependencies:
-    "@babel/helper-hoist-variables" "^7.0.0"
-    "@babel/traverse" "^7.1.0"
-    "@babel/types" "^7.0.0"
+    "@babel/helper-hoist-variables" "^7.4.4"
+    "@babel/traverse" "^7.4.4"
+    "@babel/types" "^7.4.4"
 
-"@babel/helper-create-class-features-plugin@^7.2.3":
-  version "7.2.3"
-  resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.2.3.tgz#f6e719abb90cb7f4a69591e35fd5eb89047c4a7c"
-  integrity sha512-xO/3Gn+2C7/eOUeb0VRnSP1+yvWHNxlpAot1eMhtoKDCN7POsyQP5excuT5UsV5daHxMWBeIIOeI5cmB8vMRgQ==
+"@babel/helper-create-class-features-plugin@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.4.4.tgz#fc3d690af6554cc9efc607364a82d48f58736dba"
+  integrity sha512-UbBHIa2qeAGgyiNR9RszVF7bUHEdgS4JAUNT8SiqrAN6YJVxlOxeLr5pBzb5kan302dejJ9nla4RyKcR1XT6XA==
   dependencies:
     "@babel/helper-function-name" "^7.1.0"
     "@babel/helper-member-expression-to-functions" "^7.0.0"
     "@babel/helper-optimise-call-expression" "^7.0.0"
     "@babel/helper-plugin-utils" "^7.0.0"
-    "@babel/helper-replace-supers" "^7.2.3"
+    "@babel/helper-replace-supers" "^7.4.4"
+    "@babel/helper-split-export-declaration" "^7.4.4"
 
-"@babel/helper-define-map@^7.1.0":
-  version "7.1.0"
-  resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.1.0.tgz#3b74caec329b3c80c116290887c0dd9ae468c20c"
-  integrity sha512-yPPcW8dc3gZLN+U1mhYV91QU3n5uTbx7DUdf8NnPbjS0RMwBuHi9Xt2MUgppmNz7CJxTBWsGczTiEp1CSOTPRg==
+"@babel/helper-define-map@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.4.4.tgz#6969d1f570b46bdc900d1eba8e5d59c48ba2c12a"
+  integrity sha512-IX3Ln8gLhZpSuqHJSnTNBWGDE9kdkTEWl21A/K7PQ00tseBwbqCHTvNLHSBd9M0R5rER4h5Rsvj9vw0R5SieBg==
   dependencies:
     "@babel/helper-function-name" "^7.1.0"
-    "@babel/types" "^7.0.0"
-    lodash "^4.17.10"
+    "@babel/types" "^7.4.4"
+    lodash "^4.17.11"
 
 "@babel/helper-explode-assignable-expression@^7.1.0":
   version "7.1.0"
@@ -116,12 +148,12 @@
   dependencies:
     "@babel/types" "^7.0.0"
 
-"@babel/helper-hoist-variables@^7.0.0":
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0.tgz#46adc4c5e758645ae7a45deb92bab0918c23bb88"
-  integrity sha512-Ggv5sldXUeSKsuzLkddtyhyHe2YantsxWKNi7A+7LeD12ExRDWTRk29JCXpaHPAbMaIPZSil7n+lq78WY2VY7w==
+"@babel/helper-hoist-variables@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz#0298b5f25c8c09c53102d52ac4a98f773eb2850a"
+  integrity sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w==
   dependencies:
-    "@babel/types" "^7.0.0"
+    "@babel/types" "^7.4.4"
 
 "@babel/helper-member-expression-to-functions@^7.0.0":
   version "7.0.0"
@@ -137,17 +169,17 @@
   dependencies:
     "@babel/types" "^7.0.0"
 
-"@babel/helper-module-transforms@^7.1.0":
-  version "7.2.2"
-  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.2.2.tgz#ab2f8e8d231409f8370c883d20c335190284b963"
-  integrity sha512-YRD7I6Wsv+IHuTPkAmAS4HhY0dkPobgLftHp0cRGZSdrRvmZY8rFvae/GVu3bD00qscuvK3WPHB3YdNpBXUqrA==
+"@babel/helper-module-transforms@^7.1.0", "@babel/helper-module-transforms@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.4.4.tgz#96115ea42a2f139e619e98ed46df6019b94414b8"
+  integrity sha512-3Z1yp8TVQf+B4ynN7WoHPKS8EkdTbgAEy0nU0rs/1Kw4pDgmvYH3rz3aI11KgxKCba2cn7N+tqzV1mY2HMN96w==
   dependencies:
     "@babel/helper-module-imports" "^7.0.0"
     "@babel/helper-simple-access" "^7.1.0"
-    "@babel/helper-split-export-declaration" "^7.0.0"
-    "@babel/template" "^7.2.2"
-    "@babel/types" "^7.2.2"
-    lodash "^4.17.10"
+    "@babel/helper-split-export-declaration" "^7.4.4"
+    "@babel/template" "^7.4.4"
+    "@babel/types" "^7.4.4"
+    lodash "^4.17.11"
 
 "@babel/helper-optimise-call-expression@^7.0.0":
   version "7.0.0"
@@ -161,12 +193,12 @@
   resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250"
   integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==
 
-"@babel/helper-regex@^7.0.0":
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.0.0.tgz#2c1718923b57f9bbe64705ffe5640ac64d9bdb27"
-  integrity sha512-TR0/N0NDCcUIUEbqV6dCO+LptmmSQFQ7q70lfcEB4URsjD0E1HzicrwUH+ap6BAQ2jhCX9Q4UqZy4wilujWlkg==
+"@babel/helper-regex@^7.0.0", "@babel/helper-regex@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.4.4.tgz#a47e02bc91fb259d2e6727c2a30013e3ac13c4a2"
+  integrity sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q==
   dependencies:
-    lodash "^4.17.10"
+    lodash "^4.17.11"
 
 "@babel/helper-remap-async-to-generator@^7.1.0":
   version "7.1.0"
@@ -179,15 +211,15 @@
     "@babel/traverse" "^7.1.0"
     "@babel/types" "^7.0.0"
 
-"@babel/helper-replace-supers@^7.1.0", "@babel/helper-replace-supers@^7.2.3":
-  version "7.2.3"
-  resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.2.3.tgz#19970020cf22677d62b3a689561dbd9644d8c5e5"
-  integrity sha512-GyieIznGUfPXPWu0yLS6U55Mz67AZD9cUk0BfirOWlPrXlBcan9Gz+vHGz+cPfuoweZSnPzPIm67VtQM0OWZbA==
+"@babel/helper-replace-supers@^7.1.0", "@babel/helper-replace-supers@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.4.4.tgz#aee41783ebe4f2d3ab3ae775e1cc6f1a90cefa27"
+  integrity sha512-04xGEnd+s01nY1l15EuMS1rfKktNF+1CkKmHoErDppjAAZL+IUBZpzT748x262HF7fibaQPhbvWUl5HeSt1EXg==
   dependencies:
     "@babel/helper-member-expression-to-functions" "^7.0.0"
     "@babel/helper-optimise-call-expression" "^7.0.0"
-    "@babel/traverse" "^7.2.3"
-    "@babel/types" "^7.0.0"
+    "@babel/traverse" "^7.4.4"
+    "@babel/types" "^7.4.4"
 
 "@babel/helper-simple-access@^7.1.0":
   version "7.1.0"
@@ -197,12 +229,12 @@
     "@babel/template" "^7.1.0"
     "@babel/types" "^7.0.0"
 
-"@babel/helper-split-export-declaration@^7.0.0":
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz#3aae285c0311c2ab095d997b8c9a94cad547d813"
-  integrity sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==
+"@babel/helper-split-export-declaration@^7.0.0", "@babel/helper-split-export-declaration@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz#ff94894a340be78f53f06af038b205c49d993677"
+  integrity sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==
   dependencies:
-    "@babel/types" "^7.0.0"
+    "@babel/types" "^7.4.4"
 
 "@babel/helper-wrap-function@^7.1.0":
   version "7.2.0"
@@ -223,6 +255,15 @@
     "@babel/traverse" "^7.1.5"
     "@babel/types" "^7.2.0"
 
+"@babel/helpers@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.4.4.tgz#868b0ef59c1dd4e78744562d5ce1b59c89f2f2a5"
+  integrity sha512-igczbR/0SeuPR8RFfC7tGrbdTbFL3QTvH6D+Z6zNxnTe//GyqmtHmDkzrqDmyZ3eSwPqB/LhyKoU5DXsp+Vp2A==
+  dependencies:
+    "@babel/template" "^7.4.4"
+    "@babel/traverse" "^7.4.4"
+    "@babel/types" "^7.4.4"
+
 "@babel/highlight@^7.0.0":
   version "7.0.0"
   resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4"
@@ -232,11 +273,21 @@
     esutils "^2.0.2"
     js-tokens "^4.0.0"
 
-"@babel/parser@^7.0.0", "@babel/parser@^7.2.2", "@babel/parser@^7.2.3":
+"@babel/parser@^7.0.0":
   version "7.2.3"
   resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.2.3.tgz#32f5df65744b70888d17872ec106b02434ba1489"
   integrity sha512-0LyEcVlfCoFmci8mXx8A5oIkpkOgyo8dRHtxBnK9RRBwxO2+JZPNsqtVEZQ7mJFPxnXF9lfmU24mHOPI0qnlkA==
 
+"@babel/parser@^7.1.0", "@babel/parser@^7.3.4":
+  version "7.3.4"
+  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.4.tgz#a43357e4bbf4b92a437fb9e465c192848287f27c"
+  integrity sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ==
+
+"@babel/parser@^7.2.2", "@babel/parser@^7.2.3", "@babel/parser@^7.4.4", "@babel/parser@^7.4.5":
+  version "7.4.5"
+  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.4.5.tgz#04af8d5d5a2b044a2a1bffacc1e5e6673544e872"
+  integrity sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==
+
 "@babel/plugin-proposal-async-generator-functions@^7.2.0":
   version "7.2.0"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e"
@@ -246,20 +297,20 @@
     "@babel/helper-remap-async-to-generator" "^7.1.0"
     "@babel/plugin-syntax-async-generators" "^7.2.0"
 
-"@babel/plugin-proposal-class-properties@^7.2.3":
-  version "7.2.3"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.2.3.tgz#c9e1294363b346cff333007a92080f3203698461"
-  integrity sha512-FVuQngLoN2iDrpW7LmhPZ2sO4DJxf35FOcwidwB9Ru9tMvI5URthnkVHuG14IStV+TzkMTyLMoOUlSTtrdVwqw==
+"@babel/plugin-proposal-class-properties@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.4.4.tgz#93a6486eed86d53452ab9bab35e368e9461198ce"
+  integrity sha512-WjKTI8g8d5w1Bc9zgwSz2nfrsNQsXcCf9J9cdCvrJV6RF56yztwm4TmJC0MgJ9tvwO9gUA/mcYe89bLdGfiXFg==
   dependencies:
-    "@babel/helper-create-class-features-plugin" "^7.2.3"
+    "@babel/helper-create-class-features-plugin" "^7.4.4"
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-proposal-decorators@^7.2.3":
-  version "7.2.3"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.2.3.tgz#1fe5b0d22ce0c4418f225474ebd40267430364c0"
-  integrity sha512-jhCFm7ftmue02EWIYqbhzP0iConEPsgVQeDriOs/Qc2lgr6MDtHTTrv3hE2GOOQDFjQ9tjP7nWQq0ad0JhIsQg==
+"@babel/plugin-proposal-decorators@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.4.4.tgz#de9b2a1a8ab0196f378e2a82f10b6e2a36f21cc0"
+  integrity sha512-z7MpQz3XC/iQJWXH9y+MaWcLPNSMY9RQSthrLzak8R8hCj0fuyNk+Dzi9kfNe/JxxlWQ2g7wkABbgWjW36MTcw==
   dependencies:
-    "@babel/helper-create-class-features-plugin" "^7.2.3"
+    "@babel/helper-create-class-features-plugin" "^7.4.4"
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/plugin-syntax-decorators" "^7.2.0"
 
@@ -271,10 +322,10 @@
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/plugin-syntax-json-strings" "^7.2.0"
 
-"@babel/plugin-proposal-object-rest-spread@^7.2.0":
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.2.0.tgz#88f5fec3e7ad019014c97f7ee3c992f0adbf7fb8"
-  integrity sha512-1L5mWLSvR76XYUQJXkd/EEQgjq8HHRP6lQuZTTg0VA4tTGPpGemmCdAfQIz1rzEuWAm+ecP8PyyEm30jC1eQCg==
+"@babel/plugin-proposal-object-rest-spread@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.4.tgz#1ef173fcf24b3e2df92a678f027673b55e7e3005"
+  integrity sha512-dMBG6cSPBbHeEBdFXeQ2QLc5gUpg4Vkaz8octD4aoW/ISO+jBOcsuxYL7bsb5WSu8RLP6boxrBIALEHgoHtO9g==
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/plugin-syntax-object-rest-spread" "^7.2.0"
@@ -287,14 +338,14 @@
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/plugin-syntax-optional-catch-binding" "^7.2.0"
 
-"@babel/plugin-proposal-unicode-property-regex@^7.2.0":
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.2.0.tgz#abe7281fe46c95ddc143a65e5358647792039520"
-  integrity sha512-LvRVYb7kikuOtIoUeWTkOxQEV1kYvL5B6U3iWEGCzPNRus1MzJweFqORTj+0jkxozkTSYNJozPOddxmqdqsRpw==
+"@babel/plugin-proposal-unicode-property-regex@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz#501ffd9826c0b91da22690720722ac7cb1ca9c78"
+  integrity sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA==
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
-    "@babel/helper-regex" "^7.0.0"
-    regexpu-core "^4.2.0"
+    "@babel/helper-regex" "^7.4.4"
+    regexpu-core "^4.5.4"
 
 "@babel/plugin-syntax-async-generators@^7.2.0":
   version "7.2.0"
@@ -331,7 +382,7 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-syntax-object-rest-spread@^7.2.0":
+"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.2.0":
   version "7.2.0"
   resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e"
   integrity sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==
@@ -352,10 +403,10 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-transform-async-to-generator@^7.2.0":
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.2.0.tgz#68b8a438663e88519e65b776f8938f3445b1a2ff"
-  integrity sha512-CEHzg4g5UraReozI9D4fblBYABs7IM6UerAVG7EJVrTLC5keh00aEuLUT+O40+mJCEzaXkYfTCUKIyeDfMOFFQ==
+"@babel/plugin-transform-async-to-generator@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.4.4.tgz#a3f1d01f2f21cadab20b33a82133116f14fb5894"
+  integrity sha512-YiqW2Li8TXmzgbXw+STsSqPBPFnGviiaSp6CYOq55X8GQ2SGVLrXB6pNid8HkqkZAzOH6knbai3snhP7v0fNwA==
   dependencies:
     "@babel/helper-module-imports" "^7.0.0"
     "@babel/helper-plugin-utils" "^7.0.0"
@@ -368,26 +419,26 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-transform-block-scoping@^7.2.0":
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.2.0.tgz#f17c49d91eedbcdf5dd50597d16f5f2f770132d4"
-  integrity sha512-vDTgf19ZEV6mx35yiPJe4fS02mPQUUcBNwWQSZFXSzTSbsJFQvHt7DqyS3LK8oOWALFOsJ+8bbqBgkirZteD5Q==
+"@babel/plugin-transform-block-scoping@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.4.tgz#c13279fabf6b916661531841a23c4b7dae29646d"
+  integrity sha512-jkTUyWZcTrwxu5DD4rWz6rDB5Cjdmgz6z7M7RLXOJyCUkFBawssDGcGh8M/0FTSB87avyJI1HsTwUXp9nKA1PA==
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
-    lodash "^4.17.10"
+    lodash "^4.17.11"
 
-"@babel/plugin-transform-classes@^7.2.0":
-  version "7.2.2"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.2.2.tgz#6c90542f210ee975aa2aa8c8b5af7fa73a126953"
-  integrity sha512-gEZvgTy1VtcDOaQty1l10T3jQmJKlNVxLDCs+3rCVPr6nMkODLELxViq5X9l+rfxbie3XrfrMCYYY6eX3aOcOQ==
+"@babel/plugin-transform-classes@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.4.tgz#0ce4094cdafd709721076d3b9c38ad31ca715eb6"
+  integrity sha512-/e44eFLImEGIpL9qPxSRat13I5QNRgBLu2hOQJCF7VLy/otSM/sypV1+XaIw5+502RX/+6YaSAPmldk+nhHDPw==
   dependencies:
     "@babel/helper-annotate-as-pure" "^7.0.0"
-    "@babel/helper-define-map" "^7.1.0"
+    "@babel/helper-define-map" "^7.4.4"
     "@babel/helper-function-name" "^7.1.0"
     "@babel/helper-optimise-call-expression" "^7.0.0"
     "@babel/helper-plugin-utils" "^7.0.0"
-    "@babel/helper-replace-supers" "^7.1.0"
-    "@babel/helper-split-export-declaration" "^7.0.0"
+    "@babel/helper-replace-supers" "^7.4.4"
+    "@babel/helper-split-export-declaration" "^7.4.4"
     globals "^11.1.0"
 
 "@babel/plugin-transform-computed-properties@^7.2.0":
@@ -397,21 +448,21 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-transform-destructuring@^7.2.0":
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.2.0.tgz#e75269b4b7889ec3a332cd0d0c8cff8fed0dc6f3"
-  integrity sha512-coVO2Ayv7g0qdDbrNiadE4bU7lvCd9H539m2gMknyVjjMdwF/iCOM7R+E8PkntoqLkltO0rk+3axhpp/0v68VQ==
+"@babel/plugin-transform-destructuring@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.4.tgz#9d964717829cc9e4b601fc82a26a71a4d8faf20f"
+  integrity sha512-/aOx+nW0w8eHiEHm+BTERB2oJn5D127iye/SUQl7NjHy0lf+j7h4MKMMSOwdazGq9OxgiNADncE+SRJkCxjZpQ==
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-transform-dotall-regex@^7.2.0":
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.2.0.tgz#f0aabb93d120a8ac61e925ea0ba440812dbe0e49"
-  integrity sha512-sKxnyHfizweTgKZf7XsXu/CNupKhzijptfTM+bozonIuyVrLWVUvYjE2bhuSBML8VQeMxq4Mm63Q9qvcvUcciQ==
+"@babel/plugin-transform-dotall-regex@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz#361a148bc951444312c69446d76ed1ea8e4450c3"
+  integrity sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg==
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
-    "@babel/helper-regex" "^7.0.0"
-    regexpu-core "^4.1.3"
+    "@babel/helper-regex" "^7.4.4"
+    regexpu-core "^4.5.4"
 
 "@babel/plugin-transform-duplicate-keys@^7.2.0":
   version "7.2.0"
@@ -428,17 +479,17 @@
     "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0"
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-transform-for-of@^7.2.0":
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.2.0.tgz#ab7468befa80f764bb03d3cb5eef8cc998e1cad9"
-  integrity sha512-Kz7Mt0SsV2tQk6jG5bBv5phVbkd0gd27SgYD4hH1aLMJRchM0dzHaXvrWhVZ+WxAlDoAKZ7Uy3jVTW2mKXQ1WQ==
+"@babel/plugin-transform-for-of@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz#0267fc735e24c808ba173866c6c4d1440fc3c556"
+  integrity sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ==
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-transform-function-name@^7.2.0":
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.2.0.tgz#f7930362829ff99a3174c39f0afcc024ef59731a"
-  integrity sha512-kWgksow9lHdvBC2Z4mxTsvc7YdY7w/V6B2vy9cTIPtLEE9NhwoWivaxdNM/S37elu5bqlLP/qOY906LukO9lkQ==
+"@babel/plugin-transform-function-name@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz#e1436116abb0610c2259094848754ac5230922ad"
+  integrity sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA==
   dependencies:
     "@babel/helper-function-name" "^7.1.0"
     "@babel/helper-plugin-utils" "^7.0.0"
@@ -450,6 +501,13 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
 
+"@babel/plugin-transform-member-expression-literals@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz#fa10aa5c58a2cb6afcf2c9ffa8cb4d8b3d489a2d"
+  integrity sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
+
 "@babel/plugin-transform-modules-amd@^7.2.0":
   version "7.2.0"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz#82a9bce45b95441f617a24011dc89d12da7f4ee6"
@@ -458,21 +516,21 @@
     "@babel/helper-module-transforms" "^7.1.0"
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-transform-modules-commonjs@^7.2.0":
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.2.0.tgz#c4f1933f5991d5145e9cfad1dfd848ea1727f404"
-  integrity sha512-V6y0uaUQrQPXUrmj+hgnks8va2L0zcZymeU7TtWEgdRLNkceafKXEduv7QzgQAE4lT+suwooG9dC7LFhdRAbVQ==
+"@babel/plugin-transform-modules-commonjs@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.4.tgz#0bef4713d30f1d78c2e59b3d6db40e60192cac1e"
+  integrity sha512-4sfBOJt58sEo9a2BQXnZq+Q3ZTSAUXyK3E30o36BOGnJ+tvJ6YSxF0PG6kERvbeISgProodWuI9UVG3/FMY6iw==
   dependencies:
-    "@babel/helper-module-transforms" "^7.1.0"
+    "@babel/helper-module-transforms" "^7.4.4"
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/helper-simple-access" "^7.1.0"
 
-"@babel/plugin-transform-modules-systemjs@^7.2.0":
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.2.0.tgz#912bfe9e5ff982924c81d0937c92d24994bb9068"
-  integrity sha512-aYJwpAhoK9a+1+O625WIjvMY11wkB/ok0WClVwmeo3mCjcNRjt+/8gHWrB5i+00mUju0gWsBkQnPpdvQ7PImmQ==
+"@babel/plugin-transform-modules-systemjs@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.4.4.tgz#dc83c5665b07d6c2a7b224c00ac63659ea36a405"
+  integrity sha512-MSiModfILQc3/oqnG7NrP1jHaSPryO6tA2kOMmAQApz5dayPxWiHqmq4sWH2xF5LcQK56LlbKByCd8Aah/OIkQ==
   dependencies:
-    "@babel/helper-hoist-variables" "^7.0.0"
+    "@babel/helper-hoist-variables" "^7.4.4"
     "@babel/helper-plugin-utils" "^7.0.0"
 
 "@babel/plugin-transform-modules-umd@^7.2.0":
@@ -483,10 +541,17 @@
     "@babel/helper-module-transforms" "^7.1.0"
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-transform-new-target@^7.0.0":
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0.tgz#ae8fbd89517fa7892d20e6564e641e8770c3aa4a"
-  integrity sha512-yin069FYjah+LbqfGeTfzIBODex/e++Yfa0rH0fpfam9uTbuEeEOx5GLGr210ggOV77mVRNoeqSYqeuaqSzVSw==
+"@babel/plugin-transform-named-capturing-groups-regex@^7.4.5":
+  version "7.4.5"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz#9d269fd28a370258199b4294736813a60bbdd106"
+  integrity sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg==
+  dependencies:
+    regexp-tree "^0.1.6"
+
+"@babel/plugin-transform-new-target@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz#18d120438b0cc9ee95a47f2c72bc9768fbed60a5"
+  integrity sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA==
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
 
@@ -498,15 +563,22 @@
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/helper-replace-supers" "^7.1.0"
 
-"@babel/plugin-transform-parameters@^7.2.0":
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.2.0.tgz#0d5ad15dc805e2ea866df4dd6682bfe76d1408c2"
-  integrity sha512-kB9+hhUidIgUoBQ0MsxMewhzr8i60nMa2KgeJKQWYrqQpqcBYtnpR+JgkadZVZoaEZ/eKu9mclFaVwhRpLNSzA==
+"@babel/plugin-transform-parameters@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz#7556cf03f318bd2719fe4c922d2d808be5571e16"
+  integrity sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw==
   dependencies:
-    "@babel/helper-call-delegate" "^7.1.0"
+    "@babel/helper-call-delegate" "^7.4.4"
     "@babel/helper-get-function-arity" "^7.0.0"
     "@babel/helper-plugin-utils" "^7.0.0"
 
+"@babel/plugin-transform-property-literals@^7.2.0":
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz#03e33f653f5b25c4eb572c98b9485055b389e905"
+  integrity sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
+
 "@babel/plugin-transform-react-display-name@^7.0.0":
   version "7.2.0"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.2.0.tgz#ebfaed87834ce8dc4279609a4f0c324c156e3eb0"
@@ -547,17 +619,24 @@
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/plugin-syntax-jsx" "^7.2.0"
 
-"@babel/plugin-transform-regenerator@^7.0.0":
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0.tgz#5b41686b4ed40bef874d7ed6a84bdd849c13e0c1"
-  integrity sha512-sj2qzsEx8KDVv1QuJc/dEfilkg3RRPvPYx/VnKLtItVQRWt1Wqf5eVCOLZm29CiGFfYYsA3VPjfizTCV0S0Dlw==
+"@babel/plugin-transform-regenerator@^7.4.5":
+  version "7.4.5"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz#629dc82512c55cee01341fb27bdfcb210354680f"
+  integrity sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA==
   dependencies:
-    regenerator-transform "^0.13.3"
+    regenerator-transform "^0.14.0"
 
-"@babel/plugin-transform-runtime@^7.2.0":
+"@babel/plugin-transform-reserved-words@^7.2.0":
   version "7.2.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.2.0.tgz#566bc43f7d0aedc880eaddbd29168d0f248966ea"
-  integrity sha512-jIgkljDdq4RYDnJyQsiWbdvGeei/0MOTtSHKO/rfbd/mXBxNpdlulMx49L0HQ4pug1fXannxoqCI+fYSle9eSw==
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.2.0.tgz#4792af87c998a49367597d07fedf02636d2e1634"
+  integrity sha512-fz43fqW8E1tAB3DKF19/vxbpib1fuyCwSPE418ge5ZxILnBhWyhtPgz8eh1RCGGJlwvksHkyxMxh0eenFi+kFw==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
+
+"@babel/plugin-transform-runtime@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.4.4.tgz#a50f5d16e9c3a4ac18a1a9f9803c107c380bce08"
+  integrity sha512-aMVojEjPszvau3NRg+TIH14ynZLvPewH4xhlCW1w6A3rkxTS1m4uwzRclYR9oS+rl/dr+kT+pzbfHuAWP/lc7Q==
   dependencies:
     "@babel/helper-module-imports" "^7.0.0"
     "@babel/helper-plugin-utils" "^7.0.0"
@@ -586,10 +665,10 @@
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/helper-regex" "^7.0.0"
 
-"@babel/plugin-transform-template-literals@^7.2.0":
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.2.0.tgz#d87ed01b8eaac7a92473f608c97c089de2ba1e5b"
-  integrity sha512-FkPix00J9A/XWXv4VoKJBMeSkyY9x/TqIh76wzcdfl57RJJcf8CehQ08uwfhCDNtRQYtHQKBTwKZDEyjE13Lwg==
+"@babel/plugin-transform-template-literals@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz#9d28fea7bbce637fb7612a0750989d8321d4bcb0"
+  integrity sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g==
   dependencies:
     "@babel/helper-annotate-as-pure" "^7.0.0"
     "@babel/helper-plugin-utils" "^7.0.0"
@@ -601,61 +680,68 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
 
-"@babel/plugin-transform-unicode-regex@^7.2.0":
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.2.0.tgz#4eb8db16f972f8abb5062c161b8b115546ade08b"
-  integrity sha512-m48Y0lMhrbXEJnVUaYly29jRXbQ3ksxPrS1Tg8t+MHqzXhtBYAvI51euOBaoAlZLPHsieY9XPVMf80a5x0cPcA==
+"@babel/plugin-transform-unicode-regex@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz#ab4634bb4f14d36728bf5978322b35587787970f"
+  integrity sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA==
   dependencies:
     "@babel/helper-plugin-utils" "^7.0.0"
-    "@babel/helper-regex" "^7.0.0"
-    regexpu-core "^4.1.3"
+    "@babel/helper-regex" "^7.4.4"
+    regexpu-core "^4.5.4"
 
-"@babel/preset-env@^7.2.3":
-  version "7.2.3"
-  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.2.3.tgz#948c8df4d4609c99c7e0130169f052ea6a7a8933"
-  integrity sha512-AuHzW7a9rbv5WXmvGaPX7wADxFkZIqKlbBh1dmZUQp4iwiPpkE/Qnrji6SC4UQCQzvWY/cpHET29eUhXS9cLPw==
+"@babel/preset-env@^7.4.5":
+  version "7.4.5"
+  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.4.5.tgz#2fad7f62983d5af563b5f3139242755884998a58"
+  integrity sha512-f2yNVXM+FsR5V8UwcFeIHzHWgnhXg3NpRmy0ADvALpnhB0SLbCvrCRr4BLOUYbQNLS+Z0Yer46x9dJXpXewI7w==
   dependencies:
     "@babel/helper-module-imports" "^7.0.0"
     "@babel/helper-plugin-utils" "^7.0.0"
     "@babel/plugin-proposal-async-generator-functions" "^7.2.0"
     "@babel/plugin-proposal-json-strings" "^7.2.0"
-    "@babel/plugin-proposal-object-rest-spread" "^7.2.0"
+    "@babel/plugin-proposal-object-rest-spread" "^7.4.4"
     "@babel/plugin-proposal-optional-catch-binding" "^7.2.0"
-    "@babel/plugin-proposal-unicode-property-regex" "^7.2.0"
+    "@babel/plugin-proposal-unicode-property-regex" "^7.4.4"
     "@babel/plugin-syntax-async-generators" "^7.2.0"
+    "@babel/plugin-syntax-json-strings" "^7.2.0"
     "@babel/plugin-syntax-object-rest-spread" "^7.2.0"
     "@babel/plugin-syntax-optional-catch-binding" "^7.2.0"
     "@babel/plugin-transform-arrow-functions" "^7.2.0"
-    "@babel/plugin-transform-async-to-generator" "^7.2.0"
+    "@babel/plugin-transform-async-to-generator" "^7.4.4"
     "@babel/plugin-transform-block-scoped-functions" "^7.2.0"
-    "@babel/plugin-transform-block-scoping" "^7.2.0"
-    "@babel/plugin-transform-classes" "^7.2.0"
+    "@babel/plugin-transform-block-scoping" "^7.4.4"
+    "@babel/plugin-transform-classes" "^7.4.4"
     "@babel/plugin-transform-computed-properties" "^7.2.0"
-    "@babel/plugin-transform-destructuring" "^7.2.0"
-    "@babel/plugin-transform-dotall-regex" "^7.2.0"
+    "@babel/plugin-transform-destructuring" "^7.4.4"
+    "@babel/plugin-transform-dotall-regex" "^7.4.4"
     "@babel/plugin-transform-duplicate-keys" "^7.2.0"
     "@babel/plugin-transform-exponentiation-operator" "^7.2.0"
-    "@babel/plugin-transform-for-of" "^7.2.0"
-    "@babel/plugin-transform-function-name" "^7.2.0"
+    "@babel/plugin-transform-for-of" "^7.4.4"
+    "@babel/plugin-transform-function-name" "^7.4.4"
     "@babel/plugin-transform-literals" "^7.2.0"
+    "@babel/plugin-transform-member-expression-literals" "^7.2.0"
     "@babel/plugin-transform-modules-amd" "^7.2.0"
-    "@babel/plugin-transform-modules-commonjs" "^7.2.0"
-    "@babel/plugin-transform-modules-systemjs" "^7.2.0"
+    "@babel/plugin-transform-modules-commonjs" "^7.4.4"
+    "@babel/plugin-transform-modules-systemjs" "^7.4.4"
     "@babel/plugin-transform-modules-umd" "^7.2.0"
-    "@babel/plugin-transform-new-target" "^7.0.0"
+    "@babel/plugin-transform-named-capturing-groups-regex" "^7.4.5"
+    "@babel/plugin-transform-new-target" "^7.4.4"
     "@babel/plugin-transform-object-super" "^7.2.0"
-    "@babel/plugin-transform-parameters" "^7.2.0"
-    "@babel/plugin-transform-regenerator" "^7.0.0"
+    "@babel/plugin-transform-parameters" "^7.4.4"
+    "@babel/plugin-transform-property-literals" "^7.2.0"
+    "@babel/plugin-transform-regenerator" "^7.4.5"
+    "@babel/plugin-transform-reserved-words" "^7.2.0"
     "@babel/plugin-transform-shorthand-properties" "^7.2.0"
     "@babel/plugin-transform-spread" "^7.2.0"
     "@babel/plugin-transform-sticky-regex" "^7.2.0"
-    "@babel/plugin-transform-template-literals" "^7.2.0"
+    "@babel/plugin-transform-template-literals" "^7.4.4"
     "@babel/plugin-transform-typeof-symbol" "^7.2.0"
-    "@babel/plugin-transform-unicode-regex" "^7.2.0"
-    browserslist "^4.3.4"
+    "@babel/plugin-transform-unicode-regex" "^7.4.4"
+    "@babel/types" "^7.4.4"
+    browserslist "^4.6.0"
+    core-js-compat "^3.1.1"
     invariant "^2.2.2"
     js-levenshtein "^1.1.3"
-    semver "^5.3.0"
+    semver "^5.5.0"
 
 "@babel/preset-react@^7.0.0":
   version "7.0.0"
@@ -675,14 +761,21 @@
   dependencies:
     regenerator-runtime "^0.12.0"
 
-"@babel/runtime@7.2.0", "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0":
+"@babel/runtime@7.2.0":
   version "7.2.0"
   resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.2.0.tgz#b03e42eeddf5898e00646e4c840fa07ba8dcad7f"
   integrity sha512-oouEibCbHMVdZSDlJBO6bZmID/zA/G/Qx3H1d3rSNPTD+L8UNKvCat7aKWSJ74zYbm5zWGh0GQN0hKj8zYFTCg==
   dependencies:
     regenerator-runtime "^0.12.0"
 
-"@babel/template@^7.1.0", "@babel/template@^7.1.2", "@babel/template@^7.2.2":
+"@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.5":
+  version "7.4.5"
+  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.5.tgz#582bb531f5f9dc67d2fcb682979894f75e253f12"
+  integrity sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==
+  dependencies:
+    regenerator-runtime "^0.13.2"
+
+"@babel/template@^7.0.0", "@babel/template@^7.1.2":
   version "7.2.2"
   resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.2.2.tgz#005b3fdf0ed96e88041330379e0da9a708eb2907"
   integrity sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==
@@ -691,7 +784,16 @@
     "@babel/parser" "^7.2.2"
     "@babel/types" "^7.2.2"
 
-"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5", "@babel/traverse@^7.2.2", "@babel/traverse@^7.2.3":
+"@babel/template@^7.1.0", "@babel/template@^7.2.2", "@babel/template@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.4.tgz#f4b88d1225689a08f5bc3a17483545be9e4ed237"
+  integrity sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==
+  dependencies:
+    "@babel/code-frame" "^7.0.0"
+    "@babel/parser" "^7.4.4"
+    "@babel/types" "^7.4.4"
+
+"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.5":
   version "7.2.3"
   resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.2.3.tgz#7ff50cefa9c7c0bd2d81231fdac122f3957748d8"
   integrity sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==
@@ -706,7 +808,46 @@
     globals "^11.1.0"
     lodash "^4.17.10"
 
-"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.2.2":
+"@babel/traverse@^7.1.0", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5":
+  version "7.4.5"
+  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.4.5.tgz#4e92d1728fd2f1897dafdd321efbff92156c3216"
+  integrity sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A==
+  dependencies:
+    "@babel/code-frame" "^7.0.0"
+    "@babel/generator" "^7.4.4"
+    "@babel/helper-function-name" "^7.1.0"
+    "@babel/helper-split-export-declaration" "^7.4.4"
+    "@babel/parser" "^7.4.5"
+    "@babel/types" "^7.4.4"
+    debug "^4.1.0"
+    globals "^11.1.0"
+    lodash "^4.17.11"
+
+"@babel/traverse@^7.3.4":
+  version "7.3.4"
+  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.3.4.tgz#1330aab72234f8dea091b08c4f8b9d05c7119e06"
+  integrity sha512-TvTHKp6471OYEcE/91uWmhR6PrrYywQntCHSaZ8CM8Vmp+pjAusal4nGB2WCCQd0rvI7nOMKn9GnbcvTUz3/ZQ==
+  dependencies:
+    "@babel/code-frame" "^7.0.0"
+    "@babel/generator" "^7.3.4"
+    "@babel/helper-function-name" "^7.1.0"
+    "@babel/helper-split-export-declaration" "^7.0.0"
+    "@babel/parser" "^7.3.4"
+    "@babel/types" "^7.3.4"
+    debug "^4.1.0"
+    globals "^11.1.0"
+    lodash "^4.17.11"
+
+"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.2.2", "@babel/types@^7.4.4":
+  version "7.4.4"
+  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.4.4.tgz#8db9e9a629bb7c29370009b4b779ed93fe57d5f0"
+  integrity sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==
+  dependencies:
+    esutils "^2.0.2"
+    lodash "^4.17.11"
+    to-fast-properties "^2.0.0"
+
+"@babel/types@^7.0.0-beta.49":
   version "7.2.2"
   resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.2.2.tgz#44e10fc24e33af524488b716cdaee5360ea8ed1e"
   integrity sha512-fKCuD6UFUMkR541eDWL+2ih/xFZBXPOg/7EQFeTluMDebfqR4jrpaCjLhkWlQS4hT6nRa2PMEgXKbRB5/H2fpg==
@@ -715,68 +856,292 @@
     lodash "^4.17.10"
     to-fast-properties "^2.0.0"
 
-"@emotion/cache@10.0.0":
-  version "10.0.0"
-  resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-10.0.0.tgz#e22eadcb770de4131ec707c84207e9e1ce210413"
-  integrity sha512-1/sT6GNyvWmxCtJek8ZDV+b+a+NMDx8/61UTnnF3rqrTY7bLTjw+fmXO7WgUIH0owuWKxza/J/FfAWC/RU4G7A==
+"@babel/types@^7.3.0", "@babel/types@^7.3.4":
+  version "7.3.4"
+  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.3.4.tgz#bf482eaeaffb367a28abbf9357a94963235d90ed"
+  integrity sha512-WEkp8MsLftM7O/ty580wAmZzN1nDmCACc5+jFzUt+GUFNNIi3LdRlueYz0YIlmJhlZx1QYDMZL5vdWCL0fNjFQ==
   dependencies:
-    "@emotion/sheet" "0.9.2"
-    "@emotion/stylis" "0.8.3"
-    "@emotion/utils" "0.11.1"
-    "@emotion/weak-memoize" "0.2.2"
+    esutils "^2.0.2"
+    lodash "^4.17.11"
+    to-fast-properties "^2.0.0"
 
-"@emotion/hash@0.7.1":
-  version "0.7.1"
-  resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.7.1.tgz#9833722341379fb7d67f06a4b00ab3c37913da53"
-  integrity sha512-OYpa/Sg+2GDX+jibUfpZVn1YqSVRpYmTLF2eyAfrFTIJSbwyIrc+YscayoykvaOME/wV4BV0Sa0yqdMrgse6mA==
+"@clusterws/cws@^0.14.0":
+  version "0.14.0"
+  resolved "https://registry.yarnpkg.com/@clusterws/cws/-/cws-0.14.0.tgz#242824b6884454001340222a836db6f6c5e62bfb"
+  integrity sha512-knZj3KZNHIAGsX7TUc/0Q5gcx2bKMMcTPsAOZomLKdK5a4o/umKFlttWRH84Yr1nVlQy+UMO23qfDR8gRZ/4cw==
 
-"@emotion/memoize@0.7.1":
+"@cnakazawa/watch@^1.0.3":
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef"
+  integrity sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA==
+  dependencies:
+    exec-sh "^0.3.2"
+    minimist "^1.2.0"
+
+"@emotion/babel-utils@^0.6.4":
+  version "0.6.10"
+  resolved "https://registry.yarnpkg.com/@emotion/babel-utils/-/babel-utils-0.6.10.tgz#83dbf3dfa933fae9fc566e54fbb45f14674c6ccc"
+  integrity sha512-/fnkM/LTEp3jKe++T0KyTszVGWNKPNOUJfjNKLO17BzQ6QPxgbg3whayom1Qr2oLFH3V92tDymU+dT5q676uow==
+  dependencies:
+    "@emotion/hash" "^0.6.6"
+    "@emotion/memoize" "^0.6.6"
+    "@emotion/serialize" "^0.9.1"
+    convert-source-map "^1.5.1"
+    find-root "^1.1.0"
+    source-map "^0.7.2"
+
+"@emotion/hash@^0.6.2", "@emotion/hash@^0.6.6":
+  version "0.6.6"
+  resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.6.6.tgz#62266c5f0eac6941fece302abad69f2ee7e25e44"
+  integrity sha512-ojhgxzUHZ7am3D2jHkMzPpsBAiB005GF5YU4ea+8DNPybMk01JJUM9V9YRlF/GE95tcOm8DxQvWA2jq19bGalQ==
+
+"@emotion/memoize@^0.6.1", "@emotion/memoize@^0.6.6":
+  version "0.6.6"
+  resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.6.6.tgz#004b98298d04c7ca3b4f50ca2035d4f60d2eed1b"
+  integrity sha512-h4t4jFjtm1YV7UirAFuSuFGyLa+NNxjdkq6DpFLANNQY5rHueFZHVY+8Cu1HYVP6DrheB0kv4m5xPjo7eKT7yQ==
+
+"@emotion/serialize@^0.9.1":
+  version "0.9.1"
+  resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-0.9.1.tgz#a494982a6920730dba6303eb018220a2b629c145"
+  integrity sha512-zTuAFtyPvCctHBEL8KZ5lJuwBanGSutFEncqLn/m9T1a6a93smBStK+bZzcNPgj4QS8Rkw9VTwJGhRIUVO8zsQ==
+  dependencies:
+    "@emotion/hash" "^0.6.6"
+    "@emotion/memoize" "^0.6.6"
+    "@emotion/unitless" "^0.6.7"
+    "@emotion/utils" "^0.8.2"
+
+"@emotion/stylis@^0.7.0":
   version "0.7.1"
-  resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.1.tgz#e93c13942592cf5ef01aa8297444dc192beee52f"
-  integrity sha512-Qv4LTqO11jepd5Qmlp3M1YEjBumoTHcHFdgPTQ+sFlIL5myi/7xu/POwP7IRu6odBdmLXdtIs1D6TuW6kbwbbg==
-
-"@emotion/serialize@^0.11.3":
-  version "0.11.3"
-  resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-0.11.3.tgz#c4af2d96e3ddb9a749b7b567daa7556bcae45af2"
-  integrity sha512-6Q+XH/7kMdHwtylwZvdkOVMydaGZ989axQ56NF7urTR7eiDMLGun//pFUy31ha6QR4C6JB+KJVhZ3AEAJm9Z1g==
-  dependencies:
-    "@emotion/hash" "0.7.1"
-    "@emotion/memoize" "0.7.1"
-    "@emotion/unitless" "0.7.3"
-    "@emotion/utils" "0.11.1"
-    csstype "^2.5.7"
-
-"@emotion/sheet@0.9.2":
-  version "0.9.2"
-  resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-0.9.2.tgz#74e5c6b5e489a1ba30ab246ab5eedd96916487c4"
-  integrity sha512-pVBLzIbC/QCHDKJF2E82V2H/W/B004mDFQZiyo/MSR+VC4pV5JLG0TF/zgQDFvP3fZL/5RTPGEmXlYJBMUuJ+A==
-
-"@emotion/stylis@0.8.3":
-  version "0.8.3"
-  resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.3.tgz#3ca7e9bcb31b3cb4afbaeb66156d86ee85e23246"
-  integrity sha512-M3nMfJ6ndJMYloSIbYEBq6G3eqoYD41BpDOxreE8j0cb4fzz/5qvmqU9Mb2hzsXcCnIlGlWhS03PCzVGvTAe0Q==
+  resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.7.1.tgz#50f63225e712d99e2b2b39c19c70fff023793ca5"
+  integrity sha512-/SLmSIkN13M//53TtNxgxo57mcJk/UJIDFRKwOiLIBEyBHEcipgR6hNMQ/59Sl4VjCJ0Z/3zeAZyvnSLPG/1HQ==
 
-"@emotion/unitless@0.7.3":
-  version "0.7.3"
-  resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.3.tgz#6310a047f12d21a1036fb031317219892440416f"
-  integrity sha512-4zAPlpDEh2VwXswwr/t8xGNDGg8RQiPxtxZ3qQEXyQsBV39ptTdESCjuBvGze1nLMVrxmTIKmnO/nAV8Tqjjzg==
+"@emotion/unitless@^0.6.2", "@emotion/unitless@^0.6.7":
+  version "0.6.7"
+  resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.6.7.tgz#53e9f1892f725b194d5e6a1684a7b394df592397"
+  integrity sha512-Arj1hncvEVqQ2p7Ega08uHLr1JuRYBuO5cIvcA+WWEQ5+VmkOE3ZXzl04NbQxeQpWX78G7u6MqxKuNX3wvYZxg==
 
-"@emotion/utils@0.11.1":
-  version "0.11.1"
-  resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-0.11.1.tgz#8529b7412a6eb4b48bdf6e720cc1b8e6e1e17628"
-  integrity sha512-8M3VN0hetwhsJ8dH8VkVy7xo5/1VoBsDOk/T4SJOeXwTO1c4uIqVNx2qyecLFnnUWD5vvUqHQ1gASSeUN6zcTg==
+"@emotion/utils@^0.8.2":
+  version "0.8.2"
+  resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-0.8.2.tgz#576ff7fb1230185b619a75d258cbc98f0867a8dc"
+  integrity sha512-rLu3wcBWH4P5q1CGoSSH/i9hrXs7SlbRLkoq9IGuoPYNGQvDJ3pt/wmOM+XgYjIDRMVIdkUWt0RsfzF50JfnCw==
 
-"@emotion/weak-memoize@0.2.2":
-  version "0.2.2"
-  resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.2.tgz#63985d3d8b02530e0869962f4da09142ee8e200e"
-  integrity sha512-n/VQ4mbfr81aqkx/XmVicOLjviMuy02eenSdJY33SVA7S2J42EU0P1H0mOogfYedb3wXA0d/LVtBrgTSm04WEA==
+"@jest/console@^24.7.1":
+  version "24.7.1"
+  resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.7.1.tgz#32a9e42535a97aedfe037e725bd67e954b459545"
+  integrity sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==
+  dependencies:
+    "@jest/source-map" "^24.3.0"
+    chalk "^2.0.1"
+    slash "^2.0.0"
+
+"@jest/core@^24.8.0":
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.8.0.tgz#fbbdcd42a41d0d39cddbc9f520c8bab0c33eed5b"
+  integrity sha512-R9rhAJwCBQzaRnrRgAdVfnglUuATXdwTRsYqs6NMdVcAl5euG8LtWDe+fVkN27YfKVBW61IojVsXKaOmSnqd/A==
+  dependencies:
+    "@jest/console" "^24.7.1"
+    "@jest/reporters" "^24.8.0"
+    "@jest/test-result" "^24.8.0"
+    "@jest/transform" "^24.8.0"
+    "@jest/types" "^24.8.0"
+    ansi-escapes "^3.0.0"
+    chalk "^2.0.1"
+    exit "^0.1.2"
+    graceful-fs "^4.1.15"
+    jest-changed-files "^24.8.0"
+    jest-config "^24.8.0"
+    jest-haste-map "^24.8.0"
+    jest-message-util "^24.8.0"
+    jest-regex-util "^24.3.0"
+    jest-resolve-dependencies "^24.8.0"
+    jest-runner "^24.8.0"
+    jest-runtime "^24.8.0"
+    jest-snapshot "^24.8.0"
+    jest-util "^24.8.0"
+    jest-validate "^24.8.0"
+    jest-watcher "^24.8.0"
+    micromatch "^3.1.10"
+    p-each-series "^1.0.0"
+    pirates "^4.0.1"
+    realpath-native "^1.1.0"
+    rimraf "^2.5.4"
+    strip-ansi "^5.0.0"
 
-"@gfx/zopfli@^1.0.10":
-  version "1.0.10"
-  resolved "https://registry.yarnpkg.com/@gfx/zopfli/-/zopfli-1.0.10.tgz#8cccfcbd670f676cb240812bcf8380c9a66da367"
-  integrity sha512-PAR3ICucog1HV+hDVF+VYNfnvB/JmE4C8YqxhMMEuxyycFthrv6hIEeCoNsRVF3J+SEtNLWRPTOXgcvQkZIM5A==
+"@jest/environment@^24.8.0":
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.8.0.tgz#0342261383c776bdd652168f68065ef144af0eac"
+  integrity sha512-vlGt2HLg7qM+vtBrSkjDxk9K0YtRBi7HfRFaDxoRtyi+DyVChzhF20duvpdAnKVBV6W5tym8jm0U9EfXbDk1tw==
+  dependencies:
+    "@jest/fake-timers" "^24.8.0"
+    "@jest/transform" "^24.8.0"
+    "@jest/types" "^24.8.0"
+    jest-mock "^24.8.0"
+
+"@jest/fake-timers@^24.8.0":
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.8.0.tgz#2e5b80a4f78f284bcb4bd5714b8e10dd36a8d3d1"
+  integrity sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==
+  dependencies:
+    "@jest/types" "^24.8.0"
+    jest-message-util "^24.8.0"
+    jest-mock "^24.8.0"
+
+"@jest/reporters@^24.8.0":
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.8.0.tgz#075169cd029bddec54b8f2c0fc489fd0b9e05729"
+  integrity sha512-eZ9TyUYpyIIXfYCrw0UHUWUvE35vx5I92HGMgS93Pv7du+GHIzl+/vh8Qj9MCWFK/4TqyttVBPakWMOfZRIfxw==
+  dependencies:
+    "@jest/environment" "^24.8.0"
+    "@jest/test-result" "^24.8.0"
+    "@jest/transform" "^24.8.0"
+    "@jest/types" "^24.8.0"
+    chalk "^2.0.1"
+    exit "^0.1.2"
+    glob "^7.1.2"
+    istanbul-lib-coverage "^2.0.2"
+    istanbul-lib-instrument "^3.0.1"
+    istanbul-lib-report "^2.0.4"
+    istanbul-lib-source-maps "^3.0.1"
+    istanbul-reports "^2.1.1"
+    jest-haste-map "^24.8.0"
+    jest-resolve "^24.8.0"
+    jest-runtime "^24.8.0"
+    jest-util "^24.8.0"
+    jest-worker "^24.6.0"
+    node-notifier "^5.2.1"
+    slash "^2.0.0"
+    source-map "^0.6.0"
+    string-length "^2.0.0"
+
+"@jest/source-map@^24.3.0":
+  version "24.3.0"
+  resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.3.0.tgz#563be3aa4d224caf65ff77edc95cd1ca4da67f28"
+  integrity sha512-zALZt1t2ou8le/crCeeiRYzvdnTzaIlpOWaet45lNSqNJUnXbppUUFR4ZUAlzgDmKee4Q5P/tKXypI1RiHwgag==
+  dependencies:
+    callsites "^3.0.0"
+    graceful-fs "^4.1.15"
+    source-map "^0.6.0"
+
+"@jest/test-result@^24.8.0":
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.8.0.tgz#7675d0aaf9d2484caa65e048d9b467d160f8e9d3"
+  integrity sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==
+  dependencies:
+    "@jest/console" "^24.7.1"
+    "@jest/types" "^24.8.0"
+    "@types/istanbul-lib-coverage" "^2.0.0"
+
+"@jest/test-sequencer@^24.8.0":
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-24.8.0.tgz#2f993bcf6ef5eb4e65e8233a95a3320248cf994b"
+  integrity sha512-OzL/2yHyPdCHXEzhoBuq37CE99nkme15eHkAzXRVqthreWZamEMA0WoetwstsQBCXABhczpK03JNbc4L01vvLg==
+  dependencies:
+    "@jest/test-result" "^24.8.0"
+    jest-haste-map "^24.8.0"
+    jest-runner "^24.8.0"
+    jest-runtime "^24.8.0"
+
+"@jest/transform@^24.8.0":
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.8.0.tgz#628fb99dce4f9d254c6fd9341e3eea262e06fef5"
+  integrity sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA==
+  dependencies:
+    "@babel/core" "^7.1.0"
+    "@jest/types" "^24.8.0"
+    babel-plugin-istanbul "^5.1.0"
+    chalk "^2.0.1"
+    convert-source-map "^1.4.0"
+    fast-json-stable-stringify "^2.0.0"
+    graceful-fs "^4.1.15"
+    jest-haste-map "^24.8.0"
+    jest-regex-util "^24.3.0"
+    jest-util "^24.8.0"
+    micromatch "^3.1.10"
+    realpath-native "^1.1.0"
+    slash "^2.0.0"
+    source-map "^0.6.1"
+    write-file-atomic "2.4.1"
+
+"@jest/types@^24.8.0":
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.8.0.tgz#f31e25948c58f0abd8c845ae26fcea1491dea7ad"
+  integrity sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==
+  dependencies:
+    "@types/istanbul-lib-coverage" "^2.0.0"
+    "@types/istanbul-reports" "^1.1.1"
+    "@types/yargs" "^12.0.9"
+
+"@types/babel__core@^7.1.0":
+  version "7.1.0"
+  resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.0.tgz#710f2487dda4dcfd010ca6abb2b4dc7394365c51"
+  integrity sha512-wJTeJRt7BToFx3USrCDs2BhEi4ijBInTQjOIukj6a/5tEkwpFMVZ+1ppgmE+Q/FQyc5P/VWUbx7I9NELrKruHA==
+  dependencies:
+    "@babel/parser" "^7.1.0"
+    "@babel/types" "^7.0.0"
+    "@types/babel__generator" "*"
+    "@types/babel__template" "*"
+    "@types/babel__traverse" "*"
+
+"@types/babel__generator@*":
+  version "7.0.2"
+  resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.0.2.tgz#d2112a6b21fad600d7674274293c85dce0cb47fc"
+  integrity sha512-NHcOfab3Zw4q5sEE2COkpfXjoE7o+PmqD9DQW4koUT3roNxwziUdXGnRndMat/LJNUtePwn1TlP4do3uoe3KZQ==
+  dependencies:
+    "@babel/types" "^7.0.0"
+
+"@types/babel__template@*":
+  version "7.0.2"
+  resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.0.2.tgz#4ff63d6b52eddac1de7b975a5223ed32ecea9307"
+  integrity sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==
+  dependencies:
+    "@babel/parser" "^7.1.0"
+    "@babel/types" "^7.0.0"
+
+"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6":
+  version "7.0.6"
+  resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.6.tgz#328dd1a8fc4cfe3c8458be9477b219ea158fd7b2"
+  integrity sha512-XYVgHF2sQ0YblLRMLNPB3CkFMewzFmlDsH/TneZFHUXDlABQgh88uOxuez7ZcXxayLFrqLwtDH1t+FmlFwNZxw==
+  dependencies:
+    "@babel/types" "^7.3.0"
+
+"@types/events@*":
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
+  integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==
+
+"@types/glob@^7.1.1":
+  version "7.1.1"
+  resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575"
+  integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==
+  dependencies:
+    "@types/events" "*"
+    "@types/minimatch" "*"
+    "@types/node" "*"
+
+"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff"
+  integrity sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==
+
+"@types/istanbul-lib-report@*":
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz#e5471e7fa33c61358dd38426189c037a58433b8c"
+  integrity sha512-3BUTyMzbZa2DtDI2BkERNC6jJw2Mr2Y0oGI7mRxYNBPxppbtEK1F66u3bKwU2g+wxwWI7PAoRpJnOY1grJqzHg==
+  dependencies:
+    "@types/istanbul-lib-coverage" "*"
+
+"@types/istanbul-reports@^1.1.1":
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz#7a8cbf6a406f36c8add871625b278eaf0b0d255a"
+  integrity sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==
   dependencies:
-    base64-js "^1.3.0"
+    "@types/istanbul-lib-coverage" "*"
+    "@types/istanbul-lib-report" "*"
+
+"@types/minimatch@*":
+  version "3.0.3"
+  resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
+  integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
 
 "@types/node@*":
   version "10.12.18"
@@ -795,158 +1160,171 @@
   dependencies:
     csstype "^2.2.0"
 
-"@webassemblyjs/ast@1.7.11":
-  version "1.7.11"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.7.11.tgz#b988582cafbb2b095e8b556526f30c90d057cace"
-  integrity sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==
-  dependencies:
-    "@webassemblyjs/helper-module-context" "1.7.11"
-    "@webassemblyjs/helper-wasm-bytecode" "1.7.11"
-    "@webassemblyjs/wast-parser" "1.7.11"
-
-"@webassemblyjs/floating-point-hex-parser@1.7.11":
-  version "1.7.11"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz#a69f0af6502eb9a3c045555b1a6129d3d3f2e313"
-  integrity sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==
-
-"@webassemblyjs/helper-api-error@1.7.11":
-  version "1.7.11"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz#c7b6bb8105f84039511a2b39ce494f193818a32a"
-  integrity sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==
-
-"@webassemblyjs/helper-buffer@1.7.11":
-  version "1.7.11"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz#3122d48dcc6c9456ed982debe16c8f37101df39b"
-  integrity sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==
-
-"@webassemblyjs/helper-code-frame@1.7.11":
-  version "1.7.11"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz#cf8f106e746662a0da29bdef635fcd3d1248364b"
-  integrity sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==
-  dependencies:
-    "@webassemblyjs/wast-printer" "1.7.11"
-
-"@webassemblyjs/helper-fsm@1.7.11":
-  version "1.7.11"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz#df38882a624080d03f7503f93e3f17ac5ac01181"
-  integrity sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==
-
-"@webassemblyjs/helper-module-context@1.7.11":
-  version "1.7.11"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz#d874d722e51e62ac202476935d649c802fa0e209"
-  integrity sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==
-
-"@webassemblyjs/helper-wasm-bytecode@1.7.11":
-  version "1.7.11"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz#dd9a1e817f1c2eb105b4cf1013093cb9f3c9cb06"
-  integrity sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==
-
-"@webassemblyjs/helper-wasm-section@1.7.11":
-  version "1.7.11"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz#9c9ac41ecf9fbcfffc96f6d2675e2de33811e68a"
-  integrity sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==
-  dependencies:
-    "@webassemblyjs/ast" "1.7.11"
-    "@webassemblyjs/helper-buffer" "1.7.11"
-    "@webassemblyjs/helper-wasm-bytecode" "1.7.11"
-    "@webassemblyjs/wasm-gen" "1.7.11"
-
-"@webassemblyjs/ieee754@1.7.11":
-  version "1.7.11"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz#c95839eb63757a31880aaec7b6512d4191ac640b"
-  integrity sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==
+"@types/stack-utils@^1.0.1":
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
+  integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==
+
+"@types/yargs@^12.0.2", "@types/yargs@^12.0.9":
+  version "12.0.9"
+  resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-12.0.9.tgz#693e76a52f61a2f1e7fb48c0eef167b95ea4ffd0"
+  integrity sha512-sCZy4SxP9rN2w30Hlmg5dtdRwgYQfYRiLo9usw8X9cxlf+H4FqM1xX7+sNH7NNKVdbXMJWqva7iyy+fxh/V7fA==
+
+"@webassemblyjs/ast@1.8.5":
+  version "1.8.5"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359"
+  integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==
+  dependencies:
+    "@webassemblyjs/helper-module-context" "1.8.5"
+    "@webassemblyjs/helper-wasm-bytecode" "1.8.5"
+    "@webassemblyjs/wast-parser" "1.8.5"
+
+"@webassemblyjs/floating-point-hex-parser@1.8.5":
+  version "1.8.5"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721"
+  integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==
+
+"@webassemblyjs/helper-api-error@1.8.5":
+  version "1.8.5"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7"
+  integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==
+
+"@webassemblyjs/helper-buffer@1.8.5":
+  version "1.8.5"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204"
+  integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==
+
+"@webassemblyjs/helper-code-frame@1.8.5":
+  version "1.8.5"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e"
+  integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==
+  dependencies:
+    "@webassemblyjs/wast-printer" "1.8.5"
+
+"@webassemblyjs/helper-fsm@1.8.5":
+  version "1.8.5"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452"
+  integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==
+
+"@webassemblyjs/helper-module-context@1.8.5":
+  version "1.8.5"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245"
+  integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==
+  dependencies:
+    "@webassemblyjs/ast" "1.8.5"
+    mamacro "^0.0.3"
+
+"@webassemblyjs/helper-wasm-bytecode@1.8.5":
+  version "1.8.5"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61"
+  integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==
+
+"@webassemblyjs/helper-wasm-section@1.8.5":
+  version "1.8.5"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf"
+  integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==
+  dependencies:
+    "@webassemblyjs/ast" "1.8.5"
+    "@webassemblyjs/helper-buffer" "1.8.5"
+    "@webassemblyjs/helper-wasm-bytecode" "1.8.5"
+    "@webassemblyjs/wasm-gen" "1.8.5"
+
+"@webassemblyjs/ieee754@1.8.5":
+  version "1.8.5"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e"
+  integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==
   dependencies:
     "@xtuc/ieee754" "^1.2.0"
 
-"@webassemblyjs/leb128@1.7.11":
-  version "1.7.11"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.7.11.tgz#d7267a1ee9c4594fd3f7e37298818ec65687db63"
-  integrity sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==
-  dependencies:
-    "@xtuc/long" "4.2.1"
-
-"@webassemblyjs/utf8@1.7.11":
-  version "1.7.11"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.7.11.tgz#06d7218ea9fdc94a6793aa92208160db3d26ee82"
-  integrity sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==
-
-"@webassemblyjs/wasm-edit@1.7.11":
-  version "1.7.11"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz#8c74ca474d4f951d01dbae9bd70814ee22a82005"
-  integrity sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==
-  dependencies:
-    "@webassemblyjs/ast" "1.7.11"
-    "@webassemblyjs/helper-buffer" "1.7.11"
-    "@webassemblyjs/helper-wasm-bytecode" "1.7.11"
-    "@webassemblyjs/helper-wasm-section" "1.7.11"
-    "@webassemblyjs/wasm-gen" "1.7.11"
-    "@webassemblyjs/wasm-opt" "1.7.11"
-    "@webassemblyjs/wasm-parser" "1.7.11"
-    "@webassemblyjs/wast-printer" "1.7.11"
-
-"@webassemblyjs/wasm-gen@1.7.11":
-  version "1.7.11"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz#9bbba942f22375686a6fb759afcd7ac9c45da1a8"
-  integrity sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==
-  dependencies:
-    "@webassemblyjs/ast" "1.7.11"
-    "@webassemblyjs/helper-wasm-bytecode" "1.7.11"
-    "@webassemblyjs/ieee754" "1.7.11"
-    "@webassemblyjs/leb128" "1.7.11"
-    "@webassemblyjs/utf8" "1.7.11"
-
-"@webassemblyjs/wasm-opt@1.7.11":
-  version "1.7.11"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz#b331e8e7cef8f8e2f007d42c3a36a0580a7d6ca7"
-  integrity sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==
-  dependencies:
-    "@webassemblyjs/ast" "1.7.11"
-    "@webassemblyjs/helper-buffer" "1.7.11"
-    "@webassemblyjs/wasm-gen" "1.7.11"
-    "@webassemblyjs/wasm-parser" "1.7.11"
-
-"@webassemblyjs/wasm-parser@1.7.11":
-  version "1.7.11"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz#6e3d20fa6a3519f6b084ef9391ad58211efb0a1a"
-  integrity sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==
-  dependencies:
-    "@webassemblyjs/ast" "1.7.11"
-    "@webassemblyjs/helper-api-error" "1.7.11"
-    "@webassemblyjs/helper-wasm-bytecode" "1.7.11"
-    "@webassemblyjs/ieee754" "1.7.11"
-    "@webassemblyjs/leb128" "1.7.11"
-    "@webassemblyjs/utf8" "1.7.11"
-
-"@webassemblyjs/wast-parser@1.7.11":
-  version "1.7.11"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz#25bd117562ca8c002720ff8116ef9072d9ca869c"
-  integrity sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==
-  dependencies:
-    "@webassemblyjs/ast" "1.7.11"
-    "@webassemblyjs/floating-point-hex-parser" "1.7.11"
-    "@webassemblyjs/helper-api-error" "1.7.11"
-    "@webassemblyjs/helper-code-frame" "1.7.11"
-    "@webassemblyjs/helper-fsm" "1.7.11"
-    "@xtuc/long" "4.2.1"
-
-"@webassemblyjs/wast-printer@1.7.11":
-  version "1.7.11"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz#c4245b6de242cb50a2cc950174fdbf65c78d7813"
-  integrity sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==
-  dependencies:
-    "@webassemblyjs/ast" "1.7.11"
-    "@webassemblyjs/wast-parser" "1.7.11"
-    "@xtuc/long" "4.2.1"
+"@webassemblyjs/leb128@1.8.5":
+  version "1.8.5"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10"
+  integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==
+  dependencies:
+    "@xtuc/long" "4.2.2"
+
+"@webassemblyjs/utf8@1.8.5":
+  version "1.8.5"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc"
+  integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==
+
+"@webassemblyjs/wasm-edit@1.8.5":
+  version "1.8.5"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a"
+  integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==
+  dependencies:
+    "@webassemblyjs/ast" "1.8.5"
+    "@webassemblyjs/helper-buffer" "1.8.5"
+    "@webassemblyjs/helper-wasm-bytecode" "1.8.5"
+    "@webassemblyjs/helper-wasm-section" "1.8.5"
+    "@webassemblyjs/wasm-gen" "1.8.5"
+    "@webassemblyjs/wasm-opt" "1.8.5"
+    "@webassemblyjs/wasm-parser" "1.8.5"
+    "@webassemblyjs/wast-printer" "1.8.5"
+
+"@webassemblyjs/wasm-gen@1.8.5":
+  version "1.8.5"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc"
+  integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==
+  dependencies:
+    "@webassemblyjs/ast" "1.8.5"
+    "@webassemblyjs/helper-wasm-bytecode" "1.8.5"
+    "@webassemblyjs/ieee754" "1.8.5"
+    "@webassemblyjs/leb128" "1.8.5"
+    "@webassemblyjs/utf8" "1.8.5"
+
+"@webassemblyjs/wasm-opt@1.8.5":
+  version "1.8.5"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264"
+  integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==
+  dependencies:
+    "@webassemblyjs/ast" "1.8.5"
+    "@webassemblyjs/helper-buffer" "1.8.5"
+    "@webassemblyjs/wasm-gen" "1.8.5"
+    "@webassemblyjs/wasm-parser" "1.8.5"
+
+"@webassemblyjs/wasm-parser@1.8.5":
+  version "1.8.5"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d"
+  integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==
+  dependencies:
+    "@webassemblyjs/ast" "1.8.5"
+    "@webassemblyjs/helper-api-error" "1.8.5"
+    "@webassemblyjs/helper-wasm-bytecode" "1.8.5"
+    "@webassemblyjs/ieee754" "1.8.5"
+    "@webassemblyjs/leb128" "1.8.5"
+    "@webassemblyjs/utf8" "1.8.5"
+
+"@webassemblyjs/wast-parser@1.8.5":
+  version "1.8.5"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c"
+  integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==
+  dependencies:
+    "@webassemblyjs/ast" "1.8.5"
+    "@webassemblyjs/floating-point-hex-parser" "1.8.5"
+    "@webassemblyjs/helper-api-error" "1.8.5"
+    "@webassemblyjs/helper-code-frame" "1.8.5"
+    "@webassemblyjs/helper-fsm" "1.8.5"
+    "@xtuc/long" "4.2.2"
+
+"@webassemblyjs/wast-printer@1.8.5":
+  version "1.8.5"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc"
+  integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==
+  dependencies:
+    "@webassemblyjs/ast" "1.8.5"
+    "@webassemblyjs/wast-parser" "1.8.5"
+    "@xtuc/long" "4.2.2"
 
 "@xtuc/ieee754@^1.2.0":
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"
   integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==
 
-"@xtuc/long@4.2.1":
-  version "4.2.1"
-  resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.1.tgz#5c85d662f76fa1d34575766c5dcd6615abcd30d8"
-  integrity sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==
+"@xtuc/long@4.2.2":
+  version "4.2.2"
+  resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
+  integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
 
 abab@^2.0.0:
   version "2.0.0"
@@ -958,20 +1336,18 @@ abbrev@1:
   resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
   integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
 
-accepts@~1.3.4, accepts@~1.3.5:
-  version "1.3.5"
-  resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2"
-  integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I=
+accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7:
+  version "1.3.7"
+  resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
+  integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==
   dependencies:
-    mime-types "~2.1.18"
-    negotiator "0.6.1"
+    mime-types "~2.1.24"
+    negotiator "0.6.2"
 
-acorn-dynamic-import@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278"
-  integrity sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==
-  dependencies:
-    acorn "^5.0.0"
+acorn-dynamic-import@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz#482210140582a36b83c3e342e1cfebcaa9240948"
+  integrity sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==
 
 acorn-globals@^4.1.0:
   version "4.3.0"
@@ -981,36 +1357,77 @@ acorn-globals@^4.1.0:
     acorn "^6.0.1"
     acorn-walk "^6.0.1"
 
+acorn-jsx@^3.0.0:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b"
+  integrity sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=
+  dependencies:
+    acorn "^3.0.4"
+
 acorn-jsx@^5.0.0:
   version "5.0.1"
   resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e"
   integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==
 
-acorn-walk@^6.0.1:
+acorn-walk@^6.0.1, acorn-walk@^6.1.1:
   version "6.1.1"
   resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.1.1.tgz#d363b66f5fac5f018ff9c3a1e7b6f8e310cc3913"
   integrity sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==
 
-acorn@^5.0.0, acorn@^5.5.3, acorn@^5.6.2, acorn@^5.7.3:
+acorn@^3.0.4:
+  version "3.3.0"
+  resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a"
+  integrity sha1-ReN/s56No/JbruP/U2niu18iAXo=
+
+acorn@^5.5.0, acorn@^5.5.3:
   version "5.7.3"
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279"
   integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==
 
-acorn@^6.0.1, acorn@^6.0.2:
-  version "6.0.4"
-  resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.4.tgz#77377e7353b72ec5104550aa2d2097a2fd40b754"
-  integrity sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg==
+acorn@^6.0.1, acorn@^6.0.2, acorn@^6.0.5, acorn@^6.0.7:
+  version "6.1.1"
+  resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f"
+  integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==
+
+airbnb-prop-types@^2.13.2:
+  version "2.13.2"
+  resolved "https://registry.yarnpkg.com/airbnb-prop-types/-/airbnb-prop-types-2.13.2.tgz#43147a5062dd2a4a5600e748a47b64004cc5f7fc"
+  integrity sha512-2FN6DlHr6JCSxPPi25EnqGaXC4OC3/B3k1lCd6MMYrZ51/Gf/1qDfaR+JElzWa+Tl7cY2aYOlsYJGFeQyVHIeQ==
+  dependencies:
+    array.prototype.find "^2.0.4"
+    function.prototype.name "^1.1.0"
+    has "^1.0.3"
+    is-regex "^1.0.4"
+    object-is "^1.0.1"
+    object.assign "^4.1.0"
+    object.entries "^1.1.0"
+    prop-types "^15.7.2"
+    prop-types-exact "^1.2.0"
+    react-is "^16.8.6"
 
 ajv-errors@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d"
   integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==
 
+ajv-keywords@^1.0.0:
+  version "1.5.1"
+  resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c"
+  integrity sha1-MU3QpLM2j609/NxU7eYXG4htrzw=
+
 ajv-keywords@^3.1.0:
   version "3.2.0"
   resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a"
   integrity sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=
 
+ajv@^4.7.0:
+  version "4.11.8"
+  resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
+  integrity sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=
+  dependencies:
+    co "^4.6.0"
+    json-stable-stringify "^1.0.1"
+
 ajv@^6.1.0, ajv@^6.5.3, ajv@^6.5.5, ajv@^6.6.1:
   version "6.6.2"
   resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.6.2.tgz#caceccf474bf3fc3ce3b147443711a24063cc30d"
@@ -1031,6 +1448,11 @@ ansi-colors@^3.0.0:
   resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813"
   integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==
 
+ansi-escapes@^1.1.0:
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
+  integrity sha1-06ioOzGapneTZisT52HHkRQiMG4=
+
 ansi-escapes@^3.0.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30"
@@ -1076,13 +1498,6 @@ anymatch@^2.0.0:
     micromatch "^3.1.4"
     normalize-path "^2.1.1"
 
-append-transform@^0.4.0:
-  version "0.4.0"
-  resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991"
-  integrity sha1-126/jKlNJ24keja61EpLdKthGZE=
-  dependencies:
-    default-require-extensions "^1.0.0"
-
 aproba@^1.0.3, aproba@^1.1.1:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
@@ -1111,19 +1526,12 @@ aria-query@^3.0.0:
     ast-types-flow "0.0.7"
     commander "^2.11.0"
 
-arr-diff@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf"
-  integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=
-  dependencies:
-    arr-flatten "^1.0.1"
-
 arr-diff@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
   integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=
 
-arr-flatten@^1.0.1, arr-flatten@^1.1.0:
+arr-flatten@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1"
   integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==
@@ -1138,6 +1546,11 @@ array-equal@^1.0.0:
   resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93"
   integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=
 
+array-filter@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83"
+  integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=
+
 array-flatten@1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
@@ -1168,16 +1581,19 @@ array-uniq@^1.0.1:
   resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
   integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=
 
-array-unique@^0.2.1:
-  version "0.2.1"
-  resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
-  integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=
-
 array-unique@^0.3.2:
   version "0.3.2"
   resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
   integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=
 
+array.prototype.find@^2.0.4:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.1.0.tgz#630f2eaf70a39e608ac3573e45cf8ccd0ede9ad7"
+  integrity sha512-Wn41+K1yuO5p7wRZDl7890c3xvv5UBrfVXTVIe28rSQb6LS0fZMDrQB6PAcxQFRFy6vJTLDc3A2+3CjQdzVKRg==
+  dependencies:
+    define-properties "^1.1.3"
+    es-abstract "^1.13.0"
+
 array.prototype.flat@^1.2.1:
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.1.tgz#812db8f02cad24d3fab65dd67eabe3b8903494a4"
@@ -1240,10 +1656,10 @@ astral-regex@^1.0.0:
   resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9"
   integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==
 
-async-each@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d"
-  integrity sha1-GdOGodntxufByF04iu28xW0zYC0=
+async-each@^1.0.1:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf"
+  integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==
 
 async-limiter@~1.0.0:
   version "1.0.0"
@@ -1255,7 +1671,7 @@ async@^1.5.2:
   resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
   integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=
 
-async@^2.1.4, async@^2.5.0:
+async@^2.5.0:
   version "2.6.1"
   resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610"
   integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==
@@ -1272,16 +1688,17 @@ atob@^2.1.1:
   resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
   integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
 
-autoprefixer@^9.4.3:
-  version "9.4.3"
-  resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.4.3.tgz#c97384a8fd80477b78049163a91bbc725d9c41d9"
-  integrity sha512-/XSnzDepRkAU//xLcXA/lUWxpsBuw0WiriAHOqnxkuCtzLhaz+fL4it4gp20BQ8n5SyLzK/FOc7A0+u/rti2FQ==
+autoprefixer@^9.6.0:
+  version "9.6.0"
+  resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.6.0.tgz#0111c6bde2ad20c6f17995a33fad7cf6854b4c87"
+  integrity sha512-kuip9YilBqhirhHEGHaBTZKXL//xxGnzvsD0FtBQa6z+A69qZD6s/BAX9VzDF1i9VKDquTJDQaPLSEhOnL6FvQ==
   dependencies:
-    browserslist "^4.3.6"
-    caniuse-lite "^1.0.30000921"
+    browserslist "^4.6.1"
+    caniuse-lite "^1.0.30000971"
+    chalk "^2.4.2"
     normalize-range "^0.1.2"
     num2fraction "^1.2.2"
-    postcss "^7.0.6"
+    postcss "^7.0.16"
     postcss-value-parser "^3.3.1"
 
 aws-sign2@~0.7.0:
@@ -1294,60 +1711,21 @@ aws4@^1.8.0:
   resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
   integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
 
-axios@^0.18.0:
-  version "0.18.0"
-  resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.0.tgz#32d53e4851efdc0a11993b6cd000789d70c05102"
-  integrity sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=
+axios@^0.19.0:
+  version "0.19.0"
+  resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8"
+  integrity sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==
   dependencies:
-    follow-redirects "^1.3.0"
-    is-buffer "^1.1.5"
+    follow-redirects "1.5.10"
+    is-buffer "^2.0.2"
 
-axobject-query@^2.0.1:
+axobject-query@^2.0.2:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.0.2.tgz#ea187abe5b9002b377f925d8bf7d1c561adf38f9"
   integrity sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==
   dependencies:
     ast-types-flow "0.0.7"
 
-babel-code-frame@^6.26.0:
-  version "6.26.0"
-  resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
-  integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=
-  dependencies:
-    chalk "^1.1.3"
-    esutils "^2.0.2"
-    js-tokens "^3.0.2"
-
-babel-core@^6.0.0, babel-core@^6.26.0:
-  version "6.26.3"
-  resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207"
-  integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==
-  dependencies:
-    babel-code-frame "^6.26.0"
-    babel-generator "^6.26.0"
-    babel-helpers "^6.24.1"
-    babel-messages "^6.23.0"
-    babel-register "^6.26.0"
-    babel-runtime "^6.26.0"
-    babel-template "^6.26.0"
-    babel-traverse "^6.26.0"
-    babel-types "^6.26.0"
-    babylon "^6.18.0"
-    convert-source-map "^1.5.1"
-    debug "^2.6.9"
-    json5 "^0.5.1"
-    lodash "^4.17.4"
-    minimatch "^3.0.4"
-    path-is-absolute "^1.0.1"
-    private "^0.1.8"
-    slash "^1.0.0"
-    source-map "^0.5.7"
-
-babel-core@^7.0.0-bridge.0:
-  version "7.0.0-bridge.0"
-  resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece"
-  integrity sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==
-
 babel-eslint@^10.0.1:
   version "10.0.1"
   resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.1.tgz#919681dc099614cd7d31d45c8908695092a1faed"
@@ -1360,67 +1738,62 @@ babel-eslint@^10.0.1:
     eslint-scope "3.7.1"
     eslint-visitor-keys "^1.0.0"
 
-babel-generator@^6.18.0, babel-generator@^6.26.0:
-  version "6.26.1"
-  resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90"
-  integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==
-  dependencies:
-    babel-messages "^6.23.0"
-    babel-runtime "^6.26.0"
-    babel-types "^6.26.0"
-    detect-indent "^4.0.0"
-    jsesc "^1.3.0"
-    lodash "^4.17.4"
-    source-map "^0.5.7"
-    trim-right "^1.0.1"
-
-babel-helpers@^6.24.1:
-  version "6.24.1"
-  resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2"
-  integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=
+babel-jest@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.8.0.tgz#5c15ff2b28e20b0f45df43fe6b7f2aae93dba589"
+  integrity sha512-+5/kaZt4I9efoXzPlZASyK/lN9qdRKmmUav9smVc0ruPQD7IsfucQ87gpOE8mn2jbDuS6M/YOW6n3v9ZoIfgnw==
   dependencies:
-    babel-runtime "^6.22.0"
-    babel-template "^6.24.1"
+    "@jest/transform" "^24.8.0"
+    "@jest/types" "^24.8.0"
+    "@types/babel__core" "^7.1.0"
+    babel-plugin-istanbul "^5.1.0"
+    babel-preset-jest "^24.6.0"
+    chalk "^2.4.2"
+    slash "^2.0.0"
 
-babel-jest@^23.6.0:
-  version "23.6.0"
-  resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-23.6.0.tgz#a644232366557a2240a0c083da6b25786185a2f1"
-  integrity sha512-lqKGG6LYXYu+DQh/slrQ8nxXQkEkhugdXsU6St7GmhVS7Ilc/22ArwqXNJrf0QaOBjZB0360qZMwXqDYQHXaew==
+babel-loader@^8.0.5:
+  version "8.0.5"
+  resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.5.tgz#225322d7509c2157655840bba52e46b6c2f2fe33"
+  integrity sha512-NTnHnVRd2JnRqPC0vW+iOQWU5pchDbYXsG2E6DMXEpMfUcQKclF9gmf3G3ZMhzG7IG9ji4coL0cm+FxeWxDpnw==
   dependencies:
-    babel-plugin-istanbul "^4.1.6"
-    babel-preset-jest "^23.2.0"
-
-babel-loader@^8.0.4:
-  version "8.0.4"
-  resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.4.tgz#7bbf20cbe4560629e2e41534147692d3fecbdce6"
-  integrity sha512-fhBhNkUToJcW9nV46v8w87AJOwAJDz84c1CL57n3Stj73FANM/b9TbCUK4YhdOwEyZ+OxhYpdeZDNzSI29Firw==
-  dependencies:
-    find-cache-dir "^1.0.0"
+    find-cache-dir "^2.0.0"
     loader-utils "^1.0.2"
     mkdirp "^0.5.1"
     util.promisify "^1.0.0"
 
-babel-messages@^6.23.0:
-  version "6.23.0"
-  resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e"
-  integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=
+babel-plugin-emotion@^9.2.11:
+  version "9.2.11"
+  resolved "https://registry.yarnpkg.com/babel-plugin-emotion/-/babel-plugin-emotion-9.2.11.tgz#319c005a9ee1d15bb447f59fe504c35fd5807728"
+  integrity sha512-dgCImifnOPPSeXod2znAmgc64NhaaOjGEHROR/M+lmStb3841yK1sgaDYAYMnlvWNz8GnpwIPN0VmNpbWYZ+VQ==
   dependencies:
-    babel-runtime "^6.22.0"
+    "@babel/helper-module-imports" "^7.0.0"
+    "@emotion/babel-utils" "^0.6.4"
+    "@emotion/hash" "^0.6.2"
+    "@emotion/memoize" "^0.6.1"
+    "@emotion/stylis" "^0.7.0"
+    babel-plugin-macros "^2.0.0"
+    babel-plugin-syntax-jsx "^6.18.0"
+    convert-source-map "^1.5.0"
+    find-root "^1.1.0"
+    mkdirp "^0.5.1"
+    source-map "^0.5.7"
+    touch "^2.0.1"
 
-babel-plugin-istanbul@^4.1.6:
-  version "4.1.6"
-  resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz#36c59b2192efce81c5b378321b74175add1c9a45"
-  integrity sha512-PWP9FQ1AhZhS01T/4qLSKoHGY/xvkZdVBGlKM/HuxxS3+sC66HhTNR7+MpbO/so/cz/wY94MeSWJuP1hXIPfwQ==
+babel-plugin-istanbul@^5.1.0:
+  version "5.1.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.1.tgz#7981590f1956d75d67630ba46f0c22493588c893"
+  integrity sha512-RNNVv2lsHAXJQsEJ5jonQwrJVWK8AcZpG1oxhnjCUaAjL7xahYLANhPUZbzEQHjKy1NMYUwn+0NPKQc8iSY4xQ==
   dependencies:
-    babel-plugin-syntax-object-rest-spread "^6.13.0"
-    find-up "^2.1.0"
-    istanbul-lib-instrument "^1.10.1"
-    test-exclude "^4.2.1"
+    find-up "^3.0.0"
+    istanbul-lib-instrument "^3.0.0"
+    test-exclude "^5.0.0"
 
-babel-plugin-jest-hoist@^23.2.0:
-  version "23.2.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-23.2.0.tgz#e61fae05a1ca8801aadee57a6d66b8cefaf44167"
-  integrity sha1-5h+uBaHKiAGq3uV6bWa4zvr0QWc=
+babel-plugin-jest-hoist@^24.6.0:
+  version "24.6.0"
+  resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.6.0.tgz#f7f7f7ad150ee96d7a5e8e2c5da8319579e78019"
+  integrity sha512-3pKNH6hMt9SbOv0F3WVmy5CWQ4uogS3k0GY5XLyQHJ9EGpAT9XWkFd2ZiXXtkwFHdAHa5j7w7kfxSP5lAIwu7w==
+  dependencies:
+    "@types/babel__traverse" "^7.0.6"
 
 babel-plugin-lodash@^3.3.4:
   version "3.3.4"
@@ -1433,6 +1806,15 @@ babel-plugin-lodash@^3.3.4:
     lodash "^4.17.10"
     require-package-name "^2.0.1"
 
+babel-plugin-macros@^2.0.0:
+  version "2.5.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.5.1.tgz#4a119ac2c2e19b458c259b9accd7ee34fd57ec6f"
+  integrity sha512-xN3KhAxPzsJ6OQTktCanNpIFnnMsCV+t8OloKxIL72D6+SUZYFn9qfklPgef5HyyDtzYZqqb+fs1S12+gQY82Q==
+  dependencies:
+    "@babel/runtime" "^7.4.2"
+    cosmiconfig "^5.2.0"
+    resolve "^1.10.0"
+
 babel-plugin-macros@^2.2.2:
   version "2.4.3"
   resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.4.3.tgz#870345aa538d85f04b4614fea5922b55c45dd551"
@@ -1449,47 +1831,33 @@ babel-plugin-preval@^3.0.1:
     babel-plugin-macros "^2.2.2"
     require-from-string "^2.0.2"
 
-babel-plugin-react-intl@^3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-react-intl/-/babel-plugin-react-intl-3.0.1.tgz#4abc7fff04a7bbbb7034aec0a675713f2e52181c"
-  integrity sha512-FqnEO+Tq7kJVUPKsSG3s5jaHi3pAC4RUR11IrscvjsfkOApLP2DtzNo6dtQ+tX+OzEzJx7cUms8aCw5BFyW5xg==
+babel-plugin-react-intl@^3.1.3:
+  version "3.1.3"
+  resolved "https://registry.yarnpkg.com/babel-plugin-react-intl/-/babel-plugin-react-intl-3.1.3.tgz#2a28cd43cbba1ed092c7e3376bf8f02b0f72acb8"
+  integrity sha512-Fq2u6HqYt+pggUXe8DSqZaRA2W9LfOet1dQv1tD+KYcRjL9JW/DXNEn3GPjSw3bCHJiSuGyWPYO7MdbYRVsGDw==
   dependencies:
-    "@babel/runtime" "^7.0.0"
-    intl-messageformat-parser "^1.2.0"
-    mkdirp "^0.5.1"
+    fs-extra "^8.0.1"
+    intl-messageformat-parser "^1.6.5"
 
-babel-plugin-syntax-object-rest-spread@^6.13.0:
-  version "6.13.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5"
-  integrity sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=
+babel-plugin-syntax-jsx@^6.18.0:
+  version "6.18.0"
+  resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"
+  integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=
 
-babel-plugin-transform-react-remove-prop-types@^0.4.21:
-  version "0.4.21"
-  resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.21.tgz#0087938f4348cb751b3e5055a6b38f3c61b5231b"
-  integrity sha512-+gQBtcnEhYFbMPFGr8YL7SHD4BpHifFDGEc+ES0+1iDwC9psist2+eumcLoHjBMumL7N/HI/G64XR5aQC8Nr5Q==
+babel-plugin-transform-react-remove-prop-types@^0.4.24:
+  version "0.4.24"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz#f2edaf9b4c6a5fbe5c1d678bfb531078c1555f3a"
+  integrity sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==
 
-babel-preset-jest@^23.2.0:
-  version "23.2.0"
-  resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-23.2.0.tgz#8ec7a03a138f001a1a8fb1e8113652bf1a55da46"
-  integrity sha1-jsegOhOPABoaj7HoETZSvxpV2kY=
+babel-preset-jest@^24.6.0:
+  version "24.6.0"
+  resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.6.0.tgz#66f06136eefce87797539c0d63f1769cc3915984"
+  integrity sha512-pdZqLEdmy1ZK5kyRUfvBb2IfTPb2BUvIJczlPspS8fWmBQslNNDBqVfh7BW5leOVJMDZKzjD8XEyABTk6gQ5yw==
   dependencies:
-    babel-plugin-jest-hoist "^23.2.0"
-    babel-plugin-syntax-object-rest-spread "^6.13.0"
+    "@babel/plugin-syntax-object-rest-spread" "^7.0.0"
+    babel-plugin-jest-hoist "^24.6.0"
 
-babel-register@^6.26.0:
-  version "6.26.0"
-  resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071"
-  integrity sha1-btAhFz4vy0htestFxgCahW9kcHE=
-  dependencies:
-    babel-core "^6.26.0"
-    babel-runtime "^6.26.0"
-    core-js "^2.5.0"
-    home-or-tmp "^2.0.0"
-    lodash "^4.17.4"
-    mkdirp "^0.5.1"
-    source-map-support "^0.4.15"
-
-babel-runtime@^6.22.0, babel-runtime@^6.26.0:
+babel-runtime@^6.26.0:
   version "6.26.0"
   resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
   integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4=
@@ -1497,47 +1865,6 @@ babel-runtime@^6.22.0, babel-runtime@^6.26.0:
     core-js "^2.4.0"
     regenerator-runtime "^0.11.0"
 
-babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0:
-  version "6.26.0"
-  resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02"
-  integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=
-  dependencies:
-    babel-runtime "^6.26.0"
-    babel-traverse "^6.26.0"
-    babel-types "^6.26.0"
-    babylon "^6.18.0"
-    lodash "^4.17.4"
-
-babel-traverse@^6.0.0, babel-traverse@^6.18.0, babel-traverse@^6.26.0:
-  version "6.26.0"
-  resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee"
-  integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=
-  dependencies:
-    babel-code-frame "^6.26.0"
-    babel-messages "^6.23.0"
-    babel-runtime "^6.26.0"
-    babel-types "^6.26.0"
-    babylon "^6.18.0"
-    debug "^2.6.8"
-    globals "^9.18.0"
-    invariant "^2.2.2"
-    lodash "^4.17.4"
-
-babel-types@^6.0.0, babel-types@^6.18.0, babel-types@^6.26.0:
-  version "6.26.0"
-  resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497"
-  integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=
-  dependencies:
-    babel-runtime "^6.26.0"
-    esutils "^2.0.2"
-    lodash "^4.17.4"
-    to-fast-properties "^1.0.3"
-
-babylon@^6.18.0:
-  version "6.18.0"
-  resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3"
-  integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==
-
 backoff@^2.4.1:
   version "2.5.0"
   resolved "https://registry.yarnpkg.com/backoff/-/backoff-2.5.0.tgz#f616eda9d3e4b66b8ca7fca79f695722c5f8e26f"
@@ -1550,7 +1877,7 @@ balanced-match@^1.0.0:
   resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
   integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
 
-base64-js@^1.0.2, base64-js@^1.3.0:
+base64-js@^1.0.2:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3"
   integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==
@@ -1610,26 +1937,31 @@ bluebird@^3.5.1, bluebird@^3.5.3:
   resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7"
   integrity sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==
 
+blurhash@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/blurhash/-/blurhash-1.0.0.tgz#9087bc5cc4d482f1305059d7410df4133adcab2e"
+  integrity sha512-x6fpZnd6AWde4U9m7xhUB44qIvGV4W6OdTAXGabYm4oZUOOGh5K1HAEoGAQn3iG4gbbPn9RSGce3VfNgGsX/Vw==
+
 bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0:
   version "4.11.8"
   resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
   integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==
 
-body-parser@1.18.3:
-  version "1.18.3"
-  resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4"
-  integrity sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=
+body-parser@1.19.0:
+  version "1.19.0"
+  resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
+  integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==
   dependencies:
-    bytes "3.0.0"
+    bytes "3.1.0"
     content-type "~1.0.4"
     debug "2.6.9"
     depd "~1.1.2"
-    http-errors "~1.6.3"
-    iconv-lite "0.4.23"
+    http-errors "1.7.2"
+    iconv-lite "0.4.24"
     on-finished "~2.3.0"
-    qs "6.5.2"
-    raw-body "2.3.3"
-    type-is "~1.6.16"
+    qs "6.7.0"
+    raw-body "2.4.0"
+    type-is "~1.6.17"
 
 bonjour@^3.5.0:
   version "3.5.0"
@@ -1656,16 +1988,7 @@ brace-expansion@^1.1.7:
     balanced-match "^1.0.0"
     concat-map "0.0.1"
 
-braces@^1.8.2:
-  version "1.8.5"
-  resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7"
-  integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=
-  dependencies:
-    expand-range "^1.8.1"
-    preserve "^0.2.0"
-    repeat-element "^1.1.2"
-
-braces@^2.3.0, braces@^2.3.1:
+braces@^2.3.1, braces@^2.3.2:
   version "2.3.2"
   resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729"
   integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==
@@ -1764,14 +2087,14 @@ browserify-zlib@^0.2.0:
   dependencies:
     pako "~1.0.5"
 
-browserslist@^4.0.0, browserslist@^4.3.4, browserslist@^4.3.6:
-  version "4.3.7"
-  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.3.7.tgz#f1de479a6466ea47a0a26dcc725e7504817e624a"
-  integrity sha512-pWQv51Ynb0MNk9JGMCZ8VkM785/4MQNXiFYtPqI7EEP0TJO+/d/NqRVn1uiAN0DNbnlUSpL2sh16Kspasv3pUQ==
+browserslist@^4.0.0, browserslist@^4.6.0, browserslist@^4.6.1:
+  version "4.6.2"
+  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.2.tgz#574c665950915c2ac73a4594b8537a9eba26203f"
+  integrity sha512-2neU/V0giQy9h3XMPwLhEY3+Ao0uHSwHvU8Q1Ea6AgLVL1sXbX3dzPrJ8NWe5Hi4PoTkCYXOtVR9rfRLI0J/8Q==
   dependencies:
-    caniuse-lite "^1.0.30000925"
-    electron-to-chromium "^1.3.96"
-    node-releases "^1.1.3"
+    caniuse-lite "^1.0.30000974"
+    electron-to-chromium "^1.3.150"
+    node-releases "^1.1.23"
 
 bser@^2.0.0:
   version "2.0.0"
@@ -1824,7 +2147,12 @@ bytes@3.0.0:
   resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
   integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=
 
-cacache@^11.0.2, cacache@^11.2.0:
+bytes@3.1.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6"
+  integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==
+
+cacache@^11.2.0, cacache@^11.3.2:
   version "11.3.2"
   resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.2.tgz#2d81e308e3d258ca38125b676b98b2ac9ce69bfa"
   integrity sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==
@@ -1890,16 +2218,21 @@ callsites@^2.0.0:
   resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50"
   integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=
 
-camelcase@^4.1.0:
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
-  integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=
+callsites@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.0.0.tgz#fb7eb569b72ad7a45812f93fd9430a3e410b3dd3"
+  integrity sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw==
 
 camelcase@^5.0.0:
   version "5.0.0"
   resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42"
   integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==
 
+camelcase@^5.2.0:
+  version "5.2.0"
+  resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.2.0.tgz#e7522abda5ed94cc0489e1b8466610e88404cf45"
+  integrity sha512-IXFsBS2pC+X0j0N/GE7Dm7j3bsEBp+oTpb7F50dwEVX7rf3IgwO9XatnegTsDtniKCUtEJH4fSU6Asw7uoVLfQ==
+
 caniuse-api@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0"
@@ -1910,10 +2243,10 @@ caniuse-api@^3.0.0:
     lodash.memoize "^4.1.2"
     lodash.uniq "^4.5.0"
 
-caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000921, caniuse-lite@^1.0.30000925:
-  version "1.0.30000926"
-  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000926.tgz#4361a99d818ca6e521dbe89a732de62a194a789c"
-  integrity sha512-diMkEvxfFw09SkbErCLmw/1Fx1ZZe9xfWm4aeA2PUffB48x1tfZeMsK5j4BW7zN7Y4PdqmPVVdG2eYjE5IRTag==
+caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000971, caniuse-lite@^1.0.30000974:
+  version "1.0.30000974"
+  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000974.tgz#b7afe14ee004e97ce6dc73e3f878290a12928ad8"
+  integrity sha512-xc3rkNS/Zc3CmpMKuczWEdY2sZgx09BkAxfvkxlAEBTqcMHeL8QnPqhKse+5sRTi3nrw2pJwToD2WvKn1Uhvww==
 
 capture-exit@^1.2.0:
   version "1.2.0"
@@ -1927,7 +2260,7 @@ caseless@~0.12.0:
   resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
   integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
 
-chalk@^1.1.3:
+chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
   integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=
@@ -1938,10 +2271,10 @@ chalk@^1.1.3:
     strip-ansi "^3.0.0"
     supports-color "^2.0.0"
 
-chalk@^2.0, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.2, chalk@^2.4.1:
-  version "2.4.1"
-  resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
-  integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==
+chalk@^2.0, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4.2:
+  version "2.4.2"
+  resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
+  integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
   dependencies:
     ansi-styles "^3.2.1"
     escape-string-regexp "^1.0.5"
@@ -1969,25 +2302,24 @@ cheerio@^1.0.0-rc.2:
     lodash "^4.15.0"
     parse5 "^3.0.1"
 
-chokidar@^2.0.0, chokidar@^2.0.2:
-  version "2.0.4"
-  resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26"
-  integrity sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==
+chokidar@^2.0.0, chokidar@^2.0.2, chokidar@^2.1.6:
+  version "2.1.6"
+  resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.6.tgz#b6cad653a929e244ce8a834244164d241fa954c5"
+  integrity sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==
   dependencies:
     anymatch "^2.0.0"
-    async-each "^1.0.0"
-    braces "^2.3.0"
+    async-each "^1.0.1"
+    braces "^2.3.2"
     glob-parent "^3.1.0"
-    inherits "^2.0.1"
+    inherits "^2.0.3"
     is-binary-path "^1.0.0"
     is-glob "^4.0.0"
-    lodash.debounce "^4.0.8"
-    normalize-path "^2.1.1"
+    normalize-path "^3.0.0"
     path-is-absolute "^1.0.0"
-    readdirp "^2.0.0"
-    upath "^1.0.5"
+    readdirp "^2.2.1"
+    upath "^1.1.1"
   optionalDependencies:
-    fsevents "^1.2.2"
+    fsevents "^1.2.7"
 
 chownr@^1.1.1:
   version "1.1.1"
@@ -2001,10 +2333,10 @@ chrome-trace-event@^1.0.0:
   dependencies:
     tslib "^1.9.0"
 
-ci-info@^1.5.0:
-  version "1.6.0"
-  resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497"
-  integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==
+ci-info@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
+  integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==
 
 cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
   version "1.0.4"
@@ -2034,6 +2366,13 @@ classnames@^2.2.5:
   resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
   integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
 
+cli-cursor@^1.0.1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987"
+  integrity sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=
+  dependencies:
+    restore-cursor "^1.0.1"
+
 cli-cursor@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
@@ -2046,15 +2385,6 @@ cli-width@^2.0.0:
   resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
   integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=
 
-cliui@^3.2.0:
-  version "3.2.0"
-  resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d"
-  integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=
-  dependencies:
-    string-width "^1.0.1"
-    strip-ansi "^3.0.1"
-    wrap-ansi "^2.0.0"
-
 cliui@^4.0.0:
   version "4.1.0"
   resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49"
@@ -2146,10 +2476,10 @@ combined-stream@^1.0.6, combined-stream@~1.0.6:
   dependencies:
     delayed-stream "~1.0.0"
 
-commander@^2.11.0, commander@^2.18.0, commander@^2.19.0:
-  version "2.19.0"
-  resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
-  integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==
+commander@^2.11.0, commander@^2.18.0, commander@^2.19.0, commander@^2.8.1:
+  version "2.20.0"
+  resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
+  integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==
 
 commander@~2.17.1:
   version "2.17.1"
@@ -2166,12 +2496,12 @@ component-emitter@^1.2.1:
   resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6"
   integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=
 
-compressible@~2.0.14:
-  version "2.0.15"
-  resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.15.tgz#857a9ab0a7e5a07d8d837ed43fe2defff64fe212"
-  integrity sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw==
+compressible@~2.0.16:
+  version "2.0.17"
+  resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.17.tgz#6e8c108a16ad58384a977f3a482ca20bff2f38c1"
+  integrity sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==
   dependencies:
-    mime-db ">= 1.36.0 < 2"
+    mime-db ">= 1.40.0 < 2"
 
 compression-webpack-plugin@^2.0.0:
   version "2.0.0"
@@ -2185,16 +2515,16 @@ compression-webpack-plugin@^2.0.0:
     serialize-javascript "^1.4.0"
     webpack-sources "^1.0.1"
 
-compression@^1.5.2:
-  version "1.7.3"
-  resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.3.tgz#27e0e176aaf260f7f2c2813c3e440adb9f1993db"
-  integrity sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==
+compression@^1.7.4:
+  version "1.7.4"
+  resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f"
+  integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==
   dependencies:
     accepts "~1.3.5"
     bytes "3.0.0"
-    compressible "~2.0.14"
+    compressible "~2.0.16"
     debug "2.6.9"
-    on-headers "~1.0.1"
+    on-headers "~1.0.2"
     safe-buffer "5.1.2"
     vary "~1.1.2"
 
@@ -2203,7 +2533,7 @@ concat-map@0.0.1:
   resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
   integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
 
-concat-stream@^1.5.0:
+concat-stream@^1.4.6, concat-stream@^1.5.0:
   version "1.6.2"
   resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
   integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==
@@ -2213,10 +2543,10 @@ concat-stream@^1.5.0:
     readable-stream "^2.2.2"
     typedarray "^0.0.6"
 
-connect-history-api-fallback@^1.3.0:
-  version "1.5.0"
-  resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz#b06873934bc5e344fef611a196a6faae0aee015a"
-  integrity sha1-sGhzk0vF40T+9hGhlqb6rgruAVo=
+connect-history-api-fallback@^1.6.0:
+  version "1.6.0"
+  resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc"
+  integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==
 
 console-browserify@^1.1.0:
   version "1.1.0"
@@ -2240,17 +2570,19 @@ contains-path@^0.1.0:
   resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a"
   integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=
 
-content-disposition@0.5.2:
-  version "0.5.2"
-  resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4"
-  integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ=
+content-disposition@0.5.3:
+  version "0.5.3"
+  resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd"
+  integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==
+  dependencies:
+    safe-buffer "5.1.2"
 
 content-type@~1.0.4:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
   integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
 
-convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.1:
+convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.5.1:
   version "1.6.0"
   resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20"
   integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==
@@ -2262,10 +2594,10 @@ cookie-signature@1.0.6:
   resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
   integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw=
 
-cookie@0.3.1:
-  version "0.3.1"
-  resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
-  integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=
+cookie@0.4.0:
+  version "0.4.0"
+  resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba"
+  integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==
 
 copy-concurrently@^1.0.0:
   version "1.0.5"
@@ -2284,12 +2616,26 @@ copy-descriptor@^0.1.0:
   resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
   integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=
 
+core-js-compat@^3.1.1:
+  version "3.1.3"
+  resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.1.3.tgz#0cc3ba4c7f62928c2837e1cffbe8dc78b4f1ae14"
+  integrity sha512-EP018pVhgwsKHz3YoN1hTq49aRe+h017Kjz0NQz3nXV0cCRMvH3fLQl+vEPGr4r4J5sk4sU3tUC7U1aqTCeJeA==
+  dependencies:
+    browserslist "^4.6.0"
+    core-js-pure "3.1.3"
+    semver "^6.1.0"
+
+core-js-pure@3.1.3:
+  version "3.1.3"
+  resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.1.3.tgz#4c90752d5b9471f641514f3728f51c1e0783d0b5"
+  integrity sha512-k3JWTrcQBKqjkjI0bkfXS0lbpWPxYuHWfMMjC1VDmzU4Q58IwSbuXSo99YO/hUHlw/EB4AlfA2PVxOGkrIq6dA==
+
 core-js@^1.0.0:
   version "1.2.7"
   resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
   integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=
 
-core-js@^2.4.0, core-js@^2.5.0:
+core-js@^2.4.0:
   version "2.6.1"
   resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.1.tgz#87416ae817de957a3f249b3b5ca475d4aaed6042"
   integrity sha512-L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg==
@@ -2319,6 +2665,16 @@ cosmiconfig@^5.0.0, cosmiconfig@^5.0.5:
     js-yaml "^3.9.0"
     parse-json "^4.0.0"
 
+cosmiconfig@^5.2.0:
+  version "5.2.1"
+  resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a"
+  integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==
+  dependencies:
+    import-fresh "^2.0.0"
+    is-directory "^0.3.1"
+    js-yaml "^3.13.1"
+    parse-json "^4.0.0"
+
 create-ecdh@^4.0.0:
   version "4.0.3"
   resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff"
@@ -2327,15 +2683,18 @@ create-ecdh@^4.0.0:
     bn.js "^4.1.0"
     elliptic "^6.0.0"
 
-create-emotion@^10.0.4:
-  version "10.0.5"
-  resolved "https://registry.yarnpkg.com/create-emotion/-/create-emotion-10.0.5.tgz#22487f19b59a7ed10144f808289eadffebcfab06"
-  integrity sha512-MIOSeFiMtPrAULEtd2GFYGZEzeN2xnCFoiHrjvUYjxruYCJfGqUOBmh4YEN1yU+Ww5yXr+DIZibFl7FEOP57iA==
+create-emotion@^9.2.12:
+  version "9.2.12"
+  resolved "https://registry.yarnpkg.com/create-emotion/-/create-emotion-9.2.12.tgz#0fc8e7f92c4f8bb924b0fef6781f66b1d07cb26f"
+  integrity sha512-P57uOF9NL2y98Xrbl2OuiDQUZ30GVmASsv5fbsjF4Hlraip2kyAvMm+2PoYUvFFw03Fhgtxk3RqZSm2/qHL9hA==
   dependencies:
-    "@emotion/cache" "10.0.0"
-    "@emotion/serialize" "^0.11.3"
-    "@emotion/sheet" "0.9.2"
-    "@emotion/utils" "0.11.1"
+    "@emotion/hash" "^0.6.2"
+    "@emotion/memoize" "^0.6.1"
+    "@emotion/stylis" "^0.7.0"
+    "@emotion/unitless" "^0.6.2"
+    csstype "^2.5.2"
+    stylis "^3.5.0"
+    stylis-rule-sheet "^0.0.10"
 
 create-hash@^1.1.0, create-hash@^1.1.2:
   version "1.2.0"
@@ -2368,15 +2727,6 @@ cross-env@^5.1.4:
     cross-spawn "^6.0.5"
     is-windows "^1.0.0"
 
-cross-spawn@^5.0.1:
-  version "5.1.0"
-  resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
-  integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=
-  dependencies:
-    lru-cache "^4.0.1"
-    shebang-command "^1.2.0"
-    which "^1.2.9"
-
 cross-spawn@^6.0.0, cross-spawn@^6.0.5:
   version "6.0.5"
   resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
@@ -2450,18 +2800,19 @@ css-list-helpers@^1.0.1:
   dependencies:
     tcomb "^2.5.0"
 
-css-loader@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-2.1.0.tgz#42952ac22bca5d076978638e9813abce49b8f0cc"
-  integrity sha512-MoOu+CStsGrSt5K2OeZ89q3Snf+IkxRfAIt9aAKg4piioTrhtP1iEFPu+OVn3Ohz24FO6L+rw9UJxBILiSBw5Q==
-  dependencies:
-    icss-utils "^4.0.0"
-    loader-utils "^1.2.1"
-    lodash "^4.17.11"
-    postcss "^7.0.6"
+css-loader@^2.1.1:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-2.1.1.tgz#d8254f72e412bb2238bb44dd674ffbef497333ea"
+  integrity sha512-OcKJU/lt232vl1P9EEDamhoO9iKY3tIjY5GU+XDLblAykTdgs6Ux9P1hTHve8nFKy5KPpOXOsVI/hIwi3841+w==
+  dependencies:
+    camelcase "^5.2.0"
+    icss-utils "^4.1.0"
+    loader-utils "^1.2.3"
+    normalize-path "^3.0.0"
+    postcss "^7.0.14"
     postcss-modules-extract-imports "^2.0.0"
-    postcss-modules-local-by-default "^2.0.3"
-    postcss-modules-scope "^2.0.0"
+    postcss-modules-local-by-default "^2.0.6"
+    postcss-modules-scope "^2.1.0"
     postcss-modules-values "^2.0.0"
     postcss-value-parser "^3.3.0"
     schema-utils "^1.0.0"
@@ -2491,15 +2842,6 @@ css-select@~1.2.0:
     domutils "1.5.1"
     nth-check "~1.0.1"
 
-css-selector-tokenizer@^0.7.0:
-  version "0.7.1"
-  resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz#a177271a8bca5019172f4f891fc6eed9cbf68d5d"
-  integrity sha512-xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA==
-  dependencies:
-    cssesc "^0.1.0"
-    fastparse "^1.1.1"
-    regexpu-core "^1.0.0"
-
 css-system-font-keywords@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/css-system-font-keywords/-/css-system-font-keywords-1.0.0.tgz#85c6f086aba4eb32c571a3086affc434b84823ed"
@@ -2536,50 +2878,50 @@ css-what@2.1, css-what@^2.1.2:
   resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.2.tgz#c0876d9d0480927d7d4920dcd72af3595649554d"
   integrity sha512-wan8dMWQ0GUeF7DGEPVjhHemVW/vy6xUYmFzRY8RYqgA0JtXC9rJmbScBjqSu6dg9q0lwPQy6ZAmJVr3PPTvqQ==
 
-cssesc@^0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4"
-  integrity sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=
-
 cssesc@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703"
   integrity sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==
 
-cssnano-preset-default@^4.0.6:
-  version "4.0.6"
-  resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.6.tgz#92379e2a6db4a91c0ea727f5f556eeac693eab6a"
-  integrity sha512-UPboYbFaJFtDUhJ4fqctThWbbyF4q01/7UhsZbLzp35l+nUxtzh1SifoVlEfyLM3n3Z0htd8B1YlCxy9i+bQvg==
+cssesc@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
+  integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
+
+cssnano-preset-default@^4.0.7:
+  version "4.0.7"
+  resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz#51ec662ccfca0f88b396dcd9679cdb931be17f76"
+  integrity sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==
   dependencies:
     css-declaration-sorter "^4.0.1"
     cssnano-util-raw-cache "^4.0.1"
     postcss "^7.0.0"
-    postcss-calc "^7.0.0"
-    postcss-colormin "^4.0.2"
+    postcss-calc "^7.0.1"
+    postcss-colormin "^4.0.3"
     postcss-convert-values "^4.0.1"
-    postcss-discard-comments "^4.0.1"
+    postcss-discard-comments "^4.0.2"
     postcss-discard-duplicates "^4.0.2"
     postcss-discard-empty "^4.0.1"
     postcss-discard-overridden "^4.0.1"
-    postcss-merge-longhand "^4.0.10"
-    postcss-merge-rules "^4.0.2"
+    postcss-merge-longhand "^4.0.11"
+    postcss-merge-rules "^4.0.3"
     postcss-minify-font-values "^4.0.2"
-    postcss-minify-gradients "^4.0.1"
-    postcss-minify-params "^4.0.1"
-    postcss-minify-selectors "^4.0.1"
+    postcss-minify-gradients "^4.0.2"
+    postcss-minify-params "^4.0.2"
+    postcss-minify-selectors "^4.0.2"
     postcss-normalize-charset "^4.0.1"
-    postcss-normalize-display-values "^4.0.1"
-    postcss-normalize-positions "^4.0.1"
-    postcss-normalize-repeat-style "^4.0.1"
-    postcss-normalize-string "^4.0.1"
-    postcss-normalize-timing-functions "^4.0.1"
+    postcss-normalize-display-values "^4.0.2"
+    postcss-normalize-positions "^4.0.2"
+    postcss-normalize-repeat-style "^4.0.2"
+    postcss-normalize-string "^4.0.2"
+    postcss-normalize-timing-functions "^4.0.2"
     postcss-normalize-unicode "^4.0.1"
     postcss-normalize-url "^4.0.1"
-    postcss-normalize-whitespace "^4.0.1"
-    postcss-ordered-values "^4.1.1"
-    postcss-reduce-initial "^4.0.2"
-    postcss-reduce-transforms "^4.0.1"
-    postcss-svgo "^4.0.1"
+    postcss-normalize-whitespace "^4.0.2"
+    postcss-ordered-values "^4.1.2"
+    postcss-reduce-initial "^4.0.3"
+    postcss-reduce-transforms "^4.0.2"
+    postcss-svgo "^4.0.2"
     postcss-unique-selectors "^4.0.1"
 
 cssnano-util-get-arguments@^4.0.0:
@@ -2604,13 +2946,13 @@ cssnano-util-same-parent@^4.0.0:
   resolved "https://registry.yarnpkg.com/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz#574082fb2859d2db433855835d9a8456ea18bbf3"
   integrity sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==
 
-cssnano@^4.1.8:
-  version "4.1.8"
-  resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.8.tgz#8014989679d5fd42491e4499a521dbfb85c95fd1"
-  integrity sha512-5GIY0VzAHORpbKiL3rMXp4w4M1Ki+XlXgEXyuWXVd3h6hlASb+9Vo76dNP56/elLMVBBsUfusCo1q56uW0UWig==
+cssnano@^4.1.10:
+  version "4.1.10"
+  resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.10.tgz#0ac41f0b13d13d465487e111b778d42da631b8b2"
+  integrity sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==
   dependencies:
     cosmiconfig "^5.0.0"
-    cssnano-preset-default "^4.0.6"
+    cssnano-preset-default "^4.0.7"
     is-resolvable "^1.0.0"
     postcss "^7.0.0"
 
@@ -2633,11 +2975,16 @@ cssstyle@^1.0.0:
   dependencies:
     cssom "0.3.x"
 
-csstype@^2.2.0, csstype@^2.5.7:
+csstype@^2.2.0:
   version "2.6.0"
   resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.0.tgz#6cf7b2fa7fc32aab3d746802c244d4eda71371a2"
   integrity sha512-by8hi8BlLbowQq0qtkx54d9aN73R9oUW20HISpka5kmgsR9F7nnxgfsemuR2sdCKZh+CDNf5egW9UZMm4mgJRg==
 
+csstype@^2.5.2:
+  version "2.6.5"
+  resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.5.tgz#1cd1dff742ebf4d7c991470ae71e12bb6751e034"
+  integrity sha512-JsTaiksRsel5n7XwqPAfB0l3TFKdpjW/kgAELf9vrb5adGA7UCPLajKK5s3nFrcFm3Rkyp/Qkgl73ENc1UY3cA==
+
 cyclist@~0.2.2:
   version "0.2.2"
   resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640"
@@ -2676,7 +3023,7 @@ date-now@^0.1.4:
   resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
   integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=
 
-debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9:
+debug@2.6.9, debug@^2.1.1, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9:
   version "2.6.9"
   resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
   integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
@@ -2690,32 +3037,25 @@ debug@=3.1.0:
   dependencies:
     ms "2.0.0"
 
-debug@^3.1.0, debug@^3.2.5:
+debug@^3.2.5:
   version "3.2.6"
   resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
   integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
   dependencies:
     ms "^2.1.1"
 
-debug@^4.0.1, debug@^4.1.0:
+debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
   version "4.1.1"
   resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
   integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
   dependencies:
     ms "^2.1.1"
 
-decamelize@^1.1.1, decamelize@^1.2.0:
+decamelize@^1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
   integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
 
-decamelize@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-2.0.0.tgz#656d7bbc8094c4c788ea53c5840908c9c7d063c7"
-  integrity sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg==
-  dependencies:
-    xregexp "4.0.0"
-
 decode-uri-component@^0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
@@ -2741,21 +3081,14 @@ deep-is@~0.1.3:
   resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
   integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
 
-default-gateway@^2.6.0:
-  version "2.7.2"
-  resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-2.7.2.tgz#b7ef339e5e024b045467af403d50348db4642d0f"
-  integrity sha512-lAc4i9QJR0YHSDFdzeBQKfZ1SRDG3hsJNEkrpcZa8QhBfidLAilT60BDEIVUUGqosFp425KOgB3uYqcnQrWafQ==
+default-gateway@^4.2.0:
+  version "4.2.0"
+  resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b"
+  integrity sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==
   dependencies:
-    execa "^0.10.0"
+    execa "^1.0.0"
     ip-regex "^2.1.0"
 
-default-require-extensions@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8"
-  integrity sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=
-  dependencies:
-    strip-bom "^2.0.0"
-
 define-properties@^1.1.1, define-properties@^1.1.2, define-properties@^1.1.3:
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
@@ -2785,17 +3118,18 @@ define-property@^2.0.2:
     is-descriptor "^1.0.2"
     isobject "^3.0.1"
 
-del@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/del/-/del-3.0.0.tgz#53ecf699ffcbcb39637691ab13baf160819766e5"
-  integrity sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=
+del@^4.1.1:
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4"
+  integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==
   dependencies:
+    "@types/glob" "^7.1.1"
     globby "^6.1.0"
-    is-path-cwd "^1.0.0"
-    is-path-in-cwd "^1.0.0"
-    p-map "^1.1.1"
-    pify "^3.0.0"
-    rimraf "^2.2.8"
+    is-path-cwd "^2.0.0"
+    is-path-in-cwd "^2.0.0"
+    p-map "^2.0.0"
+    pify "^4.0.1"
+    rimraf "^2.6.3"
 
 delayed-stream@~1.0.0:
   version "1.0.0"
@@ -2825,14 +3159,12 @@ destroy@~1.0.4:
   resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
   integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
 
-detect-indent@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208"
-  integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg=
-  dependencies:
-    repeating "^2.0.0"
+detect-file@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7"
+  integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=
 
-detect-libc@^1.0.2, detect-libc@^1.0.3:
+detect-libc@^1.0.2:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
   integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
@@ -2852,10 +3184,10 @@ detect-passive-events@^1.0.2:
   resolved "https://registry.yarnpkg.com/detect-passive-events/-/detect-passive-events-1.0.4.tgz#6ed477e6e5bceb79079735dcd357789d37f9a91a"
   integrity sha1-btR35uW863kHlzXc01d4nTf5qRo=
 
-diff@^3.2.0:
-  version "3.5.0"
-  resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
-  integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
+diff-sequences@^24.3.0:
+  version "24.3.0"
+  resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.3.0.tgz#0f20e8a1df1abddaf4d9c226680952e64118b975"
+  integrity sha512-xLqpez+Zj9GKSnPWS0WZw1igGocZ+uua8+y+5dDNTT934N3QuY1sp2LkHzwiaYQGz60hMq0pjAshdeXm5VUOEw==
 
 diffie-hellman@^5.0.0:
   version "5.0.3"
@@ -2891,7 +3223,7 @@ dns-txt@^2.0.2:
   dependencies:
     buffer-indexof "^1.0.0"
 
-doctrine@1.5.0:
+doctrine@1.5.0, doctrine@^1.2.2:
   version "1.5.0"
   resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa"
   integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=
@@ -2973,10 +3305,10 @@ dot-prop@^4.1.1:
   dependencies:
     is-obj "^1.0.0"
 
-dotenv@^6.2.0:
-  version "6.2.0"
-  resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.2.0.tgz#941c0410535d942c8becf28d3f357dbd9d476064"
-  integrity sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==
+dotenv@^8.0.0:
+  version "8.0.0"
+  resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.0.0.tgz#ed310c165b4e8a97bb745b0a9d99c31bda566440"
+  integrity sha512-30xVGqjLjiUOArT4+M5q9sYdvuR4riM6yK9wMcas9Vbp6zZa+ocC9dp6QoftuhTPhFAiLK/0C5Ni2nou/Bk8lg==
 
 double-ended-queue@^2.1.0-0:
   version "2.1.0-0"
@@ -3016,10 +3348,10 @@ ejs@^2.3.4, ejs@^2.6.1:
   resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0"
   integrity sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==
 
-electron-to-chromium@^1.3.96:
-  version "1.3.96"
-  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.96.tgz#25770ec99b8b07706dedf3a5f43fa50cb54c4f9a"
-  integrity sha512-ZUXBUyGLeoJxp4Nt6G/GjBRLnyz8IKQGexZ2ndWaoegThgMGFO1tdDYID5gBV32/1S83osjJHyfzvanE/8HY4Q==
+electron-to-chromium@^1.3.150:
+  version "1.3.163"
+  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.163.tgz#7fc3d637f5d8fa4ca4a052cad0de7675bd98b911"
+  integrity sha512-uCEoqQeKrjlhUSUudY0XvyNVDhWR5XmnCIV0WXr2Qo9PVzEVXI75LHGtzwro9Qh8NNetRjSitrm8AfQvPGaSqA==
 
 elliptic@^6.0.0:
   version "6.4.1"
@@ -3038,16 +3370,24 @@ emoji-mart@Gargron/emoji-mart#build:
   version "2.6.2"
   resolved "https://codeload.github.com/Gargron/emoji-mart/tar.gz/ff00dc470b5b2d9f145a6d6e977a54de5df2b4c9"
 
-emoji-regex@^6.5.1:
-  version "6.5.1"
-  resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.5.1.tgz#9baea929b155565c11ea41c6626eaa65cef992c2"
-  integrity sha512-PAHp6TxrCy7MGMFidro8uikr+zlJJKJ/Q6mm2ExZ7HwkyR9lSVFfE3kt36qcwa24BQL7y0G9axycGjK1A/0uNQ==
+emoji-regex@^7.0.2:
+  version "7.0.3"
+  resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
+  integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==
 
 emojis-list@^2.0.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
   integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k=
 
+emotion@^9.1.2:
+  version "9.2.12"
+  resolved "https://registry.yarnpkg.com/emotion/-/emotion-9.2.12.tgz#53925aaa005614e65c6e43db8243c843574d1ea9"
+  integrity sha512-hcx7jppaI8VoXxIWEhxpDW7I+B4kq9RNzQLmsrF6LY8BGKqe2N+gFAQr0EfuFucFlPs2A9HM4+xNj4NeqEWIOQ==
+  dependencies:
+    babel-plugin-emotion "^9.2.11"
+    create-emotion "^9.2.12"
+
 encodeurl@~1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
@@ -3081,41 +3421,46 @@ entities@^1.1.1, entities@~1.1.1:
   resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
   integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
 
-enzyme-adapter-react-16@^1.7.1:
-  version "1.7.1"
-  resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.7.1.tgz#c37c4cb0fd75e88a063154a7a88096474914496a"
-  integrity sha512-OQXKgfHWyHN3sFu2nKj3mhgRcqIPIJX6aOzq5AHVFES4R9Dw/vCBZFMPyaG81g2AZ5DogVh39P3MMNUbqNLTcw==
+enzyme-adapter-react-16@^1.14.0:
+  version "1.14.0"
+  resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.14.0.tgz#204722b769172bcf096cb250d33e6795c1f1858f"
+  integrity sha512-7PcOF7pb4hJUvjY7oAuPGpq3BmlCig3kxXGi2kFx0YzJHppqX1K8IIV9skT1IirxXlu8W7bneKi+oQ10QRnhcA==
   dependencies:
-    enzyme-adapter-utils "^1.9.0"
-    function.prototype.name "^1.1.0"
+    enzyme-adapter-utils "^1.12.0"
+    has "^1.0.3"
     object.assign "^4.1.0"
-    object.values "^1.0.4"
-    prop-types "^15.6.2"
-    react-is "^16.6.1"
+    object.values "^1.1.0"
+    prop-types "^15.7.2"
+    react-is "^16.8.6"
     react-test-renderer "^16.0.0-0"
+    semver "^5.7.0"
 
-enzyme-adapter-utils@^1.9.0:
-  version "1.9.0"
-  resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.9.0.tgz#3997c20f3387fdcd932b155b3740829ea10aa86c"
-  integrity sha512-uMe4xw4l/Iloh2Fz+EO23XUYMEQXj5k/5ioLUXCNOUCI8Dml5XQMO9+QwUq962hBsY5qftfHHns+d990byWHvg==
+enzyme-adapter-utils@^1.12.0:
+  version "1.12.0"
+  resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.12.0.tgz#96e3730d76b872f593e54ce1c51fa3a451422d93"
+  integrity sha512-wkZvE0VxcFx/8ZsBw0iAbk3gR1d9hK447ebnSYBf95+r32ezBq+XDSAvRErkc4LZosgH8J7et7H7/7CtUuQfBA==
   dependencies:
+    airbnb-prop-types "^2.13.2"
     function.prototype.name "^1.1.0"
     object.assign "^4.1.0"
-    prop-types "^15.6.2"
+    object.fromentries "^2.0.0"
+    prop-types "^15.7.2"
     semver "^5.6.0"
 
-enzyme@^3.8.0:
-  version "3.8.0"
-  resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.8.0.tgz#646d2d5d0798cb98fdec39afcee8a53237b47ad5"
-  integrity sha512-bfsWo5nHyZm1O1vnIsbwdfhU989jk+squU9NKvB+Puwo5j6/Wg9pN5CO0YJelm98Dao3NPjkDZk+vvgwpMwYxw==
+enzyme@^3.10.0:
+  version "3.10.0"
+  resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.10.0.tgz#7218e347c4a7746e133f8e964aada4a3523452f6"
+  integrity sha512-p2yy9Y7t/PFbPoTvrWde7JIYB2ZyGC+NgTNbVEGvZ5/EyoYSr9aG/2rSbVvyNvMHEhw9/dmGUJHWtfQIEiX9pg==
   dependencies:
     array.prototype.flat "^1.2.1"
     cheerio "^1.0.0-rc.2"
     function.prototype.name "^1.1.0"
     has "^1.0.3"
+    html-element-map "^1.0.0"
     is-boolean-object "^1.0.0"
     is-callable "^1.1.4"
     is-number-object "^1.0.3"
+    is-regex "^1.0.4"
     is-string "^1.0.4"
     is-subset "^0.1.1"
     lodash.escape "^4.0.1"
@@ -3143,7 +3488,7 @@ error-ex@^1.2.0, error-ex@^1.3.1:
   dependencies:
     is-arrayish "^0.2.1"
 
-es-abstract@^1.10.0, es-abstract@^1.11.0, es-abstract@^1.12.0, es-abstract@^1.5.0, es-abstract@^1.5.1, es-abstract@^1.6.1, es-abstract@^1.7.0:
+es-abstract@^1.10.0, es-abstract@^1.11.0, es-abstract@^1.12.0, es-abstract@^1.5.0, es-abstract@^1.5.1, es-abstract@^1.7.0:
   version "1.12.0"
   resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165"
   integrity sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==
@@ -3154,7 +3499,19 @@ es-abstract@^1.10.0, es-abstract@^1.11.0, es-abstract@^1.12.0, es-abstract@^1.5.
     is-callable "^1.1.3"
     is-regex "^1.0.4"
 
-es-to-primitive@^1.1.1:
+es-abstract@^1.13.0:
+  version "1.13.0"
+  resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9"
+  integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==
+  dependencies:
+    es-to-primitive "^1.2.0"
+    function-bind "^1.1.1"
+    has "^1.0.3"
+    is-callable "^1.1.4"
+    is-regex "^1.0.4"
+    object-keys "^1.0.12"
+
+es-to-primitive@^1.1.1, es-to-primitive@^1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377"
   integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==
@@ -3163,6 +3520,15 @@ es-to-primitive@^1.1.1:
     is-date-object "^1.0.1"
     is-symbol "^1.0.2"
 
+es5-ext@^0.10.14:
+  version "0.10.50"
+  resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.50.tgz#6d0e23a0abdb27018e5ac4fd09b412bc5517a778"
+  integrity sha512-KMzZTPBkeQV/JcSQhI5/z6d9VWJ3EnQ194USTUwIYZ2ZbpN8+SGXQKt1h68EX44+qt+Fzr8DO17vnxrw7c3agw==
+  dependencies:
+    es6-iterator "~2.0.3"
+    es6-symbol "~3.1.1"
+    next-tick "^1.0.0"
+
 es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14:
   version "0.10.46"
   resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.46.tgz#efd99f67c5a7ec789baa3daa7f79870388f7f572"
@@ -3172,7 +3538,7 @@ es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14:
     es6-symbol "~3.1.1"
     next-tick "1"
 
-es6-iterator@~2.0.3:
+es6-iterator@^2.0.1, es6-iterator@~2.0.1, es6-iterator@~2.0.3:
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
   integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c=
@@ -3181,7 +3547,30 @@ es6-iterator@~2.0.3:
     es5-ext "^0.10.35"
     es6-symbol "^3.1.1"
 
-es6-symbol@^3.1.1, es6-symbol@~3.1.1:
+es6-map@^0.1.3:
+  version "0.1.5"
+  resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0"
+  integrity sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=
+  dependencies:
+    d "1"
+    es5-ext "~0.10.14"
+    es6-iterator "~2.0.1"
+    es6-set "~0.1.5"
+    es6-symbol "~3.1.1"
+    event-emitter "~0.3.5"
+
+es6-set@~0.1.5:
+  version "0.1.5"
+  resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1"
+  integrity sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=
+  dependencies:
+    d "1"
+    es5-ext "~0.10.14"
+    es6-iterator "~2.0.1"
+    es6-symbol "3.1.1"
+    event-emitter "~0.3.5"
+
+es6-symbol@3.1.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1:
   version "3.1.1"
   resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77"
   integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=
@@ -3189,6 +3578,16 @@ es6-symbol@^3.1.1, es6-symbol@~3.1.1:
     d "1"
     es5-ext "~0.10.14"
 
+es6-weak-map@^2.0.1:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f"
+  integrity sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=
+  dependencies:
+    d "1"
+    es5-ext "^0.10.14"
+    es6-iterator "^2.0.1"
+    es6-symbol "^3.1.1"
+
 escape-html@^1.0.3, escape-html@~1.0.3:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
@@ -3211,7 +3610,17 @@ escodegen@^1.9.1:
   optionalDependencies:
     source-map "~0.6.1"
 
-eslint-import-resolver-node@^0.3.1:
+escope@^3.6.0:
+  version "3.6.0"
+  resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3"
+  integrity sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=
+  dependencies:
+    es6-map "^0.1.3"
+    es6-weak-map "^2.0.1"
+    esrecurse "^4.1.0"
+    estraverse "^4.1.1"
+
+eslint-import-resolver-node@^0.3.2:
   version "0.3.2"
   resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a"
   integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==
@@ -3219,48 +3628,49 @@ eslint-import-resolver-node@^0.3.1:
     debug "^2.6.9"
     resolve "^1.5.0"
 
-eslint-module-utils@^2.2.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz#b270362cd88b1a48ad308976ce7fa54e98411746"
-  integrity sha1-snA2LNiLGkitMIl2zn+lTphBF0Y=
+eslint-module-utils@^2.4.0:
+  version "2.4.0"
+  resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.4.0.tgz#8b93499e9b00eab80ccb6614e69f03678e84e09a"
+  integrity sha512-14tltLm38Eu3zS+mt0KvILC3q8jyIAH518MlG+HO0p+yK885Lb1UHTY/UgR91eOyGdmxAPb+OLoW4znqIT6Ndw==
   dependencies:
     debug "^2.6.8"
-    pkg-dir "^1.0.0"
+    pkg-dir "^2.0.0"
 
-eslint-plugin-import@~2.14.0:
-  version "2.14.0"
-  resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz#6b17626d2e3e6ad52cfce8807a845d15e22111a8"
-  integrity sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g==
+eslint-plugin-import@~2.17.3:
+  version "2.17.3"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.17.3.tgz#00548b4434c18faebaba04b24ae6198f280de189"
+  integrity sha512-qeVf/UwXFJbeyLbxuY8RgqDyEKCkqV7YC+E5S5uOjAp4tOc8zj01JP3ucoBM8JcEqd1qRasJSg6LLlisirfy0Q==
   dependencies:
+    array-includes "^3.0.3"
     contains-path "^0.1.0"
-    debug "^2.6.8"
+    debug "^2.6.9"
     doctrine "1.5.0"
-    eslint-import-resolver-node "^0.3.1"
-    eslint-module-utils "^2.2.0"
-    has "^1.0.1"
-    lodash "^4.17.4"
-    minimatch "^3.0.3"
+    eslint-import-resolver-node "^0.3.2"
+    eslint-module-utils "^2.4.0"
+    has "^1.0.3"
+    lodash "^4.17.11"
+    minimatch "^3.0.4"
     read-pkg-up "^2.0.0"
-    resolve "^1.6.0"
+    resolve "^1.11.0"
 
-eslint-plugin-jsx-a11y@~6.1.2:
-  version "6.1.2"
-  resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.1.2.tgz#69bca4890b36dcf0fe16dd2129d2d88b98f33f88"
-  integrity sha512-7gSSmwb3A+fQwtw0arguwMdOdzmKUgnUcbSNlo+GjKLAQFuC2EZxWqG9XHRI8VscBJD5a8raz3RuxQNFW+XJbw==
+eslint-plugin-jsx-a11y@~6.2.1:
+  version "6.2.1"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.1.tgz#4ebba9f339b600ff415ae4166e3e2e008831cf0c"
+  integrity sha512-cjN2ObWrRz0TTw7vEcGQrx+YltMvZoOEx4hWU8eEERDnBIU00OTq7Vr+jA7DFKxiwLNv4tTh5Pq2GUNEa8b6+w==
   dependencies:
     aria-query "^3.0.0"
     array-includes "^3.0.3"
     ast-types-flow "^0.0.7"
-    axobject-query "^2.0.1"
+    axobject-query "^2.0.2"
     damerau-levenshtein "^1.0.4"
-    emoji-regex "^6.5.1"
+    emoji-regex "^7.0.2"
     has "^1.0.3"
     jsx-ast-utils "^2.0.1"
 
-eslint-plugin-promise@~4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.0.1.tgz#2d074b653f35a23d1ba89d8e976a985117d1c6a2"
-  integrity sha512-Si16O0+Hqz1gDHsys6RtFRrW7cCTB6P7p3OJmKp3Y3dxpQE2qwOA7d3xnV+0mBmrPoi0RBnxlCKvqu70te6wjg==
+eslint-plugin-promise@~4.1.1:
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.1.1.tgz#1e08cb68b5b2cd8839f8d5864c796f56d82746db"
+  integrity sha512-faAHw7uzlNPy7b45J1guyjazw28M+7gJokKUjC5JSFoYfUEyy6Gw/i7YQvmv2Yk00sUjWcmzXQLpU1Ki/C2IZQ==
 
 eslint-plugin-react@~7.12.1:
   version "7.12.1"
@@ -3301,6 +3711,45 @@ eslint-visitor-keys@^1.0.0:
   resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d"
   integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==
 
+eslint@^2.7.0:
+  version "2.13.1"
+  resolved "https://registry.yarnpkg.com/eslint/-/eslint-2.13.1.tgz#e4cc8fa0f009fb829aaae23855a29360be1f6c11"
+  integrity sha1-5MyPoPAJ+4KaquI4VaKTYL4fbBE=
+  dependencies:
+    chalk "^1.1.3"
+    concat-stream "^1.4.6"
+    debug "^2.1.1"
+    doctrine "^1.2.2"
+    es6-map "^0.1.3"
+    escope "^3.6.0"
+    espree "^3.1.6"
+    estraverse "^4.2.0"
+    esutils "^2.0.2"
+    file-entry-cache "^1.1.1"
+    glob "^7.0.3"
+    globals "^9.2.0"
+    ignore "^3.1.2"
+    imurmurhash "^0.1.4"
+    inquirer "^0.12.0"
+    is-my-json-valid "^2.10.0"
+    is-resolvable "^1.0.0"
+    js-yaml "^3.5.1"
+    json-stable-stringify "^1.0.0"
+    levn "^0.3.0"
+    lodash "^4.0.0"
+    mkdirp "^0.5.0"
+    optionator "^0.8.1"
+    path-is-absolute "^1.0.0"
+    path-is-inside "^1.0.1"
+    pluralize "^1.2.1"
+    progress "^1.1.8"
+    require-uncached "^1.0.2"
+    shelljs "^0.6.0"
+    strip-json-comments "~1.0.1"
+    table "^3.7.8"
+    text-table "~0.2.0"
+    user-home "^2.0.0"
+
 eslint@^5.11.1:
   version "5.11.1"
   resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.11.1.tgz#8deda83db9f354bf9d3f53f9677af7e0e13eadda"
@@ -3344,6 +3793,14 @@ eslint@^5.11.1:
     table "^5.0.2"
     text-table "^0.2.0"
 
+espree@^3.1.6:
+  version "3.5.4"
+  resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7"
+  integrity sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==
+  dependencies:
+    acorn "^5.5.0"
+    acorn-jsx "^3.0.0"
+
 espree@^5.0.0:
   version "5.0.0"
   resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.0.tgz#fc7f984b62b36a0f543b13fb9cd7b9f4a7f5b65c"
@@ -3392,6 +3849,14 @@ etag@~1.8.1:
   resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
   integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
 
+event-emitter@~0.3.5:
+  version "0.3.5"
+  resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39"
+  integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=
+  dependencies:
+    d "1"
+    es5-ext "~0.10.14"
+
 eventemitter3@^3.0.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163"
@@ -3417,38 +3882,10 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
     md5.js "^1.3.4"
     safe-buffer "^5.1.1"
 
-exec-sh@^0.2.0:
-  version "0.2.2"
-  resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36"
-  integrity sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw==
-  dependencies:
-    merge "^1.2.0"
-
-execa@^0.10.0:
-  version "0.10.0"
-  resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50"
-  integrity sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==
-  dependencies:
-    cross-spawn "^6.0.0"
-    get-stream "^3.0.0"
-    is-stream "^1.1.0"
-    npm-run-path "^2.0.0"
-    p-finally "^1.0.0"
-    signal-exit "^3.0.0"
-    strip-eof "^1.0.0"
-
-execa@^0.7.0:
-  version "0.7.0"
-  resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777"
-  integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=
-  dependencies:
-    cross-spawn "^5.0.1"
-    get-stream "^3.0.0"
-    is-stream "^1.1.0"
-    npm-run-path "^2.0.0"
-    p-finally "^1.0.0"
-    signal-exit "^3.0.0"
-    strip-eof "^1.0.0"
+exec-sh@^0.3.2:
+  version "0.3.2"
+  resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.2.tgz#6738de2eb7c8e671d0366aea0b0db8c6f7d7391b"
+  integrity sha512-9sLAvzhI5nc8TpuQUh4ahMdCrWT00wPWz7j47/emR5+2qEfoZP5zzUXvx+vdx+H6ohhnsYC31iX04QLYJK8zTg==
 
 execa@^1.0.0:
   version "1.0.0"
@@ -3468,18 +3905,16 @@ exif-js@^2.3.0:
   resolved "https://registry.yarnpkg.com/exif-js/-/exif-js-2.3.0.tgz#9d10819bf571f873813e7640241255ab9ce1a814"
   integrity sha1-nRCBm/Vx+HOBPnZAJBJVq5zhqBQ=
 
+exit-hook@^1.0.0:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
+  integrity sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=
+
 exit@^0.1.2:
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
   integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=
 
-expand-brackets@^0.1.4:
-  version "0.1.5"
-  resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b"
-  integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=
-  dependencies:
-    is-posix-bracket "^0.1.0"
-
 expand-brackets@^2.1.4:
   version "2.1.4"
   resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622"
@@ -3493,58 +3928,58 @@ expand-brackets@^2.1.4:
     snapdragon "^0.8.1"
     to-regex "^3.0.1"
 
-expand-range@^1.8.1:
-  version "1.8.2"
-  resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337"
-  integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=
+expand-tilde@^2.0.0, expand-tilde@^2.0.2:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502"
+  integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=
   dependencies:
-    fill-range "^2.1.0"
+    homedir-polyfill "^1.0.1"
 
-expect@^23.6.0:
-  version "23.6.0"
-  resolved "https://registry.yarnpkg.com/expect/-/expect-23.6.0.tgz#1e0c8d3ba9a581c87bd71fb9bc8862d443425f98"
-  integrity sha512-dgSoOHgmtn/aDGRVFWclQyPDKl2CQRq0hmIEoUAuQs/2rn2NcvCWcSCovm6BLeuB/7EZuLGu2QfnR+qRt5OM4w==
+expect@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/expect/-/expect-24.8.0.tgz#471f8ec256b7b6129ca2524b2a62f030df38718d"
+  integrity sha512-/zYvP8iMDrzaaxHVa724eJBCKqSHmO0FA7EDkBiRHxg6OipmMn1fN+C8T9L9K8yr7UONkOifu6+LLH+z76CnaA==
   dependencies:
+    "@jest/types" "^24.8.0"
     ansi-styles "^3.2.0"
-    jest-diff "^23.6.0"
-    jest-get-type "^22.1.0"
-    jest-matcher-utils "^23.6.0"
-    jest-message-util "^23.4.0"
-    jest-regex-util "^23.3.0"
+    jest-get-type "^24.8.0"
+    jest-matcher-utils "^24.8.0"
+    jest-message-util "^24.8.0"
+    jest-regex-util "^24.3.0"
 
-express@^4.16.2, express@^4.16.3, express@^4.16.4:
-  version "4.16.4"
-  resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e"
-  integrity sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==
+express@^4.16.3, express@^4.17.1:
+  version "4.17.1"
+  resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134"
+  integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==
   dependencies:
-    accepts "~1.3.5"
+    accepts "~1.3.7"
     array-flatten "1.1.1"
-    body-parser "1.18.3"
-    content-disposition "0.5.2"
+    body-parser "1.19.0"
+    content-disposition "0.5.3"
     content-type "~1.0.4"
-    cookie "0.3.1"
+    cookie "0.4.0"
     cookie-signature "1.0.6"
     debug "2.6.9"
     depd "~1.1.2"
     encodeurl "~1.0.2"
     escape-html "~1.0.3"
     etag "~1.8.1"
-    finalhandler "1.1.1"
+    finalhandler "~1.1.2"
     fresh "0.5.2"
     merge-descriptors "1.0.1"
     methods "~1.1.2"
     on-finished "~2.3.0"
-    parseurl "~1.3.2"
+    parseurl "~1.3.3"
     path-to-regexp "0.1.7"
-    proxy-addr "~2.0.4"
-    qs "6.5.2"
-    range-parser "~1.2.0"
+    proxy-addr "~2.0.5"
+    qs "6.7.0"
+    range-parser "~1.2.1"
     safe-buffer "5.1.2"
-    send "0.16.2"
-    serve-static "1.13.2"
-    setprototypeof "1.1.0"
-    statuses "~1.4.0"
-    type-is "~1.6.16"
+    send "0.17.1"
+    serve-static "1.14.1"
+    setprototypeof "1.1.1"
+    statuses "~1.5.0"
+    type-is "~1.6.18"
     utils-merge "1.0.1"
     vary "~1.1.2"
 
@@ -3577,13 +4012,6 @@ external-editor@^3.0.0:
     iconv-lite "^0.4.24"
     tmp "^0.0.33"
 
-extglob@^0.3.1:
-  version "0.3.2"
-  resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1"
-  integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=
-  dependencies:
-    is-extglob "^1.0.0"
-
 extglob@^2.0.4:
   version "2.0.4"
   resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543"
@@ -3623,11 +4051,6 @@ fast-levenshtein@~2.0.4:
   resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
   integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
 
-fastparse@^1.1.1:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9"
-  integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==
-
 faye-websocket@^0.10.0:
   version "0.10.0"
   resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4"
@@ -3662,18 +4085,19 @@ fbjs@^0.8.4:
     setimmediate "^1.0.5"
     ua-parser-js "^0.7.18"
 
-fibers@^3.1.1:
-  version "3.1.1"
-  resolved "https://registry.yarnpkg.com/fibers/-/fibers-3.1.1.tgz#0238902ca938347bd779523692fbeefdf4f688ab"
-  integrity sha512-dl3Ukt08rHVQfY8xGD0ODwyjwrRALtaghuqGH2jByYX1wpY+nAnRQjJ6Dbqq0DnVgNVQ9yibObzbF4IlPyiwPw==
-  dependencies:
-    detect-libc "^1.0.3"
-
 figgy-pudding@^3.5.1:
   version "3.5.1"
   resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
   integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==
 
+figures@^1.3.5:
+  version "1.7.0"
+  resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
+  integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=
+  dependencies:
+    escape-string-regexp "^1.0.5"
+    object-assign "^4.1.0"
+
 figures@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
@@ -3681,6 +4105,14 @@ figures@^2.0.0:
   dependencies:
     escape-string-regexp "^1.0.5"
 
+file-entry-cache@^1.1.1:
+  version "1.3.1"
+  resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-1.3.1.tgz#44c61ea607ae4be9c1402f41f44270cbfe334ff8"
+  integrity sha1-RMYepgeuS+nBQC9B9EJwy/4zT/g=
+  dependencies:
+    flat-cache "^1.2.1"
+    object-assign "^4.0.1"
+
 file-entry-cache@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361"
@@ -3689,43 +4121,19 @@ file-entry-cache@^2.0.0:
     flat-cache "^1.2.1"
     object-assign "^4.0.1"
 
-file-loader@^3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-3.0.1.tgz#f8e0ba0b599918b51adfe45d66d1e771ad560faa"
-  integrity sha512-4sNIOXgtH/9WZq4NvlfU3Opn5ynUsqBwSLyM+I7UOwdGigTBYfVVQEwe/msZNX/j4pCJTIM14Fsw66Svo1oVrw==
+file-loader@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-4.0.0.tgz#c3570783fefb6e1bc0978a856f4bf5825b966c2a"
+  integrity sha512-roAbL6IdSGczwfXxhMi6Zq+jD4IfUpL0jWHD7fvmjdOVb7xBfdRUHe4LpBgO23VtVK5AW1OlWZo0p34Jvx3iWg==
   dependencies:
-    loader-utils "^1.0.2"
+    loader-utils "^1.2.2"
     schema-utils "^1.0.0"
 
-filename-regex@^2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26"
-  integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=
-
-fileset@^2.0.2:
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0"
-  integrity sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=
-  dependencies:
-    glob "^7.0.3"
-    minimatch "^3.0.3"
-
 filesize@^3.6.1:
   version "3.6.1"
   resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317"
   integrity sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==
 
-fill-range@^2.1.0:
-  version "2.2.4"
-  resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565"
-  integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==
-  dependencies:
-    is-number "^2.1.0"
-    isobject "^2.0.0"
-    randomatic "^3.0.0"
-    repeat-element "^1.1.2"
-    repeat-string "^1.5.2"
-
 fill-range@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7"
@@ -3736,28 +4144,19 @@ fill-range@^4.0.0:
     repeat-string "^1.6.1"
     to-regex-range "^2.1.0"
 
-finalhandler@1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105"
-  integrity sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==
+finalhandler@~1.1.2:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d"
+  integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==
   dependencies:
     debug "2.6.9"
     encodeurl "~1.0.2"
     escape-html "~1.0.3"
     on-finished "~2.3.0"
-    parseurl "~1.3.2"
-    statuses "~1.4.0"
+    parseurl "~1.3.3"
+    statuses "~1.5.0"
     unpipe "~1.0.0"
 
-find-cache-dir@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f"
-  integrity sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=
-  dependencies:
-    commondir "^1.0.1"
-    make-dir "^1.0.0"
-    pkg-dir "^2.0.0"
-
 find-cache-dir@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.0.0.tgz#4c1faed59f45184530fb9d7fa123a4d04a98472d"
@@ -3767,13 +4166,10 @@ find-cache-dir@^2.0.0:
     make-dir "^1.0.0"
     pkg-dir "^3.0.0"
 
-find-up@^1.0.0:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
-  integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=
-  dependencies:
-    path-exists "^2.0.0"
-    pinkie-promise "^2.0.0"
+find-root@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4"
+  integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==
 
 find-up@^2.0.0, find-up@^2.1.0:
   version "2.1.0"
@@ -3789,6 +4185,16 @@ find-up@^3.0.0:
   dependencies:
     locate-path "^3.0.0"
 
+findup-sync@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc"
+  integrity sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=
+  dependencies:
+    detect-file "^1.0.0"
+    is-glob "^3.1.0"
+    micromatch "^3.0.4"
+    resolve-dir "^1.0.1"
+
 flat-cache@^1.2.1:
   version "1.3.4"
   resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f"
@@ -3807,7 +4213,14 @@ flush-write-stream@^1.0.0:
     inherits "^2.0.1"
     readable-stream "^2.0.4"
 
-follow-redirects@^1.0.0, follow-redirects@^1.3.0:
+follow-redirects@1.5.10:
+  version "1.5.10"
+  resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
+  integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
+  dependencies:
+    debug "=3.1.0"
+
+follow-redirects@^1.0.0:
   version "1.6.0"
   resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.6.0.tgz#d12452c031e8c67eb6637d861bfc7a8090167933"
   integrity sha512-4Oh4eI3S9OueVV41AgJ1oLjpaJUhbJ7JDGOMhe0AFqoSejl5Q2nn3eGglAzRUKVKZE8jG5MNn66TjCJMAnpsWA==
@@ -3829,13 +4242,6 @@ for-in@^1.0.1, for-in@^1.0.2:
   resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
   integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=
 
-for-own@^0.1.4:
-  version "0.1.5"
-  resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce"
-  integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=
-  dependencies:
-    for-in "^1.0.1"
-
 for-own@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b"
@@ -3882,6 +4288,31 @@ from2@^2.1.0:
     inherits "^2.0.1"
     readable-stream "^2.0.0"
 
+front-matter@2.1.2:
+  version "2.1.2"
+  resolved "https://registry.yarnpkg.com/front-matter/-/front-matter-2.1.2.tgz#f75983b9f2f413be658c93dfd7bd8ce4078f5cdb"
+  integrity sha1-91mDufL0E75ljJPf172M5AePXNs=
+  dependencies:
+    js-yaml "^3.4.6"
+
+fs-extra@^3.0.1:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291"
+  integrity sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=
+  dependencies:
+    graceful-fs "^4.1.2"
+    jsonfile "^3.0.0"
+    universalify "^0.1.0"
+
+fs-extra@^8.0.1:
+  version "8.0.1"
+  resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.0.1.tgz#90294081f978b1f182f347a440a209154344285b"
+  integrity sha512-W+XLrggcDzlle47X/XnS7FXrXu9sDo+Ze9zpndeBxdgv88FHLm1HtmkhEwavruS6koanBjp098rUpHs65EmG7A==
+  dependencies:
+    graceful-fs "^4.1.2"
+    jsonfile "^4.0.0"
+    universalify "^0.1.0"
+
 fs-minipass@^1.2.5:
   version "1.2.5"
   resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d"
@@ -3904,15 +4335,15 @@ fs.realpath@^1.0.0:
   resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
   integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
 
-fsevents@*, fsevents@^1.2.2, fsevents@^1.2.3:
-  version "1.2.4"
-  resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426"
-  integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==
+fsevents@^1.2.7:
+  version "1.2.9"
+  resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f"
+  integrity sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==
   dependencies:
-    nan "^2.9.2"
-    node-pre-gyp "^0.10.0"
+    nan "^2.12.1"
+    node-pre-gyp "^0.12.0"
 
-function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1:
+function-bind@^1.0.2, function-bind@^1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
   integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
@@ -3945,6 +4376,20 @@ gauge@~2.7.3:
     strip-ansi "^3.0.1"
     wide-align "^1.1.0"
 
+generate-function@^2.0.0:
+  version "2.3.1"
+  resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f"
+  integrity sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==
+  dependencies:
+    is-property "^1.0.2"
+
+generate-object-property@^1.1.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0"
+  integrity sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=
+  dependencies:
+    is-property "^1.0.0"
+
 generic-pool@2.4.3:
   version "2.4.3"
   resolved "https://registry.yarnpkg.com/generic-pool/-/generic-pool-2.4.3.tgz#780c36f69dfad05a5a045dd37be7adca11a4f6ff"
@@ -3955,11 +4400,6 @@ get-caller-file@^1.0.1:
   resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a"
   integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==
 
-get-stream@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
-  integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=
-
 get-stream@^4.0.0:
   version "4.1.0"
   resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
@@ -3979,21 +4419,6 @@ getpass@^0.1.1:
   dependencies:
     assert-plus "^1.0.0"
 
-glob-base@^0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4"
-  integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=
-  dependencies:
-    glob-parent "^2.0.0"
-    is-glob "^2.0.0"
-
-glob-parent@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28"
-  integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=
-  dependencies:
-    is-glob "^2.0.0"
-
 glob-parent@^3.1.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae"
@@ -4002,7 +4427,19 @@ glob-parent@^3.1.0:
     is-glob "^3.1.0"
     path-dirname "^1.0.0"
 
-glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3:
+glob@^7.0.0, glob@~7.1.1:
+  version "7.1.4"
+  resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255"
+  integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==
+  dependencies:
+    fs.realpath "^1.0.0"
+    inflight "^1.0.4"
+    inherits "2"
+    minimatch "^3.0.4"
+    once "^1.3.0"
+    path-is-absolute "^1.0.0"
+
+glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3:
   version "7.1.3"
   resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1"
   integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==
@@ -4014,17 +4451,37 @@ glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3:
     once "^1.3.0"
     path-is-absolute "^1.0.0"
 
-global-modules-path@^2.3.0:
-  version "2.3.1"
-  resolved "https://registry.yarnpkg.com/global-modules-path/-/global-modules-path-2.3.1.tgz#e541f4c800a1a8514a990477b267ac67525b9931"
-  integrity sha512-y+shkf4InI7mPRHSo2b/k6ix6+NLDtyccYv86whhxrSGX9wjPX1VMITmrDbE1eh7zkzhiWtW2sHklJYoQ62Cxg==
+global-modules@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea"
+  integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==
+  dependencies:
+    global-prefix "^1.0.1"
+    is-windows "^1.0.1"
+    resolve-dir "^1.0.0"
+
+global-prefix@^1.0.1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe"
+  integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=
+  dependencies:
+    expand-tilde "^2.0.2"
+    homedir-polyfill "^1.0.1"
+    ini "^1.3.4"
+    is-windows "^1.0.1"
+    which "^1.2.14"
 
-globals@^11.1.0, globals@^11.7.0:
+globals@^11.1.0:
+  version "11.12.0"
+  resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
+  integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
+
+globals@^11.7.0:
   version "11.9.0"
   resolved "https://registry.yarnpkg.com/globals/-/globals-11.9.0.tgz#bde236808e987f290768a93d065060d78e6ab249"
   integrity sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg==
 
-globals@^9.18.0:
+globals@^9.2.0:
   version "9.18.0"
   resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
   integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==
@@ -4040,7 +4497,23 @@ globby@^6.1.0:
     pify "^2.0.0"
     pinkie-promise "^2.0.0"
 
-graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2:
+globule@^1.0.0:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.1.tgz#5dffb1b191f22d20797a9369b49eab4e9839696d"
+  integrity sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==
+  dependencies:
+    glob "~7.1.1"
+    lodash "~4.17.10"
+    minimatch "~3.0.2"
+
+gonzales-pe-sl@^4.2.3:
+  version "4.2.3"
+  resolved "https://registry.yarnpkg.com/gonzales-pe-sl/-/gonzales-pe-sl-4.2.3.tgz#6a868bc380645f141feeb042c6f97fcc71b59fe6"
+  integrity sha1-aoaLw4BkXxQf7rBCxvl/zHG1n+Y=
+  dependencies:
+    minimist "1.1.x"
+
+graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6:
   version "4.1.15"
   resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
   integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==
@@ -4063,10 +4536,10 @@ handle-thing@^2.0.0:
   resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.0.tgz#0e039695ff50c93fc288557d696f3c1dc6776754"
   integrity sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==
 
-handlebars@^4.0.3:
-  version "4.0.12"
-  resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5"
-  integrity sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==
+handlebars@^4.1.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.0.tgz#0d6a6f34ff1f63cecec8423aa4169827bf787c3a"
+  integrity sha512-l2jRuU1NAWK6AW5qqcTATWQJvNPEwkM7NEKSiv/gqOsoSQbVoWyqVEY5GS+XPQ88zLNmqASRpzfdm8d79hJS+w==
   dependencies:
     async "^2.5.0"
     optimist "^0.6.1"
@@ -4193,25 +4666,24 @@ hmac-drbg@^1.0.0:
     minimalistic-assert "^1.0.0"
     minimalistic-crypto-utils "^1.0.1"
 
-hoist-non-react-statics@^2.5.0, hoist-non-react-statics@^2.5.5:
+hoist-non-react-statics@^2.5.0:
   version "2.5.5"
   resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47"
   integrity sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==
 
-hoist-non-react-statics@^3.2.1:
-  version "3.2.1"
-  resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.2.1.tgz#c09c0555c84b38a7ede6912b61efddafd6e75e1e"
-  integrity sha512-TFsu3TV3YLY+zFTZDrN8L2DTFanObwmBLpWvJs1qfUuEQ5bTAdFcwfx2T/bsCXfM9QHSLvjfP+nihEl0yvozxw==
+hoist-non-react-statics@^3.3.0:
+  version "3.3.0"
+  resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz#b09178f0122184fb95acf525daaecb4d8f45958b"
+  integrity sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==
   dependencies:
-    react-is "^16.3.2"
+    react-is "^16.7.0"
 
-home-or-tmp@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8"
-  integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg=
+homedir-polyfill@^1.0.1:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8"
+  integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==
   dependencies:
-    os-homedir "^1.0.0"
-    os-tmpdir "^1.0.1"
+    parse-passwd "^1.0.0"
 
 hoopy@^0.1.2:
   version "0.1.4"
@@ -4248,6 +4720,13 @@ html-comment-regex@^1.1.0:
   resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7"
   integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==
 
+html-element-map@^1.0.0:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/html-element-map/-/html-element-map-1.0.1.tgz#3c4fcb4874ebddfe4283b51c8994e7713782b592"
+  integrity sha512-BZSfdEm6n706/lBfXKWa4frZRZcT5k1cOusw95ijZsHlI+GdgY0v95h6IzO3iIDf2ROwq570YTwqNPqHcNMozw==
+  dependencies:
+    array-filter "^1.0.0"
+
 html-encoding-sniffer@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8"
@@ -4255,7 +4734,7 @@ html-encoding-sniffer@^1.0.2:
   dependencies:
     whatwg-encoding "^1.0.1"
 
-html-entities@^1.2.0:
+html-entities@^1.2.1:
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f"
   integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=
@@ -4277,7 +4756,18 @@ http-deceiver@^1.2.7:
   resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"
   integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=
 
-http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3:
+http-errors@1.7.2, http-errors@~1.7.2:
+  version "1.7.2"
+  resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f"
+  integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==
+  dependencies:
+    depd "~1.1.2"
+    inherits "2.0.3"
+    setprototypeof "1.1.1"
+    statuses ">= 1.5.0 < 2"
+    toidentifier "1.0.0"
+
+http-errors@~1.6.2:
   version "1.6.3"
   resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d"
   integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=
@@ -4297,17 +4787,17 @@ http-parser-js@>=0.4.0:
   resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.0.tgz#d65edbede84349d0dc30320815a15d39cc3cbbd8"
   integrity sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==
 
-http-proxy-middleware@~0.18.0:
-  version "0.18.0"
-  resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz#0987e6bb5a5606e5a69168d8f967a87f15dd8aab"
-  integrity sha512-Fs25KVMPAIIcgjMZkVHJoKg9VcXcC1C8yb9JUgeDvVXY0S/zgVIhMb+qVswDIgtJe2DfckMSY2d6TuTEutlk6Q==
+http-proxy-middleware@^0.19.1:
+  version "0.19.1"
+  resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a"
+  integrity sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==
   dependencies:
-    http-proxy "^1.16.2"
+    http-proxy "^1.17.0"
     is-glob "^4.0.0"
-    lodash "^4.17.5"
-    micromatch "^3.1.9"
+    lodash "^4.17.11"
+    micromatch "^3.1.10"
 
-http-proxy@^1.16.2:
+http-proxy@^1.17.0:
   version "1.17.0"
   resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.17.0.tgz#7ad38494658f84605e2f6db4436df410f4e5be9a"
   integrity sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==
@@ -4330,13 +4820,6 @@ https-browserify@^1.0.0:
   resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
   integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
 
-iconv-lite@0.4.23:
-  version "0.4.23"
-  resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63"
-  integrity sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==
-  dependencies:
-    safer-buffer ">= 2.1.2 < 3"
-
 iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
   version "0.4.24"
   resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
@@ -4349,12 +4832,12 @@ icss-replace-symbols@^1.1.0:
   resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded"
   integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=
 
-icss-utils@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.0.0.tgz#d52cf4bcdcfa1c45c2dbefb4ffdf6b00ef608098"
-  integrity sha512-bA/xGiwWM17qjllIs9X/y0EjsB7e0AV08F3OL8UPsoNkNRibIuu8f1eKTnQ8QO1DteKKTxTUAn+IEWUToIwGOA==
+icss-utils@^4.1.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.0.tgz#339dbbffb9f8729a243b701e1c29d4cc58c52f0e"
+  integrity sha512-3DEun4VOeMvSczifM3F2cKQrDQ5Pj6WKhkOq6HD4QTnDUAq8MQRxy5TX6Sy1iY6WPBe4gQ3p5vTECjbIkglkkQ==
   dependencies:
-    postcss "^7.0.5"
+    postcss "^7.0.14"
 
 ieee754@^1.1.4:
   version "1.1.12"
@@ -4373,6 +4856,11 @@ ignore-walk@^3.0.1:
   dependencies:
     minimatch "^3.0.4"
 
+ignore@^3.1.2:
+  version "3.3.10"
+  resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043"
+  integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==
+
 ignore@^4.0.6:
   version "4.0.6"
   resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
@@ -4405,14 +4893,6 @@ import-from@^2.1.0:
   dependencies:
     resolve-from "^3.0.0"
 
-import-local@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc"
-  integrity sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ==
-  dependencies:
-    pkg-dir "^2.0.0"
-    resolve-cwd "^2.0.0"
-
 import-local@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d"
@@ -4462,11 +4942,30 @@ inherits@2.0.1:
   resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
   integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=
 
-ini@~1.3.0:
+ini@^1.3.4, ini@~1.3.0:
   version "1.3.5"
   resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
   integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
 
+inquirer@^0.12.0:
+  version "0.12.0"
+  resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e"
+  integrity sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=
+  dependencies:
+    ansi-escapes "^1.1.0"
+    ansi-regex "^2.0.0"
+    chalk "^1.0.0"
+    cli-cursor "^1.0.1"
+    cli-width "^2.0.0"
+    figures "^1.3.5"
+    lodash "^4.3.0"
+    readline2 "^1.0.1"
+    run-async "^0.1.0"
+    rx-lite "^3.1.2"
+    string-width "^1.0.1"
+    strip-ansi "^3.0.0"
+    through "^2.3.6"
+
 inquirer@^6.1.0:
   version "6.2.1"
   resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.1.tgz#9943fc4882161bdb0b0c9276769c75b32dbfcd52"
@@ -4486,34 +4985,39 @@ inquirer@^6.1.0:
     strip-ansi "^5.0.0"
     through "^2.3.6"
 
-internal-ip@^3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-3.0.1.tgz#df5c99876e1d2eb2ea2d74f520e3f669a00ece27"
-  integrity sha512-NXXgESC2nNVtU+pqmC9e6R8B1GpKxzsAQhffvh5AL79qKnodd+L7tnEQmTiUAVngqLalPbSqRA7XGIEL5nCd0Q==
+internal-ip@^4.3.0:
+  version "4.3.0"
+  resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907"
+  integrity sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==
   dependencies:
-    default-gateway "^2.6.0"
-    ipaddr.js "^1.5.2"
+    default-gateway "^4.2.0"
+    ipaddr.js "^1.9.0"
 
 interpret@^1.1.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296"
   integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==
 
-intersection-observer@^0.5.1:
-  version "0.5.1"
-  resolved "https://registry.yarnpkg.com/intersection-observer/-/intersection-observer-0.5.1.tgz#e340fc56ce74290fe2b2394d1ce88c4353ac6dfa"
-  integrity sha512-Zd7Plneq82kiXFixs7bX62YnuZ0BMRci9br7io88LwDyF3V43cQMI+G5IiTlTNTt+LsDUppl19J/M2Fp9UkH6g==
+intersection-observer@^0.7.0:
+  version "0.7.0"
+  resolved "https://registry.yarnpkg.com/intersection-observer/-/intersection-observer-0.7.0.tgz#ee16bee978db53516ead2f0a8154b09b400bbdc9"
+  integrity sha512-Id0Fij0HsB/vKWGeBe9PxeY45ttRiBmhFyyt/geBdDHBYNctMRTE3dC1U3ujzz3lap+hVXlEcVaB56kZP/eEUg==
 
 intl-format-cache@^2.0.5:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/intl-format-cache/-/intl-format-cache-2.1.0.tgz#04a369fecbfad6da6005bae1f14333332dcf9316"
   integrity sha1-BKNp/sv61tpgBbrh8UMzMy3PkxY=
 
-intl-messageformat-parser@1.4.0, intl-messageformat-parser@^1.2.0:
+intl-messageformat-parser@1.4.0:
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-1.4.0.tgz#b43d45a97468cadbe44331d74bb1e8dea44fc075"
   integrity sha1-tD1FqXRoytvkQzHXS7Ho3qRPwHU=
 
+intl-messageformat-parser@^1.6.5:
+  version "1.6.5"
+  resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-1.6.5.tgz#40f5fc19855f203389a3fc926cc3c88d7a573496"
+  integrity sha512-hngOkdq6FZxT6iEpEqOzGO/8rshM/v+sShGBl6yv8SQmU6lCc4vtfBHNqpSC0Dxuq4tedMkYFQGnKy5b1Tx5GA==
+
 intl-messageformat@^2.0.0, intl-messageformat@^2.1.0, intl-messageformat@^2.2.0:
   version "2.2.0"
   resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-2.2.0.tgz#345bcd46de630b7683330c2e52177ff5eab484fc"
@@ -4521,10 +5025,10 @@ intl-messageformat@^2.0.0, intl-messageformat@^2.1.0, intl-messageformat@^2.2.0:
   dependencies:
     intl-messageformat-parser "1.4.0"
 
-intl-relativeformat@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/intl-relativeformat/-/intl-relativeformat-2.1.0.tgz#010f1105802251f40ac47d0e3e1a201348a255df"
-  integrity sha1-AQ8RBYAiUfQKxH0OPhogE0iiVd8=
+intl-relativeformat@^2.1.0, intl-relativeformat@^2.2.0:
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/intl-relativeformat/-/intl-relativeformat-2.2.0.tgz#6aca95d019ec8d30b6c5653b6629f9983ea5b6c5"
+  integrity sha512-4bV/7kSKaPEmu6ArxXf9xjv1ny74Zkwuey8Pm01NH4zggPP7JHwg2STk8Y3JdspCKRDriwIyLRfEXnj2ZLr4Bw==
   dependencies:
     intl-messageformat "^2.0.0"
 
@@ -4540,11 +5044,6 @@ invariant@^2.1.1, invariant@^2.2.1, invariant@^2.2.2, invariant@^2.2.4:
   dependencies:
     loose-envify "^1.0.0"
 
-invert-kv@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6"
-  integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY=
-
 invert-kv@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02"
@@ -4560,15 +5059,10 @@ ip@^1.1.0, ip@^1.1.5:
   resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
   integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
 
-ipaddr.js@1.8.0:
-  version "1.8.0"
-  resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e"
-  integrity sha1-6qM9bd16zo9/b+DJygRA5wZzix4=
-
-ipaddr.js@^1.5.2:
-  version "1.8.1"
-  resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.1.tgz#fa4b79fa47fd3def5e3b159825161c0a519c9427"
-  integrity sha1-+kt5+kf9Pe9eOxWYJRYcClGclCc=
+ipaddr.js@1.9.0, ipaddr.js@^1.9.0:
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.0.tgz#37df74e430a0e47550fe54a2defe30d8acd95f65"
+  integrity sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==
 
 is-absolute-url@^2.0.0:
   version "2.1.0"
@@ -4616,6 +5110,11 @@ is-buffer@^1.1.5:
   resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
   integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
 
+is-buffer@^2.0.2:
+  version "2.0.3"
+  resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725"
+  integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==
+
 is-builtin-module@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe"
@@ -4628,12 +5127,12 @@ is-callable@^1.1.3, is-callable@^1.1.4:
   resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
   integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==
 
-is-ci@^1.0.10:
-  version "1.2.1"
-  resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c"
-  integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==
+is-ci@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c"
+  integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==
   dependencies:
-    ci-info "^1.5.0"
+    ci-info "^2.0.0"
 
 is-color-stop@^1.0.0:
   version "1.1.0"
@@ -4689,18 +5188,6 @@ is-directory@^0.3.1:
   resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1"
   integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=
 
-is-dotfile@^1.0.0:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1"
-  integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=
-
-is-equal-shallow@^0.1.3:
-  version "0.1.3"
-  resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534"
-  integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=
-  dependencies:
-    is-primitive "^2.0.0"
-
 is-extendable@^0.1.0, is-extendable@^0.1.1:
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
@@ -4713,23 +5200,11 @@ is-extendable@^1.0.1:
   dependencies:
     is-plain-object "^2.0.4"
 
-is-extglob@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0"
-  integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=
-
 is-extglob@^2.1.0, is-extglob@^2.1.1:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
   integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
 
-is-finite@^1.0.0:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa"
-  integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=
-  dependencies:
-    number-is-nan "^1.0.0"
-
 is-fullwidth-code-point@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
@@ -4742,17 +5217,10 @@ is-fullwidth-code-point@^2.0.0:
   resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
   integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
 
-is-generator-fn@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-1.0.0.tgz#969d49e1bb3329f6bb7f09089be26578b2ddd46a"
-  integrity sha1-lp1J4bszKfa7fwkIm+JleLLd1Go=
-
-is-glob@^2.0.0, is-glob@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863"
-  integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=
-  dependencies:
-    is-extglob "^1.0.0"
+is-generator-fn@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.0.0.tgz#038c31b774709641bda678b1f06a4e3227c10b3e"
+  integrity sha512-elzyIdM7iKoFHzcrndIqjYomImhxrFRnGP3galODoII4TB9gI7mZ+FnlLQmmjf27SxHS2gKEeyhX5/+YRS6H9g==
 
 is-glob@^3.1.0:
   version "3.1.0"
@@ -4768,6 +5236,22 @@ is-glob@^4.0.0:
   dependencies:
     is-extglob "^2.1.1"
 
+is-my-ip-valid@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz#7b351b8e8edd4d3995d4d066680e664d94696824"
+  integrity sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==
+
+is-my-json-valid@^2.10.0:
+  version "2.20.0"
+  resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.20.0.tgz#1345a6fca3e8daefc10d0fa77067f54cedafd59a"
+  integrity sha512-XTHBZSIIxNsIsZXg7XB5l8z/OBFosl1Wao4tXLpeC7eKU4Vm/kdop2azkPqULwnfGQjmeDIyey9g7afMMtdWAA==
+  dependencies:
+    generate-function "^2.0.0"
+    generate-object-property "^1.1.0"
+    is-my-ip-valid "^1.0.0"
+    jsonpointer "^4.0.0"
+    xtend "^4.0.0"
+
 is-nan@^1.2.1:
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.2.1.tgz#9faf65b6fb6db24b7f5c0628475ea71f988401e2"
@@ -4780,13 +5264,6 @@ is-number-object@^1.0.3:
   resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.3.tgz#f265ab89a9f445034ef6aff15a8f00b00f551799"
   integrity sha1-8mWrian0RQNO9q/xWo8AsA9VF5k=
 
-is-number@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f"
-  integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=
-  dependencies:
-    kind-of "^3.0.2"
-
 is-number@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195"
@@ -4794,34 +5271,29 @@ is-number@^3.0.0:
   dependencies:
     kind-of "^3.0.2"
 
-is-number@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff"
-  integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==
-
 is-obj@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
   integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8=
 
-is-path-cwd@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d"
-  integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=
+is-path-cwd@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.1.0.tgz#2e0c7e463ff5b7a0eb60852d851a6809347a124c"
+  integrity sha512-Sc5j3/YnM8tDeyCsVeKlm/0p95075DyLmDEIkSgQ7mXkrOX+uTCtmQFm0CYzVyJwcCCmO3k8qfJt17SxQwB5Zw==
 
-is-path-in-cwd@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52"
-  integrity sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==
+is-path-in-cwd@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb"
+  integrity sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==
   dependencies:
-    is-path-inside "^1.0.0"
+    is-path-inside "^2.1.0"
 
-is-path-inside@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036"
-  integrity sha1-jvW33lBDej/cprToZe96pVy0gDY=
+is-path-inside@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2"
+  integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==
   dependencies:
-    path-is-inside "^1.0.1"
+    path-is-inside "^1.0.2"
 
 is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4:
   version "2.0.4"
@@ -4830,21 +5302,16 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4:
   dependencies:
     isobject "^3.0.1"
 
-is-posix-bracket@^0.1.0:
-  version "0.1.1"
-  resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4"
-  integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=
-
-is-primitive@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575"
-  integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU=
-
 is-promise@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
   integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=
 
+is-property@^1.0.0, is-property@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84"
+  integrity sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=
+
 is-regex@^1.0.4:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
@@ -4891,12 +5358,7 @@ is-typedarray@~1.0.0:
   resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
   integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
 
-is-utf8@^0.2.0:
-  version "0.2.1"
-  resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
-  integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=
-
-is-windows@^1.0.0, is-windows@^1.0.2:
+is-windows@^1.0.0, is-windows@^1.0.1, is-windows@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
   integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==
@@ -4946,392 +5408,402 @@ isstream@~0.1.2:
   resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
   integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
 
-istanbul-api@^1.3.1:
-  version "1.3.7"
-  resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.3.7.tgz#a86c770d2b03e11e3f778cd7aedd82d2722092aa"
-  integrity sha512-4/ApBnMVeEPG3EkSzcw25wDe4N66wxwn+KKn6b47vyek8Xb3NBAcg4xfuQbS7BqcZuTX4wxfD5lVagdggR3gyA==
-  dependencies:
-    async "^2.1.4"
-    fileset "^2.0.2"
-    istanbul-lib-coverage "^1.2.1"
-    istanbul-lib-hook "^1.2.2"
-    istanbul-lib-instrument "^1.10.2"
-    istanbul-lib-report "^1.1.5"
-    istanbul-lib-source-maps "^1.2.6"
-    istanbul-reports "^1.5.1"
-    js-yaml "^3.7.0"
-    mkdirp "^0.5.1"
-    once "^1.4.0"
-
-istanbul-lib-coverage@^1.2.0, istanbul-lib-coverage@^1.2.1:
-  version "1.2.1"
-  resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz#ccf7edcd0a0bb9b8f729feeb0930470f9af664f0"
-  integrity sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ==
+istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.3:
+  version "2.0.3"
+  resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#0b891e5ad42312c2b9488554f603795f9a2211ba"
+  integrity sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==
 
-istanbul-lib-hook@^1.2.2:
-  version "1.2.2"
-  resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.2.2.tgz#bc6bf07f12a641fbf1c85391d0daa8f0aea6bf86"
-  integrity sha512-/Jmq7Y1VeHnZEQ3TL10VHyb564mn6VrQXHchON9Jf/AEcmQ3ZIiyD1BVzNOKTZf/G3gE+kiGK6SmpF9y3qGPLw==
-  dependencies:
-    append-transform "^0.4.0"
-
-istanbul-lib-instrument@^1.10.1, istanbul-lib-instrument@^1.10.2:
-  version "1.10.2"
-  resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz#1f55ed10ac3c47f2bdddd5307935126754d0a9ca"
-  integrity sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A==
-  dependencies:
-    babel-generator "^6.18.0"
-    babel-template "^6.16.0"
-    babel-traverse "^6.18.0"
-    babel-types "^6.18.0"
-    babylon "^6.18.0"
-    istanbul-lib-coverage "^1.2.1"
-    semver "^5.3.0"
+istanbul-lib-instrument@^3.0.0, istanbul-lib-instrument@^3.0.1:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz#a2b5484a7d445f1f311e93190813fa56dfb62971"
+  integrity sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA==
+  dependencies:
+    "@babel/generator" "^7.0.0"
+    "@babel/parser" "^7.0.0"
+    "@babel/template" "^7.0.0"
+    "@babel/traverse" "^7.0.0"
+    "@babel/types" "^7.0.0"
+    istanbul-lib-coverage "^2.0.3"
+    semver "^5.5.0"
 
-istanbul-lib-report@^1.1.5:
-  version "1.1.5"
-  resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.5.tgz#f2a657fc6282f96170aaf281eb30a458f7f4170c"
-  integrity sha512-UsYfRMoi6QO/doUshYNqcKJqVmFe9w51GZz8BS3WB0lYxAllQYklka2wP9+dGZeHYaWIdcXUx8JGdbqaoXRXzw==
+istanbul-lib-report@^2.0.4:
+  version "2.0.4"
+  resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.4.tgz#bfd324ee0c04f59119cb4f07dab157d09f24d7e4"
+  integrity sha512-sOiLZLAWpA0+3b5w5/dq0cjm2rrNdAfHWaGhmn7XEFW6X++IV9Ohn+pnELAl9K3rfpaeBfbmH9JU5sejacdLeA==
   dependencies:
-    istanbul-lib-coverage "^1.2.1"
-    mkdirp "^0.5.1"
-    path-parse "^1.0.5"
-    supports-color "^3.1.2"
+    istanbul-lib-coverage "^2.0.3"
+    make-dir "^1.3.0"
+    supports-color "^6.0.0"
 
-istanbul-lib-source-maps@^1.2.4, istanbul-lib-source-maps@^1.2.6:
-  version "1.2.6"
-  resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.6.tgz#37b9ff661580f8fca11232752ee42e08c6675d8f"
-  integrity sha512-TtbsY5GIHgbMsMiRw35YBHGpZ1DVFEO19vxxeiDMYaeOFOCzfnYVxvl6pOUIZR4dtPhAGpSMup8OyF8ubsaqEg==
+istanbul-lib-source-maps@^3.0.1:
+  version "3.0.2"
+  resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.2.tgz#f1e817229a9146e8424a28e5d69ba220fda34156"
+  integrity sha512-JX4v0CiKTGp9fZPmoxpu9YEkPbEqCqBbO3403VabKjH+NRXo72HafD5UgnjTEqHL2SAjaZK1XDuDOkn6I5QVfQ==
   dependencies:
-    debug "^3.1.0"
-    istanbul-lib-coverage "^1.2.1"
-    mkdirp "^0.5.1"
-    rimraf "^2.6.1"
-    source-map "^0.5.3"
+    debug "^4.1.1"
+    istanbul-lib-coverage "^2.0.3"
+    make-dir "^1.3.0"
+    rimraf "^2.6.2"
+    source-map "^0.6.1"
 
-istanbul-reports@^1.5.1:
-  version "1.5.1"
-  resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.5.1.tgz#97e4dbf3b515e8c484caea15d6524eebd3ff4e1a"
-  integrity sha512-+cfoZ0UXzWjhAdzosCPP3AN8vvef8XDkWtTfgaN+7L3YTpNYITnCaEkceo5SEYy644VkHka/P1FvkWvrG/rrJw==
+istanbul-reports@^2.1.1:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.1.1.tgz#72ef16b4ecb9a4a7bd0e2001e00f95d1eec8afa9"
+  integrity sha512-FzNahnidyEPBCI0HcufJoSEoKykesRlFcSzQqjH9x0+LC8tnnE/p/90PBLu8iZTxr8yYZNyTtiAujUqyN+CIxw==
   dependencies:
-    handlebars "^4.0.3"
+    handlebars "^4.1.0"
 
-jest-changed-files@^23.4.2:
-  version "23.4.2"
-  resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-23.4.2.tgz#1eed688370cd5eebafe4ae93d34bb3b64968fe83"
-  integrity sha512-EyNhTAUWEfwnK0Is/09LxoqNDOn7mU7S3EHskG52djOFS/z+IT0jT3h3Ql61+dklcG7bJJitIWEMB4Sp1piHmA==
+jest-changed-files@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.8.0.tgz#7e7eb21cf687587a85e50f3d249d1327e15b157b"
+  integrity sha512-qgANC1Yrivsq+UrLXsvJefBKVoCsKB0Hv+mBb6NMjjZ90wwxCDmU3hsCXBya30cH+LnPYjwgcU65i6yJ5Nfuug==
   dependencies:
+    "@jest/types" "^24.8.0"
+    execa "^1.0.0"
     throat "^4.0.0"
 
-jest-cli@^23.6.0:
-  version "23.6.0"
-  resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-23.6.0.tgz#61ab917744338f443ef2baa282ddffdd658a5da4"
-  integrity sha512-hgeD1zRUp1E1zsiyOXjEn4LzRLWdJBV//ukAHGlx6s5mfCNJTbhbHjgxnDUXA8fsKWN/HqFFF6X5XcCwC/IvYQ==
+jest-cli@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.8.0.tgz#b075ac914492ed114fa338ade7362a301693e989"
+  integrity sha512-+p6J00jSMPQ116ZLlHJJvdf8wbjNbZdeSX9ptfHX06/MSNaXmKihQzx5vQcw0q2G6JsdVkUIdWbOWtSnaYs3yA==
   dependencies:
-    ansi-escapes "^3.0.0"
+    "@jest/core" "^24.8.0"
+    "@jest/test-result" "^24.8.0"
+    "@jest/types" "^24.8.0"
     chalk "^2.0.1"
     exit "^0.1.2"
-    glob "^7.1.2"
-    graceful-fs "^4.1.11"
-    import-local "^1.0.0"
-    is-ci "^1.0.10"
-    istanbul-api "^1.3.1"
-    istanbul-lib-coverage "^1.2.0"
-    istanbul-lib-instrument "^1.10.1"
-    istanbul-lib-source-maps "^1.2.4"
-    jest-changed-files "^23.4.2"
-    jest-config "^23.6.0"
-    jest-environment-jsdom "^23.4.0"
-    jest-get-type "^22.1.0"
-    jest-haste-map "^23.6.0"
-    jest-message-util "^23.4.0"
-    jest-regex-util "^23.3.0"
-    jest-resolve-dependencies "^23.6.0"
-    jest-runner "^23.6.0"
-    jest-runtime "^23.6.0"
-    jest-snapshot "^23.6.0"
-    jest-util "^23.4.0"
-    jest-validate "^23.6.0"
-    jest-watcher "^23.4.0"
-    jest-worker "^23.2.0"
-    micromatch "^2.3.11"
-    node-notifier "^5.2.1"
-    prompts "^0.1.9"
-    realpath-native "^1.0.0"
-    rimraf "^2.5.4"
-    slash "^1.0.0"
-    string-length "^2.0.0"
-    strip-ansi "^4.0.0"
-    which "^1.2.12"
-    yargs "^11.0.0"
+    import-local "^2.0.0"
+    is-ci "^2.0.0"
+    jest-config "^24.8.0"
+    jest-util "^24.8.0"
+    jest-validate "^24.8.0"
+    prompts "^2.0.1"
+    realpath-native "^1.1.0"
+    yargs "^12.0.2"
 
-jest-config@^23.6.0:
-  version "23.6.0"
-  resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-23.6.0.tgz#f82546a90ade2d8c7026fbf6ac5207fc22f8eb1d"
-  integrity sha512-i8V7z9BeDXab1+VNo78WM0AtWpBRXJLnkT+lyT+Slx/cbP5sZJ0+NDuLcmBE5hXAoK0aUp7vI+MOxR+R4d8SRQ==
+jest-config@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.8.0.tgz#77db3d265a6f726294687cbbccc36f8a76ee0f4f"
+  integrity sha512-Czl3Nn2uEzVGsOeaewGWoDPD8GStxCpAe0zOYs2x2l0fZAgPbCr3uwUkgNKV3LwE13VXythM946cd5rdGkkBZw==
   dependencies:
-    babel-core "^6.0.0"
-    babel-jest "^23.6.0"
+    "@babel/core" "^7.1.0"
+    "@jest/test-sequencer" "^24.8.0"
+    "@jest/types" "^24.8.0"
+    babel-jest "^24.8.0"
     chalk "^2.0.1"
     glob "^7.1.1"
-    jest-environment-jsdom "^23.4.0"
-    jest-environment-node "^23.4.0"
-    jest-get-type "^22.1.0"
-    jest-jasmine2 "^23.6.0"
-    jest-regex-util "^23.3.0"
-    jest-resolve "^23.6.0"
-    jest-util "^23.4.0"
-    jest-validate "^23.6.0"
-    micromatch "^2.3.11"
-    pretty-format "^23.6.0"
-
-jest-diff@^23.6.0:
-  version "23.6.0"
-  resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-23.6.0.tgz#1500f3f16e850bb3d71233408089be099f610c7d"
-  integrity sha512-Gz9l5Ov+X3aL5L37IT+8hoCUsof1CVYBb2QEkOupK64XyRR3h+uRpYIm97K7sY8diFxowR8pIGEdyfMKTixo3g==
+    jest-environment-jsdom "^24.8.0"
+    jest-environment-node "^24.8.0"
+    jest-get-type "^24.8.0"
+    jest-jasmine2 "^24.8.0"
+    jest-regex-util "^24.3.0"
+    jest-resolve "^24.8.0"
+    jest-util "^24.8.0"
+    jest-validate "^24.8.0"
+    micromatch "^3.1.10"
+    pretty-format "^24.8.0"
+    realpath-native "^1.1.0"
+
+jest-diff@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.8.0.tgz#146435e7d1e3ffdf293d53ff97e193f1d1546172"
+  integrity sha512-wxetCEl49zUpJ/bvUmIFjd/o52J+yWcoc5ZyPq4/W1LUKGEhRYDIbP1KcF6t+PvqNrGAFk4/JhtxDq/Nnzs66g==
   dependencies:
     chalk "^2.0.1"
-    diff "^3.2.0"
-    jest-get-type "^22.1.0"
-    pretty-format "^23.6.0"
+    diff-sequences "^24.3.0"
+    jest-get-type "^24.8.0"
+    pretty-format "^24.8.0"
 
-jest-docblock@^23.2.0:
-  version "23.2.0"
-  resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-23.2.0.tgz#f085e1f18548d99fdd69b20207e6fd55d91383a7"
-  integrity sha1-8IXh8YVI2Z/dabICB+b9VdkTg6c=
+jest-docblock@^24.3.0:
+  version "24.3.0"
+  resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.3.0.tgz#b9c32dac70f72e4464520d2ba4aec02ab14db5dd"
+  integrity sha512-nlANmF9Yq1dufhFlKG9rasfQlrY7wINJbo3q01tu56Jv5eBU5jirylhF2O5ZBnLxzOVBGRDz/9NAwNyBtG4Nyg==
   dependencies:
     detect-newline "^2.1.0"
 
-jest-each@^23.6.0:
-  version "23.6.0"
-  resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-23.6.0.tgz#ba0c3a82a8054387016139c733a05242d3d71575"
-  integrity sha512-x7V6M/WGJo6/kLoissORuvLIeAoyo2YqLOoCDkohgJ4XOXSqOtyvr8FbInlAWS77ojBsZrafbozWoKVRdtxFCg==
+jest-each@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.8.0.tgz#a05fd2bf94ddc0b1da66c6d13ec2457f35e52775"
+  integrity sha512-NrwK9gaL5+XgrgoCsd9svsoWdVkK4gnvyhcpzd6m487tXHqIdYeykgq3MKI1u4I+5Zf0tofr70at9dWJDeb+BA==
   dependencies:
+    "@jest/types" "^24.8.0"
     chalk "^2.0.1"
-    pretty-format "^23.6.0"
-
-jest-environment-jsdom@^23.4.0:
-  version "23.4.0"
-  resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-23.4.0.tgz#056a7952b3fea513ac62a140a2c368c79d9e6023"
-  integrity sha1-BWp5UrP+pROsYqFAosNox52eYCM=
-  dependencies:
-    jest-mock "^23.2.0"
-    jest-util "^23.4.0"
+    jest-get-type "^24.8.0"
+    jest-util "^24.8.0"
+    pretty-format "^24.8.0"
+
+jest-environment-jsdom@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.8.0.tgz#300f6949a146cabe1c9357ad9e9ecf9f43f38857"
+  integrity sha512-qbvgLmR7PpwjoFjM/sbuqHJt/NCkviuq9vus9NBn/76hhSidO+Z6Bn9tU8friecegbJL8gzZQEMZBQlFWDCwAQ==
+  dependencies:
+    "@jest/environment" "^24.8.0"
+    "@jest/fake-timers" "^24.8.0"
+    "@jest/types" "^24.8.0"
+    jest-mock "^24.8.0"
+    jest-util "^24.8.0"
     jsdom "^11.5.1"
 
-jest-environment-node@^23.4.0:
-  version "23.4.0"
-  resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-23.4.0.tgz#57e80ed0841dea303167cce8cd79521debafde10"
-  integrity sha1-V+gO0IQd6jAxZ8zozXlSHeuv3hA=
+jest-environment-node@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.8.0.tgz#d3f726ba8bc53087a60e7a84ca08883a4c892231"
+  integrity sha512-vIGUEScd1cdDgR6sqn2M08sJTRLQp6Dk/eIkCeO4PFHxZMOgy+uYLPMC4ix3PEfM5Au/x3uQ/5Tl0DpXXZsJ/Q==
   dependencies:
-    jest-mock "^23.2.0"
-    jest-util "^23.4.0"
+    "@jest/environment" "^24.8.0"
+    "@jest/fake-timers" "^24.8.0"
+    "@jest/types" "^24.8.0"
+    jest-mock "^24.8.0"
+    jest-util "^24.8.0"
 
-jest-get-type@^22.1.0:
-  version "22.4.3"
-  resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4"
-  integrity sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w==
+jest-get-type@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.8.0.tgz#a7440de30b651f5a70ea3ed7ff073a32dfe646fc"
+  integrity sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ==
 
-jest-haste-map@^23.6.0:
-  version "23.6.0"
-  resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-23.6.0.tgz#2e3eb997814ca696d62afdb3f2529f5bbc935e16"
-  integrity sha512-uyNhMyl6dr6HaXGHp8VF7cK6KpC6G9z9LiMNsst+rJIZ8l7wY0tk8qwjPmEghczojZ2/ZhtEdIabZ0OQRJSGGg==
+jest-haste-map@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.8.0.tgz#51794182d877b3ddfd6e6d23920e3fe72f305800"
+  integrity sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==
   dependencies:
+    "@jest/types" "^24.8.0"
+    anymatch "^2.0.0"
     fb-watchman "^2.0.0"
-    graceful-fs "^4.1.11"
+    graceful-fs "^4.1.15"
     invariant "^2.2.4"
-    jest-docblock "^23.2.0"
-    jest-serializer "^23.0.1"
-    jest-worker "^23.2.0"
-    micromatch "^2.3.11"
-    sane "^2.0.0"
-
-jest-jasmine2@^23.6.0:
-  version "23.6.0"
-  resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-23.6.0.tgz#840e937f848a6c8638df24360ab869cc718592e0"
-  integrity sha512-pe2Ytgs1nyCs8IvsEJRiRTPC0eVYd8L/dXJGU08GFuBwZ4sYH/lmFDdOL3ZmvJR8QKqV9MFuwlsAi/EWkFUbsQ==
-  dependencies:
-    babel-traverse "^6.0.0"
+    jest-serializer "^24.4.0"
+    jest-util "^24.8.0"
+    jest-worker "^24.6.0"
+    micromatch "^3.1.10"
+    sane "^4.0.3"
+    walker "^1.0.7"
+  optionalDependencies:
+    fsevents "^1.2.7"
+
+jest-jasmine2@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.8.0.tgz#a9c7e14c83dd77d8b15e820549ce8987cc8cd898"
+  integrity sha512-cEky88npEE5LKd5jPpTdDCLvKkdyklnaRycBXL6GNmpxe41F0WN44+i7lpQKa/hcbXaQ+rc9RMaM4dsebrYong==
+  dependencies:
+    "@babel/traverse" "^7.1.0"
+    "@jest/environment" "^24.8.0"
+    "@jest/test-result" "^24.8.0"
+    "@jest/types" "^24.8.0"
     chalk "^2.0.1"
     co "^4.6.0"
-    expect "^23.6.0"
-    is-generator-fn "^1.0.0"
-    jest-diff "^23.6.0"
-    jest-each "^23.6.0"
-    jest-matcher-utils "^23.6.0"
-    jest-message-util "^23.4.0"
-    jest-snapshot "^23.6.0"
-    jest-util "^23.4.0"
-    pretty-format "^23.6.0"
-
-jest-leak-detector@^23.6.0:
-  version "23.6.0"
-  resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-23.6.0.tgz#e4230fd42cf381a1a1971237ad56897de7e171de"
-  integrity sha512-f/8zA04rsl1Nzj10HIyEsXvYlMpMPcy0QkQilVZDFOaPbv2ur71X5u2+C4ZQJGyV/xvVXtCCZ3wQ99IgQxftCg==
-  dependencies:
-    pretty-format "^23.6.0"
-
-jest-matcher-utils@^23.6.0:
-  version "23.6.0"
-  resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-23.6.0.tgz#726bcea0c5294261a7417afb6da3186b4b8cac80"
-  integrity sha512-rosyCHQfBcol4NsckTn01cdelzWLU9Cq7aaigDf8VwwpIRvWE/9zLgX2bON+FkEW69/0UuYslUe22SOdEf2nog==
+    expect "^24.8.0"
+    is-generator-fn "^2.0.0"
+    jest-each "^24.8.0"
+    jest-matcher-utils "^24.8.0"
+    jest-message-util "^24.8.0"
+    jest-runtime "^24.8.0"
+    jest-snapshot "^24.8.0"
+    jest-util "^24.8.0"
+    pretty-format "^24.8.0"
+    throat "^4.0.0"
+
+jest-leak-detector@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.8.0.tgz#c0086384e1f650c2d8348095df769f29b48e6980"
+  integrity sha512-cG0yRSK8A831LN8lIHxI3AblB40uhv0z+SsQdW3GoMMVcK+sJwrIIyax5tu3eHHNJ8Fu6IMDpnLda2jhn2pD/g==
+  dependencies:
+    pretty-format "^24.8.0"
+
+jest-matcher-utils@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.8.0.tgz#2bce42204c9af12bde46f83dc839efe8be832495"
+  integrity sha512-lex1yASY51FvUuHgm0GOVj7DCYEouWSlIYmCW7APSqB9v8mXmKSn5+sWVF0MhuASG0bnYY106/49JU1FZNl5hw==
   dependencies:
     chalk "^2.0.1"
-    jest-get-type "^22.1.0"
-    pretty-format "^23.6.0"
+    jest-diff "^24.8.0"
+    jest-get-type "^24.8.0"
+    pretty-format "^24.8.0"
 
-jest-message-util@^23.4.0:
-  version "23.4.0"
-  resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-23.4.0.tgz#17610c50942349508d01a3d1e0bda2c079086a9f"
-  integrity sha1-F2EMUJQjSVCNAaPR4L2iwHkIap8=
+jest-message-util@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.8.0.tgz#0d6891e72a4beacc0292b638685df42e28d6218b"
+  integrity sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==
   dependencies:
-    "@babel/code-frame" "^7.0.0-beta.35"
+    "@babel/code-frame" "^7.0.0"
+    "@jest/test-result" "^24.8.0"
+    "@jest/types" "^24.8.0"
+    "@types/stack-utils" "^1.0.1"
     chalk "^2.0.1"
-    micromatch "^2.3.11"
-    slash "^1.0.0"
+    micromatch "^3.1.10"
+    slash "^2.0.0"
     stack-utils "^1.0.1"
 
-jest-mock@^23.2.0:
-  version "23.2.0"
-  resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-23.2.0.tgz#ad1c60f29e8719d47c26e1138098b6d18b261134"
-  integrity sha1-rRxg8p6HGdR8JuETgJi20YsmETQ=
+jest-mock@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.8.0.tgz#2f9d14d37699e863f1febf4e4d5a33b7fdbbde56"
+  integrity sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==
+  dependencies:
+    "@jest/types" "^24.8.0"
+
+jest-pnp-resolver@^1.2.1:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz#ecdae604c077a7fbc70defb6d517c3c1c898923a"
+  integrity sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==
 
-jest-regex-util@^23.3.0:
-  version "23.3.0"
-  resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-23.3.0.tgz#5f86729547c2785c4002ceaa8f849fe8ca471bc5"
-  integrity sha1-X4ZylUfCeFxAAs6qj4Sf6MpHG8U=
+jest-regex-util@^24.3.0:
+  version "24.3.0"
+  resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.3.0.tgz#d5a65f60be1ae3e310d5214a0307581995227b36"
+  integrity sha512-tXQR1NEOyGlfylyEjg1ImtScwMq8Oh3iJbGTjN7p0J23EuVX1MA8rwU69K4sLbCmwzgCUbVkm0FkSF9TdzOhtg==
 
-jest-resolve-dependencies@^23.6.0:
-  version "23.6.0"
-  resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-23.6.0.tgz#b4526af24c8540d9a3fab102c15081cf509b723d"
-  integrity sha512-EkQWkFWjGKwRtRyIwRwI6rtPAEyPWlUC2MpzHissYnzJeHcyCn1Hc8j7Nn1xUVrS5C6W5+ZL37XTem4D4pLZdA==
+jest-resolve-dependencies@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.8.0.tgz#19eec3241f2045d3f990dba331d0d7526acff8e0"
+  integrity sha512-hyK1qfIf/krV+fSNyhyJeq3elVMhK9Eijlwy+j5jqmZ9QsxwKBiP6qukQxaHtK8k6zql/KYWwCTQ+fDGTIJauw==
   dependencies:
-    jest-regex-util "^23.3.0"
-    jest-snapshot "^23.6.0"
+    "@jest/types" "^24.8.0"
+    jest-regex-util "^24.3.0"
+    jest-snapshot "^24.8.0"
 
-jest-resolve@^23.6.0:
-  version "23.6.0"
-  resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-23.6.0.tgz#cf1d1a24ce7ee7b23d661c33ba2150f3aebfa0ae"
-  integrity sha512-XyoRxNtO7YGpQDmtQCmZjum1MljDqUCob7XlZ6jy9gsMugHdN2hY4+Acz9Qvjz2mSsOnPSH7skBmDYCHXVZqkA==
+jest-resolve@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.8.0.tgz#84b8e5408c1f6a11539793e2b5feb1b6e722439f"
+  integrity sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==
   dependencies:
+    "@jest/types" "^24.8.0"
     browser-resolve "^1.11.3"
     chalk "^2.0.1"
-    realpath-native "^1.0.0"
-
-jest-runner@^23.6.0:
-  version "23.6.0"
-  resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-23.6.0.tgz#3894bd219ffc3f3cb94dc48a4170a2e6f23a5a38"
-  integrity sha512-kw0+uj710dzSJKU6ygri851CObtCD9cN8aNkg8jWJf4ewFyEa6kwmiH/r/M1Ec5IL/6VFa0wnAk6w+gzUtjJzA==
-  dependencies:
+    jest-pnp-resolver "^1.2.1"
+    realpath-native "^1.1.0"
+
+jest-runner@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.8.0.tgz#4f9ae07b767db27b740d7deffad0cf67ccb4c5bb"
+  integrity sha512-utFqC5BaA3JmznbissSs95X1ZF+d+4WuOWwpM9+Ak356YtMhHE/GXUondZdcyAAOTBEsRGAgH/0TwLzfI9h7ow==
+  dependencies:
+    "@jest/console" "^24.7.1"
+    "@jest/environment" "^24.8.0"
+    "@jest/test-result" "^24.8.0"
+    "@jest/types" "^24.8.0"
+    chalk "^2.4.2"
     exit "^0.1.2"
-    graceful-fs "^4.1.11"
-    jest-config "^23.6.0"
-    jest-docblock "^23.2.0"
-    jest-haste-map "^23.6.0"
-    jest-jasmine2 "^23.6.0"
-    jest-leak-detector "^23.6.0"
-    jest-message-util "^23.4.0"
-    jest-runtime "^23.6.0"
-    jest-util "^23.4.0"
-    jest-worker "^23.2.0"
+    graceful-fs "^4.1.15"
+    jest-config "^24.8.0"
+    jest-docblock "^24.3.0"
+    jest-haste-map "^24.8.0"
+    jest-jasmine2 "^24.8.0"
+    jest-leak-detector "^24.8.0"
+    jest-message-util "^24.8.0"
+    jest-resolve "^24.8.0"
+    jest-runtime "^24.8.0"
+    jest-util "^24.8.0"
+    jest-worker "^24.6.0"
     source-map-support "^0.5.6"
     throat "^4.0.0"
 
-jest-runtime@^23.6.0:
-  version "23.6.0"
-  resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-23.6.0.tgz#059e58c8ab445917cd0e0d84ac2ba68de8f23082"
-  integrity sha512-ycnLTNPT2Gv+TRhnAYAQ0B3SryEXhhRj1kA6hBPSeZaNQkJ7GbZsxOLUkwg6YmvWGdX3BB3PYKFLDQCAE1zNOw==
-  dependencies:
-    babel-core "^6.0.0"
-    babel-plugin-istanbul "^4.1.6"
+jest-runtime@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.8.0.tgz#05f94d5b05c21f6dc54e427cd2e4980923350620"
+  integrity sha512-Mq0aIXhvO/3bX44ccT+czU1/57IgOMyy80oM0XR/nyD5zgBcesF84BPabZi39pJVA6UXw+fY2Q1N+4BiVUBWOA==
+  dependencies:
+    "@jest/console" "^24.7.1"
+    "@jest/environment" "^24.8.0"
+    "@jest/source-map" "^24.3.0"
+    "@jest/transform" "^24.8.0"
+    "@jest/types" "^24.8.0"
+    "@types/yargs" "^12.0.2"
     chalk "^2.0.1"
-    convert-source-map "^1.4.0"
     exit "^0.1.2"
-    fast-json-stable-stringify "^2.0.0"
-    graceful-fs "^4.1.11"
-    jest-config "^23.6.0"
-    jest-haste-map "^23.6.0"
-    jest-message-util "^23.4.0"
-    jest-regex-util "^23.3.0"
-    jest-resolve "^23.6.0"
-    jest-snapshot "^23.6.0"
-    jest-util "^23.4.0"
-    jest-validate "^23.6.0"
-    micromatch "^2.3.11"
-    realpath-native "^1.0.0"
-    slash "^1.0.0"
-    strip-bom "3.0.0"
-    write-file-atomic "^2.1.0"
-    yargs "^11.0.0"
+    glob "^7.1.3"
+    graceful-fs "^4.1.15"
+    jest-config "^24.8.0"
+    jest-haste-map "^24.8.0"
+    jest-message-util "^24.8.0"
+    jest-mock "^24.8.0"
+    jest-regex-util "^24.3.0"
+    jest-resolve "^24.8.0"
+    jest-snapshot "^24.8.0"
+    jest-util "^24.8.0"
+    jest-validate "^24.8.0"
+    realpath-native "^1.1.0"
+    slash "^2.0.0"
+    strip-bom "^3.0.0"
+    yargs "^12.0.2"
 
-jest-serializer@^23.0.1:
-  version "23.0.1"
-  resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-23.0.1.tgz#a3776aeb311e90fe83fab9e533e85102bd164165"
-  integrity sha1-o3dq6zEekP6D+rnlM+hRAr0WQWU=
+jest-serializer@^24.4.0:
+  version "24.4.0"
+  resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.4.0.tgz#f70c5918c8ea9235ccb1276d232e459080588db3"
+  integrity sha512-k//0DtglVstc1fv+GY/VHDIjrtNjdYvYjMlbLUed4kxrE92sIUewOi5Hj3vrpB8CXfkJntRPDRjCrCvUhBdL8Q==
 
-jest-snapshot@^23.6.0:
-  version "23.6.0"
-  resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-23.6.0.tgz#f9c2625d1b18acda01ec2d2b826c0ce58a5aa17a"
-  integrity sha512-tM7/Bprftun6Cvj2Awh/ikS7zV3pVwjRYU2qNYS51VZHgaAMBs5l4o/69AiDHhQrj5+LA2Lq4VIvK7zYk/bswg==
+jest-snapshot@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.8.0.tgz#3bec6a59da2ff7bc7d097a853fb67f9d415cb7c6"
+  integrity sha512-5ehtWoc8oU9/cAPe6fez6QofVJLBKyqkY2+TlKTOf0VllBB/mqUNdARdcjlZrs9F1Cv+/HKoCS/BknT0+tmfPg==
   dependencies:
-    babel-types "^6.0.0"
+    "@babel/types" "^7.0.0"
+    "@jest/types" "^24.8.0"
     chalk "^2.0.1"
-    jest-diff "^23.6.0"
-    jest-matcher-utils "^23.6.0"
-    jest-message-util "^23.4.0"
-    jest-resolve "^23.6.0"
+    expect "^24.8.0"
+    jest-diff "^24.8.0"
+    jest-matcher-utils "^24.8.0"
+    jest-message-util "^24.8.0"
+    jest-resolve "^24.8.0"
     mkdirp "^0.5.1"
     natural-compare "^1.4.0"
-    pretty-format "^23.6.0"
+    pretty-format "^24.8.0"
     semver "^5.5.0"
 
-jest-util@^23.4.0:
-  version "23.4.0"
-  resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-23.4.0.tgz#4d063cb927baf0a23831ff61bec2cbbf49793561"
-  integrity sha1-TQY8uSe68KI4Mf9hvsLLv0l5NWE=
-  dependencies:
-    callsites "^2.0.0"
+jest-util@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.8.0.tgz#41f0e945da11df44cc76d64ffb915d0716f46cd1"
+  integrity sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==
+  dependencies:
+    "@jest/console" "^24.7.1"
+    "@jest/fake-timers" "^24.8.0"
+    "@jest/source-map" "^24.3.0"
+    "@jest/test-result" "^24.8.0"
+    "@jest/types" "^24.8.0"
+    callsites "^3.0.0"
     chalk "^2.0.1"
-    graceful-fs "^4.1.11"
-    is-ci "^1.0.10"
-    jest-message-util "^23.4.0"
+    graceful-fs "^4.1.15"
+    is-ci "^2.0.0"
     mkdirp "^0.5.1"
-    slash "^1.0.0"
+    slash "^2.0.0"
     source-map "^0.6.0"
 
-jest-validate@^23.6.0:
-  version "23.6.0"
-  resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-23.6.0.tgz#36761f99d1ed33fcd425b4e4c5595d62b6597474"
-  integrity sha512-OFKapYxe72yz7agrDAWi8v2WL8GIfVqcbKRCLbRG9PAxtzF9b1SEDdTpytNDN12z2fJynoBwpMpvj2R39plI2A==
+jest-validate@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.8.0.tgz#624c41533e6dfe356ffadc6e2423a35c2d3b4849"
+  integrity sha512-+/N7VOEMW1Vzsrk3UWBDYTExTPwf68tavEPKDnJzrC6UlHtUDU/fuEdXqFoHzv9XnQ+zW6X3qMZhJ3YexfeLDA==
   dependencies:
+    "@jest/types" "^24.8.0"
+    camelcase "^5.0.0"
     chalk "^2.0.1"
-    jest-get-type "^22.1.0"
+    jest-get-type "^24.8.0"
     leven "^2.1.0"
-    pretty-format "^23.6.0"
+    pretty-format "^24.8.0"
 
-jest-watcher@^23.4.0:
-  version "23.4.0"
-  resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-23.4.0.tgz#d2e28ce74f8dad6c6afc922b92cabef6ed05c91c"
-  integrity sha1-0uKM50+NrWxq/JIrksq+9u0FyRw=
+jest-watcher@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.8.0.tgz#58d49915ceddd2de85e238f6213cef1c93715de4"
+  integrity sha512-SBjwHt5NedQoVu54M5GEx7cl7IGEFFznvd/HNT8ier7cCAx/Qgu9ZMlaTQkvK22G1YOpcWBLQPFSImmxdn3DAw==
   dependencies:
+    "@jest/test-result" "^24.8.0"
+    "@jest/types" "^24.8.0"
+    "@types/yargs" "^12.0.9"
     ansi-escapes "^3.0.0"
     chalk "^2.0.1"
+    jest-util "^24.8.0"
     string-length "^2.0.0"
 
-jest-worker@^23.2.0:
-  version "23.2.0"
-  resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-23.2.0.tgz#faf706a8da36fae60eb26957257fa7b5d8ea02b9"
-  integrity sha1-+vcGqNo2+uYOsmlXJX+ntdjqArk=
+jest-worker@^24.6.0:
+  version "24.6.0"
+  resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.6.0.tgz#7f81ceae34b7cde0c9827a6980c35b7cdc0161b3"
+  integrity sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==
   dependencies:
     merge-stream "^1.0.1"
+    supports-color "^6.1.0"
 
-jest@^23.6.0:
-  version "23.6.0"
-  resolved "https://registry.yarnpkg.com/jest/-/jest-23.6.0.tgz#ad5835e923ebf6e19e7a1d7529a432edfee7813d"
-  integrity sha512-lWzcd+HSiqeuxyhG+EnZds6iO3Y3ZEnMrfZq/OTGvF/C+Z4fPMCdhWTGSAiO2Oym9rbEXfwddHhh6jqrTF3+Lw==
+jest@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/jest/-/jest-24.8.0.tgz#d5dff1984d0d1002196e9b7f12f75af1b2809081"
+  integrity sha512-o0HM90RKFRNWmAWvlyV8i5jGZ97pFwkeVoGvPW1EtLTgJc2+jcuqcbbqcSZLE/3f2S5pt0y2ZBETuhpWNl1Reg==
   dependencies:
-    import-local "^1.0.0"
-    jest-cli "^23.6.0"
+    import-local "^2.0.0"
+    jest-cli "^24.8.0"
 
 js-base64@^2.1.9:
   version "2.5.0"
@@ -5339,9 +5811,9 @@ js-base64@^2.1.9:
   integrity sha512-wlEBIZ5LP8usDylWbDNhKPEFVFdI5hCHpnVoT/Ysvoi/PRhJENm/Rlh9TvjYB38HFfKZN7OzEbRjmjvLkFw11g==
 
 js-levenshtein@^1.1.3:
-  version "1.1.4"
-  resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.4.tgz#3a56e3cbf589ca0081eb22cd9ba0b1290a16d26e"
-  integrity sha512-PxfGzSs0ztShKrUYPIn5r0MtyAhYcCwmndozzpz8YObbPnD1jFxzlBGbRnX2mIu6Z13xN6+PTu05TQFnZFlzow==
+  version "1.1.6"
+  resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d"
+  integrity sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==
 
 js-string-escape@1.0.1:
   version "1.0.1"
@@ -5353,15 +5825,10 @@ js-string-escape@1.0.1:
   resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
   integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
 
-js-tokens@^3.0.2:
-  version "3.0.2"
-  resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
-  integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls=
-
-js-yaml@^3.11.0, js-yaml@^3.12.0, js-yaml@^3.7.0, js-yaml@^3.9.0:
-  version "3.12.0"
-  resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1"
-  integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==
+js-yaml@^3.12.0, js-yaml@^3.13.1, js-yaml@^3.4.6, js-yaml@^3.5.1, js-yaml@^3.5.4, js-yaml@^3.9.0:
+  version "3.13.1"
+  resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
+  integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
   dependencies:
     argparse "^1.0.7"
     esprima "^4.0.0"
@@ -5403,11 +5870,6 @@ jsdom@^11.5.1:
     ws "^5.2.0"
     xml-name-validator "^3.0.0"
 
-jsesc@^1.3.0:
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b"
-  integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s=
-
 jsesc@^2.5.1:
   version "2.5.2"
   resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
@@ -5438,7 +5900,7 @@ json-stable-stringify-without-jsonify@^1.0.1:
   resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
   integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
 
-json-stable-stringify@^1.0.1:
+json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af"
   integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=
@@ -5455,7 +5917,7 @@ json3@^3.3.2:
   resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1"
   integrity sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=
 
-json5@^0.5.0, json5@^0.5.1:
+json5@^0.5.0:
   version "0.5.1"
   resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
   integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=
@@ -5474,11 +5936,30 @@ json5@^2.1.0:
   dependencies:
     minimist "^1.2.0"
 
+jsonfile@^3.0.0:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66"
+  integrity sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=
+  optionalDependencies:
+    graceful-fs "^4.1.6"
+
+jsonfile@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
+  integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
+  optionalDependencies:
+    graceful-fs "^4.1.6"
+
 jsonify@~0.0.0:
   version "0.0.0"
   resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
   integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=
 
+jsonpointer@^4.0.0:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9"
+  integrity sha1-T9kss04OnbPInIYi7PUfm5eMbLk=
+
 jsprim@^1.2.2:
   version "1.4.1"
   resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
@@ -5501,7 +5982,7 @@ keycode@^2.1.7:
   resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.2.0.tgz#3d0af56dc7b8b8e5cba8d0a97f107204eec22b04"
   integrity sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ=
 
-killable@^1.0.0:
+killable@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892"
   integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==
@@ -5530,22 +6011,20 @@ kind-of@^6.0.0, kind-of@^6.0.2:
   resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051"
   integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==
 
-kleur@^2.0.1:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/kleur/-/kleur-2.0.2.tgz#b704f4944d95e255d038f0cb05fb8a602c55a300"
-  integrity sha512-77XF9iTllATmG9lSlIv0qdQ2BQ/h9t0bJllHlbvsQ0zUWfU7Yi0S8L5JXzPZgkefIiajLmBJJ4BsMJmqcf7oxQ==
+kleur@^3.0.2:
+  version "3.0.2"
+  resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.2.tgz#83c7ec858a41098b613d5998a7b653962b504f68"
+  integrity sha512-3h7B2WRT5LNXOtQiAaWonilegHcPSf9nLVXlSTci8lu1dZUuui61+EsPEZqSVxY7rXYmB2DVKMQILxaO5WL61Q==
 
 knot.js@^1.1.5:
   version "1.1.5"
   resolved "https://registry.yarnpkg.com/knot.js/-/knot.js-1.1.5.tgz#28e72522f703f50fe98812fde224dd72728fef5d"
   integrity sha1-KOclIvcD9Q/piBL94iTdcnKP710=
 
-lcid@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835"
-  integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=
-  dependencies:
-    invert-kv "^1.0.0"
+known-css-properties@^0.3.0:
+  version "0.3.0"
+  resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.3.0.tgz#a3d135bbfc60ee8c6eacf2f7e7e6f2d4755e49a4"
+  integrity sha512-QMQcnKAiQccfQTqtBh/qwquGZ2XK/DXND1jrcN9M8gMMy99Gwla7GQjndVUsEqIaRyP6bsFRuhwRj5poafBGJQ==
 
 lcid@^2.0.0:
   version "2.0.0"
@@ -5572,17 +6051,6 @@ levn@^0.3.0, levn@~0.3.0:
     prelude-ls "~1.1.2"
     type-check "~0.3.2"
 
-load-json-file@^1.0.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0"
-  integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=
-  dependencies:
-    graceful-fs "^4.1.2"
-    parse-json "^2.2.0"
-    pify "^2.0.0"
-    pinkie-promise "^2.0.0"
-    strip-bom "^2.0.0"
-
 load-json-file@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8"
@@ -5593,6 +6061,16 @@ load-json-file@^2.0.0:
     pify "^2.0.0"
     strip-bom "^3.0.0"
 
+load-json-file@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b"
+  integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs=
+  dependencies:
+    graceful-fs "^4.1.2"
+    parse-json "^4.0.0"
+    pify "^3.0.0"
+    strip-bom "^3.0.0"
+
 loader-runner@^2.3.0:
   version "2.3.1"
   resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.1.tgz#026f12fe7c3115992896ac02ba022ba92971b979"
@@ -5608,7 +6086,7 @@ loader-utils@0.2.x:
     json5 "^0.5.0"
     object-assign "^4.0.1"
 
-loader-utils@^1.0.1, loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.1:
+loader-utils@^1.0.1, loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.2, loader-utils@^1.2.3:
   version "1.2.3"
   resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7"
   integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==
@@ -5633,10 +6111,10 @@ locate-path@^3.0.0:
     p-locate "^3.0.0"
     path-exists "^3.0.0"
 
-lodash.debounce@^4.0.8:
-  version "4.0.8"
-  resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
-  integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168=
+lodash.capitalize@^4.1.0:
+  version "4.2.1"
+  resolved "https://registry.yarnpkg.com/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz#f826c9b4e2a8511d84e3aca29db05e1a4f3b72a9"
+  integrity sha1-+CbJtOKoUR2E46yinbBeGk87cqk=
 
 lodash.defaults@^4.0.1:
   version "4.2.0"
@@ -5678,6 +6156,11 @@ lodash.isobject@^3.0.2:
   resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-3.0.2.tgz#3c8fb8d5b5bf4bf90ae06e14f2a530a4ed935e1d"
   integrity sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=
 
+lodash.kebabcase@^4.0.0:
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36"
+  integrity sha1-hImxyw0p/4gZXM7KRI/21swpXDY=
+
 lodash.memoize@^4.1.2:
   version "4.1.2"
   resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
@@ -5698,15 +6181,15 @@ lodash.uniq@^4.5.0:
   resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
   integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
 
-lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.7.11:
+lodash@^4.0.0, lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.7.11, lodash@~4.17.10:
   version "4.17.11"
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
   integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
 
-loglevel@^1.4.1:
-  version "1.6.1"
-  resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa"
-  integrity sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=
+loglevel@^1.6.2:
+  version "1.6.2"
+  resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.2.tgz#668c77948a03dbd22502a3513ace1f62a80cc372"
+  integrity sha512-Jt2MHrCNdtIe1W6co3tF5KXGRkzF+TYffiQstfXa04mrss9IKXzAAXYWak8LbZseAQY03sH2GzMCMU0ZOUc9bg==
 
 loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
   version "1.4.0"
@@ -5715,14 +6198,6 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3
   dependencies:
     js-tokens "^3.0.0 || ^4.0.0"
 
-lru-cache@^4.0.1:
-  version "4.1.5"
-  resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd"
-  integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==
-  dependencies:
-    pseudomap "^1.0.2"
-    yallist "^2.1.2"
-
 lru-cache@^5.1.1:
   version "5.1.1"
   resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"
@@ -5730,7 +6205,7 @@ lru-cache@^5.1.1:
   dependencies:
     yallist "^3.0.2"
 
-make-dir@^1.0.0:
+make-dir@^1.0.0, make-dir@^1.3.0:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
   integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==
@@ -5744,6 +6219,11 @@ makeerror@1.0.x:
   dependencies:
     tmpl "1.0.x"
 
+mamacro@^0.0.3:
+  version "0.0.3"
+  resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4"
+  integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==
+
 map-age-cleaner@^0.1.1:
   version "0.1.3"
   resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a"
@@ -5773,11 +6253,6 @@ marky@^1.2.1:
   resolved "https://registry.yarnpkg.com/marky/-/marky-1.2.1.tgz#a3fcf82ffd357756b8b8affec9fdbf3a30dc1b02"
   integrity sha512-md9k+Gxa3qLH6sUKpeC2CNkJK/Ld+bEz5X96nYwloqphQE0CKCVEKco/6jxEZixinqNdz5RFi/KaCyfbMDMAXQ==
 
-math-random@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac"
-  integrity sha1-izqsWIuKZuSXXjzepn97sylgH6w=
-
 md5.js@^1.3.4:
   version "1.3.5"
   resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
@@ -5797,13 +6272,6 @@ media-typer@0.3.0:
   resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
   integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
 
-mem@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76"
-  integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=
-  dependencies:
-    mimic-fn "^1.0.0"
-
 mem@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/mem/-/mem-4.0.0.tgz#6437690d9471678f6cc83659c00cbafcd6b0cdaf"
@@ -5813,12 +6281,12 @@ mem@^4.0.0:
     mimic-fn "^1.0.0"
     p-is-promise "^1.1.0"
 
-memoize-one@^4.0.0:
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-4.1.0.tgz#a2387c58c03fff27ca390c31b764a79addf3f906"
-  integrity sha512-2GApq0yI/b22J2j9rhbrAlsHb0Qcz+7yWxeLG8h+95sl1XPUgeLimQSOdur4Vw7cUhrBHwaUZxWFZueojqNRzA==
+memoize-one@^5.0.0:
+  version "5.0.4"
+  resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.0.4.tgz#005928aced5c43d890a4dfab18ca908b0ec92cbc"
+  integrity sha512-P0z5IeAH6qHHGkJIXWw0xC2HNEgkx/9uWWBQw64FJj3/ol14VYdfVGWWr0fXfjhhv3TKVIqUq65os6O4GUNksA==
 
-memory-fs@^0.4.0, memory-fs@~0.4.1:
+memory-fs@^0.4.0, memory-fs@^0.4.1, memory-fs@~0.4.1:
   version "0.4.1"
   resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552"
   integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=
@@ -5848,26 +6316,7 @@ methods@~1.1.2:
   resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
   integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
 
-micromatch@^2.3.11:
-  version "2.3.11"
-  resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565"
-  integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=
-  dependencies:
-    arr-diff "^2.0.0"
-    array-unique "^0.2.1"
-    braces "^1.8.2"
-    expand-brackets "^0.1.4"
-    extglob "^0.3.1"
-    filename-regex "^2.0.0"
-    is-extglob "^1.0.0"
-    is-glob "^2.0.1"
-    kind-of "^3.0.2"
-    normalize-path "^2.0.1"
-    object.omit "^2.0.0"
-    parse-glob "^3.0.4"
-    regex-cache "^0.4.2"
-
-micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8, micromatch@^3.1.9:
+micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8:
   version "3.1.10"
   resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23"
   integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==
@@ -5894,27 +6343,39 @@ miller-rabin@^4.0.0:
     bn.js "^4.0.0"
     brorand "^1.0.1"
 
-"mime-db@>= 1.36.0 < 2", mime-db@~1.37.0:
+mime-db@1.40.0, "mime-db@>= 1.40.0 < 2":
+  version "1.40.0"
+  resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32"
+  integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==
+
+mime-db@~1.37.0:
   version "1.37.0"
   resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8"
   integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==
 
-mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.19:
+mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19:
   version "2.1.21"
   resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96"
   integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==
   dependencies:
     mime-db "~1.37.0"
 
-mime@1.4.1:
-  version "1.4.1"
-  resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6"
-  integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==
+mime-types@~2.1.24:
+  version "2.1.24"
+  resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81"
+  integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==
+  dependencies:
+    mime-db "1.40.0"
 
-mime@^2.3.1:
-  version "2.4.0"
-  resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.0.tgz#e051fd881358585f3279df333fe694da0bcffdd6"
-  integrity sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==
+mime@1.6.0:
+  version "1.6.0"
+  resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
+  integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
+
+mime@^2.4.2:
+  version "2.4.3"
+  resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.3.tgz#229687331e86f68924e6cb59e1cdd937f18275fe"
+  integrity sha512-QgrPRJfE+riq5TPZMcHZOtm8c6K/yYrMbKIoRfapfiGLxS8OTeIfRhUGW5LU7MlRa52KOAGCfUNruqLrIBvWZw==
 
 mimic-fn@^1.0.0:
   version "1.2.0"
@@ -5940,7 +6401,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1:
   resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
   integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
 
-minimatch@^3.0.3, minimatch@^3.0.4:
+minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2:
   version "3.0.4"
   resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
   integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
@@ -5952,6 +6413,11 @@ minimist@0.0.8:
   resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
   integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
 
+minimist@1.1.x:
+  version "1.1.3"
+  resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.1.3.tgz#3bedfd91a92d39016fcfaa1c681e8faa1a1efda8"
+  integrity sha1-O+39kaktOQFvz6ocaB6Pqhoe/ag=
+
 minimist@^1.1.1, minimist@^1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
@@ -6043,7 +6509,7 @@ ms@2.0.0:
   resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
   integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
 
-ms@^2.1.1:
+ms@2.1.1, ms@^2.1.1:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
   integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
@@ -6061,15 +6527,20 @@ multicast-dns@^6.0.1:
     dns-packet "^1.3.1"
     thunky "^1.0.2"
 
+mute-stream@0.0.5:
+  version "0.0.5"
+  resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0"
+  integrity sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=
+
 mute-stream@0.0.7:
   version "0.0.7"
   resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
   integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=
 
-nan@^2.9.2:
-  version "2.12.1"
-  resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552"
-  integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==
+nan@^2.12.1:
+  version "2.14.0"
+  resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
+  integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
 
 nanomatch@^1.2.9:
   version "1.2.13"
@@ -6113,17 +6584,17 @@ needle@^2.2.1:
     iconv-lite "^0.4.4"
     sax "^1.2.4"
 
-negotiator@0.6.1:
-  version "0.6.1"
-  resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
-  integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=
+negotiator@0.6.2:
+  version "0.6.2"
+  resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
+  integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==
 
 neo-async@^2.5.0:
   version "2.6.0"
   resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.0.tgz#b9d15e4d71c6762908654b5183ed38b753340835"
   integrity sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==
 
-next-tick@1:
+next-tick@1, next-tick@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
   integrity sha1-yobR/ogoFpsBICCOPchCS524NCw=
@@ -6180,6 +6651,11 @@ node-libs-browser@^2.0.0:
     util "^0.10.3"
     vm-browserify "0.0.4"
 
+node-modules-regexp@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40"
+  integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=
+
 node-notifier@^5.2.1:
   version "5.3.0"
   resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.3.0.tgz#c77a4a7b84038733d5fb351aafd8a268bfe19a01"
@@ -6190,10 +6666,10 @@ node-notifier@^5.2.1:
     shellwords "^0.1.1"
     which "^1.3.0"
 
-node-pre-gyp@^0.10.0:
-  version "0.10.3"
-  resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc"
-  integrity sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A==
+node-pre-gyp@^0.12.0:
+  version "0.12.0"
+  resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149"
+  integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==
   dependencies:
     detect-libc "^1.0.2"
     mkdirp "^0.5.1"
@@ -6206,10 +6682,10 @@ node-pre-gyp@^0.10.0:
     semver "^5.3.0"
     tar "^4"
 
-node-releases@^1.1.3:
-  version "1.1.3"
-  resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.3.tgz#aad9ce0dcb98129c753f772c0aa01360fb90fbd2"
-  integrity sha512-6VrvH7z6jqqNFY200kdB6HdzkgM96Oaj9v3dqGfgp6mF+cHmU4wyQKZ2/WPDRVoR0Jz9KqbamaBN0ZhdUaysUQ==
+node-releases@^1.1.23:
+  version "1.1.23"
+  resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.23.tgz#de7409f72de044a2fa59c097f436ba89c39997f0"
+  integrity sha512-uq1iL79YjfYC0WXoHbC/z28q/9pOl8kSHaXdWmAAc8No+bDwqkZbzIJz55g/MUsPgSGm9LZ7QSUbzTcH5tz47w==
   dependencies:
     semver "^5.3.0"
 
@@ -6221,6 +6697,13 @@ nopt@^4.0.1:
     abbrev "1"
     osenv "^0.1.4"
 
+nopt@~1.0.10:
+  version "1.0.10"
+  resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee"
+  integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=
+  dependencies:
+    abbrev "1"
+
 normalize-package-data@^2.3.2:
   version "2.4.0"
   resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f"
@@ -6231,13 +6714,18 @@ normalize-package-data@^2.3.2:
     semver "2 || 3 || 4 || 5"
     validate-npm-package-license "^3.0.1"
 
-normalize-path@^2.0.1, normalize-path@^2.1.1:
+normalize-path@^2.1.1:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9"
   integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=
   dependencies:
     remove-trailing-separator "^1.0.1"
 
+normalize-path@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
+  integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
+
 normalize-range@^0.1.2:
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
@@ -6361,7 +6849,7 @@ object.assign@^4.1.0:
     has-symbols "^1.0.0"
     object-keys "^1.0.11"
 
-object.entries@^1.0.4:
+object.entries@^1.0.4, object.entries@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.0.tgz#2024fc6d6ba246aee38bdb0ffd5cfbcf371b7519"
   integrity sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==
@@ -6389,14 +6877,6 @@ object.getownpropertydescriptors@^2.0.3:
     define-properties "^1.1.2"
     es-abstract "^1.5.1"
 
-object.omit@^2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa"
-  integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=
-  dependencies:
-    for-own "^0.1.4"
-    is-extendable "^0.1.1"
-
 object.pick@^1.3.0:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747"
@@ -6404,25 +6884,25 @@ object.pick@^1.3.0:
   dependencies:
     isobject "^3.0.1"
 
-object.values@^1.0.4:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.0.4.tgz#e524da09b4f66ff05df457546ec72ac99f13069a"
-  integrity sha1-5STaCbT2b/Bd9FdUbscqyZ8TBpo=
+object.values@^1.0.4, object.values@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.0.tgz#bf6810ef5da3e5325790eaaa2be213ea84624da9"
+  integrity sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==
   dependencies:
-    define-properties "^1.1.2"
-    es-abstract "^1.6.1"
-    function-bind "^1.1.0"
-    has "^1.0.1"
+    define-properties "^1.1.3"
+    es-abstract "^1.12.0"
+    function-bind "^1.1.1"
+    has "^1.0.3"
 
 obuf@^1.0.0, obuf@^1.1.2:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e"
   integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==
 
-offline-plugin@^5.0.6:
-  version "5.0.6"
-  resolved "https://registry.yarnpkg.com/offline-plugin/-/offline-plugin-5.0.6.tgz#7a7b244220cddb8a8cabecb172ec5c0be03e74b2"
-  integrity sha512-qvcDmeI30xmvSlmqjopAj7QCuM1MEzvmDyuMTN2saDReSay5nUqCpKysexH1KUNXv5H/TfmHd+rngNPkRFj3YA==
+offline-plugin@^5.0.7:
+  version "5.0.7"
+  resolved "https://registry.yarnpkg.com/offline-plugin/-/offline-plugin-5.0.7.tgz#26936ad1a7699f4d67e0a095a258972a4ccf1788"
+  integrity sha512-ArMFt4QFjK0wg8B5+R/6tt65u6Dk+Pkx4PAcW5O7mgIF3ywMepaQqFOQgfZD4ybanuGwuJihxUwMRgkzd+YGYw==
   dependencies:
     deep-extend "^0.5.1"
     ejs "^2.3.4"
@@ -6437,10 +6917,10 @@ on-finished@~2.3.0:
   dependencies:
     ee-first "1.1.1"
 
-on-headers@~1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7"
-  integrity sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=
+on-headers@~1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f"
+  integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==
 
 once@^1.3.0, once@^1.3.1, once@^1.4.0:
   version "1.4.0"
@@ -6449,6 +6929,11 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0:
   dependencies:
     wrappy "1"
 
+onetime@^1.0.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789"
+  integrity sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=
+
 onetime@^2.0.0:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
@@ -6461,10 +6946,10 @@ opener@^1.5.1:
   resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed"
   integrity sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==
 
-opn@^5.1.0:
-  version "5.4.0"
-  resolved "https://registry.yarnpkg.com/opn/-/opn-5.4.0.tgz#cb545e7aab78562beb11aa3bfabc7042e1761035"
-  integrity sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw==
+opn@^5.5.0:
+  version "5.5.0"
+  resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc"
+  integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==
   dependencies:
     is-wsl "^1.1.0"
 
@@ -6505,15 +6990,6 @@ os-homedir@^1.0.0:
   resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
   integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
 
-os-locale@^2.0.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2"
-  integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==
-  dependencies:
-    execa "^0.7.0"
-    lcid "^1.0.0"
-    mem "^1.1.0"
-
 os-locale@^3.0.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a"
@@ -6523,7 +6999,7 @@ os-locale@^3.0.0:
     lcid "^2.0.0"
     mem "^4.0.0"
 
-os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2:
+os-tmpdir@^1.0.0, os-tmpdir@~1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
   integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
@@ -6541,6 +7017,13 @@ p-defer@^1.0.0:
   resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c"
   integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=
 
+p-each-series@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71"
+  integrity sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=
+  dependencies:
+    p-reduce "^1.0.0"
+
 p-finally@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
@@ -6579,10 +7062,15 @@ p-locate@^3.0.0:
   dependencies:
     p-limit "^2.0.0"
 
-p-map@^1.1.1:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b"
-  integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==
+p-map@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175"
+  integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==
+
+p-reduce@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa"
+  integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=
 
 p-try@^1.0.0:
   version "1.0.0"
@@ -6639,16 +7127,6 @@ parse-css-font@^2.0.2:
     tcomb "^2.5.0"
     unquote "^1.1.0"
 
-parse-glob@^3.0.4:
-  version "3.0.4"
-  resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c"
-  integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw=
-  dependencies:
-    glob-base "^0.3.0"
-    is-dotfile "^1.0.0"
-    is-extglob "^1.0.0"
-    is-glob "^2.0.0"
-
 parse-json@^2.2.0:
   version "2.2.0"
   resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
@@ -6664,6 +7142,11 @@ parse-json@^4.0.0:
     error-ex "^1.3.1"
     json-parse-better-errors "^1.0.1"
 
+parse-passwd@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
+  integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=
+
 parse5@4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608"
@@ -6676,10 +7159,10 @@ parse5@^3.0.1:
   dependencies:
     "@types/node" "*"
 
-parseurl@~1.3.2:
-  version "1.3.2"
-  resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3"
-  integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=
+parseurl@~1.3.2, parseurl@~1.3.3:
+  version "1.3.3"
+  resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
+  integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
 
 pascalcase@^0.1.1:
   version "0.1.1"
@@ -6701,19 +7184,12 @@ path-dirname@^1.0.0:
   resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0"
   integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=
 
-path-exists@^2.0.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b"
-  integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=
-  dependencies:
-    pinkie-promise "^2.0.0"
-
 path-exists@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
   integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=
 
-path-is-absolute@^1.0.0, path-is-absolute@^1.0.1:
+path-is-absolute@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
   integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
@@ -6728,7 +7204,7 @@ path-key@^2.0.0, path-key@^2.0.1:
   resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
   integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
 
-path-parse@^1.0.5, path-parse@^1.0.6:
+path-parse@^1.0.6:
   version "1.0.6"
   resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
   integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
@@ -6745,15 +7221,6 @@ path-to-regexp@^1.7.0:
   dependencies:
     isarray "0.0.1"
 
-path-type@^1.0.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441"
-  integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=
-  dependencies:
-    graceful-fs "^4.1.2"
-    pify "^2.0.0"
-    pinkie-promise "^2.0.0"
-
 path-type@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73"
@@ -6761,6 +7228,13 @@ path-type@^2.0.0:
   dependencies:
     pify "^2.0.0"
 
+path-type@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f"
+  integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==
+  dependencies:
+    pify "^3.0.0"
+
 pbkdf2@^3.0.3:
   version "3.0.17"
   resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6"
@@ -6842,6 +7316,11 @@ pify@^3.0.0:
   resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
   integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=
 
+pify@^4.0.1:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231"
+  integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==
+
 pinkie-promise@^2.0.0:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
@@ -6854,12 +7333,12 @@ pinkie@^2.0.0:
   resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
   integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
 
-pkg-dir@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4"
-  integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q=
+pirates@^4.0.1:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87"
+  integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==
   dependencies:
-    find-up "^1.0.0"
+    node-modules-regexp "^1.0.0"
 
 pkg-dir@^2.0.0:
   version "2.0.0"
@@ -6875,6 +7354,11 @@ pkg-dir@^3.0.0:
   dependencies:
     find-up "^3.0.0"
 
+pluralize@^1.2.1:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45"
+  integrity sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=
+
 pluralize@^7.0.0:
   version "7.0.0"
   resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
@@ -6885,7 +7369,7 @@ pn@^1.1.0:
   resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb"
   integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==
 
-portfinder@^1.0.9:
+portfinder@^1.0.20:
   version "1.0.20"
   resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.20.tgz#bea68632e54b2e13ab7b0c4775e9b41bf270e44a"
   integrity sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==
@@ -6899,7 +7383,7 @@ posix-character-classes@^0.1.0:
   resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
   integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=
 
-postcss-calc@^7.0.0:
+postcss-calc@^7.0.1:
   version "7.0.1"
   resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.1.tgz#36d77bab023b0ecbb9789d84dcb23c4941145436"
   integrity sha512-oXqx0m6tb4N3JGdmeMSc/i91KppbYsFZKdH0xMOqK8V1rJlzrKlTdokz8ozUXLVejydRN6u2IddxpcijRj2FqQ==
@@ -6909,10 +7393,10 @@ postcss-calc@^7.0.0:
     postcss-selector-parser "^5.0.0-rc.4"
     postcss-value-parser "^3.3.1"
 
-postcss-colormin@^4.0.2:
-  version "4.0.2"
-  resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-4.0.2.tgz#93cd1fa11280008696887db1a528048b18e7ed99"
-  integrity sha512-1QJc2coIehnVFsz0otges8kQLsryi4lo19WD+U5xCWvXd0uw/Z+KKYnbiNDCnO9GP+PvErPHCG0jNvWTngk9Rw==
+postcss-colormin@^4.0.3:
+  version "4.0.3"
+  resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-4.0.3.tgz#ae060bce93ed794ac71264f08132d550956bd381"
+  integrity sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==
   dependencies:
     browserslist "^4.0.0"
     color "^3.0.0"
@@ -6928,10 +7412,10 @@ postcss-convert-values@^4.0.1:
     postcss "^7.0.0"
     postcss-value-parser "^3.0.0"
 
-postcss-discard-comments@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-4.0.1.tgz#30697735b0c476852a7a11050eb84387a67ef55d"
-  integrity sha512-Ay+rZu1Sz6g8IdzRjUgG2NafSNpp2MSMOQUb+9kkzzzP+kh07fP0yNbhtFejURnyVXSX3FYy2nVNW1QTnNjgBQ==
+postcss-discard-comments@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz#1fbabd2c246bff6aaad7997b2b0918f4d7af4033"
+  integrity sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==
   dependencies:
     postcss "^7.0.0"
 
@@ -6974,20 +7458,20 @@ postcss-loader@^3.0.0:
     postcss-load-config "^2.0.0"
     schema-utils "^1.0.0"
 
-postcss-merge-longhand@^4.0.10:
-  version "4.0.10"
-  resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-4.0.10.tgz#c4d63ab57bdc054ab4067ab075d488c8c2978380"
-  integrity sha512-hME10s6CSjm9nlVIcO1ukR7Jr5RisTaaC1y83jWCivpuBtPohA3pZE7cGTIVSYjXvLnXozHTiVOkG4dnnl756g==
+postcss-merge-longhand@^4.0.11:
+  version "4.0.11"
+  resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz#62f49a13e4a0ee04e7b98f42bb16062ca2549e24"
+  integrity sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==
   dependencies:
     css-color-names "0.0.4"
     postcss "^7.0.0"
     postcss-value-parser "^3.0.0"
     stylehacks "^4.0.0"
 
-postcss-merge-rules@^4.0.2:
-  version "4.0.2"
-  resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-4.0.2.tgz#2be44401bf19856f27f32b8b12c0df5af1b88e74"
-  integrity sha512-UiuXwCCJtQy9tAIxsnurfF0mrNHKc4NnNx6NxqmzNNjXpQwLSukUxELHTRF0Rg1pAmcoKLih8PwvZbiordchag==
+postcss-merge-rules@^4.0.3:
+  version "4.0.3"
+  resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz#362bea4ff5a1f98e4075a713c6cb25aefef9a650"
+  integrity sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==
   dependencies:
     browserslist "^4.0.0"
     caniuse-api "^3.0.0"
@@ -7004,20 +7488,20 @@ postcss-minify-font-values@^4.0.2:
     postcss "^7.0.0"
     postcss-value-parser "^3.0.0"
 
-postcss-minify-gradients@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-4.0.1.tgz#6da95c6e92a809f956bb76bf0c04494953e1a7dd"
-  integrity sha512-pySEW3E6Ly5mHm18rekbWiAjVi/Wj8KKt2vwSfVFAWdW6wOIekgqxKxLU7vJfb107o3FDNPkaYFCxGAJBFyogA==
+postcss-minify-gradients@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz#93b29c2ff5099c535eecda56c4aa6e665a663471"
+  integrity sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==
   dependencies:
     cssnano-util-get-arguments "^4.0.0"
     is-color-stop "^1.0.0"
     postcss "^7.0.0"
     postcss-value-parser "^3.0.0"
 
-postcss-minify-params@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-4.0.1.tgz#5b2e2d0264dd645ef5d68f8fec0d4c38c1cf93d2"
-  integrity sha512-h4W0FEMEzBLxpxIVelRtMheskOKKp52ND6rJv+nBS33G1twu2tCyurYj/YtgU76+UDCvWeNs0hs8HFAWE2OUFg==
+postcss-minify-params@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz#6b9cef030c11e35261f95f618c90036d680db874"
+  integrity sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==
   dependencies:
     alphanum-sort "^1.0.0"
     browserslist "^4.0.0"
@@ -7026,10 +7510,10 @@ postcss-minify-params@^4.0.1:
     postcss-value-parser "^3.0.0"
     uniqs "^2.0.0"
 
-postcss-minify-selectors@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-4.0.1.tgz#a891c197977cc37abf60b3ea06b84248b1c1e9cd"
-  integrity sha512-8+plQkomve3G+CodLCgbhAKrb5lekAnLYuL1d7Nz+/7RANpBEVdgBkPNwljfSKvZ9xkkZTZITd04KP+zeJTJqg==
+postcss-minify-selectors@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz#e2e5eb40bfee500d0cd9243500f5f8ea4262fbd8"
+  integrity sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==
   dependencies:
     alphanum-sort "^1.0.0"
     has "^1.0.0"
@@ -7043,22 +7527,22 @@ postcss-modules-extract-imports@^2.0.0:
   dependencies:
     postcss "^7.0.5"
 
-postcss-modules-local-by-default@^2.0.3:
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-2.0.3.tgz#6a199d596ec3ef57b8f5ced96d786b8cb16a7dec"
-  integrity sha512-jv4CQ8IQ0+TkaAIP7H4kgu/jQbrjte8xU61SYJAIOby+o3H0MGWX6eN1WXUKHccK6/EEjcAERjyIP8MXzAWAbQ==
+postcss-modules-local-by-default@^2.0.6:
+  version "2.0.6"
+  resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-2.0.6.tgz#dd9953f6dd476b5fd1ef2d8830c8929760b56e63"
+  integrity sha512-oLUV5YNkeIBa0yQl7EYnxMgy4N6noxmiwZStaEJUSe2xPMcdNc8WmBQuQCx18H5psYbVxz8zoHk0RAAYZXP9gA==
   dependencies:
-    css-selector-tokenizer "^0.7.0"
     postcss "^7.0.6"
+    postcss-selector-parser "^6.0.0"
     postcss-value-parser "^3.3.1"
 
-postcss-modules-scope@^2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.0.1.tgz#2c0f2394cde4cd09147db054c68917e38f6d43a4"
-  integrity sha512-7+6k9c3/AuZ5c596LJx9n923A/j3nF3ormewYBF1RrIQvjvjXe1xE8V8A1KFyFwXbvnshT6FBZFX0k/F1igneg==
+postcss-modules-scope@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.1.0.tgz#ad3f5bf7856114f6fcab901b0502e2a2bc39d4eb"
+  integrity sha512-91Rjps0JnmtUB0cujlc8KIKCsJXWjzuxGeT/+Q2i2HXKZ7nBUeF9YQTZZTNvHVoNYj1AthsjnGLtqDUE0Op79A==
   dependencies:
-    css-selector-tokenizer "^0.7.0"
     postcss "^7.0.6"
+    postcss-selector-parser "^6.0.0"
 
 postcss-modules-values@^2.0.0:
   version "2.0.0"
@@ -7075,48 +7559,48 @@ postcss-normalize-charset@^4.0.1:
   dependencies:
     postcss "^7.0.0"
 
-postcss-normalize-display-values@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.1.tgz#d9a83d47c716e8a980f22f632c8b0458cfb48a4c"
-  integrity sha512-R5mC4vaDdvsrku96yXP7zak+O3Mm9Y8IslUobk7IMP+u/g+lXvcN4jngmHY5zeJnrQvE13dfAg5ViU05ZFDwdg==
+postcss-normalize-display-values@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz#0dbe04a4ce9063d4667ed2be476bb830c825935a"
+  integrity sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==
   dependencies:
     cssnano-util-get-match "^4.0.0"
     postcss "^7.0.0"
     postcss-value-parser "^3.0.0"
 
-postcss-normalize-positions@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-4.0.1.tgz#ee2d4b67818c961964c6be09d179894b94fd6ba1"
-  integrity sha512-GNoOaLRBM0gvH+ZRb2vKCIujzz4aclli64MBwDuYGU2EY53LwiP7MxOZGE46UGtotrSnmarPPZ69l2S/uxdaWA==
+postcss-normalize-positions@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz#05f757f84f260437378368a91f8932d4b102917f"
+  integrity sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==
   dependencies:
     cssnano-util-get-arguments "^4.0.0"
     has "^1.0.0"
     postcss "^7.0.0"
     postcss-value-parser "^3.0.0"
 
-postcss-normalize-repeat-style@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.1.tgz#5293f234b94d7669a9f805495d35b82a581c50e5"
-  integrity sha512-fFHPGIjBUyUiswY2rd9rsFcC0t3oRta4wxE1h3lpwfQZwFeFjXFSiDtdJ7APCmHQOnUZnqYBADNRPKPwFAONgA==
+postcss-normalize-repeat-style@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz#c4ebbc289f3991a028d44751cbdd11918b17910c"
+  integrity sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==
   dependencies:
     cssnano-util-get-arguments "^4.0.0"
     cssnano-util-get-match "^4.0.0"
     postcss "^7.0.0"
     postcss-value-parser "^3.0.0"
 
-postcss-normalize-string@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-4.0.1.tgz#23c5030c2cc24175f66c914fa5199e2e3c10fef3"
-  integrity sha512-IJoexFTkAvAq5UZVxWXAGE0yLoNN/012v7TQh5nDo6imZJl2Fwgbhy3J2qnIoaDBrtUP0H7JrXlX1jjn2YcvCQ==
+postcss-normalize-string@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz#cd44c40ab07a0c7a36dc5e99aace1eca4ec2690c"
+  integrity sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==
   dependencies:
     has "^1.0.0"
     postcss "^7.0.0"
     postcss-value-parser "^3.0.0"
 
-postcss-normalize-timing-functions@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.1.tgz#8be83e0b9cb3ff2d1abddee032a49108f05f95d7"
-  integrity sha512-1nOtk7ze36+63ONWD8RCaRDYsnzorrj+Q6fxkQV+mlY5+471Qx9kspqv0O/qQNMeApg8KNrRf496zHwJ3tBZ7w==
+postcss-normalize-timing-functions@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz#8e009ca2a3949cdaf8ad23e6b6ab99cb5e7d28d9"
+  integrity sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==
   dependencies:
     cssnano-util-get-match "^4.0.0"
     postcss "^7.0.0"
@@ -7141,10 +7625,10 @@ postcss-normalize-url@^4.0.1:
     postcss "^7.0.0"
     postcss-value-parser "^3.0.0"
 
-postcss-normalize-whitespace@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.1.tgz#d14cb639b61238418ac8bc8d3b7bdd65fc86575e"
-  integrity sha512-U8MBODMB2L+nStzOk6VvWWjZgi5kQNShCyjRhMT3s+W9Jw93yIjOnrEkKYD3Ul7ChWbEcjDWmXq0qOL9MIAnAw==
+postcss-normalize-whitespace@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz#bf1d4070fe4fcea87d1348e825d8cc0c5faa7d82"
+  integrity sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==
   dependencies:
     postcss "^7.0.0"
     postcss-value-parser "^3.0.0"
@@ -7158,29 +7642,29 @@ postcss-object-fit-images@^1.1.2:
     postcss "^5.0.16"
     quote "^0.4.0"
 
-postcss-ordered-values@^4.1.1:
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-4.1.1.tgz#2e3b432ef3e489b18333aeca1f1295eb89be9fc2"
-  integrity sha512-PeJiLgJWPzkVF8JuKSBcylaU+hDJ/TX3zqAMIjlghgn1JBi6QwQaDZoDIlqWRcCAI8SxKrt3FCPSRmOgKRB97Q==
+postcss-ordered-values@^4.1.2:
+  version "4.1.2"
+  resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz#0cf75c820ec7d5c4d280189559e0b571ebac0eee"
+  integrity sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==
   dependencies:
     cssnano-util-get-arguments "^4.0.0"
     postcss "^7.0.0"
     postcss-value-parser "^3.0.0"
 
-postcss-reduce-initial@^4.0.2:
-  version "4.0.2"
-  resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-4.0.2.tgz#bac8e325d67510ee01fa460676dc8ea9e3b40f15"
-  integrity sha512-epUiC39NonKUKG+P3eAOKKZtm5OtAtQJL7Ye0CBN1f+UQTHzqotudp+hki7zxXm7tT0ZAKDMBj1uihpPjP25ug==
+postcss-reduce-initial@^4.0.3:
+  version "4.0.3"
+  resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz#7fd42ebea5e9c814609639e2c2e84ae270ba48df"
+  integrity sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==
   dependencies:
     browserslist "^4.0.0"
     caniuse-api "^3.0.0"
     has "^1.0.0"
     postcss "^7.0.0"
 
-postcss-reduce-transforms@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.1.tgz#8600d5553bdd3ad640f43bff81eb52f8760d4561"
-  integrity sha512-sZVr3QlGs0pjh6JAIe6DzWvBaqYw05V1t3d9Tp+VnFRT5j+rsqoWsysh/iSD7YNsULjq9IAylCznIwVd5oU/zA==
+postcss-reduce-transforms@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz#17efa405eacc6e07be3414a5ca2d1074681d4e29"
+  integrity sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==
   dependencies:
     cssnano-util-get-match "^4.0.0"
     has "^1.0.0"
@@ -7205,10 +7689,19 @@ postcss-selector-parser@^5.0.0-rc.4:
     indexes-of "^1.0.1"
     uniq "^1.0.1"
 
-postcss-svgo@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.1.tgz#5628cdb38f015de6b588ce6d0bf0724b492b581d"
-  integrity sha512-YD5uIk5NDRySy0hcI+ZJHwqemv2WiqqzDgtvgMzO8EGSkK5aONyX8HMVFRFJSdO8wUWTuisUFn/d7yRRbBr5Qw==
+postcss-selector-parser@^6.0.0:
+  version "6.0.2"
+  resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz#934cf799d016c83411859e09dcecade01286ec5c"
+  integrity sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==
+  dependencies:
+    cssesc "^3.0.0"
+    indexes-of "^1.0.1"
+    uniq "^1.0.1"
+
+postcss-svgo@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.2.tgz#17b997bc711b333bab143aaed3b8d3d6e3d38258"
+  integrity sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==
   dependencies:
     is-svg "^3.0.0"
     postcss "^7.0.0"
@@ -7239,14 +7732,14 @@ postcss@^5.0.16:
     source-map "^0.5.6"
     supports-color "^3.2.3"
 
-postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.5, postcss@^7.0.6:
-  version "7.0.7"
-  resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.7.tgz#2754d073f77acb4ef08f1235c36c5721a7201614"
-  integrity sha512-HThWSJEPkupqew2fnuQMEI2YcTj/8gMV3n80cMdJsKxfIh5tHf7nM5JigNX6LxVMqo6zkgQNAI88hyFvBk41Pg==
+postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.5, postcss@^7.0.6:
+  version "7.0.17"
+  resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.17.tgz#4da1bdff5322d4a0acaab4d87f3e782436bad31f"
+  integrity sha512-546ZowA+KZ3OasvQZHsbuEpysvwTZNGJv9EfyCQdsIDltPSWHAeTQ5fQy/Npi2ZDtLI3zs7Ps/p6wThErhm9fQ==
   dependencies:
-    chalk "^2.4.1"
+    chalk "^2.4.2"
     source-map "^0.6.1"
-    supports-color "^5.5.0"
+    supports-color "^6.1.0"
 
 postgres-array@~1.0.0:
   version "1.0.3"
@@ -7280,20 +7773,22 @@ prelude-ls@~1.1.2:
   resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
   integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=
 
-preserve@^0.2.0:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
-  integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=
+prettier@^1.17.0:
+  version "1.18.2"
+  resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.18.2.tgz#6823e7c5900017b4bd3acf46fe9ac4b4d7bda9ea"
+  integrity sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==
 
-pretty-format@^23.6.0:
-  version "23.6.0"
-  resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.6.0.tgz#5eaac8eeb6b33b987b7fe6097ea6a8a146ab5760"
-  integrity sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw==
+pretty-format@^24.8.0:
+  version "24.8.0"
+  resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.8.0.tgz#8dae7044f58db7cb8be245383b565a963e3c27f2"
+  integrity sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw==
   dependencies:
-    ansi-regex "^3.0.0"
+    "@jest/types" "^24.8.0"
+    ansi-regex "^4.0.0"
     ansi-styles "^3.2.0"
+    react-is "^16.8.4"
 
-private@^0.1.6, private@^0.1.8:
+private@^0.1.6:
   version "0.1.8"
   resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
   integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==
@@ -7308,6 +7803,11 @@ process@^0.11.10:
   resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
   integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
 
+progress@^1.1.8:
+  version "1.1.8"
+  resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be"
+  integrity sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=
+
 progress@^2.0.0:
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
@@ -7325,13 +7825,22 @@ promise@^7.1.1:
   dependencies:
     asap "~2.0.3"
 
-prompts@^0.1.9:
-  version "0.1.14"
-  resolved "https://registry.yarnpkg.com/prompts/-/prompts-0.1.14.tgz#a8e15c612c5c9ec8f8111847df3337c9cbd443b2"
-  integrity sha512-rxkyiE9YH6zAz/rZpywySLKkpaj0NMVyNw1qhsubdbjjSgcayjTShDreZGlFMcGSu5sab3bAKPfFk78PB90+8w==
+prompts@^2.0.1:
+  version "2.0.3"
+  resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.0.3.tgz#c5ccb324010b2e8f74752aadceeb57134c1d2522"
+  integrity sha512-H8oWEoRZpybm6NV4to9/1limhttEo13xK62pNvn2JzY0MA03p7s0OjtmhXyon3uJmxiJJVSuUwEJFFssI3eBiQ==
+  dependencies:
+    kleur "^3.0.2"
+    sisteransi "^1.0.0"
+
+prop-types-exact@^1.2.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/prop-types-exact/-/prop-types-exact-1.2.0.tgz#825d6be46094663848237e3925a98c6e944e9869"
+  integrity sha512-K+Tk3Kd9V0odiXFP9fwDHUYRyvK3Nun3GVyPapSIs5OBkITAm15W0CPFD/YKTkMUAbc0b9CUwRQp2ybiBIq+eA==
   dependencies:
-    kleur "^2.0.1"
-    sisteransi "^0.1.1"
+    has "^1.0.3"
+    object.assign "^4.1.0"
+    reflect.ownkeys "^0.2.0"
 
 prop-types-extra@^1.0.1:
   version "1.1.0"
@@ -7341,32 +7850,28 @@ prop-types-extra@^1.0.1:
     react-is "^16.3.2"
     warning "^3.0.0"
 
-prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2:
-  version "15.6.2"
-  resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102"
-  integrity sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==
+prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
+  version "15.7.2"
+  resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
+  integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
   dependencies:
-    loose-envify "^1.3.1"
+    loose-envify "^1.4.0"
     object-assign "^4.1.1"
+    react-is "^16.8.1"
 
-proxy-addr@~2.0.4:
-  version "2.0.4"
-  resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93"
-  integrity sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==
+proxy-addr@~2.0.5:
+  version "2.0.5"
+  resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.5.tgz#34cbd64a2d81f4b1fd21e76f9f06c8a45299ee34"
+  integrity sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==
   dependencies:
     forwarded "~0.1.2"
-    ipaddr.js "1.8.0"
+    ipaddr.js "1.9.0"
 
 prr@~1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
   integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY=
 
-pseudomap@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
-  integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM=
-
 psl@^1.1.24, psl@^1.1.28:
   version "1.1.31"
   resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184"
@@ -7429,7 +7934,12 @@ q@^1.1.2:
   resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
   integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
 
-qs@6.5.2, qs@~6.5.2:
+qs@6.7.0:
+  version "6.7.0"
+  resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
+  integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==
+
+qs@~6.5.2:
   version "6.5.2"
   resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
   integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
@@ -7466,10 +7976,10 @@ railroad-diagrams@^1.0.0:
   resolved "https://registry.yarnpkg.com/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz#eb7e6267548ddedfb899c1b90e57374559cddb7e"
   integrity sha1-635iZ1SN3t+4mcG5Dlc3RVnN234=
 
-rails-ujs@^5.2.2:
-  version "5.2.2"
-  resolved "https://registry.yarnpkg.com/rails-ujs/-/rails-ujs-5.2.2.tgz#ab01dd087a323975637b50e93e7afcc0f9068568"
-  integrity sha512-tJl7MdysGrQEKmwF7BJkz5XwUOkdnI9E7SvSbT39yO7pdFc96D4hWKm6Sb15pU4n5mt4rLPb/6kkyTQujP1k7Q==
+rails-ujs@^5.2.3:
+  version "5.2.3"
+  resolved "https://registry.yarnpkg.com/rails-ujs/-/rails-ujs-5.2.3.tgz#4b65ea781a6befe62e96da6362165286a1fe4099"
+  integrity sha512-rYgj185MowWFBJI1wdac2FkX4yFYe4+3jJPlB+CTY7a4rmIyg0TqE4vYZmSBBesp7blPUa57oqKzwQjN7eVbEQ==
 
 randexp@0.4.6:
   version "0.4.6"
@@ -7479,15 +7989,6 @@ randexp@0.4.6:
     discontinuous-range "1.0.0"
     ret "~0.1.10"
 
-randomatic@^3.0.0:
-  version "3.1.1"
-  resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed"
-  integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==
-  dependencies:
-    is-number "^4.0.0"
-    kind-of "^6.0.0"
-    math-random "^1.0.1"
-
 randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
   version "2.0.6"
   resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80"
@@ -7503,19 +8004,19 @@ randomfill@^1.0.3:
     randombytes "^2.0.5"
     safe-buffer "^5.1.0"
 
-range-parser@^1.0.3, range-parser@~1.2.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e"
-  integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=
+range-parser@^1.2.1, range-parser@~1.2.1:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
+  integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
 
-raw-body@2.3.3:
-  version "2.3.3"
-  resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3"
-  integrity sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==
+raw-body@2.4.0:
+  version "2.4.0"
+  resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332"
+  integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==
   dependencies:
-    bytes "3.0.0"
-    http-errors "1.6.3"
-    iconv-lite "0.4.23"
+    bytes "3.1.0"
+    http-errors "1.7.2"
+    iconv-lite "0.4.24"
     unpipe "1.0.0"
 
 rc@^1.2.7:
@@ -7528,15 +8029,15 @@ rc@^1.2.7:
     minimist "^1.2.0"
     strip-json-comments "~2.0.1"
 
-react-dom@^16.7.0:
-  version "16.7.0"
-  resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.7.0.tgz#a17b2a7ca89ee7390bc1ed5eb81783c7461748b8"
-  integrity sha512-D0Ufv1ExCAmF38P2Uh1lwpminZFRXEINJe53zRAbm4KPwSyd6DY/uDoS0Blj9jvPpn1+wivKpZYc8aAAN/nAkg==
+react-dom@^16.8.6:
+  version "16.8.6"
+  resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.6.tgz#71d6303f631e8b0097f56165ef608f051ff6e10f"
+  integrity sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA==
   dependencies:
     loose-envify "^1.1.0"
     object-assign "^4.1.1"
     prop-types "^15.6.2"
-    scheduler "^0.12.0"
+    scheduler "^0.13.6"
 
 react-event-listener@^0.6.0:
   version "0.6.5"
@@ -7594,21 +8095,21 @@ react-intl-translations-manager@^5.0.3:
     json-stable-stringify "^1.0.1"
     mkdirp "^0.5.1"
 
-react-intl@^2.7.2:
-  version "2.7.2"
-  resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-2.7.2.tgz#efe97e3fc0e99b4e88a6e6150854d3d1852a4381"
-  integrity sha512-3dcNGLqEw2FKkX+1L2WYLgjP0MVJkvWuVd1uLcnwifIQe8JQvnd9Bss4hb4Gvg/YhBIRcs4LM6C2bAgyklucjw==
+react-intl@^2.9.0:
+  version "2.9.0"
+  resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-2.9.0.tgz#c97c5d17d4718f1575fdbd5a769f96018a3b1843"
+  integrity sha512-27jnDlb/d2A7mSJwrbOBnUgD+rPep+abmoJE511Tf8BnoONIAUehy/U1zZCHGO17mnOwMWxqN4qC0nW11cD6rA==
   dependencies:
-    hoist-non-react-statics "^2.5.5"
+    hoist-non-react-statics "^3.3.0"
     intl-format-cache "^2.0.5"
     intl-messageformat "^2.1.0"
     intl-relativeformat "^2.1.0"
     invariant "^2.1.1"
 
-react-is@^16.3.2, react-is@^16.6.1, react-is@^16.6.3, react-is@^16.7.0:
-  version "16.7.0"
-  resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.7.0.tgz#c1bd21c64f1f1364c6f70695ec02d69392f41bfa"
-  integrity sha512-Z0VRQdF4NPDoI0tsXVMLkJLiwEBa+RP66g0xDHxgxysxSoCUccSten4RTF/UFvZF1dZvZ9Zu1sx+MDXwcOR34g==
+react-is@^16.3.2, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.2, react-is@^16.8.4, react-is@^16.8.6:
+  version "16.8.6"
+  resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16"
+  integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==
 
 react-lifecycles-compat@^3.0.2, react-lifecycles-compat@^3.0.4:
   version "3.0.4"
@@ -7660,17 +8161,17 @@ react-redux-loading-bar@^4.0.8:
     prop-types "^15.6.2"
     react-lifecycles-compat "^3.0.2"
 
-react-redux@^6.0.0:
-  version "6.0.0"
-  resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-6.0.0.tgz#09e86eeed5febb98e9442458ad2970c8f1a173ef"
-  integrity sha512-EmbC3uLl60pw2VqSSkj6HpZ6jTk12RMrwXMBdYtM6niq0MdEaRq9KYCwpJflkOZj349BLGQm1MI/JO1W96kLWQ==
+react-redux@^6.0.1:
+  version "6.0.1"
+  resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-6.0.1.tgz#0d423e2c1cb10ada87293d47e7de7c329623ba4d"
+  integrity sha512-T52I52Kxhbqy/6TEfBv85rQSDz6+Y28V/pf52vDWs1YRXG19mcFOGfHnY2HsNFHyhP+ST34Aih98fvt6tqwVcQ==
   dependencies:
-    "@babel/runtime" "^7.2.0"
-    hoist-non-react-statics "^3.2.1"
+    "@babel/runtime" "^7.3.1"
+    hoist-non-react-statics "^3.3.0"
     invariant "^2.2.4"
     loose-envify "^1.4.0"
-    prop-types "^15.6.2"
-    react-is "^16.6.3"
+    prop-types "^15.7.2"
+    react-is "^16.8.2"
 
 react-router-dom@^4.1.1:
   version "4.3.1"
@@ -7705,14 +8206,14 @@ react-router@^4.3.1:
     prop-types "^15.6.1"
     warning "^4.0.1"
 
-react-select@^2.2.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/react-select/-/react-select-2.2.0.tgz#67c8b5c2dcb8df0384f2a103efe952570f5d6b93"
-  integrity sha512-FOnsm/zrJ2pZvYsEfs58Xvru0SHL1jXAZTCFTWcOxmQSnRKgYuXUDFdpDiET90GLtJEF+t6BaZeD43bUH6/NZQ==
+react-select@^2.4.4:
+  version "2.4.4"
+  resolved "https://registry.yarnpkg.com/react-select/-/react-select-2.4.4.tgz#ba72468ef1060c7d46fbb862b0748f96491f1f73"
+  integrity sha512-C4QPLgy9h42J/KkdrpVxNmkY6p4lb49fsrbDk/hRcZpX7JvZPNb6mGj+c5SzyEtBv1DmQ9oPH4NmhAFvCrg8Jw==
   dependencies:
     classnames "^2.2.5"
-    create-emotion "^10.0.4"
-    memoize-one "^4.0.0"
+    emotion "^9.1.2"
+    memoize-one "^5.0.0"
     prop-types "^15.6.0"
     raf "^3.4.0"
     react-input-autosize "^2.2.1"
@@ -7725,47 +8226,47 @@ react-sparklines@^1.7.0:
   dependencies:
     prop-types "^15.5.10"
 
-react-swipeable-views-core@^0.13.0:
-  version "0.13.0"
-  resolved "https://registry.yarnpkg.com/react-swipeable-views-core/-/react-swipeable-views-core-0.13.0.tgz#6bf8a8132a756355444537672a14e84b1e3b53c2"
-  integrity sha512-MAe119eSN4obiqsIp+qoUWtLbyjz+dWEfz+qPurPvyIFoXxuxpBnsDy36+C7cBaCi5z4dRmfoMlm1dBAdIzvig==
+react-swipeable-views-core@^0.13.1:
+  version "0.13.1"
+  resolved "https://registry.yarnpkg.com/react-swipeable-views-core/-/react-swipeable-views-core-0.13.1.tgz#8829a922462a8bdd701709cd1b385393d38f1527"
+  integrity sha512-EP8sCvvD7VDiZLglPt9icMuMNu8qLRLk0ab/fB1HXv7lX8ClnwF3UMCM0ZrN3sguSY7CsX3LevducGGsT1VcDg==
   dependencies:
     "@babel/runtime" "7.0.0"
     warning "^4.0.1"
 
-react-swipeable-views-utils@^0.13.0:
-  version "0.13.0"
-  resolved "https://registry.yarnpkg.com/react-swipeable-views-utils/-/react-swipeable-views-utils-0.13.0.tgz#0ea17aa67f88a69d534c79d591f8d82ef98346a4"
-  integrity sha512-1I4BhDqA6qkRdW0nexnudh/QdvVAVy0a7M5OyU2TrjaTovg6ufBouzqfqjZfUZUxVdOftTkPtisHmcqqZ+b1TA==
+react-swipeable-views-utils@^0.13.3:
+  version "0.13.3"
+  resolved "https://registry.yarnpkg.com/react-swipeable-views-utils/-/react-swipeable-views-utils-0.13.3.tgz#c234d8d836bb085803631a9fef0adb2f9597221f"
+  integrity sha512-CZkJwiNQPISkyTsPMUPiJgwJBrUVd7NC3WSUvx30uwvPb0Sy2w2+tpU51qeYc6YwIhex0s5Eu5YPjK3PDBh+gA==
   dependencies:
     "@babel/runtime" "7.0.0"
     fbjs "^0.8.4"
     keycode "^2.1.7"
     prop-types "^15.6.0"
     react-event-listener "^0.6.0"
-    react-swipeable-views-core "^0.13.0"
+    react-swipeable-views-core "^0.13.1"
 
-react-swipeable-views@^0.13.0:
-  version "0.13.0"
-  resolved "https://registry.yarnpkg.com/react-swipeable-views/-/react-swipeable-views-0.13.0.tgz#a200cef1005d55af6a27b97048afe9a4056e0ab8"
-  integrity sha512-r6H8lbtcI99oKykpLxYrI6O9im1lJ4D5/hf8bkNeQLdHZ9ftxS03qgEtguy3GpT5VB9yS4gErYWeaTrhCrysEg==
+react-swipeable-views@^0.13.3:
+  version "0.13.3"
+  resolved "https://registry.yarnpkg.com/react-swipeable-views/-/react-swipeable-views-0.13.3.tgz#2ad886767c6b2de88000606a14bedde12156e6d0"
+  integrity sha512-LBHRA5ZouipmoLLwi0cqB8qc7NHLskbXmT1I+ZztC9JfmgKrfichw5R+7q4igQ+5VbaP6jL1vn8BtHW96WYNFQ==
   dependencies:
     "@babel/runtime" "7.0.0"
     dom-helpers "^3.2.1"
     prop-types "^15.5.4"
-    react-swipeable-views-core "^0.13.0"
-    react-swipeable-views-utils "^0.13.0"
+    react-swipeable-views-core "^0.13.1"
+    react-swipeable-views-utils "^0.13.3"
     warning "^4.0.1"
 
-react-test-renderer@^16.0.0-0, react-test-renderer@^16.7.0:
-  version "16.7.0"
-  resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.7.0.tgz#1ca96c2b450ab47c36ba92cd8c03fcefc52ea01c"
-  integrity sha512-tFbhSjknSQ6+ttzmuGdv+SjQfmvGcq3PFKyPItohwhhOBmRoTf1We3Mlt3rJtIn85mjPXOkKV+TaKK4irvk9Yg==
+react-test-renderer@^16.0.0-0, react-test-renderer@^16.8.6:
+  version "16.8.6"
+  resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.8.6.tgz#188d8029b8c39c786f998aa3efd3ffe7642d5ba1"
+  integrity sha512-H2srzU5IWYT6cZXof6AhUcx/wEyJddQ8l7cLM/F7gDXYyPr4oq+vCIxJYXVGhId1J706sqziAjuOEjyNkfgoEw==
   dependencies:
     object-assign "^4.1.1"
     prop-types "^15.6.2"
-    react-is "^16.7.0"
-    scheduler "^0.12.0"
+    react-is "^16.8.6"
+    scheduler "^0.13.6"
 
 react-textarea-autosize@^7.1.0:
   version "7.1.0"
@@ -7792,23 +8293,15 @@ react-transition-group@^2.2.0, react-transition-group@^2.2.1:
     prop-types "^15.6.2"
     react-lifecycles-compat "^3.0.4"
 
-react@^16.7.0:
-  version "16.7.0"
-  resolved "https://registry.yarnpkg.com/react/-/react-16.7.0.tgz#b674ec396b0a5715873b350446f7ea0802ab6381"
-  integrity sha512-StCz3QY8lxTb5cl2HJxjwLFOXPIFQp+p+hxQfc8WE0QiLfCtIlKj8/+5tjjKm8uSTlAW+fCPaavGFS06V9Ar3A==
+react@^16.8.6:
+  version "16.8.6"
+  resolved "https://registry.yarnpkg.com/react/-/react-16.8.6.tgz#ad6c3a9614fd3a4e9ef51117f54d888da01f2bbe"
+  integrity sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==
   dependencies:
     loose-envify "^1.1.0"
     object-assign "^4.1.1"
     prop-types "^15.6.2"
-    scheduler "^0.12.0"
-
-read-pkg-up@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02"
-  integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=
-  dependencies:
-    find-up "^1.0.0"
-    read-pkg "^1.0.0"
+    scheduler "^0.13.6"
 
 read-pkg-up@^2.0.0:
   version "2.0.0"
@@ -7818,14 +8311,13 @@ read-pkg-up@^2.0.0:
     find-up "^2.0.0"
     read-pkg "^2.0.0"
 
-read-pkg@^1.0.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28"
-  integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=
+read-pkg-up@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978"
+  integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==
   dependencies:
-    load-json-file "^1.0.0"
-    normalize-package-data "^2.3.2"
-    path-type "^1.0.0"
+    find-up "^3.0.0"
+    read-pkg "^3.0.0"
 
 read-pkg@^2.0.0:
   version "2.0.0"
@@ -7836,6 +8328,15 @@ read-pkg@^2.0.0:
     normalize-package-data "^2.3.2"
     path-type "^2.0.0"
 
+read-pkg@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389"
+  integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=
+  dependencies:
+    load-json-file "^4.0.0"
+    normalize-package-data "^2.3.2"
+    path-type "^3.0.0"
+
 "readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6:
   version "2.3.6"
   resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
@@ -7858,7 +8359,7 @@ readable-stream@^3.0.6:
     string_decoder "^1.1.1"
     util-deprecate "^1.0.1"
 
-readdirp@^2.0.0:
+readdirp@^2.2.1:
   version "2.2.1"
   resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525"
   integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==
@@ -7867,10 +8368,19 @@ readdirp@^2.0.0:
     micromatch "^3.1.10"
     readable-stream "^2.0.2"
 
-realpath-native@^1.0.0:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.0.2.tgz#cd51ce089b513b45cf9b1516c82989b51ccc6560"
-  integrity sha512-+S3zTvVt9yTntFrBpm7TQmQ3tzpCrnA1a/y+3cUHAc9ZR6aIjG0WNLR+Rj79QpJktY+VeW/TQtFlQ1bzsehI8g==
+readline2@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35"
+  integrity sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=
+  dependencies:
+    code-point-at "^1.0.0"
+    is-fullwidth-code-point "^1.0.0"
+    mute-stream "0.0.5"
+
+realpath-native@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c"
+  integrity sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA==
   dependencies:
     util.promisify "^1.0.0"
 
@@ -7911,14 +8421,19 @@ redux@^4.0.1:
     loose-envify "^1.4.0"
     symbol-observable "^1.2.0"
 
-regenerate-unicode-properties@^7.0.0:
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz#107405afcc4a190ec5ed450ecaa00ed0cafa7a4c"
-  integrity sha512-s5NGghCE4itSlUS+0WUj88G6cfMVMmH8boTPNvABf8od+2dhT9WDlWu8n01raQAJZMOK8Ch6jSexaRO7swd6aw==
+reflect.ownkeys@^0.2.0:
+  version "0.2.0"
+  resolved "https://registry.yarnpkg.com/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz#749aceec7f3fdf8b63f927a04809e90c5c0b3460"
+  integrity sha1-dJrO7H8/34tj+SegSAnpDFwLNGA=
+
+regenerate-unicode-properties@^8.0.2:
+  version "8.1.0"
+  resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e"
+  integrity sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==
   dependencies:
     regenerate "^1.4.0"
 
-regenerate@^1.2.1, regenerate@^1.4.0:
+regenerate@^1.4.0:
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
   integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==
@@ -7933,19 +8448,17 @@ regenerator-runtime@^0.12.0:
   resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de"
   integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==
 
-regenerator-transform@^0.13.3:
-  version "0.13.3"
-  resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.13.3.tgz#264bd9ff38a8ce24b06e0636496b2c856b57bcbb"
-  integrity sha512-5ipTrZFSq5vU2YoGoww4uaRVAK4wyYC4TSICibbfEPOruUu8FFP7ErV0BjmbIOEpn3O/k9na9UEdYR/3m7N6uA==
-  dependencies:
-    private "^0.1.6"
+regenerator-runtime@^0.13.2:
+  version "0.13.2"
+  resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz#32e59c9a6fb9b1a4aff09b4930ca2d4477343447"
+  integrity sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==
 
-regex-cache@^0.4.2:
-  version "0.4.4"
-  resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd"
-  integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==
+regenerator-transform@^0.14.0:
+  version "0.14.0"
+  resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.0.tgz#2ca9aaf7a2c239dd32e4761218425b8c7a86ecaf"
+  integrity sha512-rtOelq4Cawlbmq9xuMR5gdFmv7ku/sFoB7sRiywx7aq53bc52b4j6zvH7Te1Vt/X2YveDKnCGUbioieU7FEL3w==
   dependencies:
-    is-equal-shallow "^0.1.3"
+    private "^0.1.6"
 
 regex-not@^1.0.0, regex-not@^1.0.2:
   version "1.0.2"
@@ -7955,49 +8468,33 @@ regex-not@^1.0.0, regex-not@^1.0.2:
     extend-shallow "^3.0.2"
     safe-regex "^1.1.0"
 
+regexp-tree@^0.1.6:
+  version "0.1.10"
+  resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.10.tgz#d837816a039c7af8a8d64d7a7c3cf6a1d93450bc"
+  integrity sha512-K1qVSbcedffwuIslMwpe6vGlj+ZXRnGkvjAtFHfDZZZuEdA/h0dxljAPu9vhUo6Rrx2U2AwJ+nSQ6hK+lrP5MQ==
+
 regexpp@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f"
   integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==
 
-regexpu-core@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b"
-  integrity sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=
-  dependencies:
-    regenerate "^1.2.1"
-    regjsgen "^0.2.0"
-    regjsparser "^0.1.4"
-
-regexpu-core@^4.1.3, regexpu-core@^4.2.0:
-  version "4.4.0"
-  resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.4.0.tgz#8d43e0d1266883969720345e70c275ee0aec0d32"
-  integrity sha512-eDDWElbwwI3K0Lo6CqbQbA6FwgtCz4kYTarrri1okfkRLZAqstU+B3voZBCjg8Fl6iq0gXrJG6MvRgLthfvgOA==
+regexpu-core@^4.5.4:
+  version "4.5.4"
+  resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.5.4.tgz#080d9d02289aa87fe1667a4f5136bc98a6aebaae"
+  integrity sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ==
   dependencies:
     regenerate "^1.4.0"
-    regenerate-unicode-properties "^7.0.0"
+    regenerate-unicode-properties "^8.0.2"
     regjsgen "^0.5.0"
     regjsparser "^0.6.0"
     unicode-match-property-ecmascript "^1.0.4"
-    unicode-match-property-value-ecmascript "^1.0.2"
-
-regjsgen@^0.2.0:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7"
-  integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=
+    unicode-match-property-value-ecmascript "^1.1.0"
 
 regjsgen@^0.5.0:
   version "0.5.0"
   resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.0.tgz#a7634dc08f89209c2049adda3525711fb97265dd"
   integrity sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==
 
-regjsparser@^0.1.4:
-  version "0.1.5"
-  resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c"
-  integrity sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=
-  dependencies:
-    jsesc "~0.5.0"
-
 regjsparser@^0.6.0:
   version "0.6.0"
   resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.0.tgz#f1e6ae8b7da2bae96c99399b868cd6c933a2ba9c"
@@ -8005,10 +8502,10 @@ regjsparser@^0.6.0:
   dependencies:
     jsesc "~0.5.0"
 
-rellax@^1.7.1:
-  version "1.7.1"
-  resolved "https://registry.yarnpkg.com/rellax/-/rellax-1.7.1.tgz#2f82aaa1c1d8116eef08fc533c59655a097c8be2"
-  integrity sha512-z31r9RjKeK5wJU5C6hKBupreKQ7xi+lQHda6ttlc0N1VEyL2ZCPMyckTtvliGRsxqTPqhdCasdhexs8N5aZ4+A==
+rellax@^1.10.0:
+  version "1.10.0"
+  resolved "https://registry.yarnpkg.com/rellax/-/rellax-1.10.0.tgz#0308b813b458f9175d37ffb4272e1f616eab1341"
+  integrity sha512-BtxD9b8cAQcTs6iat1fqKvHMjIZ8CaxjsC5U/cIIVHC4LjkIsr0ZmeqxUm5ZvBvyjLwfPbU8Wcryp77sR5C8QA==
 
 remove-trailing-separator@^1.0.1:
   version "1.1.0"
@@ -8020,18 +8517,11 @@ repeat-element@^1.1.2:
   resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce"
   integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==
 
-repeat-string@^1.5.2, repeat-string@^1.6.1:
+repeat-string@^1.6.1:
   version "1.6.1"
   resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
   integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc=
 
-repeating@^2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda"
-  integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=
-  dependencies:
-    is-finite "^1.0.0"
-
 request-promise-core@1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6"
@@ -8099,7 +8589,7 @@ require-package-name@^2.0.1:
   resolved "https://registry.yarnpkg.com/require-package-name/-/require-package-name-2.0.1.tgz#c11e97276b65b8e2923f75dabf5fb2ef0c3841b9"
   integrity sha1-wR6XJ2tluOKSP3Xav1+y7ww4Qbk=
 
-require-uncached@^1.0.3:
+require-uncached@^1.0.2, require-uncached@^1.0.3:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3"
   integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=
@@ -8124,6 +8614,14 @@ resolve-cwd@^2.0.0:
   dependencies:
     resolve-from "^3.0.0"
 
+resolve-dir@^1.0.0, resolve-dir@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43"
+  integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=
+  dependencies:
+    expand-tilde "^2.0.0"
+    global-modules "^1.0.0"
+
 resolve-from@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226"
@@ -8149,13 +8647,21 @@ resolve@1.1.7:
   resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
   integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=
 
-resolve@^1.3.2, resolve@^1.5.0, resolve@^1.6.0, resolve@^1.8.1, resolve@^1.9.0:
-  version "1.9.0"
-  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.9.0.tgz#a14c6fdfa8f92a7df1d996cb7105fa744658ea06"
-  integrity sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==
+resolve@^1.10.0, resolve@^1.11.0, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.8.1, resolve@^1.9.0:
+  version "1.11.0"
+  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.0.tgz#4014870ba296176b86343d50b60f3b50609ce232"
+  integrity sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==
   dependencies:
     path-parse "^1.0.6"
 
+restore-cursor@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541"
+  integrity sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=
+  dependencies:
+    exit-hook "^1.0.0"
+    onetime "^1.0.0"
+
 restore-cursor@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
@@ -8179,12 +8685,12 @@ rgba-regex@^1.0.0:
   resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3"
   integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=
 
-rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.2:
-  version "2.6.2"
-  resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
-  integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==
+rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3, rimraf@~2.6.2:
+  version "2.6.3"
+  resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
+  integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==
   dependencies:
-    glob "^7.0.5"
+    glob "^7.1.3"
 
 ripemd160@^2.0.0, ripemd160@^2.0.1:
   version "2.0.2"
@@ -8207,6 +8713,13 @@ rsvp@^3.3.3:
   resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a"
   integrity sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw==
 
+run-async@^0.1.0:
+  version "0.1.0"
+  resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389"
+  integrity sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=
+  dependencies:
+    once "^1.3.0"
+
 run-async@^2.2.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
@@ -8221,6 +8734,11 @@ run-queue@^1.0.0, run-queue@^1.0.3:
   dependencies:
     aproba "^1.1.1"
 
+rx-lite@^3.1.2:
+  version "3.1.2"
+  resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102"
+  integrity sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=
+
 rxjs@^6.1.0:
   version "6.3.3"
   resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55"
@@ -8245,21 +8763,40 @@ safe-regex@^1.1.0:
   resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
   integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
 
-sane@^2.0.0:
-  version "2.5.2"
-  resolved "https://registry.yarnpkg.com/sane/-/sane-2.5.2.tgz#b4dc1861c21b427e929507a3e751e2a2cb8ab3fa"
-  integrity sha1-tNwYYcIbQn6SlQej51HiosuKs/o=
+sane@^4.0.3:
+  version "4.0.3"
+  resolved "https://registry.yarnpkg.com/sane/-/sane-4.0.3.tgz#e878c3f19e25cc57fbb734602f48f8a97818b181"
+  integrity sha512-hSLkC+cPHiBQs7LSyXkotC3UUtyn8C4FMn50TNaacRyvBlI+3ebcxMpqckmTdtXVtel87YS7GXN3UIOj7NiGVQ==
   dependencies:
+    "@cnakazawa/watch" "^1.0.3"
     anymatch "^2.0.0"
     capture-exit "^1.2.0"
-    exec-sh "^0.2.0"
+    exec-sh "^0.3.2"
+    execa "^1.0.0"
     fb-watchman "^2.0.0"
     micromatch "^3.1.4"
     minimist "^1.1.1"
     walker "~1.0.5"
-    watch "~0.18.0"
-  optionalDependencies:
-    fsevents "^1.2.3"
+
+sass-lint@^1.13.1:
+  version "1.13.1"
+  resolved "https://registry.yarnpkg.com/sass-lint/-/sass-lint-1.13.1.tgz#5fd2b2792e9215272335eb0f0dc607f61e8acc8f"
+  integrity sha512-DSyah8/MyjzW2BWYmQWekYEKir44BpLqrCFsgs9iaWiVTcwZfwXHF586hh3D1n+/9ihUNMfd8iHAyb9KkGgs7Q==
+  dependencies:
+    commander "^2.8.1"
+    eslint "^2.7.0"
+    front-matter "2.1.2"
+    fs-extra "^3.0.1"
+    glob "^7.0.0"
+    globule "^1.0.0"
+    gonzales-pe-sl "^4.2.3"
+    js-yaml "^3.5.4"
+    known-css-properties "^0.3.0"
+    lodash.capitalize "^4.1.0"
+    lodash.kebabcase "^4.0.0"
+    merge "^1.2.0"
+    path-is-absolute "^1.0.0"
+    util "^0.10.3"
 
 sass-loader@^7.0.3:
   version "7.1.0"
@@ -8273,10 +8810,10 @@ sass-loader@^7.0.3:
     pify "^3.0.0"
     semver "^5.5.0"
 
-sass@^1.15.2:
-  version "1.15.2"
-  resolved "https://registry.yarnpkg.com/sass/-/sass-1.15.2.tgz#539f464a61e29a9e4f560ec9dc2ccc5236db8474"
-  integrity sha512-YFncPpx3ewKEhMg9sWdCxKUpPN/jwVLa0Q9iO2tcV5Y5Z/YAlFV6k6JaQwq3tmbN6FXKjUYElXRHcG0g4D1zkQ==
+sass@^1.20.3:
+  version "1.20.3"
+  resolved "https://registry.yarnpkg.com/sass/-/sass-1.20.3.tgz#18284a7bac6eab9cbb80453288473194f29efb84"
+  integrity sha512-kvf+w5XT7FrmFrCKz1gPHqegufG+gxifC8oQesX/s8gkShdeiTqiuvP0c8TvfBwMAuI1YGOgobZQ2KIJGn//jA==
   dependencies:
     chokidar "^2.0.0"
 
@@ -8285,22 +8822,14 @@ sax@^1.2.4, sax@~1.2.4:
   resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
   integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
 
-scheduler@^0.12.0:
-  version "0.12.0"
-  resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.12.0.tgz#8ab17699939c0aedc5a196a657743c496538647b"
-  integrity sha512-t7MBR28Akcp4Jm+QoR63XgAi9YgCUmgvDHqf5otgAj4QvdoBE4ImCX0ffehefePPG+aitiYHp0g/mW6s4Tp+dw==
+scheduler@^0.13.6:
+  version "0.13.6"
+  resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.6.tgz#466a4ec332467b31a91b9bf74e5347072e4cd889"
+  integrity sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==
   dependencies:
     loose-envify "^1.1.0"
     object-assign "^4.1.1"
 
-schema-utils@^0.4.4:
-  version "0.4.7"
-  resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187"
-  integrity sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==
-  dependencies:
-    ajv "^6.1.0"
-    ajv-keywords "^3.1.0"
-
 schema-utils@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770"
@@ -8323,27 +8852,32 @@ select-hose@^2.0.0:
   resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
   integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=
 
-selfsigned@^1.9.1:
+selfsigned@^1.10.4:
   version "1.10.4"
   resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.4.tgz#cdd7eccfca4ed7635d47a08bf2d5d3074092e2cd"
   integrity sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw==
   dependencies:
     node-forge "0.7.5"
 
-"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0:
-  version "5.6.0"
-  resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004"
-  integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==
+"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0:
+  version "5.7.0"
+  resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b"
+  integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==
 
 semver@4.3.2:
   version "4.3.2"
   resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.2.tgz#c7a07158a80bedd052355b770d82d6640f803be7"
   integrity sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c=
 
-send@0.16.2:
-  version "0.16.2"
-  resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1"
-  integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==
+semver@^6.1.0, semver@^6.1.1:
+  version "6.1.1"
+  resolved "https://registry.yarnpkg.com/semver/-/semver-6.1.1.tgz#53f53da9b30b2103cd4f15eab3a18ecbcb210c9b"
+  integrity sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==
+
+send@0.17.1:
+  version "0.17.1"
+  resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8"
+  integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==
   dependencies:
     debug "2.6.9"
     depd "~1.1.2"
@@ -8352,19 +8886,24 @@ send@0.16.2:
     escape-html "~1.0.3"
     etag "~1.8.1"
     fresh "0.5.2"
-    http-errors "~1.6.2"
-    mime "1.4.1"
-    ms "2.0.0"
+    http-errors "~1.7.2"
+    mime "1.6.0"
+    ms "2.1.1"
     on-finished "~2.3.0"
-    range-parser "~1.2.0"
-    statuses "~1.4.0"
+    range-parser "~1.2.1"
+    statuses "~1.5.0"
 
 serialize-javascript@^1.4.0:
   version "1.6.1"
   resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.6.1.tgz#4d1f697ec49429a847ca6f442a2a755126c4d879"
   integrity sha512-A5MOagrPFga4YaKQSWHryl7AXvbQkEqpw4NNYMTNYUNV51bA8ABHgYFpqKx+YFFrw59xMV1qGH1R4AgoNIVgCw==
 
-serve-index@^1.7.2:
+serialize-javascript@^1.7.0:
+  version "1.7.0"
+  resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.7.0.tgz#d6e0dfb2a3832a8c94468e6eb1db97e55a192a65"
+  integrity sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA==
+
+serve-index@^1.9.1:
   version "1.9.1"
   resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239"
   integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=
@@ -8377,15 +8916,15 @@ serve-index@^1.7.2:
     mime-types "~2.1.17"
     parseurl "~1.3.2"
 
-serve-static@1.13.2:
-  version "1.13.2"
-  resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1"
-  integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==
+serve-static@1.14.1:
+  version "1.14.1"
+  resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9"
+  integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==
   dependencies:
     encodeurl "~1.0.2"
     escape-html "~1.0.3"
-    parseurl "~1.3.2"
-    send "0.16.2"
+    parseurl "~1.3.3"
+    send "0.17.1"
 
 set-blocking@^2.0.0, set-blocking@~2.0.0:
   version "2.0.0"
@@ -8422,6 +8961,11 @@ setprototypeof@1.1.0:
   resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
   integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==
 
+setprototypeof@1.1.1:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683"
+  integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==
+
 sha.js@^2.4.0, sha.js@^2.4.8:
   version "2.4.11"
   resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7"
@@ -8451,6 +8995,11 @@ shebang-regex@^1.0.0:
   resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
   integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
 
+shelljs@^0.6.0:
+  version "0.6.1"
+  resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.6.1.tgz#ec6211bed1920442088fe0f70b2837232ed2c8a8"
+  integrity sha1-7GIRvtGSBEIIj+D3Cyg3Iy7SyKg=
+
 shellwords@^0.1.1:
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
@@ -8468,16 +9017,26 @@ simple-swizzle@^0.2.2:
   dependencies:
     is-arrayish "^0.3.1"
 
-sisteransi@^0.1.1:
-  version "0.1.1"
-  resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-0.1.1.tgz#5431447d5f7d1675aac667ccd0b865a4994cb3ce"
-  integrity sha512-PmGOd02bM9YO5ifxpw36nrNMBTptEtfRl4qUYl9SndkolplkrZZOW7PGHjrZL53QvMVj9nQ+TKqUnRsw4tJa4g==
+sisteransi@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.0.tgz#77d9622ff909080f1c19e5f4a1df0c1b0a27b88c"
+  integrity sha512-N+z4pHB4AmUv0SjveWRd6q1Nj5w62m5jodv+GD8lvmbY/83T/rpbJGZOnK5T149OldDj4Db07BSv9xY4K6NTPQ==
 
 slash@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
   integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=
 
+slash@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44"
+  integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==
+
+slice-ansi@0.0.4:
+  version "0.0.4"
+  resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
+  integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=
+
 slice-ansi@2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.0.0.tgz#5373bdb8559b45676e8541c66916cdd6251612e7"
@@ -8553,14 +9112,7 @@ source-map-resolve@^0.5.0:
     source-map-url "^0.4.0"
     urix "^0.1.0"
 
-source-map-support@^0.4.15:
-  version "0.4.18"
-  resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f"
-  integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==
-  dependencies:
-    source-map "^0.5.6"
-
-source-map-support@^0.5.6, source-map-support@~0.5.6:
+source-map-support@^0.5.6:
   version "0.5.9"
   resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f"
   integrity sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==
@@ -8568,6 +9120,14 @@ source-map-support@^0.5.6, source-map-support@~0.5.6:
     buffer-from "^1.0.0"
     source-map "^0.6.0"
 
+source-map-support@~0.5.10:
+  version "0.5.12"
+  resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599"
+  integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==
+  dependencies:
+    buffer-from "^1.0.0"
+    source-map "^0.6.0"
+
 source-map-url@^0.4.0:
   version "0.4.0"
   resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
@@ -8583,6 +9143,11 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
   resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
   integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
 
+source-map@^0.7.2:
+  version "0.7.3"
+  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
+  integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
+
 spdx-correct@^3.0.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4"
@@ -8691,16 +9256,11 @@ static-extend@^0.1.1:
     define-property "^0.2.5"
     object-copy "^0.1.0"
 
-"statuses@>= 1.4.0 < 2":
+"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0:
   version "1.5.0"
   resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
   integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
 
-statuses@~1.4.0:
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087"
-  integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==
-
 stealthy-require@^1.1.0:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b"
@@ -8814,18 +9374,11 @@ strip-ansi@^5.0.0:
   dependencies:
     ansi-regex "^4.0.0"
 
-strip-bom@3.0.0, strip-bom@^3.0.0:
+strip-bom@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
   integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=
 
-strip-bom@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e"
-  integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=
-  dependencies:
-    is-utf8 "^0.2.0"
-
 strip-eof@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
@@ -8836,13 +9389,10 @@ strip-json-comments@^2.0.1, strip-json-comments@~2.0.1:
   resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
   integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
 
-style-loader@0.23.1:
-  version "0.23.1"
-  resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.23.1.tgz#cb9154606f3e771ab6c4ab637026a1049174d925"
-  integrity sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg==
-  dependencies:
-    loader-utils "^1.1.0"
-    schema-utils "^1.0.0"
+strip-json-comments@~1.0.1:
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91"
+  integrity sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=
 
 stylehacks@^4.0.0:
   version "4.0.1"
@@ -8853,6 +9403,16 @@ stylehacks@^4.0.0:
     postcss "^7.0.0"
     postcss-selector-parser "^3.0.0"
 
+stylis-rule-sheet@^0.0.10:
+  version "0.0.10"
+  resolved "https://registry.yarnpkg.com/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz#44e64a2b076643f4b52e5ff71efc04d8c3c4a430"
+  integrity sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw==
+
+stylis@^3.5.0:
+  version "3.5.4"
+  resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe"
+  integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==
+
 substring-trie@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/substring-trie/-/substring-trie-1.0.2.tgz#7b42592391628b4f2cb17365c6cce4257c7b7af5"
@@ -8863,20 +9423,27 @@ supports-color@^2.0.0:
   resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
   integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
 
-supports-color@^3.1.2, supports-color@^3.2.3:
+supports-color@^3.2.3:
   version "3.2.3"
   resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6"
   integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=
   dependencies:
     has-flag "^1.0.0"
 
-supports-color@^5.1.0, supports-color@^5.3.0, supports-color@^5.5.0:
+supports-color@^5.3.0, supports-color@^5.5.0:
   version "5.5.0"
   resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
   integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
   dependencies:
     has-flag "^3.0.0"
 
+supports-color@^6.0.0, supports-color@^6.1.0:
+  version "6.1.0"
+  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3"
+  integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==
+  dependencies:
+    has-flag "^3.0.0"
+
 svgo@^1.0.0:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.1.1.tgz#12384b03335bcecd85cfa5f4e3375fed671cb985"
@@ -8907,6 +9474,18 @@ symbol-tree@^3.2.2:
   resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6"
   integrity sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=
 
+table@^3.7.8:
+  version "3.8.3"
+  resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f"
+  integrity sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=
+  dependencies:
+    ajv "^4.7.0"
+    ajv-keywords "^1.0.0"
+    chalk "^1.1.1"
+    lodash "^4.0.0"
+    slice-ansi "0.0.4"
+    string-width "^2.0.0"
+
 table@^5.0.2:
   version "5.1.1"
   resolved "https://registry.yarnpkg.com/table/-/table-5.1.1.tgz#92030192f1b7b51b6eeab23ed416862e47b70837"
@@ -8940,41 +9519,42 @@ tcomb@^2.5.0:
   resolved "https://registry.yarnpkg.com/tcomb/-/tcomb-2.7.0.tgz#10d62958041669a5d53567b9a4ee8cde22b1c2b0"
   integrity sha1-ENYpWAQWaaXVNWe5pO6M3iKxwrA=
 
-terser-webpack-plugin@^1.1.0:
-  version "1.2.1"
-  resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.2.1.tgz#7545da9ae5f4f9ae6a0ac961eb46f5e7c845cc26"
-  integrity sha512-GGSt+gbT0oKcMDmPx4SRSfJPE1XaN3kQRWG4ghxKQw9cn5G9x6aCKSsgYdvyM0na9NJ4Drv0RG6jbBByZ5CMjw==
+terser-webpack-plugin@^1.1.0, terser-webpack-plugin@^1.3.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.3.0.tgz#69aa22426299f4b5b3775cbed8cb2c5d419aa1d4"
+  integrity sha512-W2YWmxPjjkUcOWa4pBEv4OP4er1aeQJlSo2UhtCFQCuRXEHjOFscO8VyWHj9JLlA0RzQb8Y2/Ta78XZvT54uGg==
   dependencies:
-    cacache "^11.0.2"
+    cacache "^11.3.2"
     find-cache-dir "^2.0.0"
+    is-wsl "^1.1.0"
+    loader-utils "^1.2.3"
     schema-utils "^1.0.0"
-    serialize-javascript "^1.4.0"
+    serialize-javascript "^1.7.0"
     source-map "^0.6.1"
-    terser "^3.8.1"
-    webpack-sources "^1.1.0"
-    worker-farm "^1.5.2"
+    terser "^4.0.0"
+    webpack-sources "^1.3.0"
+    worker-farm "^1.7.0"
 
-terser@^3.8.1:
-  version "3.14.0"
-  resolved "https://registry.yarnpkg.com/terser/-/terser-3.14.0.tgz#49a8ddf34a1308a901d787dab03a42c51b557447"
-  integrity sha512-KQC1QNKbC/K1ZUjLIWsezW7wkTJuB4v9ptQQUNOzAPVHuVf2LrwEcB0I9t2HTEYUwAFVGiiS6wc+P4ClLDc5FQ==
+terser@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/terser/-/terser-4.0.0.tgz#ef356f6f359a963e2cc675517f21c1c382877374"
+  integrity sha512-dOapGTU0hETFl1tCo4t56FN+2jffoKyER9qBGoUFyZ6y7WLoKT0bF+lAYi6B6YsILcGF3q1C2FBh8QcKSCgkgA==
   dependencies:
-    commander "~2.17.1"
+    commander "^2.19.0"
     source-map "~0.6.1"
-    source-map-support "~0.5.6"
+    source-map-support "~0.5.10"
 
-test-exclude@^4.2.1:
-  version "4.2.3"
-  resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.3.tgz#a9a5e64474e4398339245a0a769ad7c2f4a97c20"
-  integrity sha512-SYbXgY64PT+4GAL2ocI3HwPa4Q4TBKm0cwAVeKOt/Aoc0gSpNRjJX8w0pA1LMKZ3LBmd8pYBqApFNQLII9kavA==
+test-exclude@^5.0.0:
+  version "5.1.0"
+  resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.1.0.tgz#6ba6b25179d2d38724824661323b73e03c0c1de1"
+  integrity sha512-gwf0S2fFsANC55fSeSqpb8BYk6w3FDvwZxfNjeF6FRgvFa43r+7wRiA/Q0IxoRU37wB/LE8IQ4221BsNucTaCA==
   dependencies:
     arrify "^1.0.1"
-    micromatch "^2.3.11"
-    object-assign "^4.1.0"
-    read-pkg-up "^1.0.1"
+    minimatch "^3.0.4"
+    read-pkg-up "^4.0.0"
     require-main-filename "^1.0.1"
 
-text-table@^0.2.0:
+text-table@^0.2.0, text-table@~0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
   integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
@@ -9043,11 +9623,6 @@ to-arraybuffer@^1.0.0:
   resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
   integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=
 
-to-fast-properties@^1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"
-  integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=
-
 to-fast-properties@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
@@ -9078,6 +9653,18 @@ to-regex@^3.0.1, to-regex@^3.0.2:
     regex-not "^1.0.2"
     safe-regex "^1.1.0"
 
+toidentifier@1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
+  integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
+
+touch@^2.0.1:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/touch/-/touch-2.0.2.tgz#ca0b2a3ae3211246a61b16ba9e6cbf1596287164"
+  integrity sha512-qjNtvsFXTRq7IuMLweVgFxmEuQ6gLbRs2jQxL80TtZ31dEKWYIxRXquij6w6VimyDek5hD3PytljHmEtAs2u0A==
+  dependencies:
+    nopt "~1.0.10"
+
 tough-cookie@>=2.3.3, tough-cookie@^2.3.4:
   version "2.5.0"
   resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
@@ -9140,13 +9727,13 @@ type-check@~0.3.2:
   dependencies:
     prelude-ls "~1.1.2"
 
-type-is@~1.6.16:
-  version "1.6.16"
-  resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194"
-  integrity sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==
+type-is@~1.6.17, type-is@~1.6.18:
+  version "1.6.18"
+  resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
+  integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
   dependencies:
     media-typer "0.3.0"
-    mime-types "~2.1.18"
+    mime-types "~2.1.24"
 
 typedarray@^0.0.6:
   version "0.0.6"
@@ -9158,7 +9745,7 @@ ua-parser-js@^0.7.18:
   resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.19.tgz#94151be4c0a7fb1d001af7022fdaca4642659e4b"
   integrity sha512-T3PVJ6uz8i0HzPxOF9SWzWAlfN/DavlpQqepn22xgve/5QecC+XMCAtmUNnY7C9StehaV6exjUCI801lOI7QlQ==
 
-uglify-js@^3.0.0, uglify-js@^3.1.4:
+uglify-js@^3.1.4:
   version "3.4.9"
   resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3"
   integrity sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==
@@ -9166,20 +9753,6 @@ uglify-js@^3.0.0, uglify-js@^3.1.4:
     commander "~2.17.1"
     source-map "~0.6.1"
 
-uglifyjs-webpack-plugin@^2.1.1:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-2.1.1.tgz#6937d7513a37280d4792f1fb536bef35e08e420a"
-  integrity sha512-TQEcyMNkObX/H+FfcKjiDgs5RcXX8vW2UUUrDTOfQgg3lrafztfeM5WAwXo+AzqozJK6NP9w98xNpG/dutzSsg==
-  dependencies:
-    cacache "^11.2.0"
-    find-cache-dir "^2.0.0"
-    schema-utils "^1.0.0"
-    serialize-javascript "^1.4.0"
-    source-map "^0.6.1"
-    uglify-js "^3.0.0"
-    webpack-sources "^1.1.0"
-    worker-farm "^1.5.2"
-
 unicode-astral-regex@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/unicode-astral-regex/-/unicode-astral-regex-1.0.1.tgz#2cab8529480646f9614ddbc7b62158ad05123feb"
@@ -9198,15 +9771,15 @@ unicode-match-property-ecmascript@^1.0.4:
     unicode-canonical-property-names-ecmascript "^1.0.4"
     unicode-property-aliases-ecmascript "^1.0.4"
 
-unicode-match-property-value-ecmascript@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.2.tgz#9f1dc76926d6ccf452310564fd834ace059663d4"
-  integrity sha512-Rx7yODZC1L/T8XKo/2kNzVAQaRE88AaMvI1EF/Xnj3GW2wzN6fop9DDWuFAKUVFH7vozkz26DzP0qyWLKLIVPQ==
+unicode-match-property-value-ecmascript@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz#5b4b426e08d13a80365e0d657ac7a6c1ec46a277"
+  integrity sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==
 
 unicode-property-aliases-ecmascript@^1.0.4:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.4.tgz#5a533f31b4317ea76f17d807fa0d116546111dd0"
-  integrity sha512-2WSLa6OdYd2ng8oqiGIWnJqyFArvhn+5vgx5GTxMbUYjCYKUcuKS62YLFF0R/BDGlB1yzXjQOLtPAfHsgirEpg==
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz#a9cc6cc7ce63a0a3023fc99e341b94431d405a57"
+  integrity sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==
 
 union-value@^1.0.0:
   version "1.0.0"
@@ -9242,6 +9815,11 @@ unique-slug@^2.0.0:
   dependencies:
     imurmurhash "^0.1.4"
 
+universalify@^0.1.0:
+  version "0.1.2"
+  resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
+  integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
+
 unpipe@1.0.0, unpipe@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
@@ -9260,10 +9838,10 @@ unset-value@^1.0.0:
     has-value "^0.3.1"
     isobject "^3.0.0"
 
-upath@^1.0.5:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd"
-  integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==
+upath@^1.1.1:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068"
+  integrity sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==
 
 uri-js@^4.2.2:
   version "4.2.2"
@@ -9298,6 +9876,13 @@ use@^3.1.0:
   resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
   integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==
 
+user-home@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f"
+  integrity sha1-nHC/2Babwdy/SGBODwS4tJzenp8=
+  dependencies:
+    os-homedir "^1.0.0"
+
 util-deprecate@^1.0.1, util-deprecate@~1.0.1:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
@@ -9335,11 +9920,6 @@ uuid@^3.0.1, uuid@^3.1.0, uuid@^3.3.2:
   resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
   integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
 
-uws@10.148.0:
-  version "10.148.0"
-  resolved "https://registry.yarnpkg.com/uws/-/uws-10.148.0.tgz#3fcd35f083ca515e091cd33b2d78f0f51a666215"
-  integrity sha512-aJpFgMMyxubiE/ll4nj9nWoQbv0HzZZDWXfwyu78nuFObX0Zoyv3TWjkqKPQ1vb2sMPZoz67tri7QNE6dybNmQ==
-
 v8-compile-cache@^2.0.2:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.2.tgz#a428b28bb26790734c4fc8bc9fa106fccebf6a6c"
@@ -9391,7 +9971,7 @@ w3c-hr-time@^1.0.1:
   dependencies:
     browser-process-hrtime "^0.1.2"
 
-walker@~1.0.5:
+walker@^1.0.7, walker@~1.0.5:
   version "1.0.7"
   resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb"
   integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=
@@ -9412,14 +9992,6 @@ warning@^4.0.1:
   dependencies:
     loose-envify "^1.0.0"
 
-watch@~0.18.0:
-  version "0.18.0"
-  resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986"
-  integrity sha1-KAlUdsbffJDJYxOJkMClQj60uYY=
-  dependencies:
-    exec-sh "^0.2.0"
-    minimist "^1.2.0"
-
 watchpack@^1.5.0:
   version "1.6.0"
   resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00"
@@ -9454,12 +10026,13 @@ webpack-assets-manifest@^3.1.1:
     tapable "^1.0.0"
     webpack-sources "^1.0.0"
 
-webpack-bundle-analyzer@^3.0.3:
-  version "3.0.3"
-  resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.0.3.tgz#dbc7fff8f52058b6714a20fddf309d0790e3e0a0"
-  integrity sha512-naLWiRfmtH4UJgtUktRTLw6FdoZJ2RvCR9ePbwM9aRMsS/KjFerkPZG9epEvXRAw5d5oPdrs9+3p+afNjxW8Xw==
+webpack-bundle-analyzer@^3.3.2:
+  version "3.3.2"
+  resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.3.2.tgz#3da733a900f515914e729fcebcd4c40dde71fc6f"
+  integrity sha512-7qvJLPKB4rRWZGjVp5U1KEjwutbDHSKboAl0IfafnrdXMrgC0tOtZbQD6Rw0u4cmpgRN4O02Fc0t8eAT+FgGzA==
   dependencies:
-    acorn "^5.7.3"
+    acorn "^6.0.7"
+    acorn-walk "^6.1.1"
     bfj "^6.1.1"
     chalk "^2.4.1"
     commander "^2.18.0"
@@ -9472,67 +10045,69 @@ webpack-bundle-analyzer@^3.0.3:
     opener "^1.5.1"
     ws "^6.0.0"
 
-webpack-cli@^3.1.2:
-  version "3.1.2"
-  resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.1.2.tgz#17d7e01b77f89f884a2bbf9db545f0f6a648e746"
-  integrity sha512-Cnqo7CeqeSvC6PTdts+dywNi5CRlIPbLx1AoUPK2T6vC1YAugMG3IOoO9DmEscd+Dghw7uRlnzV1KwOe5IrtgQ==
+webpack-cli@^3.3.4:
+  version "3.3.4"
+  resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.4.tgz#de27e281c48a897b8c219cb093e261d5f6afe44a"
+  integrity sha512-ubJGQEKMtBSpT+LiL5hXvn2GIOWiRWItR1DGUqJRhwRBeGhpRXjvF5f0erqdRJLErkfqS5/Ldkkedh4AL5Q1ZQ==
   dependencies:
     chalk "^2.4.1"
     cross-spawn "^6.0.5"
     enhanced-resolve "^4.1.0"
-    global-modules-path "^2.3.0"
+    findup-sync "^2.0.0"
+    global-modules "^1.0.0"
     import-local "^2.0.0"
     interpret "^1.1.0"
     loader-utils "^1.1.0"
+    prettier "^1.17.0"
     supports-color "^5.5.0"
     v8-compile-cache "^2.0.2"
-    yargs "^12.0.2"
+    yargs "^12.0.5"
 
-webpack-dev-middleware@3.4.0:
-  version "3.4.0"
-  resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.4.0.tgz#1132fecc9026fd90f0ecedac5cbff75d1fb45890"
-  integrity sha512-Q9Iyc0X9dP9bAsYskAVJ/hmIZZQwf/3Sy4xCAZgL5cUkjZmUZLt4l5HpbST/Pdgjn3u6pE7u5OdGd1apgzRujA==
+webpack-dev-middleware@^3.7.0:
+  version "3.7.0"
+  resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.0.tgz#ef751d25f4e9a5c8a35da600c5fda3582b5c6cff"
+  integrity sha512-qvDesR1QZRIAZHOE3iQ4CXLZZSQ1lAUsSpnQmlB1PBfoN/xdRjmge3Dok0W4IdaVLJOGJy3sGI4sZHwjRU0PCA==
   dependencies:
-    memory-fs "~0.4.1"
-    mime "^2.3.1"
-    range-parser "^1.0.3"
+    memory-fs "^0.4.1"
+    mime "^2.4.2"
+    range-parser "^1.2.1"
     webpack-log "^2.0.0"
 
-webpack-dev-server@^3.1.14:
-  version "3.1.14"
-  resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.1.14.tgz#60fb229b997fc5a0a1fc6237421030180959d469"
-  integrity sha512-mGXDgz5SlTxcF3hUpfC8hrQ11yhAttuUQWf1Wmb+6zo3x6rb7b9mIfuQvAPLdfDRCGRGvakBWHdHOa0I9p/EVQ==
+webpack-dev-server@^3.5.1:
+  version "3.5.1"
+  resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.5.1.tgz#4290ac709bb989dc7382c912899f79fd5677dabf"
+  integrity sha512-0IdMGddJcnK9zesZOeHWl4uAOVfypn7DSrdNWtclROkVBXy/TcBN+6eEG1wNfLT9dXVfaRZZsLTJt0mJtgTQgw==
   dependencies:
     ansi-html "0.0.7"
     bonjour "^3.5.0"
-    chokidar "^2.0.0"
-    compression "^1.5.2"
-    connect-history-api-fallback "^1.3.0"
-    debug "^3.1.0"
-    del "^3.0.0"
-    express "^4.16.2"
-    html-entities "^1.2.0"
-    http-proxy-middleware "~0.18.0"
+    chokidar "^2.1.6"
+    compression "^1.7.4"
+    connect-history-api-fallback "^1.6.0"
+    debug "^4.1.1"
+    del "^4.1.1"
+    express "^4.17.1"
+    html-entities "^1.2.1"
+    http-proxy-middleware "^0.19.1"
     import-local "^2.0.0"
-    internal-ip "^3.0.1"
+    internal-ip "^4.3.0"
     ip "^1.1.5"
-    killable "^1.0.0"
-    loglevel "^1.4.1"
-    opn "^5.1.0"
-    portfinder "^1.0.9"
+    killable "^1.0.1"
+    loglevel "^1.6.2"
+    opn "^5.5.0"
+    portfinder "^1.0.20"
     schema-utils "^1.0.0"
-    selfsigned "^1.9.1"
-    semver "^5.6.0"
-    serve-index "^1.7.2"
+    selfsigned "^1.10.4"
+    semver "^6.1.1"
+    serve-index "^1.9.1"
     sockjs "0.3.19"
     sockjs-client "1.3.0"
     spdy "^4.0.0"
-    strip-ansi "^3.0.0"
-    supports-color "^5.1.0"
+    strip-ansi "^3.0.1"
+    supports-color "^6.1.0"
     url "^0.11.0"
-    webpack-dev-middleware "3.4.0"
+    webpack-dev-middleware "^3.7.0"
     webpack-log "^2.0.0"
-    yargs "12.0.2"
+    yargs "12.0.5"
 
 webpack-log@^2.0.0:
   version "2.0.0"
@@ -9542,10 +10117,10 @@ webpack-log@^2.0.0:
     ansi-colors "^3.0.0"
     uuid "^3.3.2"
 
-webpack-merge@^4.1.5:
-  version "4.1.5"
-  resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.1.5.tgz#2be31e846c20767d1bef56bdca64c328a681190a"
-  integrity sha512-sVcM+MMJv6DO0C0GLLltx8mUlGMKXE0zBsuMqZ9jz2X9gsekALw6Rs0cAfTWc97VuWS6NpVUa78959zANnMMLQ==
+webpack-merge@^4.2.1:
+  version "4.2.1"
+  resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.1.tgz#5e923cf802ea2ace4fd5af1d3247368a633489b4"
+  integrity sha512-4p8WQyS98bUJcCvFMbdGZyZmsKuWjWVnVHnAS3FFg0HDaRVrPbkivx2RYCre8UiemD67RsiFFLfn4JhLAin8Vw==
   dependencies:
     lodash "^4.17.5"
 
@@ -9557,17 +10132,17 @@ webpack-sources@^1.0.0, webpack-sources@^1.0.1, webpack-sources@^1.1.0, webpack-
     source-list-map "^2.0.0"
     source-map "~0.6.1"
 
-webpack@^4.28.3:
-  version "4.28.3"
-  resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.28.3.tgz#8acef6e77fad8a01bfd0c2b25aa3636d46511874"
-  integrity sha512-vLZN9k5I7Nr/XB1IDG9GbZB4yQd1sPuvufMFgJkx0b31fi2LD97KQIjwjxE7xytdruAYfu5S0FLBLjdxmwGJCg==
-  dependencies:
-    "@webassemblyjs/ast" "1.7.11"
-    "@webassemblyjs/helper-module-context" "1.7.11"
-    "@webassemblyjs/wasm-edit" "1.7.11"
-    "@webassemblyjs/wasm-parser" "1.7.11"
-    acorn "^5.6.2"
-    acorn-dynamic-import "^3.0.0"
+webpack@^4.34.0:
+  version "4.34.0"
+  resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.34.0.tgz#a4c30129482f7b4ece4c0842002dedf2b56fab58"
+  integrity sha512-ry2IQy1wJjOefLe1uJLzn5tG/DdIKzQqNlIAd2L84kcaADqNvQDTBlo8UcCNyDaT5FiaB+16jhAkb63YeG3H8Q==
+  dependencies:
+    "@webassemblyjs/ast" "1.8.5"
+    "@webassemblyjs/helper-module-context" "1.8.5"
+    "@webassemblyjs/wasm-edit" "1.8.5"
+    "@webassemblyjs/wasm-parser" "1.8.5"
+    acorn "^6.0.5"
+    acorn-dynamic-import "^4.0.0"
     ajv "^6.1.0"
     ajv-keywords "^3.1.0"
     chrome-trace-event "^1.0.0"
@@ -9581,7 +10156,7 @@ webpack@^4.28.3:
     mkdirp "~0.5.0"
     neo-async "^2.5.0"
     node-libs-browser "^2.0.0"
-    schema-utils "^0.4.4"
+    schema-utils "^1.0.0"
     tapable "^1.1.0"
     terser-webpack-plugin "^1.1.0"
     watchpack "^1.5.0"
@@ -9647,7 +10222,7 @@ which-module@^2.0.0:
   resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
   integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
 
-which@^1.2.12, which@^1.2.9, which@^1.3.0:
+which@^1.2.14, which@^1.2.9, which@^1.3.0:
   version "1.3.1"
   resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
   integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
@@ -9671,10 +10246,10 @@ wordwrap@~1.0.0:
   resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
   integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=
 
-worker-farm@^1.5.2:
-  version "1.6.0"
-  resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.6.0.tgz#aecc405976fab5a95526180846f0dba288f3a4a0"
-  integrity sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==
+worker-farm@^1.7.0:
+  version "1.7.0"
+  resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8"
+  integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==
   dependencies:
     errno "~0.1.7"
 
@@ -9691,10 +10266,10 @@ wrappy@1:
   resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
   integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
 
-write-file-atomic@^2.1.0:
-  version "2.3.0"
-  resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab"
-  integrity sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==
+write-file-atomic@2.4.1:
+  version "2.4.1"
+  resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.1.tgz#d0b05463c188ae804396fd5ab2a370062af87529"
+  integrity sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==
   dependencies:
     graceful-fs "^4.1.11"
     imurmurhash "^0.1.4"
@@ -9726,43 +10301,21 @@ xml-name-validator@^3.0.0:
   resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
   integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
 
-xregexp@4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.0.0.tgz#e698189de49dd2a18cc5687b05e17c8e43943020"
-  integrity sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg==
-
 xtend@^4.0.0, xtend@~4.0.1:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
   integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68=
 
-y18n@^3.2.1:
-  version "3.2.1"
-  resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
-  integrity sha1-bRX7qITAhnnA136I53WegR4H+kE=
-
 "y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
   integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
 
-yallist@^2.1.2:
-  version "2.1.2"
-  resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
-  integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=
-
 yallist@^3.0.0, yallist@^3.0.2:
   version "3.0.3"
   resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9"
   integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==
 
-yargs-parser@^10.1.0:
-  version "10.1.0"
-  resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8"
-  integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==
-  dependencies:
-    camelcase "^4.1.0"
-
 yargs-parser@^11.1.1:
   version "11.1.1"
   resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4"
@@ -9771,57 +10324,7 @@ yargs-parser@^11.1.1:
     camelcase "^5.0.0"
     decamelize "^1.2.0"
 
-yargs-parser@^7.0.0:
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9"
-  integrity sha1-jQrELxbqVd69MyyvTEA4s+P139k=
-  dependencies:
-    camelcase "^4.1.0"
-
-yargs-parser@^9.0.2:
-  version "9.0.2"
-  resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077"
-  integrity sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=
-  dependencies:
-    camelcase "^4.1.0"
-
-yargs@12.0.2:
-  version "12.0.2"
-  resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.2.tgz#fe58234369392af33ecbef53819171eff0f5aadc"
-  integrity sha512-e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ==
-  dependencies:
-    cliui "^4.0.0"
-    decamelize "^2.0.0"
-    find-up "^3.0.0"
-    get-caller-file "^1.0.1"
-    os-locale "^3.0.0"
-    require-directory "^2.1.1"
-    require-main-filename "^1.0.1"
-    set-blocking "^2.0.0"
-    string-width "^2.0.0"
-    which-module "^2.0.0"
-    y18n "^3.2.1 || ^4.0.0"
-    yargs-parser "^10.1.0"
-
-yargs@^11.0.0:
-  version "11.1.0"
-  resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77"
-  integrity sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==
-  dependencies:
-    cliui "^4.0.0"
-    decamelize "^1.1.1"
-    find-up "^2.1.0"
-    get-caller-file "^1.0.1"
-    os-locale "^2.0.0"
-    require-directory "^2.1.1"
-    require-main-filename "^1.0.1"
-    set-blocking "^2.0.0"
-    string-width "^2.0.0"
-    which-module "^2.0.0"
-    y18n "^3.2.1"
-    yargs-parser "^9.0.2"
-
-yargs@^12.0.2:
+yargs@12.0.5, yargs@^12.0.2, yargs@^12.0.5:
   version "12.0.5"
   resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13"
   integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==
@@ -9838,22 +10341,3 @@ yargs@^12.0.2:
     which-module "^2.0.0"
     y18n "^3.2.1 || ^4.0.0"
     yargs-parser "^11.1.1"
-
-yargs@^8.0.2:
-  version "8.0.2"
-  resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360"
-  integrity sha1-YpmpBVsc78lp/355wdkY3Osiw2A=
-  dependencies:
-    camelcase "^4.1.0"
-    cliui "^3.2.0"
-    decamelize "^1.1.1"
-    get-caller-file "^1.0.1"
-    os-locale "^2.0.0"
-    read-pkg-up "^2.0.0"
-    require-directory "^2.1.1"
-    require-main-filename "^1.0.1"
-    set-blocking "^2.0.0"
-    string-width "^2.0.0"
-    which-module "^2.0.0"
-    y18n "^3.2.1"
-    yargs-parser "^7.0.0"